Skip to content

Commit 15e1c08

Browse files
committed
feat: added netlify function for saving locators interactions
1 parent b898b82 commit 15e1c08

File tree

4 files changed

+172
-4
lines changed

4 files changed

+172
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { Handler } from "@netlify/functions";
2+
import { Response } from "@netlify/functions/dist/function/response";
3+
import Airtable from "airtable";
4+
import invariant from "tiny-invariant";
5+
6+
const saveLocatorsInteraction = async (
7+
type: "generate" | "copy",
8+
amount: number,
9+
stateTime: number
10+
) => {
11+
const { AIRTABLE_API_KEY, AIRTABLE_BASE, AIRTABLE_LOCATORS_TABLE } =
12+
process.env;
13+
14+
invariant(AIRTABLE_API_KEY, "Airtable API key is not defined.");
15+
invariant(AIRTABLE_BASE, "Airtable base is not defined.");
16+
invariant(AIRTABLE_LOCATORS_TABLE, "Airtable table id is not defined.");
17+
18+
Airtable.configure({
19+
apiKey: AIRTABLE_API_KEY,
20+
endpointUrl: "https://api.airtable.com",
21+
});
22+
const base = Airtable.base(AIRTABLE_BASE);
23+
24+
return new Promise((resolve, reject) => {
25+
base(AIRTABLE_LOCATORS_TABLE).create(
26+
{
27+
action_type: type,
28+
locators_number: amount,
29+
state_time: stateTime,
30+
created_at: new Date().toISOString(),
31+
},
32+
(err) => {
33+
if (err) {
34+
reject(err);
35+
}
36+
resolve(true);
37+
}
38+
);
39+
});
40+
};
41+
42+
const headers = {
43+
"Access-Control-Allow-Origin": "*",
44+
"Access-Control-Allow-Headers": "Content-Type",
45+
"Access-Control-Allow-Methods": "POST, OPTIONS",
46+
};
47+
48+
const handler: Handler = async (event, _context) => {
49+
const response: Response = {
50+
statusCode: 200,
51+
headers,
52+
};
53+
54+
switch (event.httpMethod) {
55+
case "POST":
56+
if (!event.body) {
57+
response.statusCode = 400;
58+
response.body = JSON.stringify({ message: "A JSON body is required." });
59+
} else {
60+
const { type, locators, stateTime } = JSON.parse(event.body);
61+
try {
62+
if (process.env.NODE_ENV === "production") {
63+
await saveLocatorsInteraction(type, locators, stateTime);
64+
}
65+
response.body = "OK";
66+
} catch (e) {
67+
const { message } = e as Error;
68+
response.statusCode = 500;
69+
response.body = JSON.stringify({ message });
70+
}
71+
}
72+
break;
73+
case "OPTIONS":
74+
response.body = JSON.stringify({ message: "Successful preflight call." });
75+
break;
76+
default:
77+
response.statusCode = 405;
78+
break;
79+
}
80+
81+
return response;
82+
};
83+
84+
export { handler };

package.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,22 @@
66
"dev": "vite",
77
"build": "tsc && vite build",
88
"preview": "vite preview",
9-
"release": "npx standard-version"
9+
"release": "npx standard-version",
10+
"functions": "npx env-cmd -f ./.env.local netlify functions:serve"
1011
},
1112
"dependencies": {
1213
"@emotion/react": "^11.9.3",
1314
"@mantine/core": "5.0.0",
1415
"@mantine/hooks": "5.0.0",
1516
"@mantine/notifications": "^5.0.0",
17+
"@netlify/functions": "^1.0.0",
1618
"@tabler/icons": "^1.78.1",
19+
"airtable": "^0.11.4",
1720
"random": "^3.0.6",
1821
"react": "^18.2.0",
1922
"react-dom": "^18.2.0",
20-
"react-router-dom": "^6.3.0"
23+
"react-router-dom": "^6.3.0",
24+
"tiny-invariant": "^1.2.0"
2125
},
2226
"devDependencies": {
2327
"@types/node": "^18.6.3",

tsconfig.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"lib": ["DOM", "DOM.Iterable", "ESNext"],
66
"allowJs": false,
77
"skipLibCheck": true,
8-
"esModuleInterop": false,
8+
"esModuleInterop": true,
99
"allowSyntheticDefaultImports": true,
1010
"strict": true,
1111
"forceConsistentCasingInFileNames": true,
@@ -16,6 +16,6 @@
1616
"noEmit": true,
1717
"jsx": "react-jsx"
1818
},
19-
"include": ["src"],
19+
"include": ["src", "netlify/functions"],
2020
"references": [{ "path": "./tsconfig.node.json" }]
2121
}

yarn.lock

+80
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,13 @@
442442
resolved "https://registry.yarnpkg.com/@mantine/utils/-/utils-5.0.0.tgz#576ebab6b0980b996ecb70b277f4ea378dcfb474"
443443
integrity sha512-Fy9BdxWvrXkplWua8ZKmsBQODo24QB8OPn6BEmvXUt4O+3qoP27VaAWQVea4opWZsy+L5dtEe/kOXY/Q/kC2qg==
444444

445+
"@netlify/functions@^1.0.0":
446+
version "1.0.0"
447+
resolved "https://registry.yarnpkg.com/@netlify/functions/-/functions-1.0.0.tgz#5b6c02fafc567033c93b15a080cc021e5f10f254"
448+
integrity sha512-7fnJv3vr8uyyyOYPChwoec6MjzsCw1CoRUO2DhQ1BD6bOyJRlD4DUaOOGlMILB2LCT8P24p5LexEGx8AJb7xdA==
449+
dependencies:
450+
is-promise "^4.0.0"
451+
445452
"@radix-ui/[email protected]":
446453
version "1.0.0"
447454
resolved "https://registry.yarnpkg.com/@radix-ui/number/-/number-1.0.0.tgz#4c536161d0de750b3f5d55860fc3de46264f897b"
@@ -537,6 +544,11 @@
537544
resolved "https://registry.yarnpkg.com/@tabler/icons/-/icons-1.78.1.tgz#7577c1b22c736cec43718e512c89b4452c926e99"
538545
integrity sha512-QT/94Hufvzn4PxsEyN9NTh96XmNaGGgMh7sKcBZ2216pE9B+Ala98KpdNwTKKBlEvRvHw9y14zW4qFYzxGOhZw==
539546

547+
"@types/node@>=8.0.0 <15":
548+
version "14.18.23"
549+
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.23.tgz#70f5f20b0b1b38f696848c1d3647bb95694e615e"
550+
integrity sha512-MhbCWN18R4GhO8ewQWAFK4TGQdBpXWByukz7cWyJmXhvRuCIaM/oWytGPqVmDzgEnnaIc9ss6HbU5mUi+vyZPA==
551+
540552
"@types/node@^18.6.3":
541553
version "18.6.3"
542554
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.6.3.tgz#4e4a95b6fe44014563ceb514b2598b3e623d1c98"
@@ -595,6 +607,29 @@
595607
magic-string "^0.26.2"
596608
react-refresh "^0.14.0"
597609

610+
abort-controller@^3.0.0:
611+
version "3.0.0"
612+
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
613+
integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
614+
dependencies:
615+
event-target-shim "^5.0.0"
616+
617+
abortcontroller-polyfill@^1.4.0:
618+
version "1.7.3"
619+
resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz#1b5b487bd6436b5b764fd52a612509702c3144b5"
620+
integrity sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q==
621+
622+
airtable@^0.11.4:
623+
version "0.11.4"
624+
resolved "https://registry.yarnpkg.com/airtable/-/airtable-0.11.4.tgz#1f8bef44c82a185f05655fc5e9c9563b1ee775ec"
625+
integrity sha512-y8sEi/sMEdgtgvv0V8AhJyFQB9za+6qGIxllt60Ey5ELBgu+bNEc1hjY2aqzp9C38p0ORfaeRS5RSFWlcq11Aw==
626+
dependencies:
627+
"@types/node" ">=8.0.0 <15"
628+
abort-controller "^3.0.0"
629+
abortcontroller-polyfill "^1.4.0"
630+
lodash "^4.17.21"
631+
node-fetch "^2.6.7"
632+
598633
ansi-styles@^3.2.1:
599634
version "3.2.1"
600635
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
@@ -861,6 +896,11 @@ escape-string-regexp@^4.0.0:
861896
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
862897
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
863898

899+
event-target-shim@^5.0.0:
900+
version "5.0.1"
901+
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
902+
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
903+
864904
find-root@^1.1.0:
865905
version "1.1.0"
866906
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
@@ -932,6 +972,11 @@ is-core-module@^2.9.0:
932972
dependencies:
933973
has "^1.0.3"
934974

975+
is-promise@^4.0.0:
976+
version "4.0.0"
977+
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3"
978+
integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==
979+
935980
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
936981
version "4.0.0"
937982
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@@ -957,6 +1002,11 @@ lines-and-columns@^1.1.6:
9571002
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
9581003
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
9591004

1005+
lodash@^4.17.21:
1006+
version "4.17.21"
1007+
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
1008+
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
1009+
9601010
loose-envify@^1.1.0, loose-envify@^1.4.0:
9611011
version "1.4.0"
9621012
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
@@ -981,6 +1031,13 @@ nanoid@^3.3.4:
9811031
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
9821032
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
9831033

1034+
node-fetch@^2.6.7:
1035+
version "2.6.7"
1036+
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
1037+
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
1038+
dependencies:
1039+
whatwg-url "^5.0.0"
1040+
9841041
node-releases@^2.0.3:
9851042
version "2.0.5"
9861043
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.5.tgz#280ed5bc3eba0d96ce44897d8aee478bfb3d9666"
@@ -1187,11 +1244,21 @@ supports-preserve-symlinks-flag@^1.0.0:
11871244
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
11881245
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
11891246

1247+
tiny-invariant@^1.2.0:
1248+
version "1.2.0"
1249+
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.2.0.tgz#a1141f86b672a9148c72e978a19a73b9b94a15a9"
1250+
integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==
1251+
11901252
to-fast-properties@^2.0.0:
11911253
version "2.0.0"
11921254
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
11931255
integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
11941256

1257+
tr46@~0.0.3:
1258+
version "0.0.3"
1259+
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
1260+
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
1261+
11951262
tslib@^1.0.0:
11961263
version "1.14.1"
11971264
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
@@ -1231,6 +1298,19 @@ vite@^3.0.2:
12311298
optionalDependencies:
12321299
fsevents "~2.3.2"
12331300

1301+
webidl-conversions@^3.0.0:
1302+
version "3.0.1"
1303+
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
1304+
integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
1305+
1306+
whatwg-url@^5.0.0:
1307+
version "5.0.0"
1308+
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
1309+
integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
1310+
dependencies:
1311+
tr46 "~0.0.3"
1312+
webidl-conversions "^3.0.0"
1313+
12341314
yaml@^1.7.2:
12351315
version "1.10.2"
12361316
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"

0 commit comments

Comments
 (0)