diff --git a/shopify/product-quiz-template/.gitignore b/shopify/product-quiz-template/.gitignore index 72e9f94d..53e73cb5 100644 --- a/shopify/product-quiz-template/.gitignore +++ b/shopify/product-quiz-template/.gitignore @@ -4,5 +4,5 @@ node_modules/ **/.DS_Store # Shopify -shopify.app.**.toml -extensions/**/dist \ No newline at end of file +extensions/**/dist +extensions/**/node_modules \ No newline at end of file diff --git a/shopify/product-quiz-template/.ignore b/shopify/product-quiz-template/.ignore index 683d8a6a..76a73d59 100644 --- a/shopify/product-quiz-template/.ignore +++ b/shopify/product-quiz-template/.ignore @@ -1,3 +1,3 @@ # Shopify extensions/**/dist -shopify.app.**.toml \ No newline at end of file +extensions/**/node_modules \ 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 73% 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..6e188bfa 100644 --- a/shopify/product-quiz-template/api/models/shopifyGdprRequest/actions/create.js +++ b/shopify/product-quiz-template/api/models/shopifyGdprRequest/actions/create.ts @@ -3,41 +3,41 @@ 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": + case "customers/data_request": { // This process is a manual one. You must provide the customer's data to the store owners directly. // See https://shopify.dev/apps/webhooks/configuration/mandatory-webhooks#customers-data_request for more information. break; - case "customers/redact": + } + case "customers/redact": { // Any modifications that are initiated by Shopify and emitted via webhook will automatically be handled by your existing model actions. // The responsibility falls on you to redact any additional customer related data you may have in custom models. break; - case "shop/redact": + } + case "shop/redact": { // This will be received 48 hours after a store owner uninstalls your app. Any modifications that are initiated by Shopify and emitted via webhook will automatically be handled by your existing model actions. // The responsibility falls on you to redact any additional shop related data you may have in custom models. // 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/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..09943c5b 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/shopify.app.toml b/shopify/product-quiz-template/shopify.app.toml new file mode 100644 index 00000000..ce03df21 --- /dev/null +++ b/shopify/product-quiz-template/shopify.app.toml @@ -0,0 +1,3 @@ +# This toml file is used for production. Only edit this file if you have a need for it +# When you add a production config, values will be auto-populated here +# Read more at https://docs.gadget.dev/guides/plugins/shopify/shopify-app-toml \ 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..95596bbd --- /dev/null +++ b/shopify/product-quiz-template/tsconfig.json @@ -0,0 +1,20 @@ +{ + "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": "Bundler", + "resolveJsonModule": true, + "baseUrl": "/", + "noEmit": true + } +} 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 58% rename from shopify/product-quiz-template/web/components/Answers.jsx rename to shopify/product-quiz-template/web/components/Answers.tsx index ce27e208..475f16ad 100755 --- a/shopify/product-quiz-template/web/components/Answers.jsx +++ b/shopify/product-quiz-template/web/components/Answers.tsx @@ -1,4 +1,3 @@ -// @ts-nocheck import { TextField, BlockStack, @@ -10,21 +9,57 @@ import { FormLayout, } from "@shopify/polaris"; import { Fragment } from "react"; -import { useFieldArray, Controller } from "@gadgetinc/react"; +import { useFieldArray, Controller, useFormContext } from "@gadgetinc/react"; import { PlusCircleIcon, XCircleIcon, ImageIcon } from "@shopify/polaris-icons"; +import { GadgetRecordList } from "@gadget-client/product-quiz-template"; + +type QuizError = { + questions?: { + [key: string]: { + answers?: { + [key: string]: { + text?: { + message: string; + }; + recommendedProduct?: { + productSuggestion?: { + id?: { + message: string; + }; + }; + }; + }; + }; + }; + }; +}; + +type ProductImages = { + [key: string]: string; +}; + +const AnswerImage = ({ + name, + answerIndex, + productImages, +}: { + name: string; + answerIndex: number; + productImages: ProductImages | undefined; +}) => { + const { watch } = useFormContext(); -const AnswerImage = ({ name, answerIndex, productImages, watch }) => { const productSuggestionWatch = watch( `${name}.${answerIndex}.recommendedProduct.productSuggestion.id` ); return productSuggestionWatch ? ( - {productImages[productSuggestionWatch] ? ( + {productImages?.[productSuggestionWatch] ? ( ) : ( @@ -33,7 +68,33 @@ const AnswerImage = ({ name, answerIndex, productImages, watch }) => { ) : undefined; }; -export default ({ name, questionIndex, products, control, errors, watch }) => { +export default ({ + name, + questionIndex, + products, +}: { + name: string; + questionIndex: number; + products: + | GadgetRecordList<{ + id: string; + title: string | null; + images: { + edges: { + node: { + id: string; + source: string | null; + }; + }[]; + }; + }> + | undefined; +}) => { + const { + control, + formState: { errors }, + } = useFormContext(); + const { fields: answers, append: addAnswer, @@ -43,17 +104,20 @@ export default ({ name, questionIndex, products, control, errors, watch }) => { name, }); - const productsOptions = products.map((p, i) => ({ - label: p.title, + const productsOptions = products?.map((p, i) => ({ + label: p.title ?? "", value: p.id, - key: i, + key: String(i), })); - const productsImageMap = products.reduce((acc, p) => { - acc[p.id] = p.images.edges[0]?.node?.source; + const productsImageMap: ProductImages | undefined = products?.reduce( + (acc: ProductImages, p) => { + acc[p.id] = p.images.edges[0]?.node?.source ?? ""; - return acc; - }, {}); + return acc; + }, + {} + ); return ( @@ -72,8 +136,8 @@ export default ({ name, questionIndex, products, control, errors, watch }) => { autoComplete="off" {...fieldProps} error={ - errors.quiz?.questions?.[questionIndex]?.answers?.[i] - ?.text?.message + (errors.quiz as QuizError)?.questions?.[questionIndex] + ?.answers?.[i]?.text?.message } /> )} @@ -90,8 +154,9 @@ export default ({ name, questionIndex, products, control, errors, watch }) => { options={productsOptions} requiredIndicator error={ - errors.quiz?.questions?.[questionIndex]?.answers?.[i] - ?.recommendedProduct?.productSuggestion?.id?.message + (errors.quiz as QuizError)?.questions?.[questionIndex] + ?.answers?.[i]?.recommendedProduct?.productSuggestion + ?.id?.message } {...fieldProps} /> @@ -102,7 +167,7 @@ export default ({ name, questionIndex, products, control, errors, watch }) => { diff --git a/shopify/product-quiz-template/web/components/App.jsx b/shopify/product-quiz-template/web/components/App.tsx similarity index 86% rename from shopify/product-quiz-template/web/components/App.jsx rename to shopify/product-quiz-template/web/components/App.tsx index bd0fae9e..e9c1fb7d 100755 --- a/shopify/product-quiz-template/web/components/App.jsx +++ b/shopify/product-quiz-template/web/components/App.tsx @@ -22,28 +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 }) }), - [navigate] - ); + interface History { + replace: (path: string) => void; + } - const appBridgeRouter = useMemo( - () => ({ - location, - history, - }), - [location, history] + const history: History = useMemo( + () => ({ replace: (path: string) => navigate(path, { replace: true }) }), + [navigate] ); return ( @@ -51,7 +48,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 (