From cbd8de6de63a131bb47ee9f6fc4c9da73b51134f Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Tue, 5 Nov 2024 16:28:23 -0500 Subject: [PATCH 1/9] Adding type declarations and definitions for migration to ts --- shopify/product-quiz-template/.ignore | 3 +- .../api/actions/scheduledShopifySync.js | 29 - .../api/models/answer/actions/create.js | 28 - .../api/models/answer/actions/create.ts | 23 + .../answer/actions/{delete.js => delete.ts} | 25 +- .../api/models/answer/actions/update.js | 22 - .../api/models/answer/actions/update.ts | 17 + .../api/models/question/actions/create.js | 28 - .../api/models/question/actions/create.ts | 23 + .../question/actions/{delete.js => delete.ts} | 25 +- .../api/models/question/actions/update.js | 22 - .../api/models/question/actions/update.ts | 17 + .../quiz/actions/{create.js => create.ts} | 27 +- .../quiz/actions/{delete.js => delete.ts} | 25 +- .../api/models/quiz/actions/update.js | 22 - .../api/models/quiz/actions/update.ts | 17 + .../api/models/quizResult/actions/create.js | 22 - .../api/models/quizResult/actions/create.ts | 17 + .../api/models/quizResult/actions/delete.js | 21 - .../api/models/quizResult/actions/delete.ts | 10 + .../api/models/quizResult/actions/update.js | 22 - .../api/models/quizResult/actions/update.ts | 17 + .../recommendedProduct/actions/create.js | 30 - .../recommendedProduct/actions/create.ts | 23 + .../recommendedProduct/actions/delete.js | 21 - .../recommendedProduct/actions/delete.ts | 10 + .../recommendedProduct/actions/update.js | 22 - .../recommendedProduct/actions/update.ts | 17 + .../api/models/shopifyAsset/actions/create.js | 25 - .../api/models/shopifyAsset/actions/create.ts | 34 + .../api/models/shopifyAsset/actions/delete.js | 22 - .../api/models/shopifyAsset/actions/delete.ts | 31 + .../api/models/shopifyAsset/actions/update.js | 31 - .../api/models/shopifyAsset/actions/update.ts | 34 + .../shopifyAsset/{utils.js => utils.ts} | 15 +- .../actions/{create.js => create.ts} | 23 +- .../shopifyGdprRequest/actions/update.js | 23 - .../shopifyGdprRequest/actions/update.ts | 24 + .../models/shopifyProduct/actions/create.js | 23 - .../models/shopifyProduct/actions/create.ts | 24 + .../models/shopifyProduct/actions/delete.js | 22 - .../models/shopifyProduct/actions/delete.ts | 22 + .../models/shopifyProduct/actions/update.js | 23 - .../models/shopifyProduct/actions/update.ts | 24 + .../shopifyProductImage/actions/create.js | 23 - .../shopifyProductImage/actions/create.ts | 33 + .../shopifyProductImage/actions/delete.js | 22 - .../shopifyProductImage/actions/delete.ts | 31 + .../shopifyProductImage/actions/update.js | 23 - .../shopifyProductImage/actions/update.ts | 33 + .../actions/{install.js => install.ts} | 23 +- .../models/shopifyShop/actions/reinstall.js | 24 - .../models/shopifyShop/actions/reinstall.ts | 30 + .../models/shopifyShop/actions/uninstall.js | 24 - .../models/shopifyShop/actions/uninstall.ts | 30 + .../api/models/shopifyShop/actions/update.js | 23 - .../api/models/shopifyShop/actions/update.ts | 24 + .../models/shopifySync/actions/complete.js | 24 - .../models/shopifySync/actions/complete.ts | 30 + .../api/models/shopifySync/actions/error.js | 24 - .../api/models/shopifySync/actions/error.ts | 30 + .../api/models/shopifySync/actions/run.js | 25 - .../api/models/shopifySync/actions/run.ts | 29 + .../api/models/shopifyTheme/actions/create.js | 23 - .../api/models/shopifyTheme/actions/create.ts | 33 + .../api/models/shopifyTheme/actions/delete.js | 22 - .../api/models/shopifyTheme/actions/delete.ts | 31 + .../api/models/shopifyTheme/actions/update.js | 23 - .../api/models/shopifyTheme/actions/update.ts | 33 + .../shopperSuggestion/actions/create.js | 22 - .../shopperSuggestion/actions/create.ts | 24 + .../shopperSuggestion/actions/delete.js | 21 - .../shopperSuggestion/actions/delete.ts | 22 + .../shopperSuggestion/actions/update.js | 22 - .../shopperSuggestion/actions/update.ts | 24 + .../{product-quiz.js => product-quiz.ts} | 148 +- .../extensions/quiz/blocks/quiz-page.liquid | 1 + shopify/product-quiz-template/globals.d.ts | 15 + shopify/product-quiz-template/index.html | 28 +- shopify/product-quiz-template/package.json | 9 +- shopify/product-quiz-template/tsconfig.json | 19 + .../{vite.config.mjs => vite.config.mts} | 0 .../web/{api.js => api.ts} | 0 .../components/{Answers.jsx => Answers.tsx} | 0 .../web/components/{App.jsx => App.tsx} | 13 +- .../{CodeBlock.jsx => CodeBlock.tsx} | 4 +- .../{InstallTab.jsx => InstallTab.tsx} | 19 +- .../{PageTemplate.jsx => PageTemplate.tsx} | 2 +- .../components/{QuizForm.jsx => QuizForm.tsx} | 43 +- .../{QuizzesTab.jsx => QuizzesTab.tsx} | 14 +- ...nstructions.jsx => Store1Instructions.tsx} | 16 +- .../web/components/{index.js => index.ts} | 0 .../web/{main.jsx => main.tsx} | 0 ...{CreateQuizPage.jsx => CreateQuizPage.tsx} | 21 +- .../{EditQuizPage.jsx => EditQuizPage.tsx} | 22 +- .../web/routes/{HomePage.jsx => HomePage.tsx} | 4 +- .../web/routes/{index.js => index.ts} | 0 shopify/product-quiz-template/yarn.lock | 3540 +---------------- 98 files changed, 1244 insertions(+), 4464 deletions(-) delete mode 100644 shopify/product-quiz-template/api/actions/scheduledShopifySync.js delete mode 100644 shopify/product-quiz-template/api/models/answer/actions/create.js create mode 100644 shopify/product-quiz-template/api/models/answer/actions/create.ts rename shopify/product-quiz-template/api/models/answer/actions/{delete.js => delete.ts} (56%) delete mode 100644 shopify/product-quiz-template/api/models/answer/actions/update.js create mode 100644 shopify/product-quiz-template/api/models/answer/actions/update.ts delete mode 100644 shopify/product-quiz-template/api/models/question/actions/create.js create mode 100644 shopify/product-quiz-template/api/models/question/actions/create.ts rename shopify/product-quiz-template/api/models/question/actions/{delete.js => delete.ts} (56%) delete mode 100644 shopify/product-quiz-template/api/models/question/actions/update.js create mode 100644 shopify/product-quiz-template/api/models/question/actions/update.ts rename shopify/product-quiz-template/api/models/quiz/actions/{create.js => create.ts} (58%) rename shopify/product-quiz-template/api/models/quiz/actions/{delete.js => delete.ts} (62%) delete mode 100644 shopify/product-quiz-template/api/models/quiz/actions/update.js create mode 100644 shopify/product-quiz-template/api/models/quiz/actions/update.ts delete mode 100644 shopify/product-quiz-template/api/models/quizResult/actions/create.js create mode 100644 shopify/product-quiz-template/api/models/quizResult/actions/create.ts delete mode 100644 shopify/product-quiz-template/api/models/quizResult/actions/delete.js create mode 100644 shopify/product-quiz-template/api/models/quizResult/actions/delete.ts delete mode 100644 shopify/product-quiz-template/api/models/quizResult/actions/update.js create mode 100644 shopify/product-quiz-template/api/models/quizResult/actions/update.ts delete mode 100755 shopify/product-quiz-template/api/models/recommendedProduct/actions/create.js create mode 100755 shopify/product-quiz-template/api/models/recommendedProduct/actions/create.ts delete mode 100644 shopify/product-quiz-template/api/models/recommendedProduct/actions/delete.js create mode 100644 shopify/product-quiz-template/api/models/recommendedProduct/actions/delete.ts delete mode 100644 shopify/product-quiz-template/api/models/recommendedProduct/actions/update.js create mode 100644 shopify/product-quiz-template/api/models/recommendedProduct/actions/update.ts delete mode 100644 shopify/product-quiz-template/api/models/shopifyAsset/actions/create.js create mode 100644 shopify/product-quiz-template/api/models/shopifyAsset/actions/create.ts delete mode 100644 shopify/product-quiz-template/api/models/shopifyAsset/actions/delete.js create mode 100644 shopify/product-quiz-template/api/models/shopifyAsset/actions/delete.ts delete mode 100644 shopify/product-quiz-template/api/models/shopifyAsset/actions/update.js create mode 100644 shopify/product-quiz-template/api/models/shopifyAsset/actions/update.ts rename shopify/product-quiz-template/api/models/shopifyAsset/{utils.js => utils.ts} (66%) rename shopify/product-quiz-template/api/models/shopifyGdprRequest/actions/{create.js => create.ts} (78%) delete mode 100644 shopify/product-quiz-template/api/models/shopifyGdprRequest/actions/update.js create mode 100644 shopify/product-quiz-template/api/models/shopifyGdprRequest/actions/update.ts delete mode 100644 shopify/product-quiz-template/api/models/shopifyProduct/actions/create.js create mode 100644 shopify/product-quiz-template/api/models/shopifyProduct/actions/create.ts delete mode 100644 shopify/product-quiz-template/api/models/shopifyProduct/actions/delete.js create mode 100644 shopify/product-quiz-template/api/models/shopifyProduct/actions/delete.ts delete mode 100644 shopify/product-quiz-template/api/models/shopifyProduct/actions/update.js create mode 100644 shopify/product-quiz-template/api/models/shopifyProduct/actions/update.ts delete mode 100644 shopify/product-quiz-template/api/models/shopifyProductImage/actions/create.js create mode 100644 shopify/product-quiz-template/api/models/shopifyProductImage/actions/create.ts delete mode 100644 shopify/product-quiz-template/api/models/shopifyProductImage/actions/delete.js create mode 100644 shopify/product-quiz-template/api/models/shopifyProductImage/actions/delete.ts delete mode 100644 shopify/product-quiz-template/api/models/shopifyProductImage/actions/update.js create mode 100644 shopify/product-quiz-template/api/models/shopifyProductImage/actions/update.ts rename shopify/product-quiz-template/api/models/shopifyShop/actions/{install.js => install.ts} (63%) delete mode 100644 shopify/product-quiz-template/api/models/shopifyShop/actions/reinstall.js create mode 100644 shopify/product-quiz-template/api/models/shopifyShop/actions/reinstall.ts delete mode 100644 shopify/product-quiz-template/api/models/shopifyShop/actions/uninstall.js create mode 100644 shopify/product-quiz-template/api/models/shopifyShop/actions/uninstall.ts delete mode 100644 shopify/product-quiz-template/api/models/shopifyShop/actions/update.js create mode 100644 shopify/product-quiz-template/api/models/shopifyShop/actions/update.ts delete mode 100644 shopify/product-quiz-template/api/models/shopifySync/actions/complete.js create mode 100644 shopify/product-quiz-template/api/models/shopifySync/actions/complete.ts delete mode 100644 shopify/product-quiz-template/api/models/shopifySync/actions/error.js create mode 100644 shopify/product-quiz-template/api/models/shopifySync/actions/error.ts delete mode 100644 shopify/product-quiz-template/api/models/shopifySync/actions/run.js create mode 100644 shopify/product-quiz-template/api/models/shopifySync/actions/run.ts delete mode 100644 shopify/product-quiz-template/api/models/shopifyTheme/actions/create.js create mode 100644 shopify/product-quiz-template/api/models/shopifyTheme/actions/create.ts delete mode 100644 shopify/product-quiz-template/api/models/shopifyTheme/actions/delete.js create mode 100644 shopify/product-quiz-template/api/models/shopifyTheme/actions/delete.ts delete mode 100644 shopify/product-quiz-template/api/models/shopifyTheme/actions/update.js create mode 100644 shopify/product-quiz-template/api/models/shopifyTheme/actions/update.ts delete mode 100644 shopify/product-quiz-template/api/models/shopperSuggestion/actions/create.js create mode 100644 shopify/product-quiz-template/api/models/shopperSuggestion/actions/create.ts delete mode 100644 shopify/product-quiz-template/api/models/shopperSuggestion/actions/delete.js create mode 100644 shopify/product-quiz-template/api/models/shopperSuggestion/actions/delete.ts delete mode 100644 shopify/product-quiz-template/api/models/shopperSuggestion/actions/update.js create mode 100644 shopify/product-quiz-template/api/models/shopperSuggestion/actions/update.ts rename shopify/product-quiz-template/extensions/quiz/assets/{product-quiz.js => product-quiz.ts} (53%) create mode 100644 shopify/product-quiz-template/globals.d.ts create mode 100755 shopify/product-quiz-template/tsconfig.json rename shopify/product-quiz-template/{vite.config.mjs => vite.config.mts} (100%) rename shopify/product-quiz-template/web/{api.js => api.ts} (100%) rename shopify/product-quiz-template/web/components/{Answers.jsx => Answers.tsx} (100%) rename shopify/product-quiz-template/web/components/{App.jsx => App.tsx} (88%) rename shopify/product-quiz-template/web/components/{CodeBlock.jsx => CodeBlock.tsx} (81%) rename shopify/product-quiz-template/web/components/{InstallTab.jsx => InstallTab.tsx} (74%) rename shopify/product-quiz-template/web/components/{PageTemplate.jsx => PageTemplate.tsx} (76%) rename shopify/product-quiz-template/web/components/{QuizForm.jsx => QuizForm.tsx} (77%) rename shopify/product-quiz-template/web/components/{QuizzesTab.jsx => QuizzesTab.tsx} (90%) rename shopify/product-quiz-template/web/components/{Store1Instructions.jsx => Store1Instructions.tsx} (86%) rename shopify/product-quiz-template/web/components/{index.js => index.ts} (100%) rename shopify/product-quiz-template/web/{main.jsx => main.tsx} (100%) rename shopify/product-quiz-template/web/routes/{CreateQuizPage.jsx => CreateQuizPage.tsx} (76%) rename shopify/product-quiz-template/web/routes/{EditQuizPage.jsx => EditQuizPage.tsx} (80%) rename shopify/product-quiz-template/web/routes/{HomePage.jsx => HomePage.tsx} (88%) rename shopify/product-quiz-template/web/routes/{index.js => index.ts} (100%) diff --git a/shopify/product-quiz-template/.ignore b/shopify/product-quiz-template/.ignore index 683d8a6a..eedba7f6 100644 --- a/shopify/product-quiz-template/.ignore +++ b/shopify/product-quiz-template/.ignore @@ -1,3 +1,2 @@ # Shopify -extensions/**/dist -shopify.app.**.toml \ No newline at end of file +extensions/**/dist \ No newline at end of file diff --git a/shopify/product-quiz-template/api/actions/scheduledShopifySync.js b/shopify/product-quiz-template/api/actions/scheduledShopifySync.js deleted file mode 100644 index 4347ebea..00000000 --- a/shopify/product-quiz-template/api/actions/scheduledShopifySync.js +++ /dev/null @@ -1,29 +0,0 @@ -import { globalShopifySync, ScheduledShopifySyncGlobalActionContext } from "gadget-server"; - -const HourInMs = 60 * 60 * 1000; - -/** - * @param { ScheduledShopifySyncGlobalActionContext } context - */ -export async function run({ params, logger, api, connections }) { - const syncOnlyModels = connections.shopify.enabledModels - .filter(model => model.syncOnly) - .map(model => model.apiIdentifier); - - const syncSince = new Date(Date.now() - 25 * HourInMs) - - await globalShopifySync({ - apiKeys: connections.shopify.apiKeys, - syncSince, - models: syncOnlyModels - }); -}; - -export const options = { - triggers: { - api: false, - scheduler: [ - { every: "day", at: "08:21 UTC" }, - ], - }, -} \ No newline at end of file diff --git a/shopify/product-quiz-template/api/models/answer/actions/create.js b/shopify/product-quiz-template/api/models/answer/actions/create.js deleted file mode 100644 index 33cb60bd..00000000 --- a/shopify/product-quiz-template/api/models/answer/actions/create.js +++ /dev/null @@ -1,28 +0,0 @@ -import { - applyParams, - save, - ActionOptions, - CreateAnswerActionContext, -} from "gadget-server"; - -/** - * @param { CreateAnswerActionContext } context - */ -export async function run({ params, record, connections, logger, api }) { - applyParams(params, record); - - record.shop = { _link: connections.shopify.currentShopId }; - - await save(record); -} - -/** - * @param { CreateAnswerActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) {} - -/** @type { ActionOptions } */ -export const options = { - actionType: "create", - triggers: { api: true }, -}; diff --git a/shopify/product-quiz-template/api/models/answer/actions/create.ts b/shopify/product-quiz-template/api/models/answer/actions/create.ts new file mode 100644 index 00000000..41390cf2 --- /dev/null +++ b/shopify/product-quiz-template/api/models/answer/actions/create.ts @@ -0,0 +1,23 @@ +import { + applyParams, + save, + ActionOptions, + preventCrossShopDataAccess, +} from "gadget-server"; + +export const run: ActionRun = async ({ + params, + record, + connections, + logger, + api, +}) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const options: ActionOptions = { + actionType: "create", + triggers: { api: true }, +}; diff --git a/shopify/product-quiz-template/api/models/answer/actions/delete.js b/shopify/product-quiz-template/api/models/answer/actions/delete.ts similarity index 56% rename from shopify/product-quiz-template/api/models/answer/actions/delete.js rename to shopify/product-quiz-template/api/models/answer/actions/delete.ts index fcacd92c..b6c61ea3 100644 --- a/shopify/product-quiz-template/api/models/answer/actions/delete.js +++ b/shopify/product-quiz-template/api/models/answer/actions/delete.ts @@ -1,20 +1,20 @@ import { deleteRecord, ActionOptions, - DeleteAnswerActionContext, + preventCrossShopDataAccess, } from "gadget-server"; -/** - * @param { DeleteAnswerActionContext } context - */ -export async function run({ params, record, logger, api }) { +export const run: ActionRun = async ({ params, record, logger, api }) => { + await preventCrossShopDataAccess(params, record); await deleteRecord(record); -} +}; -/** - * @param { DeleteAnswerActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => { // clean up recommended product const recommendation = await api.recommendedProduct.findFirst({ filter: { @@ -28,10 +28,9 @@ export async function onSuccess({ params, record, logger, api }) { }); await api.recommendedProduct.delete(recommendation.id); -} +}; -/** @type { ActionOptions } */ -export const options = { +export const options: ActionOptions = { actionType: "delete", triggers: { api: true }, }; diff --git a/shopify/product-quiz-template/api/models/answer/actions/update.js b/shopify/product-quiz-template/api/models/answer/actions/update.js deleted file mode 100644 index 2136829b..00000000 --- a/shopify/product-quiz-template/api/models/answer/actions/update.js +++ /dev/null @@ -1,22 +0,0 @@ -import { applyParams, save, UpdateAnswerActionContext } from "gadget-server"; - -/** - * @param { UpdateAnswerActionContext } context - */ -export async function run({ params, record, logger, api }) { - applyParams(params, record); - await save(record); -}; - -/** - * @param { UpdateAnswerActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "update", - triggers: { api: true }, -}; \ No newline at end of file diff --git a/shopify/product-quiz-template/api/models/answer/actions/update.ts b/shopify/product-quiz-template/api/models/answer/actions/update.ts new file mode 100644 index 00000000..8f978557 --- /dev/null +++ b/shopify/product-quiz-template/api/models/answer/actions/update.ts @@ -0,0 +1,17 @@ +import { + ActionOptions, + applyParams, + preventCrossShopDataAccess, + save, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const options: ActionOptions = { + actionType: "update", + triggers: { api: true }, +}; diff --git a/shopify/product-quiz-template/api/models/question/actions/create.js b/shopify/product-quiz-template/api/models/question/actions/create.js deleted file mode 100644 index 392299de..00000000 --- a/shopify/product-quiz-template/api/models/question/actions/create.js +++ /dev/null @@ -1,28 +0,0 @@ -import { - applyParams, - save, - ActionOptions, - CreateQuestionActionContext, -} from "gadget-server"; - -/** - * @param { CreateQuestionActionContext } context - */ -export async function run({ params, record, connections, logger, api }) { - applyParams(params, record); - - record.shop = { _link: connections.shopify.currentShopId }; - - await save(record); -} - -/** - * @param { CreateQuestionActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) {} - -/** @type { ActionOptions } */ -export const options = { - actionType: "create", - triggers: { api: true }, -}; diff --git a/shopify/product-quiz-template/api/models/question/actions/create.ts b/shopify/product-quiz-template/api/models/question/actions/create.ts new file mode 100644 index 00000000..41390cf2 --- /dev/null +++ b/shopify/product-quiz-template/api/models/question/actions/create.ts @@ -0,0 +1,23 @@ +import { + applyParams, + save, + ActionOptions, + preventCrossShopDataAccess, +} from "gadget-server"; + +export const run: ActionRun = async ({ + params, + record, + connections, + logger, + api, +}) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const options: ActionOptions = { + actionType: "create", + triggers: { api: true }, +}; diff --git a/shopify/product-quiz-template/api/models/question/actions/delete.js b/shopify/product-quiz-template/api/models/question/actions/delete.ts similarity index 56% rename from shopify/product-quiz-template/api/models/question/actions/delete.js rename to shopify/product-quiz-template/api/models/question/actions/delete.ts index a6d6d143..274df480 100644 --- a/shopify/product-quiz-template/api/models/question/actions/delete.js +++ b/shopify/product-quiz-template/api/models/question/actions/delete.ts @@ -1,20 +1,20 @@ import { deleteRecord, ActionOptions, - DeleteQuestionActionContext, + preventCrossShopDataAccess, } from "gadget-server"; -/** - * @param { DeleteQuestionActionContext } context - */ -export async function run({ params, record, logger, api }) { +export const run: ActionRun = async ({ params, record, logger, api }) => { + await preventCrossShopDataAccess(params, record); await deleteRecord(record); -} +}; -/** - * @param { DeleteQuestionActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => { // clean up quiz answers const answers = await api.answer.findMany({ filter: { @@ -29,10 +29,9 @@ export async function onSuccess({ params, record, logger, api }) { const ids = answers.map((answer) => answer.id); await api.answer.bulkDelete(ids); -} +}; -/** @type { ActionOptions } */ -export const options = { +export const options: ActionOptions = { actionType: "delete", triggers: { api: true }, }; diff --git a/shopify/product-quiz-template/api/models/question/actions/update.js b/shopify/product-quiz-template/api/models/question/actions/update.js deleted file mode 100644 index 2f15c6a0..00000000 --- a/shopify/product-quiz-template/api/models/question/actions/update.js +++ /dev/null @@ -1,22 +0,0 @@ -import { applyParams, save, UpdateQuestionActionContext } from "gadget-server"; - -/** - * @param { UpdateQuestionActionContext } context - */ -export async function run({ params, record, logger, api }) { - applyParams(params, record); - await save(record); -}; - -/** - * @param { UpdateQuestionActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "update", - triggers: { api: true }, -}; \ No newline at end of file diff --git a/shopify/product-quiz-template/api/models/question/actions/update.ts b/shopify/product-quiz-template/api/models/question/actions/update.ts new file mode 100644 index 00000000..8f978557 --- /dev/null +++ b/shopify/product-quiz-template/api/models/question/actions/update.ts @@ -0,0 +1,17 @@ +import { + ActionOptions, + applyParams, + preventCrossShopDataAccess, + save, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const options: ActionOptions = { + actionType: "update", + triggers: { api: true }, +}; diff --git a/shopify/product-quiz-template/api/models/quiz/actions/create.js b/shopify/product-quiz-template/api/models/quiz/actions/create.ts similarity index 58% rename from shopify/product-quiz-template/api/models/quiz/actions/create.js rename to shopify/product-quiz-template/api/models/quiz/actions/create.ts index 53461b3d..caa5c72f 100644 --- a/shopify/product-quiz-template/api/models/quiz/actions/create.js +++ b/shopify/product-quiz-template/api/models/quiz/actions/create.ts @@ -2,22 +2,25 @@ import { applyParams, save, ActionOptions, - CreateQuizActionContext, + preventCrossShopDataAccess, } from "gadget-server"; -/** - * @param { CreateQuizActionContext } context - */ -export async function run({ params, record, connections, logger, api }) { +export const run: ActionRun = async ({ + params, + record, + connections, + logger, + api, +}) => { applyParams(params, record); + await preventCrossShopDataAccess(params, record); record.slug = generateSlug(record.title); - record.shop = { _link: connections.shopify.currentShopId }; await save(record); -} +}; -function generateSlug(input) { +function generateSlug(input: string) { return ( input // Convert to lowercase @@ -33,13 +36,7 @@ function generateSlug(input) { ); } -/** - * @param { CreateQuizActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) {} - -/** @type { ActionOptions } */ -export const options = { +export const options: ActionOptions = { actionType: "create", triggers: { api: true }, }; diff --git a/shopify/product-quiz-template/api/models/quiz/actions/delete.js b/shopify/product-quiz-template/api/models/quiz/actions/delete.ts similarity index 62% rename from shopify/product-quiz-template/api/models/quiz/actions/delete.js rename to shopify/product-quiz-template/api/models/quiz/actions/delete.ts index 3c8699fe..1f4d7134 100644 --- a/shopify/product-quiz-template/api/models/quiz/actions/delete.js +++ b/shopify/product-quiz-template/api/models/quiz/actions/delete.ts @@ -1,20 +1,20 @@ import { deleteRecord, ActionOptions, - DeleteQuizActionContext, + preventCrossShopDataAccess, } from "gadget-server"; -/** - * @param { DeleteQuizActionContext } context - */ -export async function run({ params, record, logger, api }) { +export const run: ActionRun = async ({ params, record, logger, api }) => { + await preventCrossShopDataAccess(params, record); await deleteRecord(record); -} +}; -/** - * @param { DeleteQuizActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => { // clean up quiz questions // on an update, remove old questions and answers and refresh quiz with new options const quizQuestions = await api.question.findMany({ @@ -30,10 +30,9 @@ export async function onSuccess({ params, record, logger, api }) { const ids = quizQuestions.map((question) => question.id); await api.question.bulkDelete(ids); -} +}; -/** @type { ActionOptions } */ -export const options = { +export const options: ActionOptions = { actionType: "delete", triggers: { api: true }, }; diff --git a/shopify/product-quiz-template/api/models/quiz/actions/update.js b/shopify/product-quiz-template/api/models/quiz/actions/update.js deleted file mode 100644 index d12ba28d..00000000 --- a/shopify/product-quiz-template/api/models/quiz/actions/update.js +++ /dev/null @@ -1,22 +0,0 @@ -import { applyParams, save, UpdateQuizActionContext } from "gadget-server"; - -/** - * @param { UpdateQuizActionContext } context - */ -export async function run({ params, record, logger, api }) { - applyParams(params, record); - await save(record); -}; - -/** - * @param { UpdateQuizActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "update", - triggers: { api: true }, -}; \ No newline at end of file diff --git a/shopify/product-quiz-template/api/models/quiz/actions/update.ts b/shopify/product-quiz-template/api/models/quiz/actions/update.ts new file mode 100644 index 00000000..8f978557 --- /dev/null +++ b/shopify/product-quiz-template/api/models/quiz/actions/update.ts @@ -0,0 +1,17 @@ +import { + ActionOptions, + applyParams, + preventCrossShopDataAccess, + save, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const options: ActionOptions = { + actionType: "update", + triggers: { api: true }, +}; diff --git a/shopify/product-quiz-template/api/models/quizResult/actions/create.js b/shopify/product-quiz-template/api/models/quizResult/actions/create.js deleted file mode 100644 index 10982414..00000000 --- a/shopify/product-quiz-template/api/models/quizResult/actions/create.js +++ /dev/null @@ -1,22 +0,0 @@ -import { applyParams, save, ActionOptions, CreateQuizResultActionContext } from "gadget-server"; - -/** - * @param { CreateQuizResultActionContext } context - */ -export async function run({ params, record, logger, api }) { - applyParams(params, record); - await save(record); -}; - -/** - * @param { CreateQuizResultActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "create", - triggers: { api: true }, -}; diff --git a/shopify/product-quiz-template/api/models/quizResult/actions/create.ts b/shopify/product-quiz-template/api/models/quizResult/actions/create.ts new file mode 100644 index 00000000..e8ef3c31 --- /dev/null +++ b/shopify/product-quiz-template/api/models/quizResult/actions/create.ts @@ -0,0 +1,17 @@ +import { + applyParams, + save, + ActionOptions, + preventCrossShopDataAccess, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const options: ActionOptions = { + actionType: "create", + triggers: { api: true }, +}; diff --git a/shopify/product-quiz-template/api/models/quizResult/actions/delete.js b/shopify/product-quiz-template/api/models/quizResult/actions/delete.js deleted file mode 100644 index de5410be..00000000 --- a/shopify/product-quiz-template/api/models/quizResult/actions/delete.js +++ /dev/null @@ -1,21 +0,0 @@ -import { deleteRecord, ActionOptions, DeleteQuizResultActionContext } from "gadget-server"; - -/** - * @param { DeleteQuizResultActionContext } context - */ -export async function run({ params, record, logger, api }) { - await deleteRecord(record); -}; - -/** - * @param { DeleteQuizResultActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "delete", - triggers: { api: true }, -}; diff --git a/shopify/product-quiz-template/api/models/quizResult/actions/delete.ts b/shopify/product-quiz-template/api/models/quizResult/actions/delete.ts new file mode 100644 index 00000000..53ad109e --- /dev/null +++ b/shopify/product-quiz-template/api/models/quizResult/actions/delete.ts @@ -0,0 +1,10 @@ +import { deleteRecord, ActionOptions } from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + await deleteRecord(record); +}; + +export const options: ActionOptions = { + actionType: "delete", + triggers: { api: true }, +}; diff --git a/shopify/product-quiz-template/api/models/quizResult/actions/update.js b/shopify/product-quiz-template/api/models/quizResult/actions/update.js deleted file mode 100644 index 97c2fedc..00000000 --- a/shopify/product-quiz-template/api/models/quizResult/actions/update.js +++ /dev/null @@ -1,22 +0,0 @@ -import { applyParams, save, UpdateQuizResultActionContext } from "gadget-server"; - -/** - * @param { UpdateQuizResultActionContext } context - */ -export async function run({ params, record, logger, api }) { - applyParams(params, record); - await save(record); -}; - -/** - * @param { UpdateQuizResultActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "update", - triggers: { api: true }, -}; \ No newline at end of file diff --git a/shopify/product-quiz-template/api/models/quizResult/actions/update.ts b/shopify/product-quiz-template/api/models/quizResult/actions/update.ts new file mode 100644 index 00000000..8f978557 --- /dev/null +++ b/shopify/product-quiz-template/api/models/quizResult/actions/update.ts @@ -0,0 +1,17 @@ +import { + ActionOptions, + applyParams, + preventCrossShopDataAccess, + save, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const options: ActionOptions = { + actionType: "update", + triggers: { api: true }, +}; diff --git a/shopify/product-quiz-template/api/models/recommendedProduct/actions/create.js b/shopify/product-quiz-template/api/models/recommendedProduct/actions/create.js deleted file mode 100755 index 76795bb5..00000000 --- a/shopify/product-quiz-template/api/models/recommendedProduct/actions/create.js +++ /dev/null @@ -1,30 +0,0 @@ -import { - applyParams, - save, - ActionOptions, - CreateRecommendedProductActionContext, -} from "gadget-server"; - -/** - * @param { CreateRecommendedProductActionContext } context - */ -export async function run({ params, record, connections, logger, api }) { - applyParams(params, record); - - record.shop = { _link: connections.shopify.currentShopId }; - - await save(record); -} - -/** - * @param { CreateRecommendedProductActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - // Your logic here -} - -/** @type { ActionOptions } */ -export const options = { - actionType: "create", - triggers: { api: true }, -}; diff --git a/shopify/product-quiz-template/api/models/recommendedProduct/actions/create.ts b/shopify/product-quiz-template/api/models/recommendedProduct/actions/create.ts new file mode 100755 index 00000000..41390cf2 --- /dev/null +++ b/shopify/product-quiz-template/api/models/recommendedProduct/actions/create.ts @@ -0,0 +1,23 @@ +import { + applyParams, + save, + ActionOptions, + preventCrossShopDataAccess, +} from "gadget-server"; + +export const run: ActionRun = async ({ + params, + record, + connections, + logger, + api, +}) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const options: ActionOptions = { + actionType: "create", + triggers: { api: true }, +}; diff --git a/shopify/product-quiz-template/api/models/recommendedProduct/actions/delete.js b/shopify/product-quiz-template/api/models/recommendedProduct/actions/delete.js deleted file mode 100644 index c726ed17..00000000 --- a/shopify/product-quiz-template/api/models/recommendedProduct/actions/delete.js +++ /dev/null @@ -1,21 +0,0 @@ -import { deleteRecord, ActionOptions, DeleteRecommendedProductActionContext } from "gadget-server"; - -/** - * @param { DeleteRecommendedProductActionContext } context - */ -export async function run({ params, record, logger, api }) { - await deleteRecord(record); -}; - -/** - * @param { DeleteRecommendedProductActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "delete", - triggers: { api: true }, -}; diff --git a/shopify/product-quiz-template/api/models/recommendedProduct/actions/delete.ts b/shopify/product-quiz-template/api/models/recommendedProduct/actions/delete.ts new file mode 100644 index 00000000..53ad109e --- /dev/null +++ b/shopify/product-quiz-template/api/models/recommendedProduct/actions/delete.ts @@ -0,0 +1,10 @@ +import { deleteRecord, ActionOptions } from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + await deleteRecord(record); +}; + +export const options: ActionOptions = { + actionType: "delete", + triggers: { api: true }, +}; diff --git a/shopify/product-quiz-template/api/models/recommendedProduct/actions/update.js b/shopify/product-quiz-template/api/models/recommendedProduct/actions/update.js deleted file mode 100644 index 74ef2fdd..00000000 --- a/shopify/product-quiz-template/api/models/recommendedProduct/actions/update.js +++ /dev/null @@ -1,22 +0,0 @@ -import { applyParams, save, UpdateRecommendedProductActionContext } from "gadget-server"; - -/** - * @param { UpdateRecommendedProductActionContext } context - */ -export async function run({ params, record, logger, api }) { - applyParams(params, record); - await save(record); -}; - -/** - * @param { UpdateRecommendedProductActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "update", - triggers: { api: true }, -}; \ No newline at end of file diff --git a/shopify/product-quiz-template/api/models/recommendedProduct/actions/update.ts b/shopify/product-quiz-template/api/models/recommendedProduct/actions/update.ts new file mode 100644 index 00000000..8f978557 --- /dev/null +++ b/shopify/product-quiz-template/api/models/recommendedProduct/actions/update.ts @@ -0,0 +1,17 @@ +import { + ActionOptions, + applyParams, + preventCrossShopDataAccess, + save, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const options: ActionOptions = { + actionType: "update", + triggers: { api: true }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifyAsset/actions/create.js b/shopify/product-quiz-template/api/models/shopifyAsset/actions/create.js deleted file mode 100644 index 30401b19..00000000 --- a/shopify/product-quiz-template/api/models/shopifyAsset/actions/create.js +++ /dev/null @@ -1,25 +0,0 @@ -import { applyParams, preventCrossShopDataAccess, save, ActionOptions, CreateShopifyAssetActionContext } from "gadget-server"; -import { processShopifyThemeVersion } from "../utils"; - -/** - * @param { CreateShopifyAssetActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { - applyParams(params, record); - await preventCrossShopDataAccess(params, record); - await save(record); -}; - -/** - * @param { CreateShopifyAssetActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { - // Your logic goes here - await processShopifyThemeVersion(record, api); -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "create", - triggers: { api: false }, -}; diff --git a/shopify/product-quiz-template/api/models/shopifyAsset/actions/create.ts b/shopify/product-quiz-template/api/models/shopifyAsset/actions/create.ts new file mode 100644 index 00000000..b091b93d --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifyAsset/actions/create.ts @@ -0,0 +1,34 @@ +import { + applyParams, + preventCrossShopDataAccess, + save, + ActionOptions, +} from "gadget-server"; +import { processShopifyThemeVersion } from "../utils"; + +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { + await processShopifyThemeVersion(record, api); +}; + +export const options: ActionOptions = { + actionType: "create", + triggers: { api: false }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifyAsset/actions/delete.js b/shopify/product-quiz-template/api/models/shopifyAsset/actions/delete.js deleted file mode 100644 index 6d2f52c4..00000000 --- a/shopify/product-quiz-template/api/models/shopifyAsset/actions/delete.js +++ /dev/null @@ -1,22 +0,0 @@ -import { preventCrossShopDataAccess, deleteRecord, ActionOptions, DeleteShopifyAssetActionContext } from "gadget-server"; - -/** - * @param { DeleteShopifyAssetActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { - await preventCrossShopDataAccess(params, record); - await deleteRecord(record); -}; - -/** - * @param { DeleteShopifyAssetActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { - // Your logic goes here -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "delete", - triggers: { api: false }, -}; diff --git a/shopify/product-quiz-template/api/models/shopifyAsset/actions/delete.ts b/shopify/product-quiz-template/api/models/shopifyAsset/actions/delete.ts new file mode 100644 index 00000000..d1374964 --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifyAsset/actions/delete.ts @@ -0,0 +1,31 @@ +import { + preventCrossShopDataAccess, + deleteRecord, + ActionOptions, +} from "gadget-server"; + +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { + await preventCrossShopDataAccess(params, record); + await deleteRecord(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { + // Your logic goes here +}; + +export const options: ActionOptions = { + actionType: "delete", + triggers: { api: false }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifyAsset/actions/update.js b/shopify/product-quiz-template/api/models/shopifyAsset/actions/update.js deleted file mode 100644 index 67714574..00000000 --- a/shopify/product-quiz-template/api/models/shopifyAsset/actions/update.js +++ /dev/null @@ -1,31 +0,0 @@ -import { - applyParams, - preventCrossShopDataAccess, - save, - ActionOptions, - UpdateShopifyAssetActionContext, -} from "gadget-server"; -import { processShopifyThemeVersion } from "../utils"; - -/** - * @param { UpdateShopifyAssetActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { - applyParams(params, record); - await preventCrossShopDataAccess(params, record); - await save(record); -} - -/** - * @param { UpdateShopifyAssetActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { - // Your logic goes here - await processShopifyThemeVersion(record, api); -} - -/** @type { ActionOptions } */ -export const options = { - actionType: "update", - triggers: { api: false }, -}; diff --git a/shopify/product-quiz-template/api/models/shopifyAsset/actions/update.ts b/shopify/product-quiz-template/api/models/shopifyAsset/actions/update.ts new file mode 100644 index 00000000..6923d516 --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifyAsset/actions/update.ts @@ -0,0 +1,34 @@ +import { + applyParams, + preventCrossShopDataAccess, + save, + ActionOptions, +} from "gadget-server"; +import { processShopifyThemeVersion } from "../utils"; + +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { + await processShopifyThemeVersion(record, api); +}; + +export const options: ActionOptions = { + actionType: "update", + triggers: { api: false }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifyAsset/utils.js b/shopify/product-quiz-template/api/models/shopifyAsset/utils.ts similarity index 66% rename from shopify/product-quiz-template/api/models/shopifyAsset/utils.js rename to shopify/product-quiz-template/api/models/shopifyAsset/utils.ts index 25ca620e..dd11ca54 100644 --- a/shopify/product-quiz-template/api/models/shopifyAsset/utils.js +++ b/shopify/product-quiz-template/api/models/shopifyAsset/utils.ts @@ -1,6 +1,17 @@ -import { logger } from "gadget-server"; +import { + CreateShopifyAssetActionContext, + logger, + UpdateShopifyAssetActionContext, +} from "gadget-server"; -export async function processShopifyThemeVersion(record, api) { +export async function processShopifyThemeVersion( + record: + | CreateShopifyAssetActionContext["record"] + | UpdateShopifyAssetActionContext["record"], + api: + | CreateShopifyAssetActionContext["api"] + | UpdateShopifyAssetActionContext["api"] +) { if (record.themeId) { // get the current asset's theme to check if it is already marked as using Online Store v2.0 const theme = await api.shopifyTheme diff --git a/shopify/product-quiz-template/api/models/shopifyGdprRequest/actions/create.js b/shopify/product-quiz-template/api/models/shopifyGdprRequest/actions/create.ts similarity index 78% rename from shopify/product-quiz-template/api/models/shopifyGdprRequest/actions/create.js rename to shopify/product-quiz-template/api/models/shopifyGdprRequest/actions/create.ts index af988c69..ac006c25 100644 --- a/shopify/product-quiz-template/api/models/shopifyGdprRequest/actions/create.js +++ b/shopify/product-quiz-template/api/models/shopifyGdprRequest/actions/create.ts @@ -3,22 +3,20 @@ import { preventCrossShopDataAccess, save, ActionOptions, - CreateShopifyGdprRequestActionContext, } from "gadget-server"; -/** - * @param { CreateShopifyGdprRequestActionContext } context - */ -export async function run({ params, record, logger, api }) { +export const run: ActionRun = async ({ params, record, logger, api }) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); -} +}; -/** - * @param { CreateShopifyGdprRequestActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => { switch (record.topic) { case "customers/data_request": // This process is a manual one. You must provide the customer's data to the store owners directly. @@ -34,10 +32,9 @@ export async function onSuccess({ params, record, logger, api }) { // See https://shopify.dev/apps/webhooks/configuration/mandatory-webhooks#shop-redact for more information. break; } -} +}; -/** @type { ActionOptions } */ -export const options = { +export const options: ActionOptions = { actionType: "create", triggers: { api: false }, }; diff --git a/shopify/product-quiz-template/api/models/shopifyGdprRequest/actions/update.js b/shopify/product-quiz-template/api/models/shopifyGdprRequest/actions/update.js deleted file mode 100644 index 0269fd6f..00000000 --- a/shopify/product-quiz-template/api/models/shopifyGdprRequest/actions/update.js +++ /dev/null @@ -1,23 +0,0 @@ -import { applyParams, preventCrossShopDataAccess, save, UpdateShopifyGdprRequestActionContext } from "gadget-server"; - -/** - * @param { UpdateShopifyGdprRequestActionContext } context - */ -export async function run({ params, record, logger, api }) { - applyParams(params, record); - await preventCrossShopDataAccess(params, record); - await save(record); -}; - -/** - * @param { UpdateShopifyGdprRequestActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "update", - triggers: { api: false }, -}; \ No newline at end of file diff --git a/shopify/product-quiz-template/api/models/shopifyGdprRequest/actions/update.ts b/shopify/product-quiz-template/api/models/shopifyGdprRequest/actions/update.ts new file mode 100644 index 00000000..03c6f6a3 --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifyGdprRequest/actions/update.ts @@ -0,0 +1,24 @@ +import { + ActionOptions, + applyParams, + preventCrossShopDataAccess, + save, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => {}; + +export const options: ActionOptions = { + actionType: "update", + triggers: { api: false }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifyProduct/actions/create.js b/shopify/product-quiz-template/api/models/shopifyProduct/actions/create.js deleted file mode 100644 index 5f6f6f1a..00000000 --- a/shopify/product-quiz-template/api/models/shopifyProduct/actions/create.js +++ /dev/null @@ -1,23 +0,0 @@ -import { applyParams, preventCrossShopDataAccess, save, ActionOptions, CreateShopifyProductActionContext } from "gadget-server"; - -/** - * @param { CreateShopifyProductActionContext } context - */ -export async function run({ params, record, logger, api }) { - applyParams(params, record); - await preventCrossShopDataAccess(params, record); - await save(record); -}; - -/** - * @param { CreateShopifyProductActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "create", - triggers: { api: false }, -}; diff --git a/shopify/product-quiz-template/api/models/shopifyProduct/actions/create.ts b/shopify/product-quiz-template/api/models/shopifyProduct/actions/create.ts new file mode 100644 index 00000000..a8a76786 --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifyProduct/actions/create.ts @@ -0,0 +1,24 @@ +import { + applyParams, + preventCrossShopDataAccess, + save, + ActionOptions, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => {}; + +export const options: ActionOptions = { + actionType: "create", + triggers: { api: false }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifyProduct/actions/delete.js b/shopify/product-quiz-template/api/models/shopifyProduct/actions/delete.js deleted file mode 100644 index 25dfdc69..00000000 --- a/shopify/product-quiz-template/api/models/shopifyProduct/actions/delete.js +++ /dev/null @@ -1,22 +0,0 @@ -import { preventCrossShopDataAccess, deleteRecord, ActionOptions, DeleteShopifyProductActionContext } from "gadget-server"; - -/** - * @param { DeleteShopifyProductActionContext } context - */ -export async function run({ params, record, logger, api }) { - await preventCrossShopDataAccess(params, record); - await deleteRecord(record); -}; - -/** - * @param { DeleteShopifyProductActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "delete", - triggers: { api: false }, -}; diff --git a/shopify/product-quiz-template/api/models/shopifyProduct/actions/delete.ts b/shopify/product-quiz-template/api/models/shopifyProduct/actions/delete.ts new file mode 100644 index 00000000..9f4cf4f3 --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifyProduct/actions/delete.ts @@ -0,0 +1,22 @@ +import { + preventCrossShopDataAccess, + deleteRecord, + ActionOptions, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + await preventCrossShopDataAccess(params, record); + await deleteRecord(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => {}; + +export const options: ActionOptions = { + actionType: "delete", + triggers: { api: false }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifyProduct/actions/update.js b/shopify/product-quiz-template/api/models/shopifyProduct/actions/update.js deleted file mode 100644 index 78dcffd5..00000000 --- a/shopify/product-quiz-template/api/models/shopifyProduct/actions/update.js +++ /dev/null @@ -1,23 +0,0 @@ -import { applyParams, preventCrossShopDataAccess, save, UpdateShopifyProductActionContext } from "gadget-server"; - -/** - * @param { UpdateShopifyProductActionContext } context - */ -export async function run({ params, record, logger, api }) { - applyParams(params, record); - await preventCrossShopDataAccess(params, record); - await save(record); -}; - -/** - * @param { UpdateShopifyProductActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "update", - triggers: { api: false }, -}; \ No newline at end of file diff --git a/shopify/product-quiz-template/api/models/shopifyProduct/actions/update.ts b/shopify/product-quiz-template/api/models/shopifyProduct/actions/update.ts new file mode 100644 index 00000000..03c6f6a3 --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifyProduct/actions/update.ts @@ -0,0 +1,24 @@ +import { + ActionOptions, + applyParams, + preventCrossShopDataAccess, + save, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => {}; + +export const options: ActionOptions = { + actionType: "update", + triggers: { api: false }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifyProductImage/actions/create.js b/shopify/product-quiz-template/api/models/shopifyProductImage/actions/create.js deleted file mode 100644 index 34d0c27e..00000000 --- a/shopify/product-quiz-template/api/models/shopifyProductImage/actions/create.js +++ /dev/null @@ -1,23 +0,0 @@ -import { applyParams, preventCrossShopDataAccess, save, ActionOptions, CreateShopifyProductImageActionContext } from "gadget-server"; - -/** - * @param { CreateShopifyProductImageActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { - applyParams(params, record); - await preventCrossShopDataAccess(params, record); - await save(record); -}; - -/** - * @param { CreateShopifyProductImageActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { - // Your logic goes here -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "create", - triggers: { api: false }, -}; diff --git a/shopify/product-quiz-template/api/models/shopifyProductImage/actions/create.ts b/shopify/product-quiz-template/api/models/shopifyProductImage/actions/create.ts new file mode 100644 index 00000000..449071ae --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifyProductImage/actions/create.ts @@ -0,0 +1,33 @@ +import { + applyParams, + preventCrossShopDataAccess, + save, + ActionOptions, +} from "gadget-server"; + +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { + // Your logic goes here +}; + +export const options: ActionOptions = { + actionType: "create", + triggers: { api: false }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifyProductImage/actions/delete.js b/shopify/product-quiz-template/api/models/shopifyProductImage/actions/delete.js deleted file mode 100644 index 770f1181..00000000 --- a/shopify/product-quiz-template/api/models/shopifyProductImage/actions/delete.js +++ /dev/null @@ -1,22 +0,0 @@ -import { preventCrossShopDataAccess, deleteRecord, ActionOptions, DeleteShopifyProductImageActionContext } from "gadget-server"; - -/** - * @param { DeleteShopifyProductImageActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { - await preventCrossShopDataAccess(params, record); - await deleteRecord(record); -}; - -/** - * @param { DeleteShopifyProductImageActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { - // Your logic goes here -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "delete", - triggers: { api: false }, -}; diff --git a/shopify/product-quiz-template/api/models/shopifyProductImage/actions/delete.ts b/shopify/product-quiz-template/api/models/shopifyProductImage/actions/delete.ts new file mode 100644 index 00000000..d1374964 --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifyProductImage/actions/delete.ts @@ -0,0 +1,31 @@ +import { + preventCrossShopDataAccess, + deleteRecord, + ActionOptions, +} from "gadget-server"; + +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { + await preventCrossShopDataAccess(params, record); + await deleteRecord(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { + // Your logic goes here +}; + +export const options: ActionOptions = { + actionType: "delete", + triggers: { api: false }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifyProductImage/actions/update.js b/shopify/product-quiz-template/api/models/shopifyProductImage/actions/update.js deleted file mode 100644 index 253e67bb..00000000 --- a/shopify/product-quiz-template/api/models/shopifyProductImage/actions/update.js +++ /dev/null @@ -1,23 +0,0 @@ -import { applyParams, preventCrossShopDataAccess, save, ActionOptions, UpdateShopifyProductImageActionContext } from "gadget-server"; - -/** - * @param { UpdateShopifyProductImageActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { - applyParams(params, record); - await preventCrossShopDataAccess(params, record); - await save(record); -}; - -/** - * @param { UpdateShopifyProductImageActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { - // Your logic goes here -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "update", - triggers: { api: false }, -}; diff --git a/shopify/product-quiz-template/api/models/shopifyProductImage/actions/update.ts b/shopify/product-quiz-template/api/models/shopifyProductImage/actions/update.ts new file mode 100644 index 00000000..8ba4073f --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifyProductImage/actions/update.ts @@ -0,0 +1,33 @@ +import { + applyParams, + preventCrossShopDataAccess, + save, + ActionOptions, +} from "gadget-server"; + +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { + // Your logic goes here +}; + +export const options: ActionOptions = { + actionType: "update", + triggers: { api: false }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifyShop/actions/install.js b/shopify/product-quiz-template/api/models/shopifyShop/actions/install.ts similarity index 63% rename from shopify/product-quiz-template/api/models/shopifyShop/actions/install.js rename to shopify/product-quiz-template/api/models/shopifyShop/actions/install.ts index f7a13143..1001f979 100644 --- a/shopify/product-quiz-template/api/models/shopifyShop/actions/install.js +++ b/shopify/product-quiz-template/api/models/shopifyShop/actions/install.ts @@ -4,22 +4,20 @@ import { transitionState, ActionOptions, ShopifyShopState, - InstallShopifyShopActionContext, } from "gadget-server"; -/** - * @param { InstallShopifyShopActionContext } context - */ -export async function run({ params, record, logger, api }) { +export const run: ActionRun = async ({ params, record, logger, api }) => { transitionState(record, { to: ShopifyShopState.Installed }); applyParams(params, record); await save(record); -} +}; -/** - * @param { InstallShopifyShopActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => { // start a Shopify sync for products on install await api.shopifySync.run({ shopifySync: { @@ -35,10 +33,9 @@ export async function onSuccess({ params, record, logger, api }) { ], }, }); -} +}; -/** @type { ActionOptions } */ -export const options = { +export const options: ActionOptions = { actionType: "create", triggers: { api: false }, }; diff --git a/shopify/product-quiz-template/api/models/shopifyShop/actions/reinstall.js b/shopify/product-quiz-template/api/models/shopifyShop/actions/reinstall.js deleted file mode 100644 index 1efec8a5..00000000 --- a/shopify/product-quiz-template/api/models/shopifyShop/actions/reinstall.js +++ /dev/null @@ -1,24 +0,0 @@ -import { applyParams, preventCrossShopDataAccess, save, transitionState, ActionOptions, ShopifyShopState, ReinstallShopifyShopActionContext } from "gadget-server"; - -/** - * @param { ReinstallShopifyShopActionContext } context - */ -export async function run({ params, record, logger, api }) { - transitionState(record, { from: ShopifyShopState.Uninstalled, to: ShopifyShopState.Installed }); - applyParams(params, record); - await preventCrossShopDataAccess(params, record); - await save(record); -}; - -/** - * @param { ReinstallShopifyShopActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "update", - triggers: { api: false }, -}; \ No newline at end of file diff --git a/shopify/product-quiz-template/api/models/shopifyShop/actions/reinstall.ts b/shopify/product-quiz-template/api/models/shopifyShop/actions/reinstall.ts new file mode 100644 index 00000000..35dc15b7 --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifyShop/actions/reinstall.ts @@ -0,0 +1,30 @@ +import { + applyParams, + preventCrossShopDataAccess, + save, + transitionState, + ActionOptions, + ShopifyShopState, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + transitionState(record, { + from: ShopifyShopState.Uninstalled, + to: ShopifyShopState.Installed, + }); + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => {}; + +export const options: ActionOptions = { + actionType: "update", + triggers: { api: false }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifyShop/actions/uninstall.js b/shopify/product-quiz-template/api/models/shopifyShop/actions/uninstall.js deleted file mode 100644 index 70f54a8a..00000000 --- a/shopify/product-quiz-template/api/models/shopifyShop/actions/uninstall.js +++ /dev/null @@ -1,24 +0,0 @@ -import { applyParams, preventCrossShopDataAccess, save, transitionState, ActionOptions, ShopifyShopState, UninstallShopifyShopActionContext } from "gadget-server"; - -/** - * @param { UninstallShopifyShopActionContext } context - */ -export async function run({ params, record, logger, api }) { - transitionState(record, { from: ShopifyShopState.Installed, to: ShopifyShopState.Uninstalled }); - applyParams(params, record); - await preventCrossShopDataAccess(params, record); - await save(record); -}; - -/** - * @param { UninstallShopifyShopActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "update", - triggers: { api: false }, -}; \ No newline at end of file diff --git a/shopify/product-quiz-template/api/models/shopifyShop/actions/uninstall.ts b/shopify/product-quiz-template/api/models/shopifyShop/actions/uninstall.ts new file mode 100644 index 00000000..0cec98af --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifyShop/actions/uninstall.ts @@ -0,0 +1,30 @@ +import { + applyParams, + preventCrossShopDataAccess, + save, + transitionState, + ActionOptions, + ShopifyShopState, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + transitionState(record, { + from: ShopifyShopState.Installed, + to: ShopifyShopState.Uninstalled, + }); + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => {}; + +export const options: ActionOptions = { + actionType: "update", + triggers: { api: false }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifyShop/actions/update.js b/shopify/product-quiz-template/api/models/shopifyShop/actions/update.js deleted file mode 100644 index f71c51e0..00000000 --- a/shopify/product-quiz-template/api/models/shopifyShop/actions/update.js +++ /dev/null @@ -1,23 +0,0 @@ -import { applyParams, preventCrossShopDataAccess, save, ActionOptions, UpdateShopifyShopActionContext } from "gadget-server"; - -/** - * @param { UpdateShopifyShopActionContext } context - */ -export async function run({ params, record, logger, api }) { - applyParams(params, record); - await preventCrossShopDataAccess(params, record); - await save(record); -}; - -/** - * @param { UpdateShopifyShopActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "update", - triggers: { api: false }, -}; \ No newline at end of file diff --git a/shopify/product-quiz-template/api/models/shopifyShop/actions/update.ts b/shopify/product-quiz-template/api/models/shopifyShop/actions/update.ts new file mode 100644 index 00000000..247bfd43 --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifyShop/actions/update.ts @@ -0,0 +1,24 @@ +import { + applyParams, + preventCrossShopDataAccess, + save, + ActionOptions, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => {}; + +export const options: ActionOptions = { + actionType: "update", + triggers: { api: false }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifySync/actions/complete.js b/shopify/product-quiz-template/api/models/shopifySync/actions/complete.js deleted file mode 100644 index a57a0df4..00000000 --- a/shopify/product-quiz-template/api/models/shopifySync/actions/complete.js +++ /dev/null @@ -1,24 +0,0 @@ -import { applyParams, preventCrossShopDataAccess, save, transitionState, ShopifySyncState, ActionOptions, CompleteShopifySyncActionContext } from "gadget-server"; - -/** - * @param { CompleteShopifySyncActionContext } context - */ -export async function run({ params, record, logger, api }) { - transitionState(record, { from: ShopifySyncState.Running, to: ShopifySyncState.Completed }); - applyParams(params, record); - await preventCrossShopDataAccess(params, record); - await save(record); -}; - -/** - * @param { CompleteShopifySyncActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "update", - triggers: { api: true }, -}; \ No newline at end of file diff --git a/shopify/product-quiz-template/api/models/shopifySync/actions/complete.ts b/shopify/product-quiz-template/api/models/shopifySync/actions/complete.ts new file mode 100644 index 00000000..97c05942 --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifySync/actions/complete.ts @@ -0,0 +1,30 @@ +import { + applyParams, + preventCrossShopDataAccess, + save, + transitionState, + ShopifySyncState, + ActionOptions, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + transitionState(record, { + from: ShopifySyncState.Running, + to: ShopifySyncState.Completed, + }); + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => {}; + +export const options: ActionOptions = { + actionType: "update", + triggers: { api: true }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifySync/actions/error.js b/shopify/product-quiz-template/api/models/shopifySync/actions/error.js deleted file mode 100644 index ea59f50a..00000000 --- a/shopify/product-quiz-template/api/models/shopifySync/actions/error.js +++ /dev/null @@ -1,24 +0,0 @@ -import { applyParams, preventCrossShopDataAccess, save, transitionState, ActionOptions, ShopifySyncState, ErrorShopifySyncActionContext } from "gadget-server"; - -/** - * @param { ErrorShopifySyncActionContext } context - */ -export async function run({ params, record, logger, api }) { - transitionState(record, { from: ShopifySyncState.Running, to: ShopifySyncState.Errored }); - applyParams(params, record); - await preventCrossShopDataAccess(params, record); - await save(record); -}; - -/** - * @param { ErrorShopifySyncActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "update", - triggers: { api: true }, -}; \ No newline at end of file diff --git a/shopify/product-quiz-template/api/models/shopifySync/actions/error.ts b/shopify/product-quiz-template/api/models/shopifySync/actions/error.ts new file mode 100644 index 00000000..42f8f38f --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifySync/actions/error.ts @@ -0,0 +1,30 @@ +import { + applyParams, + preventCrossShopDataAccess, + save, + transitionState, + ActionOptions, + ShopifySyncState, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + transitionState(record, { + from: ShopifySyncState.Running, + to: ShopifySyncState.Errored, + }); + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => {}; + +export const options: ActionOptions = { + actionType: "update", + triggers: { api: true }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifySync/actions/run.js b/shopify/product-quiz-template/api/models/shopifySync/actions/run.js deleted file mode 100644 index 42b26eed..00000000 --- a/shopify/product-quiz-template/api/models/shopifySync/actions/run.js +++ /dev/null @@ -1,25 +0,0 @@ -import { applyParams, preventCrossShopDataAccess, save, shopifySync, transitionState, ShopifySyncState, ActionOptions, RunShopifySyncActionContext } from "gadget-server"; - -/** - * @param { RunShopifySyncActionContext } context - */ -export async function run({ params, record, logger, api }) { - transitionState(record, { to: ShopifySyncState.Running }); - applyParams(params, record); - await preventCrossShopDataAccess(params, record); - await save(record); - await shopifySync(params, record); -}; - -/** - * @param { RunShopifySyncActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "create", - triggers: { api: true }, -}; diff --git a/shopify/product-quiz-template/api/models/shopifySync/actions/run.ts b/shopify/product-quiz-template/api/models/shopifySync/actions/run.ts new file mode 100644 index 00000000..feb6645c --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifySync/actions/run.ts @@ -0,0 +1,29 @@ +import { + applyParams, + preventCrossShopDataAccess, + save, + shopifySync, + transitionState, + ShopifySyncState, + ActionOptions, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + transitionState(record, { to: ShopifySyncState.Running }); + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); + await shopifySync(params, record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => {}; + +export const options: ActionOptions = { + actionType: "create", + triggers: { api: true }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifyTheme/actions/create.js b/shopify/product-quiz-template/api/models/shopifyTheme/actions/create.js deleted file mode 100644 index 83e9be46..00000000 --- a/shopify/product-quiz-template/api/models/shopifyTheme/actions/create.js +++ /dev/null @@ -1,23 +0,0 @@ -import { applyParams, preventCrossShopDataAccess, save, ActionOptions, CreateShopifyThemeActionContext } from "gadget-server"; - -/** - * @param { CreateShopifyThemeActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { - applyParams(params, record); - await preventCrossShopDataAccess(params, record); - await save(record); -}; - -/** - * @param { CreateShopifyThemeActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { - // Your logic goes here -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "create", - triggers: { api: false }, -}; diff --git a/shopify/product-quiz-template/api/models/shopifyTheme/actions/create.ts b/shopify/product-quiz-template/api/models/shopifyTheme/actions/create.ts new file mode 100644 index 00000000..449071ae --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifyTheme/actions/create.ts @@ -0,0 +1,33 @@ +import { + applyParams, + preventCrossShopDataAccess, + save, + ActionOptions, +} from "gadget-server"; + +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { + // Your logic goes here +}; + +export const options: ActionOptions = { + actionType: "create", + triggers: { api: false }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifyTheme/actions/delete.js b/shopify/product-quiz-template/api/models/shopifyTheme/actions/delete.js deleted file mode 100644 index 4c868299..00000000 --- a/shopify/product-quiz-template/api/models/shopifyTheme/actions/delete.js +++ /dev/null @@ -1,22 +0,0 @@ -import { preventCrossShopDataAccess, deleteRecord, ActionOptions, DeleteShopifyThemeActionContext } from "gadget-server"; - -/** - * @param { DeleteShopifyThemeActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { - await preventCrossShopDataAccess(params, record); - await deleteRecord(record); -}; - -/** - * @param { DeleteShopifyThemeActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { - // Your logic goes here -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "delete", - triggers: { api: false }, -}; diff --git a/shopify/product-quiz-template/api/models/shopifyTheme/actions/delete.ts b/shopify/product-quiz-template/api/models/shopifyTheme/actions/delete.ts new file mode 100644 index 00000000..d1374964 --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifyTheme/actions/delete.ts @@ -0,0 +1,31 @@ +import { + preventCrossShopDataAccess, + deleteRecord, + ActionOptions, +} from "gadget-server"; + +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { + await preventCrossShopDataAccess(params, record); + await deleteRecord(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { + // Your logic goes here +}; + +export const options: ActionOptions = { + actionType: "delete", + triggers: { api: false }, +}; diff --git a/shopify/product-quiz-template/api/models/shopifyTheme/actions/update.js b/shopify/product-quiz-template/api/models/shopifyTheme/actions/update.js deleted file mode 100644 index 59046181..00000000 --- a/shopify/product-quiz-template/api/models/shopifyTheme/actions/update.js +++ /dev/null @@ -1,23 +0,0 @@ -import { applyParams, preventCrossShopDataAccess, save, ActionOptions, UpdateShopifyThemeActionContext } from "gadget-server"; - -/** - * @param { UpdateShopifyThemeActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { - applyParams(params, record); - await preventCrossShopDataAccess(params, record); - await save(record); -}; - -/** - * @param { UpdateShopifyThemeActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { - // Your logic goes here -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "update", - triggers: { api: false }, -}; diff --git a/shopify/product-quiz-template/api/models/shopifyTheme/actions/update.ts b/shopify/product-quiz-template/api/models/shopifyTheme/actions/update.ts new file mode 100644 index 00000000..8ba4073f --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopifyTheme/actions/update.ts @@ -0,0 +1,33 @@ +import { + applyParams, + preventCrossShopDataAccess, + save, + ActionOptions, +} from "gadget-server"; + +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { + // Your logic goes here +}; + +export const options: ActionOptions = { + actionType: "update", + triggers: { api: false }, +}; diff --git a/shopify/product-quiz-template/api/models/shopperSuggestion/actions/create.js b/shopify/product-quiz-template/api/models/shopperSuggestion/actions/create.js deleted file mode 100644 index b64dc468..00000000 --- a/shopify/product-quiz-template/api/models/shopperSuggestion/actions/create.js +++ /dev/null @@ -1,22 +0,0 @@ -import { applyParams, save, ActionOptions, CreateShopperSuggestionActionContext } from "gadget-server"; - -/** - * @param { CreateShopperSuggestionActionContext } context - */ -export async function run({ params, record, logger, api }) { - applyParams(params, record); - await save(record); -}; - -/** - * @param { CreateShopperSuggestionActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "create", - triggers: { api: true }, -}; diff --git a/shopify/product-quiz-template/api/models/shopperSuggestion/actions/create.ts b/shopify/product-quiz-template/api/models/shopperSuggestion/actions/create.ts new file mode 100644 index 00000000..3077fe9d --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopperSuggestion/actions/create.ts @@ -0,0 +1,24 @@ +import { + applyParams, + save, + ActionOptions, + preventCrossShopDataAccess, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => {}; + +export const options: ActionOptions = { + actionType: "create", + triggers: { api: true }, +}; diff --git a/shopify/product-quiz-template/api/models/shopperSuggestion/actions/delete.js b/shopify/product-quiz-template/api/models/shopperSuggestion/actions/delete.js deleted file mode 100644 index 79803117..00000000 --- a/shopify/product-quiz-template/api/models/shopperSuggestion/actions/delete.js +++ /dev/null @@ -1,21 +0,0 @@ -import { deleteRecord, ActionOptions, DeleteShopperSuggestionActionContext } from "gadget-server"; - -/** - * @param { DeleteShopperSuggestionActionContext } context - */ -export async function run({ params, record, logger, api }) { - await deleteRecord(record); -}; - -/** - * @param { DeleteShopperSuggestionActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "delete", - triggers: { api: true }, -}; diff --git a/shopify/product-quiz-template/api/models/shopperSuggestion/actions/delete.ts b/shopify/product-quiz-template/api/models/shopperSuggestion/actions/delete.ts new file mode 100644 index 00000000..58445ae6 --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopperSuggestion/actions/delete.ts @@ -0,0 +1,22 @@ +import { + deleteRecord, + ActionOptions, + preventCrossShopDataAccess, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + await preventCrossShopDataAccess(params, record); + await deleteRecord(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => {}; + +export const options: ActionOptions = { + actionType: "delete", + triggers: { api: true }, +}; diff --git a/shopify/product-quiz-template/api/models/shopperSuggestion/actions/update.js b/shopify/product-quiz-template/api/models/shopperSuggestion/actions/update.js deleted file mode 100644 index 1c89c34a..00000000 --- a/shopify/product-quiz-template/api/models/shopperSuggestion/actions/update.js +++ /dev/null @@ -1,22 +0,0 @@ -import { applyParams, save, UpdateShopperSuggestionActionContext } from "gadget-server"; - -/** - * @param { UpdateShopperSuggestionActionContext } context - */ -export async function run({ params, record, logger, api }) { - applyParams(params, record); - await save(record); -}; - -/** - * @param { UpdateShopperSuggestionActionContext } context - */ -export async function onSuccess({ params, record, logger, api }) { - -}; - -/** @type { ActionOptions } */ -export const options = { - actionType: "update", - triggers: { api: true }, -}; \ No newline at end of file diff --git a/shopify/product-quiz-template/api/models/shopperSuggestion/actions/update.ts b/shopify/product-quiz-template/api/models/shopperSuggestion/actions/update.ts new file mode 100644 index 00000000..2c3f4f0d --- /dev/null +++ b/shopify/product-quiz-template/api/models/shopperSuggestion/actions/update.ts @@ -0,0 +1,24 @@ +import { + ActionOptions, + applyParams, + preventCrossShopDataAccess, + save, +} from "gadget-server"; + +export const run: ActionRun = async ({ params, record, logger, api }) => { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, +}) => {}; + +export const options: ActionOptions = { + actionType: "update", + triggers: { api: true }, +}; diff --git a/shopify/product-quiz-template/extensions/quiz/assets/product-quiz.js b/shopify/product-quiz-template/extensions/quiz/assets/product-quiz.ts similarity index 53% rename from shopify/product-quiz-template/extensions/quiz/assets/product-quiz.js rename to shopify/product-quiz-template/extensions/quiz/assets/product-quiz.ts index 190396a5..4a396efc 100644 --- a/shopify/product-quiz-template/extensions/quiz/assets/product-quiz.js +++ b/shopify/product-quiz-template/extensions/quiz/assets/product-quiz.ts @@ -1,8 +1,17 @@ -// initialize an API client object -const api = new Gadget(); +import { Client, GadgetRecordList } from "@gadget-client/product-quiz-template"; + +declare global { + interface Window { + api: Client; + shopId: string; + quizSlug: string; + } +} + +const api: Client = window.api; // query Gadget for the recommended products based on quiz answers, using a JS query -const fetchRecommendedProducts = async (answerIds) => { +const fetchRecommendedProducts = async (answerIds: string[]) => { const queryIdFilter = answerIds.map((answerId) => { return { id: { equals: answerId } }; }); @@ -35,7 +44,7 @@ const fetchRecommendedProducts = async (answerIds) => { }; // fetch the quiz questions and answers to be presented to shoppers, using a GraphQL query -const fetchQuiz = async (quizSlug) => { +const fetchQuiz = async (quizSlug: string) => { const quiz = await api.quiz.findFirst({ filter: { slug: { equals: quizSlug }, @@ -67,12 +76,33 @@ const fetchQuiz = async (quizSlug) => { }; // save the shopper's email and recommended productions to Gadget (for follow-up emails!) -const saveSelections = async (quizId, email, recommendedProducts) => { +const saveSelections = async ( + quizId: string, + email: string, + recommendedProducts: GadgetRecordList<{ + recommendedProduct: { + id: string; + productSuggestion: { + id: string; + title: string | null; + body: string | null; + handle: string | null; + images: { + edges: { + node: { + source: string | null; + }; + }[]; + }; + } | null; + } | null; + }> +) => { const productsQuery = recommendedProducts.map((rp) => { return { create: { product: { - _link: rp.recommendedProduct.productSuggestion.id, + _link: rp.recommendedProduct?.productSuggestion?.id ?? "", }, shop: { _link: window.shopId, @@ -92,13 +122,20 @@ const saveSelections = async (quizId, email, recommendedProducts) => { }); }; -const onSubmitHandler = async (evt, quizId) => { +const onSubmitHandler = async (evt: Event, quizId: string) => { evt.preventDefault(); - const email = document.getElementById("product-quiz__email").value; + const emailInput = document.getElementById("product-quiz__email"); + + if (!emailInput) { + throw new Error("Email input element not found"); + } + const email: string = (emailInput as HTMLInputElement).value; const submitButton = document.querySelector(".product-quiz__submit"); - submitButton.classList.add("disabled"); + if (submitButton) { + submitButton.classList.add("disabled"); + } const recommendedProducts = await fetchRecommendedProducts(selectedAnswers); @@ -112,28 +149,47 @@ const onSubmitHandler = async (evt, quizId) => { recommendedProducts.forEach((result) => { const { recommendedProduct } = result; const imgUrl = - recommendedProduct.productSuggestion.images?.edges?.[0]?.node?.source; - const productLink = recommendedProduct.productSuggestion.handle; + recommendedProduct?.productSuggestion?.images?.edges?.[0]?.node?.source; + const productLink = recommendedProduct?.productSuggestion?.handle; recommendedProductHTML += - `

${recommendedProduct.productSuggestion.title}

Check it out` + + `

${recommendedProduct?.productSuggestion?.title}

Check it out` + `

`; }); recommendedProductHTML += ""; - document.getElementById("questions").innerHTML = recommendedProductHTML; + const questionsElement = document.getElementById("questions"); + if (questionsElement) { + questionsElement.innerHTML = recommendedProductHTML; + } - submitButton.classList.add("hidden"); - document.querySelector(".product-quiz__submit-hr").classList.add("hidden"); - document - .querySelector(".product-quiz__email-container") - .classList.add("hidden"); + if (submitButton) { + submitButton.classList.add("hidden"); + } + const submitHrElement = document.querySelector(".product-quiz__submit-hr"); + if (submitHrElement) { + submitHrElement.classList.add("hidden"); + } + const emailContainer = document.querySelector( + ".product-quiz__email-container" + ); + if (emailContainer) { + emailContainer.classList.add("hidden"); + } }; -let selectedAnswers = []; -const selectAnswer = (evt, answerId, answerText) => { +let selectedAnswers: string[] = []; +const selectAnswer = (evt: Event, answerId: string, answerText: string) => { selectedAnswers.push(answerId); - let elId = evt.srcElement.id; - let parent = document.getElementById(elId).parentNode; + const srcElement = evt.srcElement as HTMLElement | null; + if (!srcElement) { + throw new Error("Source element not found"); + } + let elId = srcElement.id; + const element = document.getElementById(elId); + if (!element || !element.parentNode) { + throw new Error("Parent element not found"); + } + let parent = element.parentNode as HTMLElement; parent.innerHTML = "

" + decodeURI(answerText) + " selected

"; }; @@ -147,13 +203,22 @@ document.addEventListener("DOMContentLoaded", function () { customElements.define( "product-quiz", class ProductQuiz extends HTMLElement { + form: HTMLFormElement | null; + heading: HTMLElement | null; + body: HTMLElement | null; + questions: HTMLElement | null; + constructor() { super(); this.form = this.querySelector("form"); this.heading = this.querySelector(".product-quiz__title"); - this.heading.innerHTML = quiz.title; + if (this.heading) { + this.heading.innerHTML = quiz.title; + } this.body = this.querySelector(".product-quiz__body span"); - this.body.innerHTML = quiz.body; + if (this.body && quiz.body) { + this.body.innerHTML = quiz.body; + } this.questions = this.querySelector(".product-quiz__questions"); const questionContainer = this.querySelector( @@ -163,8 +228,14 @@ document.addEventListener("DOMContentLoaded", function () { ".product-quiz__question-answer" ); + if (!questionContainer) { + throw new Error("Question container element not found"); + } + questions.forEach((question, i) => { - const clonedDiv = questionContainer.cloneNode(true); + const clonedDiv = questionContainer.cloneNode( + true + ) as HTMLElement; clonedDiv.id = "question_" + i; clonedDiv.insertAdjacentHTML( "beforeend", @@ -172,11 +243,21 @@ document.addEventListener("DOMContentLoaded", function () { question.node.text + `
` ); - this.questions.appendChild(clonedDiv); + if (this.questions) { + this.questions.appendChild(clonedDiv); + } else { + throw new Error("Questions container element not found"); + } const answers = question.node.answers.edges; + if (!answerContainer) { + throw new Error("Answer container element not found"); + } + answers.forEach((answer, j) => { - const clonedSpan = answerContainer.cloneNode(true); + const clonedSpan = answerContainer.cloneNode( + true + ) as HTMLElement; clonedSpan.id = "answer_" + i + "_" + j; clonedSpan.insertAdjacentHTML( "beforeend", @@ -185,13 +266,20 @@ document.addEventListener("DOMContentLoaded", function () { clonedSpan.addEventListener("click", (evt) => { selectAnswer(evt, answer.node.id, answer.node.text); }); - this.querySelector(`.product-quiz__answers_${i}`).appendChild( - clonedSpan + const answersContainer = this.querySelector( + `.product-quiz__answers_${i}` ); + if (answersContainer) { + answersContainer.appendChild(clonedSpan); + } else { + throw new Error( + `Answers container element not found for question ${i}` + ); + } }); }); - this.form.addEventListener("submit", async function (evt) { + this.form?.addEventListener("submit", async function (evt) { await onSubmitHandler(evt, quiz.id); }); } diff --git a/shopify/product-quiz-template/extensions/quiz/blocks/quiz-page.liquid b/shopify/product-quiz-template/extensions/quiz/blocks/quiz-page.liquid index 96dd496d..d929f189 100644 --- a/shopify/product-quiz-template/extensions/quiz/blocks/quiz-page.liquid +++ b/shopify/product-quiz-template/extensions/quiz/blocks/quiz-page.liquid @@ -8,6 +8,7 @@ diff --git a/shopify/product-quiz-template/globals.d.ts b/shopify/product-quiz-template/globals.d.ts new file mode 100644 index 00000000..dd383dd1 --- /dev/null +++ b/shopify/product-quiz-template/globals.d.ts @@ -0,0 +1,15 @@ +// custom.d.ts +declare module "*.webm" { + const src: string; + export default src; +} + +declare module "*.js?raw" { + const src: string; + export default src; +} + +declare module "*.liquid?raw" { + const src: string; + export default src; +} diff --git a/shopify/product-quiz-template/index.html b/shopify/product-quiz-template/index.html index e8ce7452..3ddb5f84 100755 --- a/shopify/product-quiz-template/index.html +++ b/shopify/product-quiz-template/index.html @@ -1,15 +1,17 @@ - - - - New Gadget App Welcome Page - - - - - -
- - - + + + + New Gadget App Welcome Page + + + + + + +
+ + + + \ No newline at end of file diff --git a/shopify/product-quiz-template/package.json b/shopify/product-quiz-template/package.json index c9724c07..5030f932 100755 --- a/shopify/product-quiz-template/package.json +++ b/shopify/product-quiz-template/package.json @@ -12,12 +12,10 @@ "@shopify/app-bridge-react": "^4.1.1", "@shopify/polaris": "^13.9.0", "@shopify/polaris-icons": "^9.3.0", - "ejs": "^3.1.9", "fastify": "^4.24.2", "gadget-server": "link:.gadget/server", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-hook-form": "^7.48.2", "react-router-dom": "^6.6.1", "shopify-api-node": "3.11.3" }, @@ -31,12 +29,11 @@ "generate": "shopify app generate" }, "devDependencies": { - "@shopify/app": "^3.58.2", "@types/node": "^20.12.8", - "@types/react": "^18.0.28", + "@types/react": "^18.2.64", "@types/react-dom": "^18.0.11", "@vitejs/plugin-react-swc": "3.2.0", - "typescript": "^4.5.3", + "typescript": "^5.4.5", "vite": "^5.3.5" } -} \ No newline at end of file +} diff --git a/shopify/product-quiz-template/tsconfig.json b/shopify/product-quiz-template/tsconfig.json new file mode 100755 index 00000000..8e3d03f9 --- /dev/null +++ b/shopify/product-quiz-template/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "strict": true, + "esModuleInterop": true, + "allowJs": true, + "noImplicitAny": true, + "sourceMap": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "forceConsistentCasingInFileNames": true, + "target": "es2020", + "lib": ["es2020", "DOM"], + "skipLibCheck": true, + "jsx": "react-jsx", + "moduleResolution": "node", + "resolveJsonModule": true, + "baseUrl": "/" + } +} diff --git a/shopify/product-quiz-template/vite.config.mjs b/shopify/product-quiz-template/vite.config.mts similarity index 100% rename from shopify/product-quiz-template/vite.config.mjs rename to shopify/product-quiz-template/vite.config.mts diff --git a/shopify/product-quiz-template/web/api.js b/shopify/product-quiz-template/web/api.ts similarity index 100% rename from shopify/product-quiz-template/web/api.js rename to shopify/product-quiz-template/web/api.ts diff --git a/shopify/product-quiz-template/web/components/Answers.jsx b/shopify/product-quiz-template/web/components/Answers.tsx similarity index 100% rename from shopify/product-quiz-template/web/components/Answers.jsx rename to shopify/product-quiz-template/web/components/Answers.tsx diff --git a/shopify/product-quiz-template/web/components/App.jsx b/shopify/product-quiz-template/web/components/App.tsx similarity index 88% rename from shopify/product-quiz-template/web/components/App.jsx rename to shopify/product-quiz-template/web/components/App.tsx index bd0fae9e..1a135bea 100755 --- a/shopify/product-quiz-template/web/components/App.jsx +++ b/shopify/product-quiz-template/web/components/App.tsx @@ -22,19 +22,25 @@ const Error404 = () => { useEffect(() => { if ( + process.env.GADGET_PUBLIC_SHOPIFY_APP_URL && location.pathname === - new URL(process.env.GADGET_PUBLIC_SHOPIFY_APP_URL).pathname + new URL(process.env.GADGET_PUBLIC_SHOPIFY_APP_URL).pathname ) return navigate("/", { replace: true }); }, [location.pathname]); + return
404 not found
; }; export default () => { const navigate = useNavigate(); const location = useLocation(); - const history = useMemo( - () => ({ replace: (path) => navigate(path, { replace: true }) }), + interface History { + replace: (path: string) => void; + } + + const history: History = useMemo( + () => ({ replace: (path: string) => navigate(path, { replace: true }) }), [navigate] ); @@ -51,7 +57,6 @@ export default () => { type={AppType.Embedded} shopifyApiKey={window.gadgetConfig.apiKeys.shopify} api={api} - router={appBridgeRouter} > diff --git a/shopify/product-quiz-template/web/components/CodeBlock.jsx b/shopify/product-quiz-template/web/components/CodeBlock.tsx similarity index 81% rename from shopify/product-quiz-template/web/components/CodeBlock.jsx rename to shopify/product-quiz-template/web/components/CodeBlock.tsx index e1a52edf..9d05568a 100644 --- a/shopify/product-quiz-template/web/components/CodeBlock.jsx +++ b/shopify/product-quiz-template/web/components/CodeBlock.tsx @@ -1,6 +1,6 @@ import { Text, Card, BlockStack, Button } from "@shopify/polaris"; -export default ({ children }) => { +export default ({ children }: { children: string }) => { return ( @@ -8,7 +8,7 @@ export default ({ children }) => { Copy - +
           {children}
         
diff --git a/shopify/product-quiz-template/web/components/InstallTab.jsx b/shopify/product-quiz-template/web/components/InstallTab.tsx similarity index 74% rename from shopify/product-quiz-template/web/components/InstallTab.jsx rename to shopify/product-quiz-template/web/components/InstallTab.tsx index e9677a85..6817030d 100644 --- a/shopify/product-quiz-template/web/components/InstallTab.jsx +++ b/shopify/product-quiz-template/web/components/InstallTab.tsx @@ -14,9 +14,12 @@ import { default as Store1Instructions } from "./Store1Instructions"; import store2Install from "../assets/store2Install.webm"; export default () => { - const [selected, setSelected] = useState("Select"); + const [selected, setSelected] = useState("Select"); - const handleSelectChange = useCallback((value) => setSelected(value), []); + const handleSelectChange = useCallback( + (value: string) => setSelected(value), + [] + ); const [storeResponse] = useFindFirst(api.shopifyShop, { select: { @@ -37,22 +40,22 @@ export default () => { if (storeResponse.fetching) return ; - const themes = storeResponse.data.themes.edges; - const themeSelections = themes.map((theme) => ({ + const themes = storeResponse?.data?.themes.edges; + const themeSelections = themes?.map((theme) => ({ label: theme.node.role === "main" ? `${theme.node.name} (Live)` - : theme.node.name, + : theme.node.name ?? "", value: theme.node.id, })); - const selectedIsShop2 = themes.find((theme) => theme.node.id === selected) + const selectedIsShop2 = themes?.find((theme) => theme.node.id === selected) ?.node.usingOnlineStore2; return (