From c2a3c508a34eccc340904d73ec41253913868025 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Mon, 19 Aug 2024 11:06:04 -0400 Subject: [PATCH 01/43] Adding the initial code for the product-reviews template --- .../workflows/product-reviews-template.yaml | 21 + product-reviews-template/.gitignore | 3 + .../filters/shopify/shopifyCustomer.gelly | 3 + .../filters/shopify/shopifyGdprRequest.gelly | 3 + .../filters/shopify/shopifyOrder.gelly | 3 + .../filters/shopify/shopifyProduct.gelly | 3 + .../filters/shopify/shopifyShop.gelly | 3 + .../filters/shopify/shopifySync.gelly | 3 + .../accessControl/permissions.gadget.ts | 76 + .../api/models/review/actions/create.js | 21 + .../api/models/review/actions/delete.js | 20 + .../api/models/review/actions/update.js | 21 + .../api/models/review/schema.gadget.ts | 28 + .../api/models/session/schema.gadget.ts | 17 + .../models/shopifyCustomer/actions/create.js | 21 + .../models/shopifyCustomer/actions/delete.js | 20 + .../models/shopifyCustomer/actions/update.js | 21 + .../models/shopifyCustomer/schema.gadget.ts | 48 + .../shopifyGdprRequest/actions/create.js | 35 + .../shopifyGdprRequest/actions/update.js | 21 + .../shopifyGdprRequest/schema.gadget.ts | 10 + .../api/models/shopifyOrder/actions/create.js | 21 + .../api/models/shopifyOrder/actions/delete.js | 20 + .../api/models/shopifyOrder/actions/update.js | 21 + .../api/models/shopifyOrder/schema.gadget.ts | 97 + .../models/shopifyProduct/actions/create.js | 21 + .../models/shopifyProduct/actions/delete.js | 20 + .../models/shopifyProduct/actions/update.js | 21 + .../models/shopifyProduct/schema.gadget.ts | 35 + .../api/models/shopifyShop/actions/install.js | 19 + .../models/shopifyShop/actions/reinstall.js | 21 + .../models/shopifyShop/actions/uninstall.js | 21 + .../api/models/shopifyShop/actions/update.js | 21 + .../api/models/shopifyShop/schema.gadget.ts | 74 + .../api/models/shopifySync/actions/abort.js | 25 + .../models/shopifySync/actions/complete.js | 24 + .../api/models/shopifySync/actions/error.js | 24 + .../api/models/shopifySync/actions/run.js | 25 + .../api/models/shopifySync/schema.gadget.ts | 10 + product-reviews-template/index.html | 19 + product-reviews-template/package.json | 31 + product-reviews-template/settings.gadget.ts | 25 + product-reviews-template/vite.config.mjs | 8 + product-reviews-template/web/api.js | 5 + .../web/components/App.css | 4 + .../web/components/App.jsx | 128 ++ product-reviews-template/web/main.jsx | 17 + product-reviews-template/web/routes/about.jsx | 20 + product-reviews-template/web/routes/index.jsx | 69 + product-reviews-template/yarn.lock | 1567 +++++++++++++++++ 50 files changed, 2814 insertions(+) create mode 100644 .github/workflows/product-reviews-template.yaml create mode 100755 product-reviews-template/.gitignore create mode 100755 product-reviews-template/accessControl/filters/shopify/shopifyCustomer.gelly create mode 100755 product-reviews-template/accessControl/filters/shopify/shopifyGdprRequest.gelly create mode 100755 product-reviews-template/accessControl/filters/shopify/shopifyOrder.gelly create mode 100755 product-reviews-template/accessControl/filters/shopify/shopifyProduct.gelly create mode 100755 product-reviews-template/accessControl/filters/shopify/shopifyShop.gelly create mode 100755 product-reviews-template/accessControl/filters/shopify/shopifySync.gelly create mode 100755 product-reviews-template/accessControl/permissions.gadget.ts create mode 100755 product-reviews-template/api/models/review/actions/create.js create mode 100755 product-reviews-template/api/models/review/actions/delete.js create mode 100755 product-reviews-template/api/models/review/actions/update.js create mode 100755 product-reviews-template/api/models/review/schema.gadget.ts create mode 100755 product-reviews-template/api/models/session/schema.gadget.ts create mode 100755 product-reviews-template/api/models/shopifyCustomer/actions/create.js create mode 100755 product-reviews-template/api/models/shopifyCustomer/actions/delete.js create mode 100755 product-reviews-template/api/models/shopifyCustomer/actions/update.js create mode 100755 product-reviews-template/api/models/shopifyCustomer/schema.gadget.ts create mode 100755 product-reviews-template/api/models/shopifyGdprRequest/actions/create.js create mode 100755 product-reviews-template/api/models/shopifyGdprRequest/actions/update.js create mode 100755 product-reviews-template/api/models/shopifyGdprRequest/schema.gadget.ts create mode 100755 product-reviews-template/api/models/shopifyOrder/actions/create.js create mode 100755 product-reviews-template/api/models/shopifyOrder/actions/delete.js create mode 100755 product-reviews-template/api/models/shopifyOrder/actions/update.js create mode 100755 product-reviews-template/api/models/shopifyOrder/schema.gadget.ts create mode 100755 product-reviews-template/api/models/shopifyProduct/actions/create.js create mode 100755 product-reviews-template/api/models/shopifyProduct/actions/delete.js create mode 100755 product-reviews-template/api/models/shopifyProduct/actions/update.js create mode 100755 product-reviews-template/api/models/shopifyProduct/schema.gadget.ts create mode 100755 product-reviews-template/api/models/shopifyShop/actions/install.js create mode 100755 product-reviews-template/api/models/shopifyShop/actions/reinstall.js create mode 100755 product-reviews-template/api/models/shopifyShop/actions/uninstall.js create mode 100755 product-reviews-template/api/models/shopifyShop/actions/update.js create mode 100755 product-reviews-template/api/models/shopifyShop/schema.gadget.ts create mode 100755 product-reviews-template/api/models/shopifySync/actions/abort.js create mode 100755 product-reviews-template/api/models/shopifySync/actions/complete.js create mode 100755 product-reviews-template/api/models/shopifySync/actions/error.js create mode 100755 product-reviews-template/api/models/shopifySync/actions/run.js create mode 100755 product-reviews-template/api/models/shopifySync/schema.gadget.ts create mode 100755 product-reviews-template/index.html create mode 100755 product-reviews-template/package.json create mode 100755 product-reviews-template/settings.gadget.ts create mode 100755 product-reviews-template/vite.config.mjs create mode 100755 product-reviews-template/web/api.js create mode 100755 product-reviews-template/web/components/App.css create mode 100755 product-reviews-template/web/components/App.jsx create mode 100755 product-reviews-template/web/main.jsx create mode 100755 product-reviews-template/web/routes/about.jsx create mode 100755 product-reviews-template/web/routes/index.jsx create mode 100644 product-reviews-template/yarn.lock diff --git a/.github/workflows/product-reviews-template.yaml b/.github/workflows/product-reviews-template.yaml new file mode 100644 index 00000000..8e42c4c5 --- /dev/null +++ b/.github/workflows/product-reviews-template.yaml @@ -0,0 +1,21 @@ +name: Product Reviews Deployment + +on: + push: + paths: + - "product-reviews-template/**" + branches: + - main + workflow_dispatch: + +jobs: + push-to-development-environment: + runs-on: macos-latest + steps: + - name: Checkout the current repository + uses: actions/checkout@v4 + - name: Push to development environment + run: npx ggt push --app=product-reviews-template --env=development --force --allow-unknown-directory + working-directory: product-reviews-template/ + env: + GGT_TOKEN: ${{ secrets.PRODUCT_REVIEWS_DEPLOY_TOKEN }} diff --git a/product-reviews-template/.gitignore b/product-reviews-template/.gitignore new file mode 100755 index 00000000..430b978a --- /dev/null +++ b/product-reviews-template/.gitignore @@ -0,0 +1,3 @@ +.gadget/ +node_modules/ +**/.DS_Store \ No newline at end of file diff --git a/product-reviews-template/accessControl/filters/shopify/shopifyCustomer.gelly b/product-reviews-template/accessControl/filters/shopify/shopifyCustomer.gelly new file mode 100755 index 00000000..b3c39c4d --- /dev/null +++ b/product-reviews-template/accessControl/filters/shopify/shopifyCustomer.gelly @@ -0,0 +1,3 @@ +filter ($session: Session) on ShopifyCustomer [ + where shopId == $session.shopId +] diff --git a/product-reviews-template/accessControl/filters/shopify/shopifyGdprRequest.gelly b/product-reviews-template/accessControl/filters/shopify/shopifyGdprRequest.gelly new file mode 100755 index 00000000..2e5e7ff6 --- /dev/null +++ b/product-reviews-template/accessControl/filters/shopify/shopifyGdprRequest.gelly @@ -0,0 +1,3 @@ +filter ($session: Session) on ShopifyGdprRequest [ + where shopId == $session.shopId +] diff --git a/product-reviews-template/accessControl/filters/shopify/shopifyOrder.gelly b/product-reviews-template/accessControl/filters/shopify/shopifyOrder.gelly new file mode 100755 index 00000000..08aa30a8 --- /dev/null +++ b/product-reviews-template/accessControl/filters/shopify/shopifyOrder.gelly @@ -0,0 +1,3 @@ +filter ($session: Session) on ShopifyOrder [ + where shopId == $session.shopId +] diff --git a/product-reviews-template/accessControl/filters/shopify/shopifyProduct.gelly b/product-reviews-template/accessControl/filters/shopify/shopifyProduct.gelly new file mode 100755 index 00000000..00e4aa12 --- /dev/null +++ b/product-reviews-template/accessControl/filters/shopify/shopifyProduct.gelly @@ -0,0 +1,3 @@ +filter ($session: Session) on ShopifyProduct [ + where shopId == $session.shopId +] diff --git a/product-reviews-template/accessControl/filters/shopify/shopifyShop.gelly b/product-reviews-template/accessControl/filters/shopify/shopifyShop.gelly new file mode 100755 index 00000000..82dc1ae7 --- /dev/null +++ b/product-reviews-template/accessControl/filters/shopify/shopifyShop.gelly @@ -0,0 +1,3 @@ +filter ($session: Session) on ShopifyShop [ + where id == $session.shopId +] diff --git a/product-reviews-template/accessControl/filters/shopify/shopifySync.gelly b/product-reviews-template/accessControl/filters/shopify/shopifySync.gelly new file mode 100755 index 00000000..d4daf96e --- /dev/null +++ b/product-reviews-template/accessControl/filters/shopify/shopifySync.gelly @@ -0,0 +1,3 @@ +filter ($session: Session) on ShopifySync [ + where shopId == $session.shopId +] diff --git a/product-reviews-template/accessControl/permissions.gadget.ts b/product-reviews-template/accessControl/permissions.gadget.ts new file mode 100755 index 00000000..93c1fb45 --- /dev/null +++ b/product-reviews-template/accessControl/permissions.gadget.ts @@ -0,0 +1,76 @@ +import type { GadgetPermissions } from "gadget-server"; + +/** + * This metadata describes the access control configuration available in your application. + * Grants that are not defined here are set to false by default. + * + * View and edit your roles and permissions in the Gadget editor at https://product-reviews-template.gadget.app/edit/settings/permissions + */ +export const permissions: GadgetPermissions = { + type: "gadget/permissions/v1", + roles: { + "shopify-app-users": { + storageKey: "Role-Shopify-App", + models: { + shopifyCustomer: { + read: { + filter: + "accessControl/filters/shopify/shopifyCustomer.gelly", + }, + }, + shopifyGdprRequest: { + read: { + filter: + "accessControl/filters/shopify/shopifyGdprRequest.gelly", + }, + actions: { + create: true, + update: true, + }, + }, + shopifyOrder: { + read: { + filter: + "accessControl/filters/shopify/shopifyOrder.gelly", + }, + }, + shopifyProduct: { + read: { + filter: + "accessControl/filters/shopify/shopifyProduct.gelly", + }, + actions: { + create: true, + delete: true, + update: true, + }, + }, + shopifyShop: { + read: { + filter: "accessControl/filters/shopify/shopifyShop.gelly", + }, + actions: { + install: true, + reinstall: true, + uninstall: true, + update: true, + }, + }, + shopifySync: { + read: { + filter: "accessControl/filters/shopify/shopifySync.gelly", + }, + actions: { + abort: true, + complete: true, + error: true, + run: true, + }, + }, + }, + }, + unauthenticated: { + storageKey: "unauthenticated", + }, + }, +}; diff --git a/product-reviews-template/api/models/review/actions/create.js b/product-reviews-template/api/models/review/actions/create.js new file mode 100755 index 00000000..df4bb1db --- /dev/null +++ b/product-reviews-template/api/models/review/actions/create.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, CreateReviewActionContext } from "gadget-server"; + +/** + * @param { CreateReviewActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await save(record); +}; + +/** + * @param { CreateReviewActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { + actionType: "create", +}; diff --git a/product-reviews-template/api/models/review/actions/delete.js b/product-reviews-template/api/models/review/actions/delete.js new file mode 100755 index 00000000..7ec089e2 --- /dev/null +++ b/product-reviews-template/api/models/review/actions/delete.js @@ -0,0 +1,20 @@ +import { deleteRecord, ActionOptions, DeleteReviewActionContext } from "gadget-server"; + +/** + * @param { DeleteReviewActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + await deleteRecord(record); +}; + +/** + * @param { DeleteReviewActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { + actionType: "delete", +}; diff --git a/product-reviews-template/api/models/review/actions/update.js b/product-reviews-template/api/models/review/actions/update.js new file mode 100755 index 00000000..a798f7db --- /dev/null +++ b/product-reviews-template/api/models/review/actions/update.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, UpdateReviewActionContext } from "gadget-server"; + +/** + * @param { UpdateReviewActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await save(record); +}; + +/** + * @param { UpdateReviewActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { + actionType: "update", +}; diff --git a/product-reviews-template/api/models/review/schema.gadget.ts b/product-reviews-template/api/models/review/schema.gadget.ts new file mode 100755 index 00000000..e55496a2 --- /dev/null +++ b/product-reviews-template/api/models/review/schema.gadget.ts @@ -0,0 +1,28 @@ +import type { GadgetModel } from "gadget-server"; + +// This file describes the schema for the "review" model, go to https://product-reviews-template.gadget.app/edit to view/edit your model in Gadget +// For more information on how to update this file http://docs.gadget.dev + +export const schema: GadgetModel = { + type: "gadget/model-schema/v1", + storageKey: "05LmzBe_CIyf", + fields: { + customer: { + type: "belongsTo", + validations: { required: true }, + parent: { model: "shopifyCustomer" }, + storageKey: "bT0Adl6mg5Lc", + }, + order: { + type: "belongsTo", + parent: { model: "shopifyOrder" }, + storageKey: "6cS42mJLsWyc", + }, + product: { + type: "belongsTo", + validations: { required: true }, + parent: { model: "shopifyProduct" }, + storageKey: "YkA-cs5aMejq", + }, + }, +}; diff --git a/product-reviews-template/api/models/session/schema.gadget.ts b/product-reviews-template/api/models/session/schema.gadget.ts new file mode 100755 index 00000000..deec3e00 --- /dev/null +++ b/product-reviews-template/api/models/session/schema.gadget.ts @@ -0,0 +1,17 @@ +import type { GadgetModel } from "gadget-server"; + +// This file describes the schema for the "session" model, go to https://product-reviews-template.gadget.app/edit to view/edit your model in Gadget +// For more information on how to update this file http://docs.gadget.dev + +export const schema: GadgetModel = { + type: "gadget/model-schema/v1", + storageKey: "KhzynW8lzIdN", + fields: { + roles: { + type: "roleList", + default: ["unauthenticated"], + storageKey: "3GhoUYEo3Lq4", + }, + }, + shopify: { fields: ["shop", "shopifySID"] }, +}; diff --git a/product-reviews-template/api/models/shopifyCustomer/actions/create.js b/product-reviews-template/api/models/shopifyCustomer/actions/create.js new file mode 100755 index 00000000..2397a375 --- /dev/null +++ b/product-reviews-template/api/models/shopifyCustomer/actions/create.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, CreateShopifyCustomerActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { CreateShopifyCustomerActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +/** + * @param { CreateShopifyCustomerActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "create" }; diff --git a/product-reviews-template/api/models/shopifyCustomer/actions/delete.js b/product-reviews-template/api/models/shopifyCustomer/actions/delete.js new file mode 100755 index 00000000..8f4d586e --- /dev/null +++ b/product-reviews-template/api/models/shopifyCustomer/actions/delete.js @@ -0,0 +1,20 @@ +import { deleteRecord, ActionOptions, DeleteShopifyCustomerActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { DeleteShopifyCustomerActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + await preventCrossShopDataAccess(params, record); + await deleteRecord(record); +}; + +/** + * @param { DeleteShopifyCustomerActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "delete" }; diff --git a/product-reviews-template/api/models/shopifyCustomer/actions/update.js b/product-reviews-template/api/models/shopifyCustomer/actions/update.js new file mode 100755 index 00000000..0e97ed80 --- /dev/null +++ b/product-reviews-template/api/models/shopifyCustomer/actions/update.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, UpdateShopifyCustomerActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { UpdateShopifyCustomerActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +/** + * @param { UpdateShopifyCustomerActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "update" }; diff --git a/product-reviews-template/api/models/shopifyCustomer/schema.gadget.ts b/product-reviews-template/api/models/shopifyCustomer/schema.gadget.ts new file mode 100755 index 00000000..f8487f96 --- /dev/null +++ b/product-reviews-template/api/models/shopifyCustomer/schema.gadget.ts @@ -0,0 +1,48 @@ +import type { GadgetModel } from "gadget-server"; + +// This file describes the schema for the "shopifyCustomer" model, go to https://product-reviews-template.gadget.app/edit to view/edit your model in Gadget +// For more information on how to update this file http://docs.gadget.dev + +export const schema: GadgetModel = { + type: "gadget/model-schema/v1", + storageKey: "DataModel-Shopify-Customer", + fields: { + reviews: { + type: "hasMany", + children: { model: "review", belongsToField: "customer" }, + storageKey: "iRGpo9xzz4J3", + }, + }, + shopify: { + fields: [ + "acceptsMarketing", + "acceptsMarketingUpdatedAt", + "currency", + "dataSaleOptOut", + "email", + "emailMarketingConsent", + "firstName", + "lastName", + "lastOrder", + "lastOrderName", + "marketingOptInLevel", + "metafield", + "multipassIdentifier", + "note", + "orders", + "ordersCount", + "phone", + "shop", + "shopifyCreatedAt", + "shopifyState", + "shopifyUpdatedAt", + "smsMarketingConsent", + "statistics", + "tags", + "taxExempt", + "taxExemptions", + "totalSpent", + "verifiedEmail", + ], + }, +}; diff --git a/product-reviews-template/api/models/shopifyGdprRequest/actions/create.js b/product-reviews-template/api/models/shopifyGdprRequest/actions/create.js new file mode 100755 index 00000000..bc8ee23f --- /dev/null +++ b/product-reviews-template/api/models/shopifyGdprRequest/actions/create.js @@ -0,0 +1,35 @@ +import { applyParams, save, ActionOptions, CreateShopifyGdprRequestActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { CreateShopifyGdprRequestActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +/** + * @param { CreateShopifyGdprRequestActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + 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. + // See https://shopify.dev/apps/webhooks/configuration/mandatory-webhooks#customers-data_request for more information. + break; + 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": + // 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 = { actionType: "create" }; diff --git a/product-reviews-template/api/models/shopifyGdprRequest/actions/update.js b/product-reviews-template/api/models/shopifyGdprRequest/actions/update.js new file mode 100755 index 00000000..a61bc466 --- /dev/null +++ b/product-reviews-template/api/models/shopifyGdprRequest/actions/update.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, UpdateShopifyGdprRequestActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { UpdateShopifyGdprRequestActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +/** + * @param { UpdateShopifyGdprRequestActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "update" }; diff --git a/product-reviews-template/api/models/shopifyGdprRequest/schema.gadget.ts b/product-reviews-template/api/models/shopifyGdprRequest/schema.gadget.ts new file mode 100755 index 00000000..5ae21adc --- /dev/null +++ b/product-reviews-template/api/models/shopifyGdprRequest/schema.gadget.ts @@ -0,0 +1,10 @@ +import type { GadgetModel } from "gadget-server"; + +// This file describes the schema for the "shopifyGdprRequest" model, go to https://product-reviews-template.gadget.app/edit to view/edit your model in Gadget +// For more information on how to update this file http://docs.gadget.dev + +export const schema: GadgetModel = { + type: "gadget/model-schema/v1", + storageKey: "DataModel-Shopify-GdprRequest", + fields: {}, +}; diff --git a/product-reviews-template/api/models/shopifyOrder/actions/create.js b/product-reviews-template/api/models/shopifyOrder/actions/create.js new file mode 100755 index 00000000..1591a829 --- /dev/null +++ b/product-reviews-template/api/models/shopifyOrder/actions/create.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, CreateShopifyOrderActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { CreateShopifyOrderActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +/** + * @param { CreateShopifyOrderActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "create" }; diff --git a/product-reviews-template/api/models/shopifyOrder/actions/delete.js b/product-reviews-template/api/models/shopifyOrder/actions/delete.js new file mode 100755 index 00000000..eda11bf8 --- /dev/null +++ b/product-reviews-template/api/models/shopifyOrder/actions/delete.js @@ -0,0 +1,20 @@ +import { deleteRecord, ActionOptions, DeleteShopifyOrderActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { DeleteShopifyOrderActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + await preventCrossShopDataAccess(params, record); + await deleteRecord(record); +}; + +/** + * @param { DeleteShopifyOrderActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "delete" }; diff --git a/product-reviews-template/api/models/shopifyOrder/actions/update.js b/product-reviews-template/api/models/shopifyOrder/actions/update.js new file mode 100755 index 00000000..28592ff3 --- /dev/null +++ b/product-reviews-template/api/models/shopifyOrder/actions/update.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, UpdateShopifyOrderActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { UpdateShopifyOrderActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +/** + * @param { UpdateShopifyOrderActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "update" }; diff --git a/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts b/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts new file mode 100755 index 00000000..abad22aa --- /dev/null +++ b/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts @@ -0,0 +1,97 @@ +import type { GadgetModel } from "gadget-server"; + +// This file describes the schema for the "shopifyOrder" model, go to https://product-reviews-template.gadget.app/edit to view/edit your model in Gadget +// For more information on how to update this file http://docs.gadget.dev + +export const schema: GadgetModel = { + type: "gadget/model-schema/v1", + storageKey: "DataModel-Shopify-Order", + fields: { + reviews: { + type: "hasMany", + children: { model: "review", belongsToField: "order" }, + storageKey: "HdNAduYTU3-G", + }, + }, + shopify: { + fields: [ + "additionalFees", + "billingAddress", + "browserIp", + "buyerAcceptsMarketing", + "cancelReason", + "cancellation", + "cancelledAt", + "cartToken", + "checkoutToken", + "clientDetails", + "closedAt", + "currency", + "currentSubtotalPrice", + "currentSubtotalPriceSet", + "currentTotalAdditionalFeesSet", + "currentTotalDiscounts", + "currentTotalDiscountsSet", + "currentTotalDutiesSet", + "currentTotalPrice", + "currentTotalPriceSet", + "currentTotalTax", + "currentTotalTaxSet", + "customer", + "customerLocale", + "discountApplications", + "discountCodes", + "email", + "estimatedTaxes", + "financialStatus", + "fulfillmentStatus", + "fulfillmentsCount", + "landingSite", + "merchantOfRecordAppId", + "name", + "note", + "noteAttributes", + "number", + "orderNumber", + "orderStatusUrl", + "originalTotalAdditionalFeesSet", + "originalTotalDutiesSet", + "paymentGatewayNames", + "phone", + "poNumber", + "presentmentCurrency", + "processedAt", + "referringSite", + "risk", + "shippingAddress", + "shop", + "shopifyCreatedAt", + "shopifyProtect", + "shopifyUpdatedAt", + "sourceIdentifier", + "sourceName", + "sourceUrl", + "subtotalPrice", + "subtotalPriceSet", + "tags", + "taxExempt", + "taxLines", + "taxesIncluded", + "test", + "token", + "totalDiscounts", + "totalDiscountsSet", + "totalLineItemsPrice", + "totalLineItemsPriceSet", + "totalOutstanding", + "totalPrice", + "totalPriceSet", + "totalShippingPriceSet", + "totalTax", + "totalTaxSet", + "totalTipReceived", + "totalWeight", + "transactionsCount", + ], + }, +}; diff --git a/product-reviews-template/api/models/shopifyProduct/actions/create.js b/product-reviews-template/api/models/shopifyProduct/actions/create.js new file mode 100755 index 00000000..92ac9e7b --- /dev/null +++ b/product-reviews-template/api/models/shopifyProduct/actions/create.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, CreateShopifyProductActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { CreateShopifyProductActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +/** + * @param { CreateShopifyProductActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "create" }; diff --git a/product-reviews-template/api/models/shopifyProduct/actions/delete.js b/product-reviews-template/api/models/shopifyProduct/actions/delete.js new file mode 100755 index 00000000..6a5f95b9 --- /dev/null +++ b/product-reviews-template/api/models/shopifyProduct/actions/delete.js @@ -0,0 +1,20 @@ +import { deleteRecord, ActionOptions, DeleteShopifyProductActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { DeleteShopifyProductActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + await preventCrossShopDataAccess(params, record); + await deleteRecord(record); +}; + +/** + * @param { DeleteShopifyProductActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "delete" }; diff --git a/product-reviews-template/api/models/shopifyProduct/actions/update.js b/product-reviews-template/api/models/shopifyProduct/actions/update.js new file mode 100755 index 00000000..f3acd1ad --- /dev/null +++ b/product-reviews-template/api/models/shopifyProduct/actions/update.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, UpdateShopifyProductActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { UpdateShopifyProductActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +/** + * @param { UpdateShopifyProductActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "update" }; diff --git a/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts b/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts new file mode 100755 index 00000000..562198d4 --- /dev/null +++ b/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts @@ -0,0 +1,35 @@ +import type { GadgetModel } from "gadget-server"; + +// This file describes the schema for the "shopifyProduct" model, go to https://product-reviews-template.gadget.app/edit to view/edit your model in Gadget +// For more information on how to update this file http://docs.gadget.dev + +export const schema: GadgetModel = { + type: "gadget/model-schema/v1", + storageKey: "DataModel-Shopify-Product", + fields: { + reviews: { + type: "hasMany", + children: { model: "review", belongsToField: "product" }, + storageKey: "9q0TXpTv2hmS", + }, + }, + shopify: { + fields: [ + "body", + "category", + "compareAtPriceRange", + "handle", + "productCategory", + "productType", + "publishedAt", + "shop", + "shopifyCreatedAt", + "shopifyUpdatedAt", + "status", + "tags", + "templateSuffix", + "title", + "vendor", + ], + }, +}; diff --git a/product-reviews-template/api/models/shopifyShop/actions/install.js b/product-reviews-template/api/models/shopifyShop/actions/install.js new file mode 100755 index 00000000..d11f76e2 --- /dev/null +++ b/product-reviews-template/api/models/shopifyShop/actions/install.js @@ -0,0 +1,19 @@ +import { applyParams, save, ActionOptions, InstallShopifyShopActionContext } from "gadget-server"; + +/** + * @param { InstallShopifyShopActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await save(record); +}; + +/** + * @param { InstallShopifyShopActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "create" }; diff --git a/product-reviews-template/api/models/shopifyShop/actions/reinstall.js b/product-reviews-template/api/models/shopifyShop/actions/reinstall.js new file mode 100755 index 00000000..8f6a5538 --- /dev/null +++ b/product-reviews-template/api/models/shopifyShop/actions/reinstall.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, ReinstallShopifyShopActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { ReinstallShopifyShopActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +/** + * @param { ReinstallShopifyShopActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "update" }; diff --git a/product-reviews-template/api/models/shopifyShop/actions/uninstall.js b/product-reviews-template/api/models/shopifyShop/actions/uninstall.js new file mode 100755 index 00000000..8edc501c --- /dev/null +++ b/product-reviews-template/api/models/shopifyShop/actions/uninstall.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, UninstallShopifyShopActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { UninstallShopifyShopActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +/** + * @param { UninstallShopifyShopActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "update" }; diff --git a/product-reviews-template/api/models/shopifyShop/actions/update.js b/product-reviews-template/api/models/shopifyShop/actions/update.js new file mode 100755 index 00000000..7b09e353 --- /dev/null +++ b/product-reviews-template/api/models/shopifyShop/actions/update.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, UpdateShopifyShopActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { UpdateShopifyShopActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +/** + * @param { UpdateShopifyShopActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "update" }; diff --git a/product-reviews-template/api/models/shopifyShop/schema.gadget.ts b/product-reviews-template/api/models/shopifyShop/schema.gadget.ts new file mode 100755 index 00000000..9eaace11 --- /dev/null +++ b/product-reviews-template/api/models/shopifyShop/schema.gadget.ts @@ -0,0 +1,74 @@ +import type { GadgetModel } from "gadget-server"; + +// This file describes the schema for the "shopifyShop" model, go to https://product-reviews-template.gadget.app/edit to view/edit your model in Gadget +// For more information on how to update this file http://docs.gadget.dev + +export const schema: GadgetModel = { + type: "gadget/model-schema/v1", + storageKey: "DataModel-Shopify-Shop", + fields: {}, + shopify: { + fields: [ + "address1", + "address2", + "checkoutApiSupported", + "city", + "cookieConsentLevel", + "country", + "countryCode", + "countryName", + "countyTaxes", + "currency", + "customerAccountsV2", + "customerEmail", + "customers", + "domain", + "eligibleForCardReaderGiveaway", + "eligibleForPayments", + "email", + "enabledPresentmentCurrencies", + "finances", + "forceSsl", + "gdprRequests", + "googleAppsDomain", + "googleAppsLoginEnabled", + "hasDiscounts", + "hasGiftCards", + "hasStorefront", + "ianaTimezone", + "latitude", + "longitude", + "marketingSmsContentEnabledAtCheckout", + "moneyFormat", + "moneyInEmailsFormat", + "moneyWithCurrencyFormat", + "moneyWithCurrencyInEmailsFormat", + "multiLocationEnabled", + "myshopifyDomain", + "name", + "orders", + "passwordEnabled", + "phone", + "planDisplayName", + "planName", + "preLaunchEnabled", + "primaryLocale", + "products", + "province", + "provinceCode", + "requiresExtraPaymentsAgreement", + "setupRequired", + "shopOwner", + "shopifyCreatedAt", + "shopifyUpdatedAt", + "source", + "syncs", + "taxShipping", + "taxesIncluded", + "timezone", + "transactionalSmsDisabled", + "weightUnit", + "zipCode", + ], + }, +}; diff --git a/product-reviews-template/api/models/shopifySync/actions/abort.js b/product-reviews-template/api/models/shopifySync/actions/abort.js new file mode 100755 index 00000000..5e79c252 --- /dev/null +++ b/product-reviews-template/api/models/shopifySync/actions/abort.js @@ -0,0 +1,25 @@ +import { applyParams, save, ActionOptions, AbortShopifySyncActionContext } from "gadget-server"; +import { preventCrossShopDataAccess, abortSync } from "gadget-server/shopify"; + +/** + * @param { AbortShopifySyncActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await abortSync(params, record); + await save(record); +}; + +/** + * @param { AbortShopifySyncActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { + actionType: "update", + triggers: { api: true }, +}; diff --git a/product-reviews-template/api/models/shopifySync/actions/complete.js b/product-reviews-template/api/models/shopifySync/actions/complete.js new file mode 100755 index 00000000..d18213d9 --- /dev/null +++ b/product-reviews-template/api/models/shopifySync/actions/complete.js @@ -0,0 +1,24 @@ +import { applyParams, save, ActionOptions, CompleteShopifySyncActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { CompleteShopifySyncActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +/** + * @param { CompleteShopifySyncActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { + actionType: "update", + triggers: { api: true }, +}; diff --git a/product-reviews-template/api/models/shopifySync/actions/error.js b/product-reviews-template/api/models/shopifySync/actions/error.js new file mode 100755 index 00000000..fb04c884 --- /dev/null +++ b/product-reviews-template/api/models/shopifySync/actions/error.js @@ -0,0 +1,24 @@ +import { applyParams, save, ActionOptions, ErrorShopifySyncActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { ErrorShopifySyncActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +/** + * @param { ErrorShopifySyncActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { + actionType: "update", + triggers: { api: true }, +}; diff --git a/product-reviews-template/api/models/shopifySync/actions/run.js b/product-reviews-template/api/models/shopifySync/actions/run.js new file mode 100755 index 00000000..e74ae649 --- /dev/null +++ b/product-reviews-template/api/models/shopifySync/actions/run.js @@ -0,0 +1,25 @@ +import { applyParams, save, ActionOptions, RunShopifySyncActionContext } from "gadget-server"; +import { preventCrossShopDataAccess, shopifySync } from "gadget-server/shopify"; + +/** + * @param { RunShopifySyncActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + 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, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { + actionType: "create", + triggers: { api: true }, +}; diff --git a/product-reviews-template/api/models/shopifySync/schema.gadget.ts b/product-reviews-template/api/models/shopifySync/schema.gadget.ts new file mode 100755 index 00000000..9ec2342e --- /dev/null +++ b/product-reviews-template/api/models/shopifySync/schema.gadget.ts @@ -0,0 +1,10 @@ +import type { GadgetModel } from "gadget-server"; + +// This file describes the schema for the "shopifySync" model, go to https://product-reviews-template.gadget.app/edit to view/edit your model in Gadget +// For more information on how to update this file http://docs.gadget.dev + +export const schema: GadgetModel = { + type: "gadget/model-schema/v1", + storageKey: "DataModel-Shopify-Sync", + fields: {}, +}; diff --git a/product-reviews-template/index.html b/product-reviews-template/index.html new file mode 100755 index 00000000..67ede397 --- /dev/null +++ b/product-reviews-template/index.html @@ -0,0 +1,19 @@ + + + + + New Gadget App Welcome Page + + + + + + + + + + +
+ + + diff --git a/product-reviews-template/package.json b/product-reviews-template/package.json new file mode 100755 index 00000000..2e0234ae --- /dev/null +++ b/product-reviews-template/package.json @@ -0,0 +1,31 @@ +{ + "name": "product-reviews-template", + "version": "0.1.0", + "description": "Internal package for Gadget app product-reviews-template (Development environment)", + "license": "UNLICENSED", + "private": true, + "scripts": { + "build": "NODE_ENV=production vite build" + }, + "dependencies": { + "@gadget-client/product-reviews-template": "link:.gadget/client", + "@gadgetinc/react": "^0.16.1", + "@gadgetinc/react-shopify-app-bridge": "^0.16.0", + "@shopify/app-bridge-react": "4.0.0", + "@shopify/polaris": "^13.8.0", + "@shopify/polaris-icons": "^9.3.0", + "gadget-server": "link:.gadget/server", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "6.15.0", + "shopify-api-node": "^3.12.6" + }, + "devDependencies": { + "@types/node": "^20.12.8", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "@vitejs/plugin-react-swc": "3.2.0", + "typescript": "^5.4.5", + "vite": "^5.3.5" + } +} \ No newline at end of file diff --git a/product-reviews-template/settings.gadget.ts b/product-reviews-template/settings.gadget.ts new file mode 100755 index 00000000..2f29d507 --- /dev/null +++ b/product-reviews-template/settings.gadget.ts @@ -0,0 +1,25 @@ +import type { GadgetSettings } from "gadget-server"; + +export const settings: GadgetSettings = { + type: "gadget/settings/v1", + frameworkVersion: "v1.2.0", + plugins: { + connections: { + shopify: { + apiVersion: "2024-07", + enabledModels: [ + "shopifyCustomer", + "shopifyOrder", + "shopifyProduct", + ], + type: "partner", + scopes: [ + "write_products", + "read_products", + "read_orders", + "read_customers", + ], + }, + }, + }, +}; diff --git a/product-reviews-template/vite.config.mjs b/product-reviews-template/vite.config.mjs new file mode 100755 index 00000000..778c299f --- /dev/null +++ b/product-reviews-template/vite.config.mjs @@ -0,0 +1,8 @@ +import react from "@vitejs/plugin-react-swc"; +import { defineConfig } from "vite"; +import { gadget } from "gadget-server/vite"; + +export default defineConfig({ + plugins: [gadget(), react()], + clearScreen: false, +}); diff --git a/product-reviews-template/web/api.js b/product-reviews-template/web/api.js new file mode 100755 index 00000000..77d884b5 --- /dev/null +++ b/product-reviews-template/web/api.js @@ -0,0 +1,5 @@ +// Sets up the API client for interacting with your backend. +// For your API reference, visit: https://docs.gadget.dev/api/product-reviews-template +import { Client } from "@gadget-client/product-reviews-template"; + +export const api = new Client({ environment: window.gadgetConfig.environment }); diff --git a/product-reviews-template/web/components/App.css b/product-reviews-template/web/components/App.css new file mode 100755 index 00000000..9f7cf831 --- /dev/null +++ b/product-reviews-template/web/components/App.css @@ -0,0 +1,4 @@ +.gadgetLogo { + margin: 14px auto; + height: 44px; +} diff --git a/product-reviews-template/web/components/App.jsx b/product-reviews-template/web/components/App.jsx new file mode 100755 index 00000000..b9a2a35b --- /dev/null +++ b/product-reviews-template/web/components/App.jsx @@ -0,0 +1,128 @@ +import { + AppType, + Provider as GadgetProvider, + useGadget, +} from "@gadgetinc/react-shopify-app-bridge"; +import { NavMenu } from "@shopify/app-bridge-react"; +import { Box, Card, Page, Spinner, Text } from "@shopify/polaris"; +import { useEffect } from "react"; +import { + Link, + Outlet, + Route, + RouterProvider, + createBrowserRouter, + createRoutesFromElements, + useLocation, + useNavigate, +} from "react-router-dom"; +import { api } from "../api"; +import AboutPage from "../routes/about"; +import Index from "../routes/index"; +import "./App.css"; + +function Error404() { + const navigate = useNavigate(); + const location = useLocation(); + + useEffect(() => { + const appURL = process.env.GADGET_PUBLIC_SHOPIFY_APP_URL; + + if (appURL && location.pathname === new URL(appURL).pathname) { + navigate("/", { replace: true }); + } + }, [location.pathname]); + + return
404 not found
; +} + +function App() { + const router = createBrowserRouter( + createRoutesFromElements( + }> + } /> + } /> + } /> + + ) + ); + + return ( + <> + + + ); +} + +function Layout() { + return ( + + + + ); +} + +function AuthenticatedApp() { + // we use `isAuthenticated` to render pages once the OAuth flow is complete! + const { isAuthenticated, loading } = useGadget(); + if (loading) { + return ( +
+ +
+ ); + } + return isAuthenticated ? : ; +} + +function EmbeddedApp() { + return ( + <> + + + + Shop Information + + About + + + ); +} + +function UnauthenticatedApp() { + return ( + +
+ + + App must be viewed in the Shopify Admin + + + + Edit this page:{" "} + + web/components/App.jsx + + + + +
+
+ ); +} + +export default App; diff --git a/product-reviews-template/web/main.jsx b/product-reviews-template/web/main.jsx new file mode 100755 index 00000000..0f2d586e --- /dev/null +++ b/product-reviews-template/web/main.jsx @@ -0,0 +1,17 @@ +import { AppProvider } from "@shopify/polaris"; +import "@shopify/polaris/build/esm/styles.css"; +import enTranslations from "@shopify/polaris/locales/en.json"; +import React from "react"; +import ReactDOM from "react-dom/client"; +import App from "./components/App"; + +const root = document.getElementById("root"); +if (!root) throw new Error("#root element not found for booting react app"); + +ReactDOM.createRoot(root).render( + + + + + +); diff --git a/product-reviews-template/web/routes/about.jsx b/product-reviews-template/web/routes/about.jsx new file mode 100755 index 00000000..62e530d2 --- /dev/null +++ b/product-reviews-template/web/routes/about.jsx @@ -0,0 +1,20 @@ +import { Page, Text } from "@shopify/polaris"; +import { useNavigate } from "react-router-dom"; + +export default function () { + const navigate = useNavigate(); + + return ( + navigate("/"), + }} + > + + This is a simple Shopify Embedded App. + + + ); +} diff --git a/product-reviews-template/web/routes/index.jsx b/product-reviews-template/web/routes/index.jsx new file mode 100755 index 00000000..d8c648d7 --- /dev/null +++ b/product-reviews-template/web/routes/index.jsx @@ -0,0 +1,69 @@ +import { AutoTable } from "@gadgetinc/react/auto/polaris"; +import { + Banner, + BlockStack, + Box, + Card, + Layout, + Link, + Page, + Text, +} from "@shopify/polaris"; +import { api } from "../api"; + +export default function () { + return ( + + + + + + Successfully connected your Gadget app to Shopify + + + + + + + + + Edit this page:{" "} + + web/routes/index.jsx + + + + + + + + {/* use Autocomponents to build UI quickly: https://docs.gadget.dev/guides/frontend/autocomponents */} + + + + Shop records fetched from:{" "} + + api/models/shopifyShop/data + + + + + + + + ); +} diff --git a/product-reviews-template/yarn.lock b/product-reviews-template/yarn.lock new file mode 100644 index 00000000..2287d98e --- /dev/null +++ b/product-reviews-template/yarn.lock @@ -0,0 +1,1567 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@0no-co/graphql.web@^1.0.1", "@0no-co/graphql.web@^1.0.4", "@0no-co/graphql.web@^1.0.5": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@0no-co/graphql.web/-/graphql.web-1.0.7.tgz#c7a762c887b3482a79ffa68f63de5e96059a62e4" + integrity sha512-E3Qku4mTzdrlwVWGPxklDnME5ANrEGetvYw4i2GCRlppWXXE4QD66j7pwb8HelZwS6LnqEChhrSOGCXpbiu6MQ== + +"@babel/runtime@^7.21.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.0.tgz#3af9a91c1b739c569d5d80cc917280919c544ecb" + integrity sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw== + dependencies: + regenerator-runtime "^0.14.0" + +"@esbuild/aix-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" + integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== + +"@esbuild/android-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" + integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== + +"@esbuild/android-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" + integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== + +"@esbuild/android-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" + integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== + +"@esbuild/darwin-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" + integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== + +"@esbuild/darwin-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" + integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== + +"@esbuild/freebsd-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" + integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== + +"@esbuild/freebsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" + integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== + +"@esbuild/linux-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" + integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== + +"@esbuild/linux-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" + integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== + +"@esbuild/linux-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" + integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== + +"@esbuild/linux-loong64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" + integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== + +"@esbuild/linux-mips64el@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" + integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== + +"@esbuild/linux-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" + integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== + +"@esbuild/linux-riscv64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" + integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== + +"@esbuild/linux-s390x@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" + integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== + +"@esbuild/linux-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" + integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== + +"@esbuild/netbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" + integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== + +"@esbuild/openbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" + integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== + +"@esbuild/sunos-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" + integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== + +"@esbuild/win32-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" + integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== + +"@esbuild/win32-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" + integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== + +"@esbuild/win32-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== + +"@fastify/ajv-compiler@^3.5.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@fastify/ajv-compiler/-/ajv-compiler-3.6.0.tgz#907497a0e62a42b106ce16e279cf5788848e8e79" + integrity sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ== + dependencies: + ajv "^8.11.0" + ajv-formats "^2.1.1" + fast-uri "^2.0.0" + +"@fastify/error@^3.3.0", "@fastify/error@^3.4.0": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@fastify/error/-/error-3.4.1.tgz#b14bb4cac3dd4ec614becbc643d1511331a6425c" + integrity sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ== + +"@fastify/fast-json-stringify-compiler@^4.3.0": + version "4.3.0" + resolved "https://registry.yarnpkg.com/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-4.3.0.tgz#5df89fa4d1592cbb8780f78998355feb471646d5" + integrity sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA== + dependencies: + fast-json-stringify "^5.7.0" + +"@fastify/merge-json-schemas@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@fastify/merge-json-schemas/-/merge-json-schemas-0.1.1.tgz#3551857b8a17a24e8c799e9f51795edb07baa0bc" + integrity sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA== + dependencies: + fast-deep-equal "^3.1.3" + +"@fastify/request-context@^5.0.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@fastify/request-context/-/request-context-5.1.0.tgz#e1fdc103767af977485f19501c117eb59a49d30a" + integrity sha512-PM7wrLJOEylVDpxabOFLaYsdAiaa0lpDUcP2HMFJ1JzgiWuC6k4r3duf6Pm9YLnzlGmT+Yp4tkQjqsu7V/pSOA== + dependencies: + fastify-plugin "^4.0.0" + +"@gadget-client/product-reviews-template@link:.gadget/client": + version "0.0.0" + uid "" + +"@gadgetinc/api-client-core@0.15.30", "@gadgetinc/api-client-core@^0.15.13", "@gadgetinc/api-client-core@^0.15.24": + version "0.15.30" + resolved "https://registry.yarnpkg.com/@gadgetinc/api-client-core/-/api-client-core-0.15.30.tgz#73756633eee48b5e250b3a7451e97072a87d24bd" + integrity sha512-7rdA6exg9OOXRReXt0DL3YIMmZvG7XWOTwB9KIoWAxKKF1fCblr+hHm/bQsd3AZiUDRVj/9ga1fWhuKRR3SfbQ== + dependencies: + "@0no-co/graphql.web" "^1.0.4" + "@n1ru4l/graphql-live-query" "^0.10.0" + "@n1ru4l/json-patch-plus" "^0.2.0" + "@n1ru4l/push-pull-async-iterable-iterator" "^3.2.0" + "@urql/core" "^4.0.10" + cross-fetch "^4.0.0" + graphql "^16.8.1" + graphql-ws "^5.13.1" + isomorphic-ws "^5.0.0" + klona "^2.0.6" + tiny-graphql-query-compiler "^0.2.2" + tslib "^2.6.2" + type-fest "^3.13.1" + wonka "^6.3.2" + ws "^8.17.0" + +"@gadgetinc/react-shopify-app-bridge@^0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@gadgetinc/react-shopify-app-bridge/-/react-shopify-app-bridge-0.16.0.tgz#a27052901f4d12261de0989012ede4ded6294c3a" + integrity sha512-W7VZ0MBf2FRiZsP2pL3nIr1E3VgvZixYCuxCJj51OxuS51JCNIkb2SULhdHbO+W9jJPJIuZv+KsAav6Crmel4w== + dependencies: + "@gadgetinc/api-client-core" "^0.15.13" + crypto-js "^4.2.0" + tslib "^2.6.2" + +"@gadgetinc/react@^0.16.1": + version "0.16.2" + resolved "https://registry.yarnpkg.com/@gadgetinc/react/-/react-0.16.2.tgz#5170e1c19304b5bc941f606d4f054f2ec6121d69" + integrity sha512-1oVShl00miQwcVzSEWwE/DLCO+4JhZWICBveDXRjt31n7s5nrjt7N+X2FS3MdY87eS7H2fNn5asxVGtzPIMu8w== + dependencies: + "@0no-co/graphql.web" "^1.0.4" + "@gadgetinc/api-client-core" "^0.15.24" + "@hookform/resolvers" "^3.3.1" + date-fns "^2.30.0" + date-fns-tz "^2.0.0" + filesize "^10.1.2" + pluralize "^8.0.0" + react-fast-compare "^3.2.2" + react-hook-form "~7.48.2" + tslib "^2.6.2" + urql "^4.0.4" + yup "^1.2.0" + +"@hookform/resolvers@^3.3.1": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-3.9.0.tgz#cf540ac21c6c0cd24a40cf53d8e6d64391fb753d" + integrity sha512-bU0Gr4EepJ/EQsH/IwEzYLsT/PEj5C0ynLQ4m+GSHS+xKH4TfSelhluTgOaoc4kA5s7eCsQbM4wvZLzELmWzUg== + +"@n1ru4l/graphql-live-query@^0.10.0": + version "0.10.0" + resolved "https://registry.yarnpkg.com/@n1ru4l/graphql-live-query/-/graphql-live-query-0.10.0.tgz#2306151630b0e74b017cc1067ebbea351acf56f8" + integrity sha512-qZ7OHH/NB0NcG/Xa7irzgjE63UH0CkofZT0Bw4Ko6iRFagPRHBM8RgFXwTt/6JbFGIEUS4STRtaFoc/Eq/ZtzQ== + +"@n1ru4l/json-patch-plus@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@n1ru4l/json-patch-plus/-/json-patch-plus-0.2.0.tgz#b8fa09fd980c3460dfdc109a7c4cc5590157aa6b" + integrity sha512-pLkJy83/rVfDTyQgDSC8GeXAHEdXNHGNJrB1b7wAyGQu0iv7tpMXntKVSqj0+XKNVQbco40SZffNfVALzIt0SQ== + +"@n1ru4l/push-pull-async-iterable-iterator@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@n1ru4l/push-pull-async-iterable-iterator/-/push-pull-async-iterable-iterator-3.2.0.tgz#c15791112db68dd9315d329d652b7e797f737655" + integrity sha512-3fkKj25kEjsfObL6IlKPAlHYPq/oYwUkkQ03zsTTiDjD7vg/RxjdiLeCydqtxHZP0JgsXL3D/X5oAkMGzuUp/Q== + +"@remix-run/router@1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.8.0.tgz#e848d2f669f601544df15ce2a313955e4bf0bafc" + integrity sha512-mrfKqIHnSZRyIzBcanNJmVQELTnX+qagEDlcKO90RgRBVOZGSGvZKeDihTRfWcqoDn5N/NkUcwWTccnpN18Tfg== + +"@rollup/rollup-android-arm-eabi@4.21.0": + version "4.21.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.0.tgz#d941173f82f9b041c61b0dc1a2a91dcd06e4b31e" + integrity sha512-WTWD8PfoSAJ+qL87lE7votj3syLavxunWhzCnx3XFxFiI/BA/r3X7MUM8dVrH8rb2r4AiO8jJsr3ZjdaftmnfA== + +"@rollup/rollup-android-arm64@4.21.0": + version "4.21.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.0.tgz#7e7157c8543215245ceffc445134d9e843ba51c0" + integrity sha512-a1sR2zSK1B4eYkiZu17ZUZhmUQcKjk2/j9Me2IDjk1GHW7LB5Z35LEzj9iJch6gtUfsnvZs1ZNyDW2oZSThrkA== + +"@rollup/rollup-darwin-arm64@4.21.0": + version "4.21.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.0.tgz#f0a18a4fc8dc6eb1e94a51fa2adb22876f477947" + integrity sha512-zOnKWLgDld/svhKO5PD9ozmL6roy5OQ5T4ThvdYZLpiOhEGY+dp2NwUmxK0Ld91LrbjrvtNAE0ERBwjqhZTRAA== + +"@rollup/rollup-darwin-x64@4.21.0": + version "4.21.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.0.tgz#34b7867613e5cc42d2b85ddc0424228cc33b43f0" + integrity sha512-7doS8br0xAkg48SKE2QNtMSFPFUlRdw9+votl27MvT46vo44ATBmdZdGysOevNELmZlfd+NEa0UYOA8f01WSrg== + +"@rollup/rollup-linux-arm-gnueabihf@4.21.0": + version "4.21.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.0.tgz#422b19ff9ae02b05d3395183d1d43b38c7c8be0b" + integrity sha512-pWJsfQjNWNGsoCq53KjMtwdJDmh/6NubwQcz52aEwLEuvx08bzcy6tOUuawAOncPnxz/3siRtd8hiQ32G1y8VA== + +"@rollup/rollup-linux-arm-musleabihf@4.21.0": + version "4.21.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.0.tgz#568aa29195ef6fc57ec6ed3f518923764406a8ee" + integrity sha512-efRIANsz3UHZrnZXuEvxS9LoCOWMGD1rweciD6uJQIx2myN3a8Im1FafZBzh7zk1RJ6oKcR16dU3UPldaKd83w== + +"@rollup/rollup-linux-arm64-gnu@4.21.0": + version "4.21.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.0.tgz#22309c8bcba9a73114f69165c72bc94b2fbec085" + integrity sha512-ZrPhydkTVhyeGTW94WJ8pnl1uroqVHM3j3hjdquwAcWnmivjAwOYjTEAuEDeJvGX7xv3Z9GAvrBkEzCgHq9U1w== + +"@rollup/rollup-linux-arm64-musl@4.21.0": + version "4.21.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.0.tgz#c93c388af6d33f082894b8a60839d7265b2b9bc5" + integrity sha512-cfaupqd+UEFeURmqNP2eEvXqgbSox/LHOyN9/d2pSdV8xTrjdg3NgOFJCtc1vQ/jEke1qD0IejbBfxleBPHnPw== + +"@rollup/rollup-linux-powerpc64le-gnu@4.21.0": + version "4.21.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.0.tgz#493c5e19e395cf3c6bd860c7139c8a903dea72b4" + integrity sha512-ZKPan1/RvAhrUylwBXC9t7B2hXdpb/ufeu22pG2psV7RN8roOfGurEghw1ySmX/CmDDHNTDDjY3lo9hRlgtaHg== + +"@rollup/rollup-linux-riscv64-gnu@4.21.0": + version "4.21.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.0.tgz#a2eab4346fbe5909165ce99adb935ba30c9fb444" + integrity sha512-H1eRaCwd5E8eS8leiS+o/NqMdljkcb1d6r2h4fKSsCXQilLKArq6WS7XBLDu80Yz+nMqHVFDquwcVrQmGr28rg== + +"@rollup/rollup-linux-s390x-gnu@4.21.0": + version "4.21.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.0.tgz#0bc49a79db4345d78d757bb1b05e73a1b42fa5c3" + integrity sha512-zJ4hA+3b5tu8u7L58CCSI0A9N1vkfwPhWd/puGXwtZlsB5bTkwDNW/+JCU84+3QYmKpLi+XvHdmrlwUwDA6kqw== + +"@rollup/rollup-linux-x64-gnu@4.21.0": + version "4.21.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.0.tgz#4fd36a6a41f3406d8693321b13d4f9b7658dd4b9" + integrity sha512-e2hrvElFIh6kW/UNBQK/kzqMNY5mO+67YtEh9OA65RM5IJXYTWiXjX6fjIiPaqOkBthYF1EqgiZ6OXKcQsM0hg== + +"@rollup/rollup-linux-x64-musl@4.21.0": + version "4.21.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.0.tgz#10ebb13bd4469cbad1a5d9b073bd27ec8a886200" + integrity sha512-1vvmgDdUSebVGXWX2lIcgRebqfQSff0hMEkLJyakQ9JQUbLDkEaMsPTLOmyccyC6IJ/l3FZuJbmrBw/u0A0uCQ== + +"@rollup/rollup-win32-arm64-msvc@4.21.0": + version "4.21.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.0.tgz#2fef1a90f1402258ef915ae5a94cc91a5a1d5bfc" + integrity sha512-s5oFkZ/hFcrlAyBTONFY1TWndfyre1wOMwU+6KCpm/iatybvrRgmZVM+vCFwxmC5ZhdlgfE0N4XorsDpi7/4XQ== + +"@rollup/rollup-win32-ia32-msvc@4.21.0": + version "4.21.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.0.tgz#a18ad47a95c5f264defb60acdd8c27569f816fc1" + integrity sha512-G9+TEqRnAA6nbpqyUqgTiopmnfgnMkR3kMukFBDsiyy23LZvUCpiUwjTRx6ezYCjJODXrh52rBR9oXvm+Fp5wg== + +"@rollup/rollup-win32-x64-msvc@4.21.0": + version "4.21.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.0.tgz#20c09cf44dcb082140cc7f439dd679fe4bba3375" + integrity sha512-2jsCDZwtQvRhejHLfZ1JY6w6kEuEtfF9nzYsZxzSlNVKDX+DpsDJ+Rbjkm74nvg2rdx0gwBS+IMdvwJuq3S9pQ== + +"@shopify/app-bridge-react@4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@shopify/app-bridge-react/-/app-bridge-react-4.0.0.tgz#8c4cccda96e6a73c039d5b2e5c212f99be570a15" + integrity sha512-a300DQIyYmNl5jNFHXsAICMfafY6LizXnaG5ElaAumfoIt28owgM8daDm9BwBkHSroHArvJuZS96kpDzTVg1+Q== + dependencies: + "@shopify/app-bridge-types" "^0.0.7" + +"@shopify/app-bridge-types@^0.0.7": + version "0.0.7" + resolved "https://registry.yarnpkg.com/@shopify/app-bridge-types/-/app-bridge-types-0.0.7.tgz#7610970b4cedab1dac2ce39ae2af5611fc5ee06e" + integrity sha512-x2A86xSjBPaB4rDufkY+pGH2UK8gR/rvjeXGwttIjir1l70ELHnZj+eGzHShmBitCbVoN3fkBrDnFLZdjWqyLg== + +"@shopify/polaris-icons@^9.3.0": + version "9.3.0" + resolved "https://registry.yarnpkg.com/@shopify/polaris-icons/-/polaris-icons-9.3.0.tgz#560e268244904cafd4ad6e1547a8d57d7a9be5b4" + integrity sha512-fnH5Lcd3WFZNjlxGYGNtnjeq3P2xonRV8vChW4PqBfxdKlY/GQ/3/rIuxHzIgmLL0zukeZUaqERUN0lwSU+Xmg== + +"@shopify/polaris-tokens@^9.4.0": + version "9.4.0" + resolved "https://registry.yarnpkg.com/@shopify/polaris-tokens/-/polaris-tokens-9.4.0.tgz#acf11a4fbc4b50cc1725c23dfff99d1de20f67e7" + integrity sha512-jnCNxq9+XfWP9ijkvSsgQH5o3PeYgfWo4/zymoO+AeJvyngL+4LvlZ/nofvYj9DXLo74taTk05xui9qt22Zy2Q== + dependencies: + deepmerge "^4.3.1" + +"@shopify/polaris@^13.8.0": + version "13.9.0" + resolved "https://registry.yarnpkg.com/@shopify/polaris/-/polaris-13.9.0.tgz#2452e1ba85b58377763a3b0f41f605d9a63fce0a" + integrity sha512-zU9+mNSz5kxwKtPNWO26QlK3Ip+uZh9WNclr4PDHhzlb9d4dxOGkbfaJGPaANVEIP34tLuHVcjH+l8DhwM8mog== + dependencies: + "@shopify/polaris-icons" "^9.3.0" + "@shopify/polaris-tokens" "^9.4.0" + "@types/react" "^18.2.0" + "@types/react-dom" "^18.2.0" + "@types/react-transition-group" "^4.4.2" + react-fast-compare "^3.2.0" + react-transition-group "^4.4.2" + +"@sindresorhus/is@^4.0.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" + integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== + +"@swc/core-darwin-arm64@1.7.14": + version "1.7.14" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.14.tgz#a4530ec755ea183802cc9dfe4900ab5f6a327fea" + integrity sha512-V0OUXjOH+hdGxDYG8NkQzy25mKOpcNKFpqtZEzLe5V/CpLJPnpg1+pMz70m14s9ZFda9OxsjlvPbg1FLUwhgIQ== + +"@swc/core-darwin-x64@1.7.14": + version "1.7.14" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.7.14.tgz#2c9c717fd28dd1dde9c21cf58b01f1cda7976b1a" + integrity sha512-9iFvUnxG6FC3An5ogp5jbBfQuUmTTwy8KMB+ZddUoPB3NR1eV+Y9vOh/tfWcenSJbgOKDLgYC5D/b1mHAprsrQ== + +"@swc/core-linux-arm-gnueabihf@1.7.14": + version "1.7.14" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.14.tgz#fed055c9c65347177c8df88720f8a51793a4df06" + integrity sha512-zGJsef9qPivKSH8Vv4F/HiBXBTHZ5Hs3ZjVGo/UIdWPJF8fTL9OVADiRrl34Q7zOZEtGXRwEKLUW1SCQcbDvZA== + +"@swc/core-linux-arm64-gnu@1.7.14": + version "1.7.14" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.14.tgz#ca740c8ea26f041b2dc43ba87facec452052814f" + integrity sha512-AxV3MPsoI7i4B8FXOew3dx3N8y00YoJYvIPfxelw07RegeCEH3aHp2U2DtgbP/NV1ugZMx0TL2Z2DEvocmA51g== + +"@swc/core-linux-arm64-musl@1.7.14": + version "1.7.14" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.14.tgz#fbc6fed24f5ad58b948e5b7abe6cd1f07112bef1" + integrity sha512-JDLdNjUj3zPehd4+DrQD8Ltb3B5lD8D05IwePyDWw+uR/YPc7w/TX1FUVci5h3giJnlMCJRvi1IQYV7K1n7KtQ== + +"@swc/core-linux-x64-gnu@1.7.14": + version "1.7.14" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.14.tgz#509a37833e4fbf89506b9291d9bd131fa2017fca" + integrity sha512-Siy5OvPCLLWmMdx4msnEs8HvEVUEigSn0+3pbLjv78iwzXd0qSBNHUPZyC1xeurVaUbpNDxZTpPRIwpqNE2+Og== + +"@swc/core-linux-x64-musl@1.7.14": + version "1.7.14" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.14.tgz#81156cc6ff814ad4b8fcf6eb6658d3f247db0b57" + integrity sha512-FtEGm9mwtRYQNK43WMtUIadxHs/ja2rnDurB99os0ZoFTGG2IHuht2zD97W0wB8JbqEabT1XwSG9Y5wmN+ciEQ== + +"@swc/core-win32-arm64-msvc@1.7.14": + version "1.7.14" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.14.tgz#c605fa783b5fbe1fff784ace4c4bb074b8d6026d" + integrity sha512-Jp8KDlfq7Ntt2/BXr0y344cYgB1zf0DaLzDZ1ZJR6rYlAzWYSccLYcxHa97VGnsYhhPspMpmCvHid97oe2hl4A== + +"@swc/core-win32-ia32-msvc@1.7.14": + version "1.7.14" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.14.tgz#3e15dc3b662c9fab851a38b3e271c8e2da4ba03a" + integrity sha512-I+cFsXF0OU0J9J4zdWiQKKLURO5dvCujH9Jr8N0cErdy54l9d4gfIxdctfTF+7FyXtWKLTCkp+oby9BQhkFGWA== + +"@swc/core-win32-x64-msvc@1.7.14": + version "1.7.14" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.14.tgz#83958d92e9f07865ec9365212111fbc295660f0d" + integrity sha512-NNrprQCK6d28mG436jVo2TD+vACHseUECacEBGZ9Ef0qfOIWS1XIt2MisQKG0Oea2VvLFl6tF/V4Lnx/H0Sn3Q== + +"@swc/core@^1.3.35": + version "1.7.14" + resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.7.14.tgz#d10492b5a4168cb1e73cf561a315e8b0f62255ed" + integrity sha512-9aeXeifnyuvc2pcuuhPQgVUwdpGEzZ+9nJu0W8/hNl/aESFsJGR5i9uQJRGu0atoNr01gK092fvmqMmQAPcKow== + dependencies: + "@swc/counter" "^0.1.3" + "@swc/types" "^0.1.12" + optionalDependencies: + "@swc/core-darwin-arm64" "1.7.14" + "@swc/core-darwin-x64" "1.7.14" + "@swc/core-linux-arm-gnueabihf" "1.7.14" + "@swc/core-linux-arm64-gnu" "1.7.14" + "@swc/core-linux-arm64-musl" "1.7.14" + "@swc/core-linux-x64-gnu" "1.7.14" + "@swc/core-linux-x64-musl" "1.7.14" + "@swc/core-win32-arm64-msvc" "1.7.14" + "@swc/core-win32-ia32-msvc" "1.7.14" + "@swc/core-win32-x64-msvc" "1.7.14" + +"@swc/counter@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@swc/counter/-/counter-0.1.3.tgz#cc7463bd02949611c6329596fccd2b0ec782b0e9" + integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ== + +"@swc/types@^0.1.12": + version "0.1.12" + resolved "https://registry.yarnpkg.com/@swc/types/-/types-0.1.12.tgz#7f632c06ab4092ce0ebd046ed77ff7557442282f" + integrity sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA== + dependencies: + "@swc/counter" "^0.1.3" + +"@szmarczak/http-timer@^4.0.5": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" + integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== + dependencies: + defer-to-connect "^2.0.0" + +"@types/cacheable-request@^6.0.1": + version "6.0.3" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183" + integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "^3.1.4" + "@types/node" "*" + "@types/responselike" "^1.0.0" + +"@types/estree@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== + +"@types/http-cache-semantics@*": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" + integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== + +"@types/keyv@^3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" + integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== + dependencies: + "@types/node" "*" + +"@types/node@*": + version "22.4.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.4.1.tgz#9b595d292c65b94c20923159e2ce947731b6fdce" + integrity sha512-1tbpb9325+gPnKK0dMm+/LMriX0vKxf6RnB0SZUqfyVkQ4fMgUSySqhxE/y8Jvs4NyF1yHzTfG9KlnkIODxPKg== + dependencies: + undici-types "~6.19.2" + +"@types/node@^20.12.8": + version "20.16.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.1.tgz#0b44b15271d0e2191ca68faf1fbe506e06aed732" + integrity sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ== + dependencies: + undici-types "~6.19.2" + +"@types/prop-types@*": + version "15.7.12" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6" + integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== + +"@types/react-dom@^18.0.11", "@types/react-dom@^18.2.0": + version "18.3.0" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.0.tgz#0cbc818755d87066ab6ca74fbedb2547d74a82b0" + integrity sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg== + dependencies: + "@types/react" "*" + +"@types/react-transition-group@^4.4.2": + version "4.4.11" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.11.tgz#d963253a611d757de01ebb241143b1017d5d63d5" + integrity sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA== + dependencies: + "@types/react" "*" + +"@types/react@*", "@types/react@^18.0.28", "@types/react@^18.2.0": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.3.tgz#9679020895318b0915d7a3ab004d92d33375c45f" + integrity sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw== + dependencies: + "@types/prop-types" "*" + csstype "^3.0.2" + +"@types/responselike@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.3.tgz#cc29706f0a397cfe6df89debfe4bf5cea159db50" + integrity sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw== + dependencies: + "@types/node" "*" + +"@urql/core@^4.0.10": + version "4.3.0" + resolved "https://registry.yarnpkg.com/@urql/core/-/core-4.3.0.tgz#5e150412ed08d167861b05ceed417abbd048553f" + integrity sha512-wT+FeL8DG4x5o6RfHEnONNFVDM3616ouzATMYUClB6CB+iIu2mwfBKd7xSUxYOZmwtxna5/hDRQdMl3nbQZlnw== + dependencies: + "@0no-co/graphql.web" "^1.0.1" + wonka "^6.3.2" + +"@urql/core@^5.0.0": + version "5.0.6" + resolved "https://registry.yarnpkg.com/@urql/core/-/core-5.0.6.tgz#0d6624e30084f9137f78dc6c5bb8a599cba7f9dc" + integrity sha512-38rgSDqVNihFDauw1Pm9V7XLWIKuK8V9CKgrUF7/xEKinze8ENKP1ZeBhkG+dxWzJan7CHK+SLl46kAdvZwIlA== + dependencies: + "@0no-co/graphql.web" "^1.0.5" + wonka "^6.3.2" + +"@vitejs/plugin-react-swc@3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-react-swc/-/plugin-react-swc-3.2.0.tgz#7c4f6e116a296c27f680d05750f9dbf798cf7709" + integrity sha512-IcBoXL/mcH7JdQr/nfDlDwTdIaH8Rg7LpfQDF4nAht+juHWIuv6WhpKPCSfY4+zztAaB07qdBoFz1XCZsgo3pQ== + dependencies: + "@swc/core" "^1.3.35" + +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +abstract-logging@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/abstract-logging/-/abstract-logging-2.0.1.tgz#6b0c371df212db7129b57d2e7fcf282b8bf1c839" + integrity sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA== + +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-formats@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-3.0.1.tgz#3d5dc762bca17679c3c2ea7e90ad6b7532309578" + integrity sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ== + dependencies: + ajv "^8.0.0" + +ajv@^8.0.0, ajv@^8.10.0, ajv@^8.11.0: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" + integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== + dependencies: + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + +atomic-sleep@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" + integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== + +avvio@^8.3.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/avvio/-/avvio-8.4.0.tgz#7cbd5bca74f0c9effa944ced601f94ffd8afc5ed" + integrity sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA== + dependencies: + "@fastify/error" "^3.3.0" + fastq "^1.17.1" + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +cacheable-lookup@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" + integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== + +cacheable-request@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817" + integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^6.0.1" + responselike "^2.0.0" + +call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + +clone-response@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" + integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== + dependencies: + mimic-response "^1.0.0" + +cookie@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== + +cross-fetch@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-4.0.0.tgz#f037aef1580bb3a1a35164ea2a848ba81b445983" + integrity sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g== + dependencies: + node-fetch "^2.6.12" + +crypto-js@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631" + integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== + +csstype@^3.0.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + +date-fns-tz@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/date-fns-tz/-/date-fns-tz-2.0.1.tgz#0a9b2099031c0d74120b45de9fd23192e48ea495" + integrity sha512-fJCG3Pwx8HUoLhkepdsP7Z5RsucUi+ZBOxyM5d0ZZ6c4SdYustq0VMmOu6Wf7bli+yS/Jwp91TOCqn9jMcVrUA== + +date-fns@^2.30.0: + version "2.30.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" + integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== + dependencies: + "@babel/runtime" "^7.21.0" + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +deepmerge@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +defer-to-connect@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + +dom-helpers@^5.0.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" + integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== + dependencies: + "@babel/runtime" "^7.8.7" + csstype "^3.0.2" + +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +esbuild@^0.21.3: + version "0.21.5" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" + integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== + optionalDependencies: + "@esbuild/aix-ppc64" "0.21.5" + "@esbuild/android-arm" "0.21.5" + "@esbuild/android-arm64" "0.21.5" + "@esbuild/android-x64" "0.21.5" + "@esbuild/darwin-arm64" "0.21.5" + "@esbuild/darwin-x64" "0.21.5" + "@esbuild/freebsd-arm64" "0.21.5" + "@esbuild/freebsd-x64" "0.21.5" + "@esbuild/linux-arm" "0.21.5" + "@esbuild/linux-arm64" "0.21.5" + "@esbuild/linux-ia32" "0.21.5" + "@esbuild/linux-loong64" "0.21.5" + "@esbuild/linux-mips64el" "0.21.5" + "@esbuild/linux-ppc64" "0.21.5" + "@esbuild/linux-riscv64" "0.21.5" + "@esbuild/linux-s390x" "0.21.5" + "@esbuild/linux-x64" "0.21.5" + "@esbuild/netbsd-x64" "0.21.5" + "@esbuild/openbsd-x64" "0.21.5" + "@esbuild/sunos-x64" "0.21.5" + "@esbuild/win32-arm64" "0.21.5" + "@esbuild/win32-ia32" "0.21.5" + "@esbuild/win32-x64" "0.21.5" + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +events@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +fast-content-type-parse@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-content-type-parse/-/fast-content-type-parse-1.1.0.tgz#4087162bf5af3294d4726ff29b334f72e3a1092c" + integrity sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ== + +fast-decode-uri-component@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz#46f8b6c22b30ff7a81357d4f59abfae938202543" + integrity sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg== + +fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stringify@^5.7.0, fast-json-stringify@^5.8.0: + version "5.16.1" + resolved "https://registry.yarnpkg.com/fast-json-stringify/-/fast-json-stringify-5.16.1.tgz#a6d0c575231a3a08c376a00171d757372f2ca46e" + integrity sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g== + dependencies: + "@fastify/merge-json-schemas" "^0.1.0" + ajv "^8.10.0" + ajv-formats "^3.0.1" + fast-deep-equal "^3.1.3" + fast-uri "^2.1.0" + json-schema-ref-resolver "^1.0.1" + rfdc "^1.2.0" + +fast-querystring@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fast-querystring/-/fast-querystring-1.1.2.tgz#a6d24937b4fc6f791b4ee31dcb6f53aeafb89f53" + integrity sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg== + dependencies: + fast-decode-uri-component "^1.0.1" + +fast-redact@^3.1.1: + version "3.5.0" + resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.5.0.tgz#e9ea02f7e57d0cd8438180083e93077e496285e4" + integrity sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A== + +fast-uri@^2.0.0, fast-uri@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-2.4.0.tgz#67eae6fbbe9f25339d5d3f4c4234787b65d7d55e" + integrity sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA== + +fast-uri@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.1.tgz#cddd2eecfc83a71c1be2cc2ef2061331be8a7134" + integrity sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw== + +fastify-plugin@^4.0.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/fastify-plugin/-/fastify-plugin-4.5.1.tgz#44dc6a3cc2cce0988bc09e13f160120bbd91dbee" + integrity sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ== + +fastify@^4.24.2: + version "4.28.1" + resolved "https://registry.yarnpkg.com/fastify/-/fastify-4.28.1.tgz#39626dedf445d702ef03818da33064440b469cd1" + integrity sha512-kFWUtpNr4i7t5vY2EJPCN2KgMVpuqfU4NjnJNCgiNB900oiDeYqaNDRcAfeBbOF5hGixixxcKnOU4KN9z6QncQ== + dependencies: + "@fastify/ajv-compiler" "^3.5.0" + "@fastify/error" "^3.4.0" + "@fastify/fast-json-stringify-compiler" "^4.3.0" + abstract-logging "^2.0.1" + avvio "^8.3.0" + fast-content-type-parse "^1.1.0" + fast-json-stringify "^5.8.0" + find-my-way "^8.0.0" + light-my-request "^5.11.0" + pino "^9.0.0" + process-warning "^3.0.0" + proxy-addr "^2.0.7" + rfdc "^1.3.0" + secure-json-parse "^2.7.0" + semver "^7.5.4" + toad-cache "^3.3.0" + +fastq@^1.17.1: + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== + dependencies: + reusify "^1.0.4" + +filesize@^10.1.2: + version "10.1.4" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-10.1.4.tgz#184f256063a201f08b6e6b3cc47d21b60f5b8d89" + integrity sha512-ryBwPIIeErmxgPnm6cbESAzXjuEFubs+yKYLBZvg3CaiNcmkJChoOGcBSrZ6IwkMwPABwPpVXE6IlNdGJJrvEg== + +find-my-way@^8.0.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/find-my-way/-/find-my-way-8.2.0.tgz#ef1b83d008114a300118c9c707d8dc65947d9960" + integrity sha512-HdWXgFYc6b1BJcOBDBwjqWuHJj1WYiqrxSh25qtU4DabpMFdj/gSunNBQb83t+8Zt67D7CXEzJWTkxaShMTMOA== + dependencies: + fast-deep-equal "^3.1.3" + fast-querystring "^1.0.0" + safe-regex2 "^3.1.0" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +"gadget-server@link:.gadget/server": + version "0.0.0" + uid "" + +get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +got@^11.1.4: + version "11.8.6" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" + integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.2" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + +graphql-ws@^5.13.1: + version "5.16.0" + resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-5.16.0.tgz#849efe02f384b4332109329be01d74c345842729" + integrity sha512-Ju2RCU2dQMgSKtArPbEtsK5gNLnsQyTNIo/T7cZNp96niC1x0KdJNZV0TIoilceBPQwfb5itrGl8pkFeOUMl4A== + +graphql@^16.8.1: + version "16.9.0" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.9.0.tgz#1c310e63f16a49ce1fbb230bd0a000e99f6f115f" + integrity sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw== + +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +hasown@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +http-cache-semantics@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + +http2-wrapper@^1.0.0-beta.5.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" + integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.0.0" + +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +isomorphic-ws@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" + integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== + +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-schema-ref-resolver@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-schema-ref-resolver/-/json-schema-ref-resolver-1.0.1.tgz#6586f483b76254784fc1d2120f717bdc9f0a99bf" + integrity sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw== + dependencies: + fast-deep-equal "^3.1.3" + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +keyv@^4.0.0: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + +klona@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" + integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== + +light-my-request@^5.11.0: + version "5.13.0" + resolved "https://registry.yarnpkg.com/light-my-request/-/light-my-request-5.13.0.tgz#b29905e55e8605b77fee2a946e17b219bca35113" + integrity sha512-9IjUN9ZyCS9pTG+KqTDEQo68Sui2lHsYBrfMyVUTTZ3XhH8PMZq7xO94Kr+eP9dhi/kcKsx4N41p2IXEBil1pQ== + dependencies: + cookie "^0.6.0" + process-warning "^3.0.0" + set-cookie-parser "^2.4.1" + +lodash@^4.17.10: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + +node-fetch@^2.6.12: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-inspect@^1.13.1: + version "1.13.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" + integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== + +on-exit-leak-free@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz#fed195c9ebddb7d9e4c3842f93f281ac8dadd3b8" + integrity sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA== + +once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +p-cancelable@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" + integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== + +picocolors@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" + integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== + +pino-abstract-transport@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz#97f9f2631931e242da531b5c66d3079c12c9d1b5" + integrity sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q== + dependencies: + readable-stream "^4.0.0" + split2 "^4.0.0" + +pino-std-serializers@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz#7c625038b13718dbbd84ab446bd673dc52259e3b" + integrity sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA== + +pino@^9.0.0: + version "9.3.2" + resolved "https://registry.yarnpkg.com/pino/-/pino-9.3.2.tgz#a530d6d28f1d954b6f54416a218cbb616f52f901" + integrity sha512-WtARBjgZ7LNEkrGWxMBN/jvlFiE17LTbBoH0konmBU684Kd0uIiDwBXlcTCW7iJnA6HfIKwUssS/2AC6cDEanw== + dependencies: + atomic-sleep "^1.0.0" + fast-redact "^3.1.1" + on-exit-leak-free "^2.1.0" + pino-abstract-transport "^1.2.0" + pino-std-serializers "^7.0.0" + process-warning "^4.0.0" + quick-format-unescaped "^4.0.3" + real-require "^0.2.0" + safe-stable-stringify "^2.3.1" + sonic-boom "^4.0.1" + thread-stream "^3.0.0" + +pluralize@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" + integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== + +postcss@^8.4.41: + version "8.4.41" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.41.tgz#d6104d3ba272d882fe18fc07d15dc2da62fa2681" + integrity sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.1" + source-map-js "^1.2.0" + +process-warning@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-3.0.0.tgz#96e5b88884187a1dce6f5c3166d611132058710b" + integrity sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ== + +process-warning@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-4.0.0.tgz#581e3a7a1fb456c5f4fd239f76bce75897682d5a" + integrity sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + +prop-types@^15.6.2: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + +property-expr@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.6.tgz#f77bc00d5928a6c748414ad12882e83f24aec1e8" + integrity sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA== + +proxy-addr@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +qs@^6.5.2: + version "6.13.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" + integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== + dependencies: + side-channel "^1.0.6" + +quick-format-unescaped@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" + integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== + +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + +react-dom@^18.2.0: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" + integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.2" + +react-fast-compare@^3.2.0, react-fast-compare@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" + integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== + +react-hook-form@~7.48.2: + version "7.48.2" + resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.48.2.tgz#01150354d2be61412ff56a030b62a119283b9935" + integrity sha512-H0T2InFQb1hX7qKtDIZmvpU1Xfn/bdahWBN1fH19gSe4bBEqTfmlr7H3XWTaVtiK4/tpPaI1F3355GPMZYge+A== + +react-is@^16.13.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-router-dom@6.15.0: + version "6.15.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.15.0.tgz#6da7db61e56797266fbbef0d5e324d6ac443ee40" + integrity sha512-aR42t0fs7brintwBGAv2+mGlCtgtFQeOzK0BM1/OiqEzRejOZtpMZepvgkscpMUnKb8YO84G7s3LsHnnDNonbQ== + dependencies: + "@remix-run/router" "1.8.0" + react-router "6.15.0" + +react-router@6.15.0: + version "6.15.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.15.0.tgz#bf2cb5a4a7ed57f074d4ea88db0d95033f39cac8" + integrity sha512-NIytlzvzLwJkCQj2HLefmeakxxWHWAP+02EGqWEZy+DgfHHKQMUoBBjUQLOtFInBMhWtb3hiUy6MfFgwLjXhqg== + dependencies: + "@remix-run/router" "1.8.0" + +react-transition-group@^4.4.2: + version "4.4.5" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1" + integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== + dependencies: + "@babel/runtime" "^7.5.5" + dom-helpers "^5.0.1" + loose-envify "^1.4.0" + prop-types "^15.6.2" + +react@^18.2.0: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" + integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== + dependencies: + loose-envify "^1.1.0" + +readable-stream@^4.0.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.5.2.tgz#9e7fc4c45099baeed934bff6eb97ba6cf2729e09" + integrity sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g== + dependencies: + abort-controller "^3.0.0" + buffer "^6.0.3" + events "^3.3.0" + process "^0.11.10" + string_decoder "^1.3.0" + +real-require@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.2.0.tgz#209632dea1810be2ae063a6ac084fee7e33fba78" + integrity sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg== + +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +resolve-alpn@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + +responselike@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" + integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== + dependencies: + lowercase-keys "^2.0.0" + +ret@~0.4.0: + version "0.4.3" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.4.3.tgz#5243fa30e704a2e78a9b9b1e86079e15891aa85c" + integrity sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rfdc@^1.2.0, rfdc@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" + integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== + +rollup@^4.13.0: + version "4.21.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.21.0.tgz#28db5f5c556a5180361d35009979ccc749560b9d" + integrity sha512-vo+S/lfA2lMS7rZ2Qoubi6I5hwZwzXeUIctILZLbHI+laNtvhhOIon2S1JksA5UEDQ7l3vberd0fxK44lTYjbQ== + dependencies: + "@types/estree" "1.0.5" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.21.0" + "@rollup/rollup-android-arm64" "4.21.0" + "@rollup/rollup-darwin-arm64" "4.21.0" + "@rollup/rollup-darwin-x64" "4.21.0" + "@rollup/rollup-linux-arm-gnueabihf" "4.21.0" + "@rollup/rollup-linux-arm-musleabihf" "4.21.0" + "@rollup/rollup-linux-arm64-gnu" "4.21.0" + "@rollup/rollup-linux-arm64-musl" "4.21.0" + "@rollup/rollup-linux-powerpc64le-gnu" "4.21.0" + "@rollup/rollup-linux-riscv64-gnu" "4.21.0" + "@rollup/rollup-linux-s390x-gnu" "4.21.0" + "@rollup/rollup-linux-x64-gnu" "4.21.0" + "@rollup/rollup-linux-x64-musl" "4.21.0" + "@rollup/rollup-win32-arm64-msvc" "4.21.0" + "@rollup/rollup-win32-ia32-msvc" "4.21.0" + "@rollup/rollup-win32-x64-msvc" "4.21.0" + fsevents "~2.3.2" + +safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex2@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/safe-regex2/-/safe-regex2-3.1.0.tgz#fd7ec23908e2c730e1ce7359a5b72883a87d2763" + integrity sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug== + dependencies: + ret "~0.4.0" + +safe-stable-stringify@^2.3.1: + version "2.4.3" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" + integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== + +scheduler@^0.23.2: + version "0.23.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== + dependencies: + loose-envify "^1.1.0" + +secure-json-parse@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz#5a5f9cd6ae47df23dba3151edd06855d47e09862" + integrity sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw== + +semver@^7.5.4: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + +set-cookie-parser@^2.4.1: + version "2.7.0" + resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.7.0.tgz#ef5552b56dc01baae102acb5fc9fb8cd060c30f9" + integrity sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ== + +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + +shopify-api-node@^3.12.6: + version "3.13.4" + resolved "https://registry.yarnpkg.com/shopify-api-node/-/shopify-api-node-3.13.4.tgz#5dc24bf311121e325cdec312455050f14f958ceb" + integrity sha512-SI5fWomPxhnrvYWpL7f4lo8eQRvt0o/F53Mqp6pm4tW+0RdjTYGFKRnkBf/93WpqniB6xHeUnT3FokvAH/6oYA== + dependencies: + got "^11.1.4" + lodash "^4.17.10" + qs "^6.5.2" + stopcock "^1.0.0" + +side-channel@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" + +sonic-boom@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-4.0.1.tgz#515b7cef2c9290cb362c4536388ddeece07aed30" + integrity sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ== + dependencies: + atomic-sleep "^1.0.0" + +source-map-js@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" + integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== + +split2@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== + +stopcock@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/stopcock/-/stopcock-1.1.0.tgz#e0c875d98b819c0baa0a0edf3bcba2d7dc643175" + integrity sha512-SNTAH55X9Ra5uE1JIxiPT3WwZiNMTcdCup+7qWOULNVUqiqi62qctNJ+x1R4znNudtkyu8LGc7Ok6Ldt+8N5iQ== + +string_decoder@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +thread-stream@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-3.1.0.tgz#4b2ef252a7c215064507d4ef70c05a5e2d34c4f1" + integrity sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A== + dependencies: + real-require "^0.2.0" + +tiny-case@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-case/-/tiny-case-1.0.3.tgz#d980d66bc72b5d5a9ca86fb7c9ffdb9c898ddd03" + integrity sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q== + +tiny-graphql-query-compiler@^0.2.2: + version "0.2.3" + resolved "https://registry.yarnpkg.com/tiny-graphql-query-compiler/-/tiny-graphql-query-compiler-0.2.3.tgz#c703a1db7a9bfcb78b636d1437d5838c2b2052fb" + integrity sha512-5ZMy+38zKezoYdx8V6Bnaez4f6J1fmFvYlCWOT85eIsXIbPmJrCfHwYPUH1qEl1T1hyHgosbWiQ/M/p3KD84EQ== + +toad-cache@^3.3.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/toad-cache/-/toad-cache-3.7.0.tgz#b9b63304ea7c45ec34d91f1d2fa513517025c441" + integrity sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw== + +toposort@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" + integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg== + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +tslib@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0" + integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== + +type-fest@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" + integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== + +type-fest@^3.13.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.13.1.tgz#bb744c1f0678bea7543a2d1ec24e83e68e8c8706" + integrity sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g== + +typescript@^5.4.5: + version "5.5.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" + integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== + +undici-types@~6.19.2: + version "6.19.6" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.6.tgz#e218c3df0987f4c0e0008ca00d6b6472d9b89b36" + integrity sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org== + +urql@^4.0.4: + version "4.1.0" + resolved "https://registry.yarnpkg.com/urql/-/urql-4.1.0.tgz#a75efe572d7b2e69103649a8457d3a63fce31ee8" + integrity sha512-NfbfTvxy1sM89EQAJWm89qJZihUWk7BSMfrWgfljFXLOf+e7RK7DtV/Tbg2+82HnCG2x3LcEOJenxiFSYEC+bw== + dependencies: + "@urql/core" "^5.0.0" + wonka "^6.3.2" + +vite@^5.3.5: + version "5.4.1" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.1.tgz#2aa72370de824d23f53658affd807e4c9905b058" + integrity sha512-1oE6yuNXssjrZdblI9AfBbHCC41nnyoVoEZxQnID6yvQZAFBzxxkqoFLtHUMkYunL8hwOLEjgTuxpkRxvba3kA== + dependencies: + esbuild "^0.21.3" + postcss "^8.4.41" + rollup "^4.13.0" + optionalDependencies: + fsevents "~2.3.3" + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +wonka@^6.3.2: + version "6.3.4" + resolved "https://registry.yarnpkg.com/wonka/-/wonka-6.3.4.tgz#76eb9316e3d67d7febf4945202b5bdb2db534594" + integrity sha512-CjpbqNtBGNAeyNS/9W6q3kSkKE52+FjIj7AkFlLr11s/VWGUu6a2CdYSdGxocIhIVjaW/zchesBQUKPVU69Cqg== + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@^8.17.0: + version "8.18.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== + +yup@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/yup/-/yup-1.4.0.tgz#898dcd660f9fb97c41f181839d3d65c3ee15a43e" + integrity sha512-wPbgkJRCqIf+OHyiTBQoJiP5PFuAXaWiJK6AmYkzQAh5/c2K9hzSApBZG5wV9KoKSePF7sAxmNSvh/13YHkFDg== + dependencies: + property-expr "^2.0.5" + tiny-case "^1.0.3" + toposort "^2.0.2" + type-fest "^2.19.0" From 8fa6ce51b642cd1b39e613c89d020eefd8d07fd3 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Mon, 19 Aug 2024 11:30:12 -0400 Subject: [PATCH 02/43] Adding review model // Adds ignore files // Adds react-email packages --- product-reviews-template/.gitignore | 8 +- product-reviews-template/.ignore | 3 + .../api/models/review/schema.gadget.ts | 25 + .../api/models/shopifyShop/actions/update.js | 5 +- .../api/models/shopifyShop/schema.gadget.ts | 18 +- .../product-reviews/assets/thumbs-up.png | Bin 0 -> 18051 bytes .../product-reviews/blocks/star_rating.liquid | 21 + .../product-reviews/locales/en.default.json | 10 + .../product-reviews/shopify.extension.toml | 3 + .../product-reviews/snippets/stars.liquid | 10 + product-reviews-template/package.json | 12 +- product-reviews-template/yarn.lock | 2990 ++++++++++++++++- 12 files changed, 3064 insertions(+), 41 deletions(-) create mode 100644 product-reviews-template/.ignore create mode 100644 product-reviews-template/extensions/product-reviews/assets/thumbs-up.png create mode 100644 product-reviews-template/extensions/product-reviews/blocks/star_rating.liquid create mode 100644 product-reviews-template/extensions/product-reviews/locales/en.default.json create mode 100644 product-reviews-template/extensions/product-reviews/shopify.extension.toml create mode 100644 product-reviews-template/extensions/product-reviews/snippets/stars.liquid diff --git a/product-reviews-template/.gitignore b/product-reviews-template/.gitignore index 430b978a..0dd3eec6 100755 --- a/product-reviews-template/.gitignore +++ b/product-reviews-template/.gitignore @@ -1,3 +1,9 @@ .gadget/ node_modules/ -**/.DS_Store \ No newline at end of file +**/.DS_Store + +# Shopify +extensions/**/dist/ +extensions/**/generated/ + +shopify.app.**.toml diff --git a/product-reviews-template/.ignore b/product-reviews-template/.ignore new file mode 100644 index 00000000..a91c062c --- /dev/null +++ b/product-reviews-template/.ignore @@ -0,0 +1,3 @@ +# Shopify extension build folders +extensions/**/dist +extensions/**/generated \ No newline at end of file diff --git a/product-reviews-template/api/models/review/schema.gadget.ts b/product-reviews-template/api/models/review/schema.gadget.ts index e55496a2..cb592f9c 100755 --- a/product-reviews-template/api/models/review/schema.gadget.ts +++ b/product-reviews-template/api/models/review/schema.gadget.ts @@ -7,6 +7,16 @@ export const schema: GadgetModel = { type: "gadget/model-schema/v1", storageKey: "05LmzBe_CIyf", fields: { + anonymous: { + type: "boolean", + default: false, + storageKey: "fyHMWNtwRseY", + }, + content: { + type: "string", + validations: { required: true }, + storageKey: "IU5npbrI6A3h", + }, customer: { type: "belongsTo", validations: { required: true }, @@ -24,5 +34,20 @@ export const schema: GadgetModel = { parent: { model: "shopifyProduct" }, storageKey: "YkA-cs5aMejq", }, + rating: { + type: "number", + decimals: 0, + validations: { + required: true, + numberRange: { min: 0, max: 5 }, + }, + storageKey: "Cuw9VTG9Higw", + }, + shop: { + type: "belongsTo", + validations: { required: true }, + parent: { model: "shopifyShop" }, + storageKey: "K1OxV12nco9E", + }, }, }; diff --git a/product-reviews-template/api/models/shopifyShop/actions/update.js b/product-reviews-template/api/models/shopifyShop/actions/update.js index 7b09e353..a491ae74 100755 --- a/product-reviews-template/api/models/shopifyShop/actions/update.js +++ b/product-reviews-template/api/models/shopifyShop/actions/update.js @@ -18,4 +18,7 @@ export async function onSuccess({ params, record, logger, api, connections }) { }; /** @type { ActionOptions } */ -export const options = { actionType: "update" }; +export const options = { + actionType: "update", + triggers: { api: true }, +}; diff --git a/product-reviews-template/api/models/shopifyShop/schema.gadget.ts b/product-reviews-template/api/models/shopifyShop/schema.gadget.ts index 9eaace11..af1ed8d4 100755 --- a/product-reviews-template/api/models/shopifyShop/schema.gadget.ts +++ b/product-reviews-template/api/models/shopifyShop/schema.gadget.ts @@ -6,7 +6,23 @@ import type { GadgetModel } from "gadget-server"; export const schema: GadgetModel = { type: "gadget/model-schema/v1", storageKey: "DataModel-Shopify-Shop", - fields: {}, + fields: { + daysUntilReviewRequest: { + type: "number", + default: 7, + decimals: 0, + validations: { + required: true, + numberRange: { min: 0, max: null }, + }, + storageKey: "V66nKdXdjiQO", + }, + reviews: { + type: "hasMany", + children: { model: "review", belongsToField: "shop" }, + storageKey: "f5lg7DH1ZzLI", + }, + }, shopify: { fields: [ "address1", diff --git a/product-reviews-template/extensions/product-reviews/assets/thumbs-up.png b/product-reviews-template/extensions/product-reviews/assets/thumbs-up.png new file mode 100644 index 0000000000000000000000000000000000000000..6a2eb6ead214b514fd01f36ed12aef7ea12c53e7 GIT binary patch literal 18051 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 + {% render 'stars', rating: avg_rating %} + +{% if avg_rating >= 4 %} +
+ + {{ 'ratings.home.recommendationText' | t }} +{% endif %} + +{% schema %} +{ + "name": "Star Rating", + "target": "section", + "settings": [ + { "type": "product", "id": "product", "label": "product", "autofill": true }, + { "type": "color", "id": "colour", "label": "Star Colour", "default": "#ff0000" } + ] +} +{% endschema %} + diff --git a/product-reviews-template/extensions/product-reviews/locales/en.default.json b/product-reviews-template/extensions/product-reviews/locales/en.default.json new file mode 100644 index 00000000..57d7c397 --- /dev/null +++ b/product-reviews-template/extensions/product-reviews/locales/en.default.json @@ -0,0 +1,10 @@ +{ + "ratings": { + "stars": { + "label": "Ratings" + }, + "home": { + "recommendationText": "Recommended Product!" + } + } +} diff --git a/product-reviews-template/extensions/product-reviews/shopify.extension.toml b/product-reviews-template/extensions/product-reviews/shopify.extension.toml new file mode 100644 index 00000000..9999b03b --- /dev/null +++ b/product-reviews-template/extensions/product-reviews/shopify.extension.toml @@ -0,0 +1,3 @@ +name = "product-reviews" +type = "theme" + diff --git a/product-reviews-template/extensions/product-reviews/snippets/stars.liquid b/product-reviews-template/extensions/product-reviews/snippets/stars.liquid new file mode 100644 index 00000000..e98d5676 --- /dev/null +++ b/product-reviews-template/extensions/product-reviews/snippets/stars.liquid @@ -0,0 +1,10 @@ +{{ 'ratings.stars.label' | t }}: + +{%- for i in (1..rating) -%} + ★ +{%- endfor -%} +{%- assign blank_stars = 5 | minus: rating -%} +{%- for i in (1..blank_stars) -%} + ☆ +{%- endfor -%} + diff --git a/product-reviews-template/package.json b/product-reviews-template/package.json index 2e0234ae..c25307d3 100755 --- a/product-reviews-template/package.json +++ b/product-reviews-template/package.json @@ -5,18 +5,26 @@ "license": "UNLICENSED", "private": true, "scripts": { - "build": "NODE_ENV=production vite build" + "build": "NODE_ENV=production vite build", + "shopify": "shopify", + "dev": "shopify app dev --no-update", + "info": "shopify app info", + "scaffold": "shopify app scaffold", + "deploy": "shopify app deploy", + "generate": "shopify app generate" }, "dependencies": { "@gadget-client/product-reviews-template": "link:.gadget/client", "@gadgetinc/react": "^0.16.1", "@gadgetinc/react-shopify-app-bridge": "^0.16.0", + "@react-email/components": "0.0.22", "@shopify/app-bridge-react": "4.0.0", "@shopify/polaris": "^13.8.0", "@shopify/polaris-icons": "^9.3.0", "gadget-server": "link:.gadget/server", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-email": "^2.1.6", "react-router-dom": "6.15.0", "shopify-api-node": "^3.12.6" }, @@ -28,4 +36,4 @@ "typescript": "^5.4.5", "vite": "^5.3.5" } -} \ No newline at end of file +} diff --git a/product-reviews-template/yarn.lock b/product-reviews-template/yarn.lock index 2287d98e..e0095c8b 100644 --- a/product-reviews-template/yarn.lock +++ b/product-reviews-template/yarn.lock @@ -7,123 +7,420 @@ resolved "https://registry.yarnpkg.com/@0no-co/graphql.web/-/graphql.web-1.0.7.tgz#c7a762c887b3482a79ffa68f63de5e96059a62e4" integrity sha512-E3Qku4mTzdrlwVWGPxklDnME5ANrEGetvYw4i2GCRlppWXXE4QD66j7pwb8HelZwS6LnqEChhrSOGCXpbiu6MQ== -"@babel/runtime@^7.21.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": +"@alloc/quick-lru@^5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" + integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== + +"@ampproject/remapping@^2.2.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" + integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + +"@babel/code-frame@^7.24.2", "@babel/code-frame@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" + integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== + dependencies: + "@babel/highlight" "^7.24.7" + picocolors "^1.0.0" + +"@babel/compat-data@^7.25.2": + version "7.25.2" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.2.tgz#e41928bd33475305c586f6acbbb7e3ade7a6f7f5" + integrity sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ== + +"@babel/core@7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.5.tgz#15ab5b98e101972d171aeef92ac70d8d6718f06a" + integrity sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.24.2" + "@babel/generator" "^7.24.5" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-module-transforms" "^7.24.5" + "@babel/helpers" "^7.24.5" + "@babel/parser" "^7.24.5" + "@babel/template" "^7.24.0" + "@babel/traverse" "^7.24.5" + "@babel/types" "^7.24.5" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.24.5", "@babel/generator@^7.25.0": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.0.tgz#f858ddfa984350bc3d3b7f125073c9af6988f18e" + integrity sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw== + dependencies: + "@babel/types" "^7.25.0" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.23.6": + version "7.25.2" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz#e1d9410a90974a3a5a66e84ff55ef62e3c02d06c" + integrity sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw== + dependencies: + "@babel/compat-data" "^7.25.2" + "@babel/helper-validator-option" "^7.24.8" + browserslist "^4.23.1" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-module-imports@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz#f2f980392de5b84c3328fc71d38bd81bbb83042b" + integrity sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helper-module-transforms@^7.24.5": + version "7.25.2" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz#ee713c29768100f2776edf04d4eb23b8d27a66e6" + integrity sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ== + dependencies: + "@babel/helper-module-imports" "^7.24.7" + "@babel/helper-simple-access" "^7.24.7" + "@babel/helper-validator-identifier" "^7.24.7" + "@babel/traverse" "^7.25.2" + +"@babel/helper-simple-access@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz#bcade8da3aec8ed16b9c4953b74e506b51b5edb3" + integrity sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helper-string-parser@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d" + integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== + +"@babel/helper-validator-identifier@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" + integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== + +"@babel/helper-validator-option@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz#3725cdeea8b480e86d34df15304806a06975e33d" + integrity sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q== + +"@babel/helpers@^7.24.5": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.0.tgz#e69beb7841cb93a6505531ede34f34e6a073650a" + integrity sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw== + dependencies: + "@babel/template" "^7.25.0" + "@babel/types" "^7.25.0" + +"@babel/highlight@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" + integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== + dependencies: + "@babel/helper-validator-identifier" "^7.24.7" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" + +"@babel/parser@7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.5.tgz#4a4d5ab4315579e5398a82dcf636ca80c3392790" + integrity sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg== + +"@babel/parser@^7.24.5", "@babel/parser@^7.25.0", "@babel/parser@^7.25.3": + version "7.25.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.3.tgz#91fb126768d944966263f0657ab222a642b82065" + integrity sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw== + dependencies: + "@babel/types" "^7.25.2" + +"@babel/runtime@^7.21.0", "@babel/runtime@^7.23.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": version "7.25.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.0.tgz#3af9a91c1b739c569d5d80cc917280919c544ecb" integrity sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw== dependencies: regenerator-runtime "^0.14.0" +"@babel/template@^7.24.0", "@babel/template@^7.25.0": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.0.tgz#e733dc3134b4fede528c15bc95e89cb98c52592a" + integrity sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/parser" "^7.25.0" + "@babel/types" "^7.25.0" + +"@babel/traverse@^7.24.5", "@babel/traverse@^7.24.7", "@babel/traverse@^7.25.2": + version "7.25.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.3.tgz#f1b901951c83eda2f3e29450ce92743783373490" + integrity sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.25.0" + "@babel/parser" "^7.25.3" + "@babel/template" "^7.25.0" + "@babel/types" "^7.25.2" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/types@^7.24.5", "@babel/types@^7.24.7", "@babel/types@^7.25.0", "@babel/types@^7.25.2": + version "7.25.2" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.2.tgz#55fb231f7dc958cd69ea141a4c2997e819646125" + integrity sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q== + dependencies: + "@babel/helper-string-parser" "^7.24.8" + "@babel/helper-validator-identifier" "^7.24.7" + to-fast-properties "^2.0.0" + +"@emotion/is-prop-valid@^0.8.2": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" + integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== + dependencies: + "@emotion/memoize" "0.7.4" + +"@emotion/memoize@0.7.4": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" + integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== + +"@esbuild/aix-ppc64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz#2acd20be6d4f0458bc8c784103495ff24f13b1d3" + integrity sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g== + "@esbuild/aix-ppc64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== +"@esbuild/android-arm64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz#b45d000017385c9051a4f03e17078abb935be220" + integrity sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q== + "@esbuild/android-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== +"@esbuild/android-arm@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.11.tgz#f46f55414e1c3614ac682b29977792131238164c" + integrity sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw== + "@esbuild/android-arm@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== +"@esbuild/android-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.11.tgz#bfc01e91740b82011ef503c48f548950824922b2" + integrity sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg== + "@esbuild/android-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== +"@esbuild/darwin-arm64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz#533fb7f5a08c37121d82c66198263dcc1bed29bf" + integrity sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ== + "@esbuild/darwin-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== +"@esbuild/darwin-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz#62f3819eff7e4ddc656b7c6815a31cf9a1e7d98e" + integrity sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g== + "@esbuild/darwin-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== +"@esbuild/freebsd-arm64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz#d478b4195aa3ca44160272dab85ef8baf4175b4a" + integrity sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA== + "@esbuild/freebsd-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== +"@esbuild/freebsd-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz#7bdcc1917409178257ca6a1a27fe06e797ec18a2" + integrity sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw== + "@esbuild/freebsd-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== +"@esbuild/linux-arm64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz#58ad4ff11685fcc735d7ff4ca759ab18fcfe4545" + integrity sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg== + "@esbuild/linux-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== +"@esbuild/linux-arm@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz#ce82246d873b5534d34de1e5c1b33026f35e60e3" + integrity sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q== + "@esbuild/linux-arm@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== +"@esbuild/linux-ia32@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz#cbae1f313209affc74b80f4390c4c35c6ab83fa4" + integrity sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA== + "@esbuild/linux-ia32@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== +"@esbuild/linux-loong64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz#5f32aead1c3ec8f4cccdb7ed08b166224d4e9121" + integrity sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg== + "@esbuild/linux-loong64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== +"@esbuild/linux-mips64el@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz#38eecf1cbb8c36a616261de858b3c10d03419af9" + integrity sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg== + "@esbuild/linux-mips64el@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== +"@esbuild/linux-ppc64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz#9c5725a94e6ec15b93195e5a6afb821628afd912" + integrity sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA== + "@esbuild/linux-ppc64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== +"@esbuild/linux-riscv64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz#2dc4486d474a2a62bbe5870522a9a600e2acb916" + integrity sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ== + "@esbuild/linux-riscv64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== +"@esbuild/linux-s390x@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz#4ad8567df48f7dd4c71ec5b1753b6f37561a65a8" + integrity sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q== + "@esbuild/linux-s390x@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== +"@esbuild/linux-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz#b7390c4d5184f203ebe7ddaedf073df82a658766" + integrity sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA== + "@esbuild/linux-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== +"@esbuild/netbsd-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz#d633c09492a1721377f3bccedb2d821b911e813d" + integrity sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ== + "@esbuild/netbsd-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== +"@esbuild/openbsd-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz#17388c76e2f01125bf831a68c03a7ffccb65d1a2" + integrity sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw== + "@esbuild/openbsd-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== +"@esbuild/sunos-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz#e320636f00bb9f4fdf3a80e548cb743370d41767" + integrity sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ== + "@esbuild/sunos-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== +"@esbuild/win32-arm64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz#c778b45a496e90b6fc373e2a2bb072f1441fe0ee" + integrity sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ== + "@esbuild/win32-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== +"@esbuild/win32-ia32@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz#481a65fee2e5cce74ec44823e6b09ecedcc5194c" + integrity sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg== + "@esbuild/win32-ia32@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== +"@esbuild/win32-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz#a5d300008960bb39677c46bf16f53ec70d8dee04" + integrity sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw== + "@esbuild/win32-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" @@ -164,6 +461,33 @@ dependencies: fastify-plugin "^4.0.0" +"@floating-ui/core@^1.6.0": + version "1.6.7" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.7.tgz#7602367795a390ff0662efd1c7ae8ca74e75fb12" + integrity sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g== + dependencies: + "@floating-ui/utils" "^0.2.7" + +"@floating-ui/dom@^1.0.0": + version "1.6.10" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.10.tgz#b74c32f34a50336c86dcf1f1c845cf3a39e26d6f" + integrity sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A== + dependencies: + "@floating-ui/core" "^1.6.0" + "@floating-ui/utils" "^0.2.7" + +"@floating-ui/react-dom@^2.0.0": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.1.1.tgz#cca58b6b04fc92b4c39288252e285e0422291fb0" + integrity sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg== + dependencies: + "@floating-ui/dom" "^1.0.0" + +"@floating-ui/utils@^0.2.7": + version "0.2.7" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.7.tgz#d0ece53ce99ab5a8e37ebdfe5e32452a2bfc073e" + integrity sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA== + "@gadget-client/product-reviews-template@link:.gadget/client": version "0.0.0" uid "" @@ -221,6 +545,58 @@ resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-3.9.0.tgz#cf540ac21c6c0cd24a40cf53d8e6d64391fb753d" integrity sha512-bU0Gr4EepJ/EQsH/IwEzYLsT/PEj5C0ynLQ4m+GSHS+xKH4TfSelhluTgOaoc4kA5s7eCsQbM4wvZLzELmWzUg== +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + +"@jridgewell/gen-mapping@^0.3.2", "@jridgewell/gen-mapping@^0.3.5": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + +"@jridgewell/source-map@^0.3.3": + version "0.3.6" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.6.tgz#9d71ca886e32502eb9362c9a74a46787c36df81a" + integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + "@n1ru4l/graphql-live-query@^0.10.0": version "0.10.0" resolved "https://registry.yarnpkg.com/@n1ru4l/graphql-live-query/-/graphql-live-query-0.10.0.tgz#2306151630b0e74b017cc1067ebbea351acf56f8" @@ -236,6 +612,483 @@ resolved "https://registry.yarnpkg.com/@n1ru4l/push-pull-async-iterable-iterator/-/push-pull-async-iterable-iterator-3.2.0.tgz#c15791112db68dd9315d329d652b7e797f737655" integrity sha512-3fkKj25kEjsfObL6IlKPAlHYPq/oYwUkkQ03zsTTiDjD7vg/RxjdiLeCydqtxHZP0JgsXL3D/X5oAkMGzuUp/Q== +"@next/env@14.1.4": + version "14.1.4" + resolved "https://registry.yarnpkg.com/@next/env/-/env-14.1.4.tgz#432e80651733fbd67230bf262aee28be65252674" + integrity sha512-e7X7bbn3Z6DWnDi75UWn+REgAbLEqxI8Tq2pkFOFAMpWAWApz/YCUhtWMWn410h8Q2fYiYL7Yg5OlxMOCfFjJQ== + +"@next/swc-darwin-arm64@14.1.4": + version "14.1.4" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.4.tgz#a3bca0dc4393ac4cf3169bbf24df63441de66bb7" + integrity sha512-ubmUkbmW65nIAOmoxT1IROZdmmJMmdYvXIe8211send9ZYJu+SqxSnJM4TrPj9wmL6g9Atvj0S/2cFmMSS99jg== + +"@next/swc-darwin-x64@14.1.4": + version "14.1.4" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.4.tgz#ba3683d4e2d30099f3f2864dd7349a4d9f440140" + integrity sha512-b0Xo1ELj3u7IkZWAKcJPJEhBop117U78l70nfoQGo4xUSvv0PJSTaV4U9xQBLvZlnjsYkc8RwQN1HoH/oQmLlQ== + +"@next/swc-linux-arm64-gnu@14.1.4": + version "14.1.4" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.4.tgz#3519969293f16379954b7e196deb0c1eecbb2f8b" + integrity sha512-457G0hcLrdYA/u1O2XkRMsDKId5VKe3uKPvrKVOyuARa6nXrdhJOOYU9hkKKyQTMru1B8qEP78IAhf/1XnVqKA== + +"@next/swc-linux-arm64-musl@14.1.4": + version "14.1.4" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.4.tgz#4bb3196bd402b3f84cf5373ff1021f547264d62f" + integrity sha512-l/kMG+z6MB+fKA9KdtyprkTQ1ihlJcBh66cf0HvqGP+rXBbOXX0dpJatjZbHeunvEHoBBS69GYQG5ry78JMy3g== + +"@next/swc-linux-x64-gnu@14.1.4": + version "14.1.4" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.4.tgz#1b3372c98c83dcdab946cdb4ee06e068b8139ba3" + integrity sha512-BapIFZ3ZRnvQ1uWbmqEGJuPT9cgLwvKtxhK/L2t4QYO7l+/DxXuIGjvp1x8rvfa/x1FFSsipERZK70pewbtJtw== + +"@next/swc-linux-x64-musl@14.1.4": + version "14.1.4" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.4.tgz#8459088bdc872648ff78f121db596f2533df5808" + integrity sha512-mqVxTwk4XuBl49qn2A5UmzFImoL1iLm0KQQwtdRJRKl21ylQwwGCxJtIYo2rbfkZHoSKlh/YgztY0qH3wG1xIg== + +"@next/swc-win32-arm64-msvc@14.1.4": + version "14.1.4" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.4.tgz#84280a08c00cc3be24ddd3a12f4617b108e6dea6" + integrity sha512-xzxF4ErcumXjO2Pvg/wVGrtr9QQJLk3IyQX1ddAC/fi6/5jZCZ9xpuL9Tzc4KPWMFq8GGWFVDMshZOdHGdkvag== + +"@next/swc-win32-ia32-msvc@14.1.4": + version "14.1.4" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.4.tgz#23ff7f4bd0a27177428669ef6fa5c3923c738031" + integrity sha512-WZiz8OdbkpRw6/IU/lredZWKKZopUMhcI2F+XiMAcPja0uZYdMTZQRoQ0WZcvinn9xZAidimE7tN9W5v9Yyfyw== + +"@next/swc-win32-x64-msvc@14.1.4": + version "14.1.4" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.4.tgz#bccf5beccfde66d6c66fa4e2509118c796385eda" + integrity sha512-4Rto21sPfw555sZ/XNLqfxDUNeLhNYGO2dlPqsnuCg8N8a2a9u1ltqBOPQ4vj1Gf7eJC0W2hHG2eYUHuiXgY2w== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@one-ini/wasm@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@one-ini/wasm/-/wasm-0.1.1.tgz#6013659736c9dbfccc96e8a9c2b3de317df39323" + integrity sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw== + +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + +"@radix-ui/colors@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/colors/-/colors-1.0.1.tgz#e9703d6e1b6f3ace1855e5d784353327a548042c" + integrity sha512-xySw8f0ZVsAEP+e7iLl3EvcBXX7gsIlC1Zso/sPBW9gIWerBTgz6axrjU+MZ39wD+WFi5h5zdWpsg3+hwt2Qsg== + +"@radix-ui/primitive@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.1.0.tgz#42ef83b3b56dccad5d703ae8c42919a68798bbe2" + integrity sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA== + +"@radix-ui/react-arrow@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz#744f388182d360b86285217e43b6c63633f39e7a" + integrity sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw== + dependencies: + "@radix-ui/react-primitive" "2.0.0" + +"@radix-ui/react-collapsible@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-collapsible/-/react-collapsible-1.1.0.tgz#4d49ddcc7b7d38f6c82f1fd29674f6fab5353e77" + integrity sha512-zQY7Epa8sTL0mq4ajSJpjgn2YmCgyrG7RsQgLp3C0LQVkG7+Tf6Pv1CeNWZLyqMjhdPkBa5Lx7wYBeSu7uCSTA== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-id" "1.1.0" + "@radix-ui/react-presence" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-controllable-state" "1.1.0" + "@radix-ui/react-use-layout-effect" "1.1.0" + +"@radix-ui/react-collection@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.1.0.tgz#f18af78e46454a2360d103c2251773028b7724ed" + integrity sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw== + dependencies: + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-slot" "1.1.0" + +"@radix-ui/react-compose-refs@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz#656432461fc8283d7b591dcf0d79152fae9ecc74" + integrity sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw== + +"@radix-ui/react-context@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.0.tgz#6df8d983546cfd1999c8512f3a8ad85a6e7fcee8" + integrity sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A== + +"@radix-ui/react-direction@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.1.0.tgz#a7d39855f4d077adc2a1922f9c353c5977a09cdc" + integrity sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg== + +"@radix-ui/react-dismissable-layer@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz#2cd0a49a732372513733754e6032d3fb7988834e" + integrity sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-callback-ref" "1.1.0" + "@radix-ui/react-use-escape-keydown" "1.1.0" + +"@radix-ui/react-focus-guards@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz#8e9abb472a9a394f59a1b45f3dd26cfe3fc6da13" + integrity sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw== + +"@radix-ui/react-focus-scope@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz#ebe2891a298e0a33ad34daab2aad8dea31caf0b2" + integrity sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA== + dependencies: + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-callback-ref" "1.1.0" + +"@radix-ui/react-id@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.1.0.tgz#de47339656594ad722eb87f94a6b25f9cffae0ed" + integrity sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA== + dependencies: + "@radix-ui/react-use-layout-effect" "1.1.0" + +"@radix-ui/react-popover@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-popover/-/react-popover-1.1.1.tgz#604b783cdb3494ed4f16a58c17f0e81e61ab7775" + integrity sha512-3y1A3isulwnWhvTTwmIreiB8CF4L+qRjZnK1wYLO7pplddzXKby/GnZ2M7OZY3qgnl6p9AodUIHRYGXNah8Y7g== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-dismissable-layer" "1.1.0" + "@radix-ui/react-focus-guards" "1.1.0" + "@radix-ui/react-focus-scope" "1.1.0" + "@radix-ui/react-id" "1.1.0" + "@radix-ui/react-popper" "1.2.0" + "@radix-ui/react-portal" "1.1.1" + "@radix-ui/react-presence" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-slot" "1.1.0" + "@radix-ui/react-use-controllable-state" "1.1.0" + aria-hidden "^1.1.1" + react-remove-scroll "2.5.7" + +"@radix-ui/react-popper@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.2.0.tgz#a3e500193d144fe2d8f5d5e60e393d64111f2a7a" + integrity sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg== + dependencies: + "@floating-ui/react-dom" "^2.0.0" + "@radix-ui/react-arrow" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-callback-ref" "1.1.0" + "@radix-ui/react-use-layout-effect" "1.1.0" + "@radix-ui/react-use-rect" "1.1.0" + "@radix-ui/react-use-size" "1.1.0" + "@radix-ui/rect" "1.1.0" + +"@radix-ui/react-portal@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.1.1.tgz#1957f1eb2e1aedfb4a5475bd6867d67b50b1d15f" + integrity sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g== + dependencies: + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-layout-effect" "1.1.0" + +"@radix-ui/react-presence@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.1.0.tgz#227d84d20ca6bfe7da97104b1a8b48a833bfb478" + integrity sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ== + dependencies: + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-use-layout-effect" "1.1.0" + +"@radix-ui/react-primitive@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz#fe05715faa9203a223ccc0be15dc44b9f9822884" + integrity sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw== + dependencies: + "@radix-ui/react-slot" "1.1.0" + +"@radix-ui/react-roving-focus@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz#b30c59daf7e714c748805bfe11c76f96caaac35e" + integrity sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-collection" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-direction" "1.1.0" + "@radix-ui/react-id" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-callback-ref" "1.1.0" + "@radix-ui/react-use-controllable-state" "1.1.0" + +"@radix-ui/react-slot@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.1.0.tgz#7c5e48c36ef5496d97b08f1357bb26ed7c714b84" + integrity sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw== + dependencies: + "@radix-ui/react-compose-refs" "1.1.0" + +"@radix-ui/react-toggle-group@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.0.tgz#28714c4d1ff4961a8fd259b1feef58b4cac92f80" + integrity sha512-PpTJV68dZU2oqqgq75Uzto5o/XfOVgkrJ9rulVmfTKxWp3HfUjHE6CP/WLRR4AzPX9HWxw7vFow2me85Yu+Naw== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-direction" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-roving-focus" "1.1.0" + "@radix-ui/react-toggle" "1.1.0" + "@radix-ui/react-use-controllable-state" "1.1.0" + +"@radix-ui/react-toggle@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle/-/react-toggle-1.1.0.tgz#1f7697b82917019330a16c6f96f649f46b4606cf" + integrity sha512-gwoxaKZ0oJ4vIgzsfESBuSgJNdc0rv12VhHgcqN0TEJmmZixXG/2XpsLK8kzNWYcnaoRIEEQc0bEi3dIvdUpjw== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-controllable-state" "1.1.0" + +"@radix-ui/react-tooltip@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-1.1.1.tgz#1807386562015c49b3e83d938910dd47f8cc6175" + integrity sha512-LLE8nzNE4MzPMw3O2zlVlkLFid3y9hMUs7uCbSHyKSo+tCN4yMCf+ZCCcfrYgsOC0TiHBPQ1mtpJ2liY3ZT3SQ== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-dismissable-layer" "1.1.0" + "@radix-ui/react-id" "1.1.0" + "@radix-ui/react-popper" "1.2.0" + "@radix-ui/react-portal" "1.1.1" + "@radix-ui/react-presence" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-slot" "1.1.0" + "@radix-ui/react-use-controllable-state" "1.1.0" + "@radix-ui/react-visually-hidden" "1.1.0" + +"@radix-ui/react-use-callback-ref@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz#bce938ca413675bc937944b0d01ef6f4a6dc5bf1" + integrity sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw== + +"@radix-ui/react-use-controllable-state@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz#1321446857bb786917df54c0d4d084877aab04b0" + integrity sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw== + dependencies: + "@radix-ui/react-use-callback-ref" "1.1.0" + +"@radix-ui/react-use-escape-keydown@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz#31a5b87c3b726504b74e05dac1edce7437b98754" + integrity sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw== + dependencies: + "@radix-ui/react-use-callback-ref" "1.1.0" + +"@radix-ui/react-use-layout-effect@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz#3c2c8ce04827b26a39e442ff4888d9212268bd27" + integrity sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w== + +"@radix-ui/react-use-rect@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz#13b25b913bd3e3987cc9b073a1a164bb1cf47b88" + integrity sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ== + dependencies: + "@radix-ui/rect" "1.1.0" + +"@radix-ui/react-use-size@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz#b4dba7fbd3882ee09e8d2a44a3eed3a7e555246b" + integrity sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw== + dependencies: + "@radix-ui/react-use-layout-effect" "1.1.0" + +"@radix-ui/react-visually-hidden@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz#ad47a8572580f7034b3807c8e6740cd41038a5a2" + integrity sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ== + dependencies: + "@radix-ui/react-primitive" "2.0.0" + +"@radix-ui/rect@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.1.0.tgz#f817d1d3265ac5415dadc67edab30ae196696438" + integrity sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg== + +"@react-email/body@0.0.9": + version "0.0.9" + resolved "https://registry.yarnpkg.com/@react-email/body/-/body-0.0.9.tgz#005dbde186d7c755fa8ffaabe8544bef33b6e9a6" + integrity sha512-bSGF6j+MbfQKYnnN+Kf57lGp/J+ci+435OMIv/BKAtfmNzHL+ptRrsINJELiO8QzwnZmQjTGKSMAMMJiQS+xwQ== + +"@react-email/button@0.0.16": + version "0.0.16" + resolved "https://registry.yarnpkg.com/@react-email/button/-/button-0.0.16.tgz#cacc390dc2f3586de3d0471d2387d64b74650cdb" + integrity sha512-paptUerzDhKHEUmBuT0UecCoqo3N6ZQSyDKC1hFALTwKReGW2xQATisinho9Ybh9ZGw6IZ3n1nGtmX5k2sX70Q== + +"@react-email/code-block@0.0.6": + version "0.0.6" + resolved "https://registry.yarnpkg.com/@react-email/code-block/-/code-block-0.0.6.tgz#d8b59cf2f046733c320f5045bab72dd6262f644b" + integrity sha512-i+TEeI7AyG1pmtO2Mr+TblV08zQnOtTlYB/v45kFMlDWWKTkvIV33oLRqLYOFhCIvoO5fDZA9T+4m6PvhmcNwQ== + dependencies: + prismjs "1.29.0" + +"@react-email/code-inline@0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@react-email/code-inline/-/code-inline-0.0.3.tgz#991641afd792436e6d1222d2423909cb29100a83" + integrity sha512-SY5Nn4KhjcqqEBHvUwFlOLNmUT78elIGR+Y14eg02LrVKQJ38mFCfXNGDLk4wbP/2dnidkLYq9+60nf7mFMhnQ== + +"@react-email/column@0.0.11": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@react-email/column/-/column-0.0.11.tgz#8b75f1fcd3ed01eb7165376c87090455f78b8ddf" + integrity sha512-KvrPuQFn0hlItRRL3vmRuOJgKG+8I0oO9HM5ReLMi5Ns313JSEQogCJaXuOEFkOVeuu5YyY6zy/+5Esccc1AxQ== + +"@react-email/components@0.0.22": + version "0.0.22" + resolved "https://registry.yarnpkg.com/@react-email/components/-/components-0.0.22.tgz#848d3b908e64bb8fa7e8ab34f6a3877cdba537a0" + integrity sha512-GO6F+fS3c3aQ6OnqL8esQ/KqtrPGwz80U6uQ8Nd/ETpgFt7y1PXvSGfr8v12wyLffAagdowc/JjoThfIr0L6aA== + dependencies: + "@react-email/body" "0.0.9" + "@react-email/button" "0.0.16" + "@react-email/code-block" "0.0.6" + "@react-email/code-inline" "0.0.3" + "@react-email/column" "0.0.11" + "@react-email/container" "0.0.13" + "@react-email/font" "0.0.7" + "@react-email/head" "0.0.10" + "@react-email/heading" "0.0.13" + "@react-email/hr" "0.0.9" + "@react-email/html" "0.0.9" + "@react-email/img" "0.0.9" + "@react-email/link" "0.0.9" + "@react-email/markdown" "0.0.11" + "@react-email/preview" "0.0.10" + "@react-email/render" "0.0.17" + "@react-email/row" "0.0.9" + "@react-email/section" "0.0.13" + "@react-email/tailwind" "0.0.19" + "@react-email/text" "0.0.9" + +"@react-email/container@0.0.13": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@react-email/container/-/container-0.0.13.tgz#49aa51d9c70e5bf1afac8f8fc4c745a8aad6fb63" + integrity sha512-ftke0N1FZl8MX3XXxXiiOaiJOnrQz7ZXUyqNj81K+BK+DePWIVaSmgK6Bu8fFnsgwdKuBdqjZTEtF4sIkU3FuQ== + +"@react-email/font@0.0.7": + version "0.0.7" + resolved "https://registry.yarnpkg.com/@react-email/font/-/font-0.0.7.tgz#063c48a0cb2a611e9a1b85783397c320b41d41dd" + integrity sha512-R0/mfUV/XcUQIALjZUFT9GP+XGmIP1KPz20h9rpS5e4ji6VkQ3ENWlisxrdK5U+KA9iZQrlan+/6tUoTJ9bFsg== + +"@react-email/head@0.0.10": + version "0.0.10" + resolved "https://registry.yarnpkg.com/@react-email/head/-/head-0.0.10.tgz#f89bc5f445819797365cc72d726a1b4c37336bfb" + integrity sha512-VoH399w0/i3dJFnwH0Ixf9BTuiWhSA/y8PpsCJ7CPw8Mv8WNBqMAAsw0rmrITYI8uPd15LZ2zk2uwRDvqasMRw== + +"@react-email/heading@0.0.13": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@react-email/heading/-/heading-0.0.13.tgz#2cdfb880eea4b1dc521e6a85f9b6b82f452d0a06" + integrity sha512-MYDzjJwljKHBLueLuyqkaHxu6N4aGOL1ms2NNyJ9WXC9mmBnLs4Y/QEf9SjE4Df3AW4iT9uyfVHuaNUb7uq5QA== + dependencies: + "@radix-ui/react-slot" "1.1.0" + +"@react-email/hr@0.0.9": + version "0.0.9" + resolved "https://registry.yarnpkg.com/@react-email/hr/-/hr-0.0.9.tgz#9fe47c9ca5e1fcaa0cfb23848e035fbd79edea22" + integrity sha512-Rte+EZL3ptH3rkVU3a7fh8/06mZ6Q679tDaWDjsw3878RQC9afWqUPp5lwgA/1pTouLmJlDs2BjRnV6H84O7iw== + +"@react-email/html@0.0.9": + version "0.0.9" + resolved "https://registry.yarnpkg.com/@react-email/html/-/html-0.0.9.tgz#af90c204f1294e5c51191680430d998c4c39d529" + integrity sha512-NB74xwWaOJZxhpiy6pzkhHvugBa2vvmUa0KKnSwOEIX+WEQH8wj5UUhRN4F+Pmkiqz3QBTETUJiSsNWWFtrHgA== + +"@react-email/img@0.0.9": + version "0.0.9" + resolved "https://registry.yarnpkg.com/@react-email/img/-/img-0.0.9.tgz#472569799794a0390686dec2439a9c26981d77f3" + integrity sha512-zDlQWmlSANb2dBYhDaKD12Z4xaGD5mEf3peawBYHGxYySzMLwRT2ANGvFqpDNd7iT0C5po+/9EWR8fS1dLy0QQ== + +"@react-email/link@0.0.9": + version "0.0.9" + resolved "https://registry.yarnpkg.com/@react-email/link/-/link-0.0.9.tgz#364a9d6fa11733dd6ceea533b37c361948367c4c" + integrity sha512-rRqWGPUTGFwwtMCtsdCHNh0ewOsd4UBG/D12UcwJYFKRb0U6hUG/6VJZE3tB1QYZpLIESdvOLL6ztznh+D749g== + +"@react-email/markdown@0.0.11": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@react-email/markdown/-/markdown-0.0.11.tgz#75d2133c68d541aff263a97d403cfb616ec62406" + integrity sha512-KeDTS0bAvvtgavYAIAmxKpRxWUSr1/jufckDzu9g4QsQtth8wYaSR5wCPXuTPmhFgJMIlNSlOiBnVp+oRbDtKA== + dependencies: + md-to-react-email "5.0.2" + +"@react-email/preview@0.0.10": + version "0.0.10" + resolved "https://registry.yarnpkg.com/@react-email/preview/-/preview-0.0.10.tgz#63dff6ac1b08b0bbc2222194a1cde1e1934cb5a3" + integrity sha512-bRrv8teMMBlF7ttLp1zZUejkPUzrwMQXrigdagtEBOqsB8HxvJU2MR6Yyb3XOqBYldaIDOQJ1z61zyD2wRlKAw== + +"@react-email/render@0.0.17": + version "0.0.17" + resolved "https://registry.yarnpkg.com/@react-email/render/-/render-0.0.17.tgz#9ad401c5bbc6b71c3e93f34795c726f3f5bfeb9f" + integrity sha512-xBQ+/73+WsGuXKY7r1U73zMBNV28xdV0cp9cFjhNYipBReDHhV97IpA6v7Hl0dDtDzt+yS/72dY5vYXrF1v8NA== + dependencies: + html-to-text "9.0.5" + js-beautify "^1.14.11" + react-promise-suspense "0.3.4" + +"@react-email/row@0.0.9": + version "0.0.9" + resolved "https://registry.yarnpkg.com/@react-email/row/-/row-0.0.9.tgz#e7816992691ca89d1d99b0e926247b9f8f23d96a" + integrity sha512-ZDASHVvyKrWBS00o5pSH5khfMf46UtZhrHcSAfPSiC4nj7R8A0bf+3Wmbk8YmsaV+qWXUCUSHWwIAAlMRnJoAA== + +"@react-email/section@0.0.13": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@react-email/section/-/section-0.0.13.tgz#2b8c1286fa1b3036446da9875a89737727302af2" + integrity sha512-McsCQ5NQlNWEMEAR3EtCxHgRhxGmLD+jPvj7A3FD7y2X3fXG0hbmUGX12B63rIywSWjJoQi6tojx/8RpzbyeTA== + +"@react-email/tailwind@0.0.19": + version "0.0.19" + resolved "https://registry.yarnpkg.com/@react-email/tailwind/-/tailwind-0.0.19.tgz#71ad5dfd621d4f762df17256ecc11144ec5e242f" + integrity sha512-bA0w4D7mSNowxWhcO0jBJauFIPf2Ok7QuKlrHwCcxyX35L2pb5D6ZmXYOrD9C6ADQuVz5oEX+oed3zpSLROgPg== + +"@react-email/text@0.0.9": + version "0.0.9" + resolved "https://registry.yarnpkg.com/@react-email/text/-/text-0.0.9.tgz#d8976b6efd5555d5b6da3fb7cc1255807079eea2" + integrity sha512-UNFPGerER3zywpb1ODOS2VgHP7rgOmiTxMHn75pjvQf/gi3/jN9edEQLYvRgPv/mNn4IpJFkOrlP8jcammLeew== + "@remix-run/router@1.8.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.8.0.tgz#e848d2f669f601544df15ce2a313955e4bf0bafc" @@ -321,6 +1174,14 @@ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.0.tgz#20c09cf44dcb082140cc7f439dd679fe4bba3375" integrity sha512-2jsCDZwtQvRhejHLfZ1JY6w6kEuEtfF9nzYsZxzSlNVKDX+DpsDJ+Rbjkm74nvg2rdx0gwBS+IMdvwJuq3S9pQ== +"@selderee/plugin-htmlparser2@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz#d5b5e29a7ba6d3958a1972c7be16f4b2c188c517" + integrity sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ== + dependencies: + domhandler "^5.0.3" + selderee "^0.11.0" + "@shopify/app-bridge-react@4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@shopify/app-bridge-react/-/app-bridge-react-4.0.0.tgz#8c4cccda96e6a73c039d5b2e5c212f99be570a15" @@ -363,56 +1224,130 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== +"@socket.io/component-emitter@~3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2" + integrity sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA== + +"@swc/core-darwin-arm64@1.3.101": + version "1.3.101" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.101.tgz#9ffdc0e77c31b20877fa7405c82905e0c76738d0" + integrity sha512-mNFK+uHNPRXSnfTOG34zJOeMl2waM4hF4a2NY7dkMXrPqw9CoJn4MwTXJcyMiSz1/BnNjjTCHF3Yhj0jPxmkzQ== + "@swc/core-darwin-arm64@1.7.14": version "1.7.14" resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.14.tgz#a4530ec755ea183802cc9dfe4900ab5f6a327fea" integrity sha512-V0OUXjOH+hdGxDYG8NkQzy25mKOpcNKFpqtZEzLe5V/CpLJPnpg1+pMz70m14s9ZFda9OxsjlvPbg1FLUwhgIQ== +"@swc/core-darwin-x64@1.3.101": + version "1.3.101" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.101.tgz#e50130e21e3cfd3029fd6cea43e8309b58ad9fa6" + integrity sha512-B085j8XOx73Fg15KsHvzYWG262bRweGr3JooO1aW5ec5pYbz5Ew9VS5JKYS03w2UBSxf2maWdbPz2UFAxg0whw== + "@swc/core-darwin-x64@1.7.14": version "1.7.14" resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.7.14.tgz#2c9c717fd28dd1dde9c21cf58b01f1cda7976b1a" integrity sha512-9iFvUnxG6FC3An5ogp5jbBfQuUmTTwy8KMB+ZddUoPB3NR1eV+Y9vOh/tfWcenSJbgOKDLgYC5D/b1mHAprsrQ== +"@swc/core-linux-arm-gnueabihf@1.3.101": + version "1.3.101" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.101.tgz#8cd36328e794b3c42b6c8e578bb1f42e59ba0231" + integrity sha512-9xLKRb6zSzRGPqdz52Hy5GuB1lSjmLqa0lST6MTFads3apmx4Vgs8Y5NuGhx/h2I8QM4jXdLbpqQlifpzTlSSw== + "@swc/core-linux-arm-gnueabihf@1.7.14": version "1.7.14" resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.14.tgz#fed055c9c65347177c8df88720f8a51793a4df06" integrity sha512-zGJsef9qPivKSH8Vv4F/HiBXBTHZ5Hs3ZjVGo/UIdWPJF8fTL9OVADiRrl34Q7zOZEtGXRwEKLUW1SCQcbDvZA== +"@swc/core-linux-arm64-gnu@1.3.101": + version "1.3.101" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.101.tgz#d15e3885eb13a1512ba62f00ce4f5bb19f710a0c" + integrity sha512-oE+r1lo7g/vs96Weh2R5l971dt+ZLuhaUX+n3BfDdPxNHfObXgKMjO7E+QS5RbGjv/AwiPCxQmbdCp/xN5ICJA== + "@swc/core-linux-arm64-gnu@1.7.14": version "1.7.14" resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.14.tgz#ca740c8ea26f041b2dc43ba87facec452052814f" integrity sha512-AxV3MPsoI7i4B8FXOew3dx3N8y00YoJYvIPfxelw07RegeCEH3aHp2U2DtgbP/NV1ugZMx0TL2Z2DEvocmA51g== +"@swc/core-linux-arm64-musl@1.3.101": + version "1.3.101" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.101.tgz#851d4cc1079b091fee36f5f64335232210749d7a" + integrity sha512-OGjYG3H4BMOTnJWJyBIovCez6KiHF30zMIu4+lGJTCrxRI2fAjGLml3PEXj8tC3FMcud7U2WUn6TdG0/te2k6g== + "@swc/core-linux-arm64-musl@1.7.14": version "1.7.14" resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.14.tgz#fbc6fed24f5ad58b948e5b7abe6cd1f07112bef1" integrity sha512-JDLdNjUj3zPehd4+DrQD8Ltb3B5lD8D05IwePyDWw+uR/YPc7w/TX1FUVci5h3giJnlMCJRvi1IQYV7K1n7KtQ== +"@swc/core-linux-x64-gnu@1.3.101": + version "1.3.101" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.101.tgz#3a2a7c584db2e05a798e28361440424914563fa3" + integrity sha512-/kBMcoF12PRO/lwa8Z7w4YyiKDcXQEiLvM+S3G9EvkoKYGgkkz4Q6PSNhF5rwg/E3+Hq5/9D2R+6nrkF287ihg== + "@swc/core-linux-x64-gnu@1.7.14": version "1.7.14" resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.14.tgz#509a37833e4fbf89506b9291d9bd131fa2017fca" integrity sha512-Siy5OvPCLLWmMdx4msnEs8HvEVUEigSn0+3pbLjv78iwzXd0qSBNHUPZyC1xeurVaUbpNDxZTpPRIwpqNE2+Og== +"@swc/core-linux-x64-musl@1.3.101": + version "1.3.101" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.101.tgz#45d1d53945994f08e93703b8de24ccac88538d0c" + integrity sha512-kDN8lm4Eew0u1p+h1l3JzoeGgZPQ05qDE0czngnjmfpsH2sOZxVj1hdiCwS5lArpy7ktaLu5JdRnx70MkUzhXw== + "@swc/core-linux-x64-musl@1.7.14": version "1.7.14" resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.14.tgz#81156cc6ff814ad4b8fcf6eb6658d3f247db0b57" integrity sha512-FtEGm9mwtRYQNK43WMtUIadxHs/ja2rnDurB99os0ZoFTGG2IHuht2zD97W0wB8JbqEabT1XwSG9Y5wmN+ciEQ== +"@swc/core-win32-arm64-msvc@1.3.101": + version "1.3.101" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.101.tgz#b2610b8354e5fbca7cc5be3f728e61b046227fa8" + integrity sha512-9Wn8TTLWwJKw63K/S+jjrZb9yoJfJwCE2RV5vPCCWmlMf3U1AXj5XuWOLUX+Rp2sGKau7wZKsvywhheWm+qndQ== + "@swc/core-win32-arm64-msvc@1.7.14": version "1.7.14" resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.14.tgz#c605fa783b5fbe1fff784ace4c4bb074b8d6026d" integrity sha512-Jp8KDlfq7Ntt2/BXr0y344cYgB1zf0DaLzDZ1ZJR6rYlAzWYSccLYcxHa97VGnsYhhPspMpmCvHid97oe2hl4A== +"@swc/core-win32-ia32-msvc@1.3.101": + version "1.3.101" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.101.tgz#c919175bb4cd5e9fcfa56fbd3708167c1d445c68" + integrity sha512-onO5KvICRVlu2xmr4//V2je9O2XgS1SGKpbX206KmmjcJhXN5EYLSxW9qgg+kgV5mip+sKTHTAu7IkzkAtElYA== + "@swc/core-win32-ia32-msvc@1.7.14": version "1.7.14" resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.14.tgz#3e15dc3b662c9fab851a38b3e271c8e2da4ba03a" integrity sha512-I+cFsXF0OU0J9J4zdWiQKKLURO5dvCujH9Jr8N0cErdy54l9d4gfIxdctfTF+7FyXtWKLTCkp+oby9BQhkFGWA== +"@swc/core-win32-x64-msvc@1.3.101": + version "1.3.101" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.101.tgz#17743fe425caffc596fde5965c9c4cf9a48aa26a" + integrity sha512-T3GeJtNQV00YmiVw/88/nxJ/H43CJvFnpvBHCVn17xbahiVUOPOduh3rc9LgAkKiNt/aV8vU3OJR+6PhfMR7UQ== + "@swc/core-win32-x64-msvc@1.7.14": version "1.7.14" resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.14.tgz#83958d92e9f07865ec9365212111fbc295660f0d" integrity sha512-NNrprQCK6d28mG436jVo2TD+vACHseUECacEBGZ9Ef0qfOIWS1XIt2MisQKG0Oea2VvLFl6tF/V4Lnx/H0Sn3Q== +"@swc/core@1.3.101": + version "1.3.101" + resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.3.101.tgz#4e8f1583094a73c410e48a0bebdeccdc6c66d4a5" + integrity sha512-w5aQ9qYsd/IYmXADAnkXPGDMTqkQalIi+kfFf/MHRKTpaOL7DHjMXwPp/n8hJ0qNjRvchzmPtOqtPBiER50d8A== + dependencies: + "@swc/counter" "^0.1.1" + "@swc/types" "^0.1.5" + optionalDependencies: + "@swc/core-darwin-arm64" "1.3.101" + "@swc/core-darwin-x64" "1.3.101" + "@swc/core-linux-arm-gnueabihf" "1.3.101" + "@swc/core-linux-arm64-gnu" "1.3.101" + "@swc/core-linux-arm64-musl" "1.3.101" + "@swc/core-linux-x64-gnu" "1.3.101" + "@swc/core-linux-x64-musl" "1.3.101" + "@swc/core-win32-arm64-msvc" "1.3.101" + "@swc/core-win32-ia32-msvc" "1.3.101" + "@swc/core-win32-x64-msvc" "1.3.101" + "@swc/core@^1.3.35": version "1.7.14" resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.7.14.tgz#d10492b5a4168cb1e73cf561a315e8b0f62255ed" @@ -432,12 +1367,19 @@ "@swc/core-win32-ia32-msvc" "1.7.14" "@swc/core-win32-x64-msvc" "1.7.14" -"@swc/counter@^0.1.3": +"@swc/counter@^0.1.1", "@swc/counter@^0.1.3": version "0.1.3" resolved "https://registry.yarnpkg.com/@swc/counter/-/counter-0.1.3.tgz#cc7463bd02949611c6329596fccd2b0ec782b0e9" integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ== -"@swc/types@^0.1.12": +"@swc/helpers@0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.2.tgz#85ea0c76450b61ad7d10a37050289eded783c27d" + integrity sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw== + dependencies: + tslib "^2.4.0" + +"@swc/types@^0.1.12", "@swc/types@^0.1.5": version "0.1.12" resolved "https://registry.yarnpkg.com/@swc/types/-/types-0.1.12.tgz#7f632c06ab4092ce0ebd046ed77ff7557442282f" integrity sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA== @@ -461,7 +1403,35 @@ "@types/node" "*" "@types/responselike" "^1.0.0" -"@types/estree@1.0.5": +"@types/cookie@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" + integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== + +"@types/cors@^2.8.12": + version "2.8.17" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.17.tgz#5d718a5e494a8166f569d986794e49c48b216b2b" + integrity sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA== + dependencies: + "@types/node" "*" + +"@types/eslint-scope@^3.7.3": + version "3.7.7" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "9.6.0" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.0.tgz#51d4fe4d0316da9e9f2c80884f2c20ed5fb022ff" + integrity sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@1.0.5", "@types/estree@^1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== @@ -471,6 +1441,11 @@ resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== +"@types/json-schema@*", "@types/json-schema@^7.0.8": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + "@types/keyv@^3.1.4": version "3.1.4" resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" @@ -478,7 +1453,7 @@ dependencies: "@types/node" "*" -"@types/node@*": +"@types/node@*", "@types/node@>=10.0.0": version "22.4.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-22.4.1.tgz#9b595d292c65b94c20923159e2ce947731b6fdce" integrity sha512-1tbpb9325+gPnKK0dMm+/LMriX0vKxf6RnB0SZUqfyVkQ4fMgUSySqhxE/y8Jvs4NyF1yHzTfG9KlnkIODxPKg== @@ -492,6 +1467,11 @@ dependencies: undici-types "~6.19.2" +"@types/prismjs@^1.26.0": + version "1.26.4" + resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.4.tgz#1a9e1074619ce1d7322669e5b46fbe823925103a" + integrity sha512-rlAnzkW2sZOjbqZ743IHUhFcvzaGbqijwOu8QZnZCjfQzBqFE3s4lOTJEsxikImav9uzz/42I+O7YUs1mWgMlg== + "@types/prop-types@*": version "15.7.12" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6" @@ -519,6 +1499,15 @@ "@types/prop-types" "*" csstype "^3.0.2" +"@types/react@18.2.47": + version "18.2.47" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.47.tgz#85074b27ab563df01fbc3f68dc64bf7050b0af40" + integrity sha512-xquNkkOirwyCgoClNk85BjP+aqnIS+ckAJ8i37gAbDs14jfW/J23f2GItAf33oiUPQnqNMALiFeoM9Y5mbjpVQ== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + "@types/responselike@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.3.tgz#cc29706f0a397cfe6df89debfe4bf5cea159db50" @@ -526,6 +1515,20 @@ dependencies: "@types/node" "*" +"@types/scheduler@*": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.23.0.tgz#0a6655b3e2708eaabca00b7372fafd7a792a7b09" + integrity sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw== + +"@types/webpack@5.28.5": + version "5.28.5" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-5.28.5.tgz#0e9d9a15efa09bbda2cef41356ca4ac2031ea9a2" + integrity sha512-wR87cgvxj3p6D0Crt1r5avwqffqPXUkNlnQ1mjU93G7gCuFjufZR4I6j8cz5g1F1tTYpfOOFvly+cmIQwL9wvw== + dependencies: + "@types/node" "*" + tapable "^2.2.0" + webpack "^5" + "@urql/core@^4.0.10": version "4.3.0" resolved "https://registry.yarnpkg.com/@urql/core/-/core-4.3.0.tgz#5e150412ed08d167861b05ceed417abbd048553f" @@ -549,6 +1552,142 @@ dependencies: "@swc/core" "^1.3.35" +"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" + integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== + +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== + +"@webassemblyjs/helper-buffer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6" + integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw== + +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== + +"@webassemblyjs/helper-wasm-section@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" + integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.12.1" + +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + +"@webassemblyjs/wasm-edit@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" + integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-opt" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + "@webassemblyjs/wast-printer" "1.12.1" + +"@webassemblyjs/wasm-gen@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" + integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wasm-opt@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" + integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + +"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" + integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wast-printer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac" + integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abbrev@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-2.0.0.tgz#cf59829b8b4f03f89dda2771cb7f3653828c89bf" + integrity sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ== + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -561,6 +1700,24 @@ abstract-logging@^2.0.1: resolved "https://registry.yarnpkg.com/abstract-logging/-/abstract-logging-2.0.1.tgz#6b0c371df212db7129b57d2e7fcf282b8bf1c839" integrity sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA== +accepts@~1.3.4: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-import-attributes@^1.9.5: + version "1.9.5" + resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" + integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== + +acorn@^8.7.1, acorn@^8.8.2: + version "8.12.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" + integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== + ajv-formats@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" @@ -575,6 +1732,21 @@ ajv-formats@^3.0.1: dependencies: ajv "^8.0.0" +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + ajv@^8.0.0, ajv@^8.10.0, ajv@^8.11.0: version "8.17.1" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" @@ -585,11 +1757,77 @@ ajv@^8.0.0, ajv@^8.10.0, ajv@^8.11.0: json-schema-traverse "^1.0.0" require-from-string "^2.0.2" +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" + integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== + +aria-hidden@^1.1.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.4.tgz#b78e383fdbc04d05762c78b4a25a501e736c4522" + integrity sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A== + dependencies: + tslib "^2.0.0" + atomic-sleep@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== +autoprefixer@10.4.14: + version "10.4.14" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.14.tgz#e28d49902f8e759dd25b153264e862df2705f79d" + integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== + dependencies: + browserslist "^4.21.5" + caniuse-lite "^1.0.30001464" + fraction.js "^4.2.0" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + avvio@^8.3.0: version "8.4.0" resolved "https://registry.yarnpkg.com/avvio/-/avvio-8.4.0.tgz#7cbd5bca74f0c9effa944ced601f94ffd8afc5ed" @@ -598,28 +1836,96 @@ avvio@^8.3.0: "@fastify/error" "^3.3.0" fastq "^1.17.1" +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" +base64id@2.0.0, base64id@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== -cacheable-lookup@^5.0.3: - version "5.0.4" - resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" - integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== +binary-extensions@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== -cacheable-request@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817" - integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg== +bl@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.3, braces@~3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + +browserslist@^4.21.10, browserslist@^4.21.5, browserslist@^4.23.1: + version "4.23.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800" + integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== + dependencies: + caniuse-lite "^1.0.30001646" + electron-to-chromium "^1.5.4" + node-releases "^2.0.18" + update-browserslist-db "^1.1.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +busboy@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" + integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + dependencies: + streamsearch "^1.1.0" + +cacheable-lookup@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" + integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== + +cacheable-request@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817" + integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg== dependencies: clone-response "^1.0.2" get-stream "^5.1.0" @@ -640,6 +1946,85 @@ call-bind@^1.0.7: get-intrinsic "^1.2.4" set-function-length "^1.2.1" +camelcase-css@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" + integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + +caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001579, caniuse-lite@^1.0.30001646: + version "1.0.30001651" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz#52de59529e8b02b1aedcaaf5c05d9e23c0c28138" + integrity sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg== + +chalk@4.1.2, chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chokidar@3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chokidar@^3.5.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chrome-trace-event@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" + integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-spinners@^2.5.0: + version "2.9.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== + +client-only@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" + integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== + clone-response@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" @@ -647,11 +2032,96 @@ clone-response@^1.0.2: dependencies: mimic-response "^1.0.0" +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== + +clsx@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.0.tgz#e851283bcb5c80ee7608db18487433f7b23f77cb" + integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg== + +clsx@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" + integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +commander@11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-11.1.0.tgz#62fdce76006a68e5c1ab3314dc92e800eb83d906" + integrity sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ== + +commander@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +config-chain@^1.1.13: + version "1.1.13" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" + integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + cookie@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== +cookie@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + +cors@~2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + cross-fetch@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-4.0.0.tgz#f037aef1580bb3a1a35164ea2a848ba81b445983" @@ -659,11 +2129,25 @@ cross-fetch@^4.0.0: dependencies: node-fetch "^2.6.12" +cross-spawn@^7.0.0: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypto-js@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631" integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + csstype@^3.0.2: version "3.1.3" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" @@ -681,6 +2165,18 @@ date-fns@^2.30.0: dependencies: "@babel/runtime" "^7.21.0" +debounce@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-2.0.0.tgz#b2f914518a1481466f4edaee0b063e4d473ad549" + integrity sha512-xRetU6gL1VJbs85Mc4FoEGSjQxzpdxRyFhe3lmWFyy2EzydIcD4xzUvRJMD+NPDfMwKNhxa3PvsIOU32luIWeA== + +debug@^4.1.0, debug@^4.3.1, debug@~4.3.1, debug@~4.3.2, debug@~4.3.4: + version "4.3.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" + integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== + dependencies: + ms "2.1.2" + decompress-response@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" @@ -693,6 +2189,13 @@ deepmerge@^4.3.1: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== +defaults@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" + integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== + dependencies: + clone "^1.0.2" + defer-to-connect@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" @@ -707,6 +2210,21 @@ define-data-property@^1.1.4: es-errors "^1.3.0" gopd "^1.0.1" +detect-node-es@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493" + integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== + +didyoumean@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" + integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== + +dlv@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" + integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== + dom-helpers@^5.0.1: version "5.2.1" resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" @@ -715,6 +2233,71 @@ dom-helpers@^5.0.1: "@babel/runtime" "^7.8.7" csstype "^3.0.2" +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + +dotenv@16.0.3: + version "16.0.3" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" + integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + +editorconfig@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-1.0.4.tgz#040c9a8e9a6c5288388b87c2db07028aa89f53a3" + integrity sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q== + dependencies: + "@one-ini/wasm" "0.1.1" + commander "^10.0.0" + minimatch "9.0.1" + semver "^7.5.3" + +electron-to-chromium@^1.5.4: + version "1.5.11" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.11.tgz#258077f1077a1c72f2925cd5b326c470a7f5adef" + integrity sha512-R1CccCDYqndR25CaXFd6hp/u9RaaMcftMkphmvuepXr5b1vfLkRml6aWVeBhXJ7rbevHkKEMJtz8XqPf7ffmew== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -722,6 +2305,51 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" +engine.io-client@~6.5.2: + version "6.5.4" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-6.5.4.tgz#b8bc71ed3f25d0d51d587729262486b4b33bd0d0" + integrity sha512-GeZeeRjpD2qf49cZQ0Wvh/8NJNfeXkXXcoGh+F77oEAgo9gUHwT1fCRxSNU+YEEaysOJTnsFHmM5oAcPy4ntvQ== + dependencies: + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.1" + engine.io-parser "~5.2.1" + ws "~8.17.1" + xmlhttprequest-ssl "~2.0.0" + +engine.io-parser@~5.2.1: + version "5.2.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.2.3.tgz#00dc5b97b1f233a23c9398d0209504cf5f94d92f" + integrity sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q== + +engine.io@~6.5.2: + version "6.5.5" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.5.5.tgz#430b80d8840caab91a50e9e23cb551455195fc93" + integrity sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA== + dependencies: + "@types/cookie" "^0.4.1" + "@types/cors" "^2.8.12" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~5.2.1" + ws "~8.17.1" + +enhanced-resolve@^5.17.0: + version "5.17.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" + integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +entities@^4.2.0, entities@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + es-define-property@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" @@ -734,6 +2362,40 @@ es-errors@^1.3.0: resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== +es-module-lexer@^1.2.1: + version "1.5.4" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.5.4.tgz#a8efec3a3da991e60efa6b633a7cad6ab8d26b78" + integrity sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw== + +esbuild@0.19.11: + version "0.19.11" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.11.tgz#4a02dca031e768b5556606e1b468fe72e3325d96" + integrity sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA== + optionalDependencies: + "@esbuild/aix-ppc64" "0.19.11" + "@esbuild/android-arm" "0.19.11" + "@esbuild/android-arm64" "0.19.11" + "@esbuild/android-x64" "0.19.11" + "@esbuild/darwin-arm64" "0.19.11" + "@esbuild/darwin-x64" "0.19.11" + "@esbuild/freebsd-arm64" "0.19.11" + "@esbuild/freebsd-x64" "0.19.11" + "@esbuild/linux-arm" "0.19.11" + "@esbuild/linux-arm64" "0.19.11" + "@esbuild/linux-ia32" "0.19.11" + "@esbuild/linux-loong64" "0.19.11" + "@esbuild/linux-mips64el" "0.19.11" + "@esbuild/linux-ppc64" "0.19.11" + "@esbuild/linux-riscv64" "0.19.11" + "@esbuild/linux-s390x" "0.19.11" + "@esbuild/linux-x64" "0.19.11" + "@esbuild/netbsd-x64" "0.19.11" + "@esbuild/openbsd-x64" "0.19.11" + "@esbuild/sunos-x64" "0.19.11" + "@esbuild/win32-arm64" "0.19.11" + "@esbuild/win32-ia32" "0.19.11" + "@esbuild/win32-x64" "0.19.11" + esbuild@^0.21.3: version "0.21.5" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" @@ -763,12 +2425,66 @@ esbuild@^0.21.3: "@esbuild/win32-ia32" "0.21.5" "@esbuild/win32-x64" "0.21.5" +escalade@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" + integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +eslint-config-prettier@9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz#eb25485946dd0c66cd216a46232dc05451518d1f" + integrity sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw== + +eslint-config-turbo@1.10.12: + version "1.10.12" + resolved "https://registry.yarnpkg.com/eslint-config-turbo/-/eslint-config-turbo-1.10.12.tgz#5868252d6833dd2b5cab4414751ed31ebe2177c3" + integrity sha512-z3jfh+D7UGYlzMWGh+Kqz++hf8LOE96q3o5R8X4HTjmxaBWlLAWG+0Ounr38h+JLR2TJno0hU9zfzoPNkR9BdA== + dependencies: + eslint-plugin-turbo "1.10.12" + +eslint-plugin-turbo@1.10.12: + version "1.10.12" + resolved "https://registry.yarnpkg.com/eslint-plugin-turbo/-/eslint-plugin-turbo-1.10.12.tgz#3f95884faf35b56e0855d939585fa6cd457bb128" + integrity sha512-uNbdj+ohZaYo4tFJ6dStRXu2FZigwulR1b3URPXe0Q8YaE7thuekKNP+54CHtZPH9Zey9dmDx5btAQl9mfzGOw== + dependencies: + dotenv "16.0.3" + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + event-target-shim@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -events@^3.3.0: +events@^3.2.0, events@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== @@ -783,11 +2499,32 @@ fast-decode-uri-component@^1.0.1: resolved "https://registry.yarnpkg.com/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz#46f8b6c22b30ff7a81357d4f59abfae938202543" integrity sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg== -fast-deep-equal@^3.1.3: +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-glob@^3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + fast-json-stringify@^5.7.0, fast-json-stringify@^5.8.0: version "5.16.1" resolved "https://registry.yarnpkg.com/fast-json-stringify/-/fast-json-stringify-5.16.1.tgz#a6d0c575231a3a08c376a00171d757372f2ca46e" @@ -850,7 +2587,7 @@ fastify@^4.24.2: semver "^7.5.4" toad-cache "^3.3.0" -fastq@^1.17.1: +fastq@^1.17.1, fastq@^1.6.0: version "1.17.1" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== @@ -862,6 +2599,13 @@ filesize@^10.1.2: resolved "https://registry.yarnpkg.com/filesize/-/filesize-10.1.4.tgz#184f256063a201f08b6e6b3cc47d21b60f5b8d89" integrity sha512-ryBwPIIeErmxgPnm6cbESAzXjuEFubs+yKYLBZvg3CaiNcmkJChoOGcBSrZ6IwkMwPABwPpVXE6IlNdGJJrvEg== +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + find-my-way@^8.0.0: version "8.2.0" resolved "https://registry.yarnpkg.com/find-my-way/-/find-my-way-8.2.0.tgz#ef1b83d008114a300118c9c707d8dc65947d9960" @@ -871,11 +2615,33 @@ find-my-way@^8.0.0: fast-querystring "^1.0.0" safe-regex2 "^3.1.0" +foreground-child@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77" + integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== +fraction.js@^4.2.0: + version "4.3.7" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7" + integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew== + +framer-motion@10.17.4: + version "10.17.4" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-10.17.4.tgz#e5a739791239ffbed52e0aea39c4ff93ed61a233" + integrity sha512-CYBSs6cWfzcasAX8aofgKFZootmkQtR4qxbfTOksBLny/lbUfkGbQAFOS3qnl6Uau1N9y8tUpI7mVIrHgkFjLQ== + dependencies: + tslib "^2.4.0" + optionalDependencies: + "@emotion/is-prop-valid" "^0.8.2" + fsevents@~2.3.2, fsevents@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" @@ -890,6 +2656,11 @@ function-bind@^1.1.2: version "0.0.0" uid "" +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" @@ -901,6 +2672,11 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: has-symbols "^1.0.3" hasown "^2.0.0" +get-nonce@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" + integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== + get-stream@^5.1.0: version "5.2.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" @@ -908,6 +2684,53 @@ get-stream@^5.1.0: dependencies: pump "^3.0.0" +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@10.3.4: + version "10.3.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.4.tgz#c85c9c7ab98669102b6defda76d35c5b1ef9766f" + integrity sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.0.3" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" + +glob@^10.3.10, glob@^10.3.3: + version "10.4.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" + integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== + dependencies: + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^1.11.1" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + gopd@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" @@ -932,6 +2755,11 @@ got@^11.1.4: p-cancelable "^2.0.0" responselike "^2.0.0" +graceful-fs@^4.1.2, graceful-fs@^4.2.11, graceful-fs@^4.2.4: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + graphql-ws@^5.13.1: version "5.16.0" resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-5.16.0.tgz#849efe02f384b4332109329be01d74c345842729" @@ -942,6 +2770,16 @@ graphql@^16.8.1: resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.9.0.tgz#1c310e63f16a49ce1fbb230bd0a000e99f6f115f" integrity sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw== +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + has-property-descriptors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" @@ -959,13 +2797,34 @@ has-symbols@^1.0.3: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== -hasown@^2.0.0: +hasown@^2.0.0, hasown@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== dependencies: function-bind "^1.1.2" +html-to-text@9.0.5: + version "9.0.5" + resolved "https://registry.yarnpkg.com/html-to-text/-/html-to-text-9.0.5.tgz#6149a0f618ae7a0db8085dca9bbf96d32bb8368d" + integrity sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg== + dependencies: + "@selderee/plugin-htmlparser2" "^0.11.0" + deepmerge "^4.3.1" + dom-serializer "^2.0.0" + htmlparser2 "^8.0.2" + selderee "^0.11.0" + +htmlparser2@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21" + integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + entities "^4.4.0" + http-cache-semantics@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" @@ -979,31 +2838,157 @@ http2-wrapper@^1.0.0-beta.5.2: quick-lru "^5.1.1" resolve-alpn "^1.0.0" -ieee754@^1.2.1: +ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== +inherits@^2.0.3, inherits@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@^1.3.4: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-core-module@^2.13.0: + version "2.15.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.0.tgz#71c72ec5442ace7e76b306e9d48db361f22699ea" + integrity sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA== + dependencies: + hasown "^2.0.2" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-interactive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" + integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + isomorphic-ws@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== -"js-tokens@^3.0.0 || ^4.0.0": +jackspeak@^2.0.3: + version "2.3.6" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" + integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +jackspeak@^3.1.2: + version "3.4.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" + integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jiti@^1.19.1: + version "1.21.6" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268" + integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== + +js-beautify@^1.14.11: + version "1.15.1" + resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.15.1.tgz#4695afb508c324e1084ee0b952a102023fc65b64" + integrity sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA== + dependencies: + config-chain "^1.1.13" + editorconfig "^1.0.4" + glob "^10.3.3" + js-cookie "^3.0.5" + nopt "^7.2.0" + +js-cookie@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.5.tgz#0b7e2fd0c01552c58ba86e0841f94dc2557dcdbc" + integrity sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== +json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + json-schema-ref-resolver@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-schema-ref-resolver/-/json-schema-ref-resolver-1.0.1.tgz#6586f483b76254784fc1d2120f717bdc9f0a99bf" @@ -1011,11 +2996,21 @@ json-schema-ref-resolver@^1.0.1: dependencies: fast-deep-equal "^3.1.3" +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + json-schema-traverse@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + keyv@^4.0.0: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" @@ -1028,6 +3023,11 @@ klona@^2.0.6: resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== +leac@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/leac/-/leac-0.6.0.tgz#dcf136e382e666bd2475f44a1096061b70dc0912" + integrity sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg== + light-my-request@^5.11.0: version "5.13.0" resolved "https://registry.yarnpkg.com/light-my-request/-/light-my-request-5.13.0.tgz#b29905e55e8605b77fee2a946e17b219bca35113" @@ -1037,12 +3037,40 @@ light-my-request@^5.11.0: process-warning "^3.0.0" set-cookie-parser "^2.4.1" +lilconfig@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== + +lilconfig@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.2.tgz#e4a7c3cb549e3a606c8dcc32e5ae1005e62c05cb" + integrity sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + lodash@^4.17.10: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -loose-envify@^1.1.0, loose-envify@^1.4.0: +log-symbols@4.1.0, log-symbols@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -1054,6 +3082,65 @@ lowercase-keys@^2.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== +lru-cache@^10.2.0: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +marked@7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/marked/-/marked-7.0.4.tgz#e2558ee2d535b9df6a27c6e282dc603a18388a6d" + integrity sha512-t8eP0dXRJMtMvBojtkcsA7n48BkauktUKzfkPSCq85ZMTJ0v76Rke4DYz01omYpPTUh4p/f7HePgRo3ebG8+QQ== + +md-to-react-email@5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/md-to-react-email/-/md-to-react-email-5.0.2.tgz#2ee848a7248d4df6e6a95466a269ca6b6697a704" + integrity sha512-x6kkpdzIzUhecda/yahltfEl53mH26QdWu4abUF9+S0Jgam8P//Ciro8cdhyMHnT5MQUJYrIbO6ORM2UxPiNNA== + dependencies: + marked "7.0.4" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4, micromatch@^4.0.5: + version "4.0.7" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.7.tgz#33e8190d9fe474a9895525f5618eee136d46c2e5" + integrity sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@2.1.35, mime-types@^2.1.27, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + mimic-response@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" @@ -1064,11 +3151,77 @@ mimic-response@^3.1.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== -nanoid@^3.3.7: +minimatch@9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.1.tgz#8a555f541cf976c622daf078bb28f29fb927c253" + integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^9.0.1, minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nanoid@^3.3.6, nanoid@^3.3.7: version "3.3.7" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +next@14.1.4: + version "14.1.4" + resolved "https://registry.yarnpkg.com/next/-/next-14.1.4.tgz#203310f7310578563fd5c961f0db4729ce7a502d" + integrity sha512-1WTaXeSrUwlz/XcnhGTY7+8eiaFvdet5z9u3V2jb+Ek1vFo0VhHKSAIJvDWfQpttWjnyw14kBeq28TPq7bTeEQ== + dependencies: + "@next/env" "14.1.4" + "@swc/helpers" "0.5.2" + busboy "1.6.0" + caniuse-lite "^1.0.30001579" + graceful-fs "^4.2.11" + postcss "8.4.31" + styled-jsx "5.1.1" + optionalDependencies: + "@next/swc-darwin-arm64" "14.1.4" + "@next/swc-darwin-x64" "14.1.4" + "@next/swc-linux-arm64-gnu" "14.1.4" + "@next/swc-linux-arm64-musl" "14.1.4" + "@next/swc-linux-x64-gnu" "14.1.4" + "@next/swc-linux-x64-musl" "14.1.4" + "@next/swc-win32-arm64-msvc" "14.1.4" + "@next/swc-win32-ia32-msvc" "14.1.4" + "@next/swc-win32-x64-msvc" "14.1.4" + node-fetch@^2.6.12: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" @@ -1076,16 +3229,43 @@ node-fetch@^2.6.12: dependencies: whatwg-url "^5.0.0" +node-releases@^2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== + +nopt@^7.2.0: + version "7.2.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.2.1.tgz#1cac0eab9b8e97c9093338446eddd40b2c8ca1e7" + integrity sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w== + dependencies: + abbrev "^2.0.0" + +normalize-path@3.0.0, normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== + normalize-url@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== -object-assign@^4.1.1: +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== +object-hash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" + integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== + object-inspect@^1.13.1: version "1.13.2" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" @@ -1103,16 +3283,84 @@ once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +ora@5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" + integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== + dependencies: + bl "^4.1.0" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-spinners "^2.5.0" + is-interactive "^1.0.0" + is-unicode-supported "^0.1.0" + log-symbols "^4.1.0" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" + p-cancelable@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== -picocolors@^1.0.1: +package-json-from-dist@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz#e501cd3094b278495eb4258d4c9f6d5ac3019f00" + integrity sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw== + +parseley@^0.12.0: + version "0.12.1" + resolved "https://registry.yarnpkg.com/parseley/-/parseley-0.12.1.tgz#4afd561d50215ebe259e3e7a853e62f600683aef" + integrity sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw== + dependencies: + leac "^0.6.0" + peberminta "^0.9.0" + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-scurry@^1.10.1, path-scurry@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + +peberminta@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/peberminta/-/peberminta-0.9.0.tgz#8ec9bc0eb84b7d368126e71ce9033501dca2a352" + integrity sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ== + +picocolors@^1.0.0, picocolors@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + pino-abstract-transport@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz#97f9f2631931e242da531b5c66d3079c12c9d1b5" @@ -1143,12 +3391,79 @@ pino@^9.0.0: sonic-boom "^4.0.1" thread-stream "^3.0.0" +pirates@^4.0.1: + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + pluralize@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== -postcss@^8.4.41: +postcss-import@^15.1.0: + version "15.1.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70" + integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== + dependencies: + postcss-value-parser "^4.0.0" + read-cache "^1.0.0" + resolve "^1.1.7" + +postcss-js@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2" + integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== + dependencies: + camelcase-css "^2.0.1" + +postcss-load-config@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz#7159dcf626118d33e299f485d6afe4aff7c4a3e3" + integrity sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ== + dependencies: + lilconfig "^3.0.0" + yaml "^2.3.4" + +postcss-nested@^6.0.1: + version "6.2.0" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.2.0.tgz#4c2d22ab5f20b9cb61e2c5c5915950784d068131" + integrity sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ== + dependencies: + postcss-selector-parser "^6.1.1" + +postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.1.1: + version "6.1.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de" + integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@8.4.31: + version "8.4.31" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" + integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== + dependencies: + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +postcss@8.4.38: + version "8.4.38" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e" + integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.2.0" + +postcss@^8.4.23, postcss@^8.4.41: version "8.4.41" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.41.tgz#d6104d3ba272d882fe18fc07d15dc2da62fa2681" integrity sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ== @@ -1157,6 +3472,19 @@ postcss@^8.4.41: picocolors "^1.0.1" source-map-js "^1.2.0" +prism-react-renderer@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-2.1.0.tgz#a2f418451647412ea73d18cfe363fea20e419f9d" + integrity sha512-I5cvXHjA1PVGbGm1MsWCpvBCRrYyxEri0MC7/JbfIfYfcXAxHyO5PaUjs3A8H5GW6kJcLhTHxxMaOZZpRZD2iQ== + dependencies: + "@types/prismjs" "^1.26.0" + clsx "^1.2.1" + +prismjs@1.29.0: + version "1.29.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12" + integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== + process-warning@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-3.0.0.tgz#96e5b88884187a1dce6f5c3166d611132058710b" @@ -1186,6 +3514,11 @@ property-expr@^2.0.5: resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.6.tgz#f77bc00d5928a6c748414ad12882e83f24aec1e8" integrity sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA== +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== + proxy-addr@^2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -1202,6 +3535,11 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" +punycode@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + qs@^6.5.2: version "6.13.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" @@ -1209,6 +3547,11 @@ qs@^6.5.2: dependencies: side-channel "^1.0.6" +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + quick-format-unescaped@^4.0.3: version "4.0.4" resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" @@ -1219,6 +3562,13 @@ quick-lru@^5.1.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + react-dom@^18.2.0: version "18.3.1" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" @@ -1227,6 +3577,52 @@ react-dom@^18.2.0: loose-envify "^1.1.0" scheduler "^0.23.2" +react-email@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/react-email/-/react-email-2.1.6.tgz#657ce068c052260c8f731b6e30a1766b02785886" + integrity sha512-BtR9VI1CMq4953wfiBmzupKlWcRThaWG2dDgl1vWAllK3tNNmJNerwY4VlmASRDQZE3LpLXU3+lf8N/VAKdbZQ== + dependencies: + "@babel/core" "7.24.5" + "@babel/parser" "7.24.5" + "@radix-ui/colors" "1.0.1" + "@radix-ui/react-collapsible" "1.1.0" + "@radix-ui/react-popover" "1.1.1" + "@radix-ui/react-slot" "1.1.0" + "@radix-ui/react-toggle-group" "1.1.0" + "@radix-ui/react-tooltip" "1.1.1" + "@swc/core" "1.3.101" + "@types/react" "18.2.47" + "@types/react-dom" "^18.2.0" + "@types/webpack" "5.28.5" + autoprefixer "10.4.14" + chalk "4.1.2" + chokidar "3.5.3" + clsx "2.1.0" + commander "11.1.0" + debounce "2.0.0" + esbuild "0.19.11" + eslint-config-prettier "9.0.0" + eslint-config-turbo "1.10.12" + framer-motion "10.17.4" + glob "10.3.4" + log-symbols "4.1.0" + mime-types "2.1.35" + next "14.1.4" + normalize-path "3.0.0" + ora "5.4.1" + postcss "8.4.38" + prism-react-renderer "2.1.0" + react "^18.2.0" + react-dom "^18.2.0" + socket.io "4.7.3" + socket.io-client "4.7.3" + sonner "1.3.1" + source-map-js "1.0.2" + stacktrace-parser "0.1.10" + tailwind-merge "2.2.0" + tailwindcss "3.4.0" + typescript "5.1.6" + react-fast-compare@^3.2.0, react-fast-compare@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" @@ -1242,6 +3638,32 @@ react-is@^16.13.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-promise-suspense@0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/react-promise-suspense/-/react-promise-suspense-0.3.4.tgz#05d19a75703d71374674840056cfef2fcd38809d" + integrity sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ== + dependencies: + fast-deep-equal "^2.0.1" + +react-remove-scroll-bar@^2.3.4: + version "2.3.6" + resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz#3e585e9d163be84a010180b18721e851ac81a29c" + integrity sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g== + dependencies: + react-style-singleton "^2.2.1" + tslib "^2.0.0" + +react-remove-scroll@2.5.7: + version "2.5.7" + resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz#15a1fd038e8497f65a695bf26a4a57970cac1ccb" + integrity sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA== + dependencies: + react-remove-scroll-bar "^2.3.4" + react-style-singleton "^2.2.1" + tslib "^2.1.0" + use-callback-ref "^1.3.0" + use-sidecar "^1.1.2" + react-router-dom@6.15.0: version "6.15.0" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.15.0.tgz#6da7db61e56797266fbbef0d5e324d6ac443ee40" @@ -1257,6 +3679,15 @@ react-router@6.15.0: dependencies: "@remix-run/router" "1.8.0" +react-style-singleton@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4" + integrity sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g== + dependencies: + get-nonce "^1.0.0" + invariant "^2.2.4" + tslib "^2.0.0" + react-transition-group@^4.4.2: version "4.4.5" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1" @@ -1274,6 +3705,22 @@ react@^18.2.0: dependencies: loose-envify "^1.1.0" +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== + dependencies: + pify "^2.3.0" + +readable-stream@^3.4.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readable-stream@^4.0.0: version "4.5.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.5.2.tgz#9e7fc4c45099baeed934bff6eb97ba6cf2729e09" @@ -1285,6 +3732,13 @@ readable-stream@^4.0.0: process "^0.11.10" string_decoder "^1.3.0" +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + real-require@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.2.0.tgz#209632dea1810be2ae063a6ac084fee7e33fba78" @@ -1305,6 +3759,15 @@ resolve-alpn@^1.0.0: resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== +resolve@^1.1.7, resolve@^1.22.2: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + responselike@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" @@ -1312,6 +3775,14 @@ responselike@^2.0.0: dependencies: lowercase-keys "^2.0.0" +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + ret@~0.4.0: version "0.4.3" resolved "https://registry.yarnpkg.com/ret/-/ret-0.4.3.tgz#5243fa30e704a2e78a9b9b1e86079e15891aa85c" @@ -1352,7 +3823,14 @@ rollup@^4.13.0: "@rollup/rollup-win32-x64-msvc" "4.21.0" fsevents "~2.3.2" -safe-buffer@~5.2.0: +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -1376,16 +3854,44 @@ scheduler@^0.23.2: dependencies: loose-envify "^1.1.0" +schema-utils@^3.1.1, schema-utils@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + secure-json-parse@^2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz#5a5f9cd6ae47df23dba3151edd06855d47e09862" integrity sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw== -semver@^7.5.4: +selderee@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/selderee/-/selderee-0.11.0.tgz#6af0c7983e073ad3e35787ffe20cefd9daf0ec8a" + integrity sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA== + dependencies: + parseley "^0.12.0" + +semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.5.3, semver@^7.5.4: version "7.6.3" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== +serialize-javascript@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== + dependencies: + randombytes "^2.1.0" + set-cookie-parser@^2.4.1: version "2.7.0" resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.7.0.tgz#ef5552b56dc01baae102acb5fc9fb8cd060c30f9" @@ -1403,6 +3909,18 @@ set-function-length@^1.2.1: gopd "^1.0.1" has-property-descriptors "^1.0.2" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + shopify-api-node@^3.12.6: version "3.13.4" resolved "https://registry.yarnpkg.com/shopify-api-node/-/shopify-api-node-3.13.4.tgz#5dc24bf311121e325cdec312455050f14f958ceb" @@ -1423,6 +3941,55 @@ side-channel@^1.0.6: get-intrinsic "^1.2.4" object-inspect "^1.13.1" +signal-exit@^3.0.2: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + +socket.io-adapter@~2.5.2: + version "2.5.5" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz#c7a1f9c703d7756844751b6ff9abfc1780664082" + integrity sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg== + dependencies: + debug "~4.3.4" + ws "~8.17.1" + +socket.io-client@4.7.3: + version "4.7.3" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-4.7.3.tgz#b49e006fc1ccaea65229a4b435c083b10439ecc4" + integrity sha512-nU+ywttCyBitXIl9Xe0RSEfek4LneYkJxCeNnKCuhwoH4jGXO1ipIUw/VA/+Vvv2G1MTym11fzFC0SxkrcfXDw== + dependencies: + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.2" + engine.io-client "~6.5.2" + socket.io-parser "~4.2.4" + +socket.io-parser@~4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.4.tgz#c806966cf7270601e47469ddeec30fbdfda44c83" + integrity sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew== + dependencies: + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.1" + +socket.io@4.7.3: + version "4.7.3" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.7.3.tgz#a0f1a4511eb23fe182ae3a018875a31501be3ffc" + integrity sha512-SE+UIQXBQE+GPG2oszWMlsEmWtHVqw/h1VrYJGK5/MC7CH5p58N448HwIrtREcvR4jfdOJAY4ieQfxMr55qbbw== + dependencies: + accepts "~1.3.4" + base64id "~2.0.0" + cors "~2.8.5" + debug "~4.3.2" + engine.io "~6.5.2" + socket.io-adapter "~2.5.2" + socket.io-parser "~4.2.4" + sonic-boom@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-4.0.1.tgz#515b7cef2c9290cb362c4536388ddeece07aed30" @@ -1430,28 +3997,217 @@ sonic-boom@^4.0.1: dependencies: atomic-sleep "^1.0.0" -source-map-js@^1.2.0: +sonner@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/sonner/-/sonner-1.3.1.tgz#64aa2971d1110b6fe349f961d148c933f38ee9fa" + integrity sha512-+rOAO56b2eI3q5BtgljERSn2umRk63KFIvgb2ohbZ5X+Eb5u+a/7/0ZgswYqgBMg8dyl7n6OXd9KasA8QF9ToA== + +source-map-js@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-js@^1.0.2, source-map-js@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + split2@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== +stacktrace-parser@0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" + integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== + dependencies: + type-fest "^0.7.1" + stopcock@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/stopcock/-/stopcock-1.1.0.tgz#e0c875d98b819c0baa0a0edf3bcba2d7dc643175" integrity sha512-SNTAH55X9Ra5uE1JIxiPT3WwZiNMTcdCup+7qWOULNVUqiqi62qctNJ+x1R4znNudtkyu8LGc7Ok6Ldt+8N5iQ== -string_decoder@^1.3.0: +streamsearch@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" + integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== + +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: + name string-width-cjs + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +string_decoder@^1.1.1, string_decoder@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: safe-buffer "~5.2.0" +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +styled-jsx@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.1.tgz#839a1c3aaacc4e735fed0781b8619ea5d0009d1f" + integrity sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw== + dependencies: + client-only "0.0.1" + +sucrase@^3.32.0: + version "3.35.0" + resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263" + integrity sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA== + dependencies: + "@jridgewell/gen-mapping" "^0.3.2" + commander "^4.0.0" + glob "^10.3.10" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tailwind-merge@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.2.0.tgz#b6bb1c63ef26283c9e6675ba237df83bbd554688" + integrity sha512-SqqhhaL0T06SW59+JVNfAqKdqLs0497esifRrZ7jOaefP3o64fdFNDMrAQWZFMxTLJPiHVjRLUywT8uFz1xNWQ== + dependencies: + "@babel/runtime" "^7.23.5" + +tailwindcss@3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.0.tgz#045a9c474e6885ebd0436354e611a76af1c76839" + integrity sha512-VigzymniH77knD1dryXbyxR+ePHihHociZbXnLZHUyzf2MMs2ZVqlUrZ3FvpXP8pno9JzmILt1sZPD19M3IxtA== + dependencies: + "@alloc/quick-lru" "^5.2.0" + arg "^5.0.2" + chokidar "^3.5.3" + didyoumean "^1.2.2" + dlv "^1.1.3" + fast-glob "^3.3.0" + glob-parent "^6.0.2" + is-glob "^4.0.3" + jiti "^1.19.1" + lilconfig "^2.1.0" + micromatch "^4.0.5" + normalize-path "^3.0.0" + object-hash "^3.0.0" + picocolors "^1.0.0" + postcss "^8.4.23" + postcss-import "^15.1.0" + postcss-js "^4.0.1" + postcss-load-config "^4.0.1" + postcss-nested "^6.0.1" + postcss-selector-parser "^6.0.11" + resolve "^1.22.2" + sucrase "^3.32.0" + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +terser-webpack-plugin@^5.3.10: + version "5.3.10" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" + integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== + dependencies: + "@jridgewell/trace-mapping" "^0.3.20" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.1" + terser "^5.26.0" + +terser@^5.26.0: + version "5.31.6" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.6.tgz#c63858a0f0703988d0266a82fcbf2d7ba76422b1" + integrity sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" + commander "^2.20.0" + source-map-support "~0.5.20" + +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + thread-stream@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-3.1.0.tgz#4b2ef252a7c215064507d4ef70c05a5e2d34c4f1" @@ -1469,6 +4225,18 @@ tiny-graphql-query-compiler@^0.2.2: resolved "https://registry.yarnpkg.com/tiny-graphql-query-compiler/-/tiny-graphql-query-compiler-0.2.3.tgz#c703a1db7a9bfcb78b636d1437d5838c2b2052fb" integrity sha512-5ZMy+38zKezoYdx8V6Bnaez4f6J1fmFvYlCWOT85eIsXIbPmJrCfHwYPUH1qEl1T1hyHgosbWiQ/M/p3KD84EQ== +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + toad-cache@^3.3.0: version "3.7.0" resolved "https://registry.yarnpkg.com/toad-cache/-/toad-cache-3.7.0.tgz#b9b63304ea7c45ec34d91f1d2fa513517025c441" @@ -1484,11 +4252,21 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== -tslib@^2.6.2: +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== + +tslib@^2.0.0, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0" integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== +type-fest@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" + integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== + type-fest@^2.19.0: version "2.19.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" @@ -1499,6 +4277,11 @@ type-fest@^3.13.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.13.1.tgz#bb744c1f0678bea7543a2d1ec24e83e68e8c8706" integrity sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g== +typescript@5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== + typescript@^5.4.5: version "5.5.4" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" @@ -1509,6 +4292,21 @@ undici-types@~6.19.2: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.6.tgz#e218c3df0987f4c0e0008ca00d6b6472d9b89b36" integrity sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org== +update-browserslist-db@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" + integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== + dependencies: + escalade "^3.1.2" + picocolors "^1.0.1" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + urql@^4.0.4: version "4.1.0" resolved "https://registry.yarnpkg.com/urql/-/urql-4.1.0.tgz#a75efe572d7b2e69103649a8457d3a63fce31ee8" @@ -1517,6 +4315,31 @@ urql@^4.0.4: "@urql/core" "^5.0.0" wonka "^6.3.2" +use-callback-ref@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.2.tgz#6134c7f6ff76e2be0b56c809b17a650c942b1693" + integrity sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA== + dependencies: + tslib "^2.0.0" + +use-sidecar@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2" + integrity sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw== + dependencies: + detect-node-es "^1.1.0" + tslib "^2.0.0" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +vary@^1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + vite@^5.3.5: version "5.4.1" resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.1.tgz#2aa72370de824d23f53658affd807e4c9905b058" @@ -1528,11 +4351,61 @@ vite@^5.3.5: optionalDependencies: fsevents "~2.3.3" +watchpack@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da" + integrity sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== + dependencies: + defaults "^1.0.3" + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== +webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack@^5: + version "5.93.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.93.0.tgz#2e89ec7035579bdfba9760d26c63ac5c3462a5e5" + integrity sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^1.0.5" + "@webassemblyjs/ast" "^1.12.1" + "@webassemblyjs/wasm-edit" "^1.12.1" + "@webassemblyjs/wasm-parser" "^1.12.1" + acorn "^8.7.1" + acorn-import-attributes "^1.9.5" + browserslist "^4.21.10" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.17.0" + es-module-lexer "^1.2.1" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.11" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.2.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.3.10" + watchpack "^2.4.1" + webpack-sources "^3.2.3" + whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" @@ -1541,11 +4414,36 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + wonka@^6.3.2: version "6.3.4" resolved "https://registry.yarnpkg.com/wonka/-/wonka-6.3.4.tgz#76eb9316e3d67d7febf4945202b5bdb2db534594" integrity sha512-CjpbqNtBGNAeyNS/9W6q3kSkKE52+FjIj7AkFlLr11s/VWGUu6a2CdYSdGxocIhIVjaW/zchesBQUKPVU69Cqg== +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -1556,6 +4454,26 @@ ws@^8.17.0: resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== +ws@~8.17.1: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" + integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== + +xmlhttprequest-ssl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz#91360c86b914e67f44dce769180027c0da618c67" + integrity sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yaml@^2.3.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.0.tgz#c6165a721cf8000e91c36490a41d7be25176cf5d" + integrity sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw== + yup@^1.2.0: version "1.4.0" resolved "https://registry.yarnpkg.com/yup/-/yup-1.4.0.tgz#898dcd660f9fb97c41f181839d3d65c3ee15a43e" From ae3849b2a51c40fc632e8504f96d9ee58ede91e8 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Wed, 21 Aug 2024 09:37:59 -0400 Subject: [PATCH 03/43] Adding request email code in order update --- .../filters/review/tenancy.gelly | 3 + .../shopify/shopifyOrderLineItem.gelly | 3 + .../accessControl/permissions.gadget.ts | 14 +++ .../api/actions/sendReviewRequests.js | 34 +++++ .../api/models/review/actions/update.js | 2 +- .../api/models/review/schema.gadget.ts | 5 + .../api/models/shopifyOrder/actions/create.js | 11 +- .../api/models/shopifyOrder/actions/update.js | 30 ++++- .../api/models/shopifyOrder/schema.gadget.ts | 6 + .../shopifyOrderLineItem/actions/create.js | 21 ++++ .../shopifyOrderLineItem/actions/delete.js | 20 +++ .../shopifyOrderLineItem/actions/update.js | 21 ++++ .../shopifyOrderLineItem/schema.gadget.ts | 43 +++++++ .../models/shopifyProduct/schema.gadget.ts | 1 + .../api/models/shopifyShop/actions/install.js | 117 +++++++++++++++++- .../api/models/shopifyShop/schema.gadget.ts | 11 ++ product-reviews-template/package.json | 1 + product-reviews-template/settings.gadget.ts | 5 + product-reviews-template/yarn.lock | 6 + 19 files changed, 343 insertions(+), 11 deletions(-) create mode 100755 product-reviews-template/accessControl/filters/review/tenancy.gelly create mode 100755 product-reviews-template/accessControl/filters/shopify/shopifyOrderLineItem.gelly create mode 100755 product-reviews-template/api/actions/sendReviewRequests.js create mode 100755 product-reviews-template/api/models/shopifyOrderLineItem/actions/create.js create mode 100755 product-reviews-template/api/models/shopifyOrderLineItem/actions/delete.js create mode 100755 product-reviews-template/api/models/shopifyOrderLineItem/actions/update.js create mode 100755 product-reviews-template/api/models/shopifyOrderLineItem/schema.gadget.ts diff --git a/product-reviews-template/accessControl/filters/review/tenancy.gelly b/product-reviews-template/accessControl/filters/review/tenancy.gelly new file mode 100755 index 00000000..8e517d2b --- /dev/null +++ b/product-reviews-template/accessControl/filters/review/tenancy.gelly @@ -0,0 +1,3 @@ +filter ($session: Session) on Review [ + where shopId == $session.shopId +] diff --git a/product-reviews-template/accessControl/filters/shopify/shopifyOrderLineItem.gelly b/product-reviews-template/accessControl/filters/shopify/shopifyOrderLineItem.gelly new file mode 100755 index 00000000..b4e009c1 --- /dev/null +++ b/product-reviews-template/accessControl/filters/shopify/shopifyOrderLineItem.gelly @@ -0,0 +1,3 @@ +filter ($session: Session) on ShopifyOrderLineItem [ + where shopId == $session.shopId +] diff --git a/product-reviews-template/accessControl/permissions.gadget.ts b/product-reviews-template/accessControl/permissions.gadget.ts index 93c1fb45..af75eb50 100755 --- a/product-reviews-template/accessControl/permissions.gadget.ts +++ b/product-reviews-template/accessControl/permissions.gadget.ts @@ -12,6 +12,14 @@ export const permissions: GadgetPermissions = { "shopify-app-users": { storageKey: "Role-Shopify-App", models: { + review: { + read: { + filter: "accessControl/filters/review/tenancy.gelly", + }, + actions: { + update: true, + }, + }, shopifyCustomer: { read: { filter: @@ -34,6 +42,12 @@ export const permissions: GadgetPermissions = { "accessControl/filters/shopify/shopifyOrder.gelly", }, }, + shopifyOrderLineItem: { + read: { + filter: + "accessControl/filters/shopify/shopifyOrderLineItem.gelly", + }, + }, shopifyProduct: { read: { filter: diff --git a/product-reviews-template/api/actions/sendReviewRequests.js b/product-reviews-template/api/actions/sendReviewRequests.js new file mode 100755 index 00000000..e91fba4e --- /dev/null +++ b/product-reviews-template/api/actions/sendReviewRequests.js @@ -0,0 +1,34 @@ +import { SendReviewRequestsGlobalActionContext } from "gadget-server"; + +/** + * @param { SendReviewRequestsGlobalActionContext } context + */ +export async function run({ params, logger, api, connections }) { + let orders = await api.shopifyOrder.findMany({ + first: 250, + filter: { + fulfillmentStatus: { + equals: "fulfilled", + }, + requestReviewAfter: { + lessThanOrEqual: new Date(), + }, + }, + select: { + lineItems: { + edges: { + node: { + productId: true, + }, + }, + }, + }, + }); + + let allOrders = orders; + + while (orders.hasNextPage) { + orders = await orders.nextPage(); + allOrders = allOrders.concat(orders); + } +} diff --git a/product-reviews-template/api/models/review/actions/update.js b/product-reviews-template/api/models/review/actions/update.js index a798f7db..c4310745 100755 --- a/product-reviews-template/api/models/review/actions/update.js +++ b/product-reviews-template/api/models/review/actions/update.js @@ -12,7 +12,7 @@ export async function run({ params, record, logger, api, connections }) { * @param { UpdateReviewActionContext } context */ export async function onSuccess({ params, record, logger, api, connections }) { - // Your logic goes here + // Add logic to create metaobject in Shopify (if approved) }; /** @type { ActionOptions } */ diff --git a/product-reviews-template/api/models/review/schema.gadget.ts b/product-reviews-template/api/models/review/schema.gadget.ts index cb592f9c..906f5005 100755 --- a/product-reviews-template/api/models/review/schema.gadget.ts +++ b/product-reviews-template/api/models/review/schema.gadget.ts @@ -12,6 +12,11 @@ export const schema: GadgetModel = { default: false, storageKey: "fyHMWNtwRseY", }, + approved: { + type: "boolean", + default: false, + storageKey: "yZssP-8duQ5f", + }, content: { type: "string", validations: { required: true }, diff --git a/product-reviews-template/api/models/shopifyOrder/actions/create.js b/product-reviews-template/api/models/shopifyOrder/actions/create.js index 1591a829..959282f8 100755 --- a/product-reviews-template/api/models/shopifyOrder/actions/create.js +++ b/product-reviews-template/api/models/shopifyOrder/actions/create.js @@ -1,4 +1,9 @@ -import { applyParams, save, ActionOptions, CreateShopifyOrderActionContext } from "gadget-server"; +import { + applyParams, + save, + ActionOptions, + CreateShopifyOrderActionContext, +} from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; /** @@ -8,14 +13,14 @@ export async function run({ params, record, logger, api, connections }) { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); -}; +} /** * @param { CreateShopifyOrderActionContext } context */ export async function onSuccess({ params, record, logger, api, connections }) { // Your logic goes here -}; +} /** @type { ActionOptions } */ export const options = { actionType: "create" }; diff --git a/product-reviews-template/api/models/shopifyOrder/actions/update.js b/product-reviews-template/api/models/shopifyOrder/actions/update.js index 28592ff3..4bcd9612 100755 --- a/product-reviews-template/api/models/shopifyOrder/actions/update.js +++ b/product-reviews-template/api/models/shopifyOrder/actions/update.js @@ -1,5 +1,11 @@ -import { applyParams, save, ActionOptions, UpdateShopifyOrderActionContext } from "gadget-server"; +import { + applyParams, + save, + ActionOptions, + UpdateShopifyOrderActionContext, +} from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; +import { DateTime } from "luxon"; /** * @param { UpdateShopifyOrderActionContext } context @@ -7,15 +13,33 @@ import { preventCrossShopDataAccess } from "gadget-server/shopify"; export async function run({ params, record, logger, api, connections }) { applyParams(params, record); await preventCrossShopDataAccess(params, record); + + if ( + record.changed("fulfillmentStatus") && + record.fulfillmentStatus === "fulfilled" + ) { + const shop = await api.shopifyShop.findOne(record.shopId, { + select: { + daysUntilReviewRequest: true, + }, + }); + + record.requestReviewAfter = DateTime.fromJSDate( + new Date(record.shopifyCreatedAt) + ) + .plus({ days: shop.daysUntilReviewRequest }) + .toJSDate(); + } + await save(record); -}; +} /** * @param { UpdateShopifyOrderActionContext } context */ export async function onSuccess({ params, record, logger, api, connections }) { // Your logic goes here -}; +} /** @type { ActionOptions } */ export const options = { actionType: "update" }; diff --git a/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts b/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts index abad22aa..fd2c7553 100755 --- a/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts +++ b/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts @@ -7,6 +7,11 @@ export const schema: GadgetModel = { type: "gadget/model-schema/v1", storageKey: "DataModel-Shopify-Order", fields: { + requestReviewAfter: { + type: "dateTime", + includeTime: true, + storageKey: "ztIqc2_TMPaB", + }, reviews: { type: "hasMany", children: { model: "review", belongsToField: "order" }, @@ -47,6 +52,7 @@ export const schema: GadgetModel = { "fulfillmentStatus", "fulfillmentsCount", "landingSite", + "lineItems", "merchantOfRecordAppId", "name", "note", diff --git a/product-reviews-template/api/models/shopifyOrderLineItem/actions/create.js b/product-reviews-template/api/models/shopifyOrderLineItem/actions/create.js new file mode 100755 index 00000000..d65c01bb --- /dev/null +++ b/product-reviews-template/api/models/shopifyOrderLineItem/actions/create.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, CreateShopifyOrderLineItemActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { CreateShopifyOrderLineItemActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +/** + * @param { CreateShopifyOrderLineItemActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "create" }; diff --git a/product-reviews-template/api/models/shopifyOrderLineItem/actions/delete.js b/product-reviews-template/api/models/shopifyOrderLineItem/actions/delete.js new file mode 100755 index 00000000..d2dd1caa --- /dev/null +++ b/product-reviews-template/api/models/shopifyOrderLineItem/actions/delete.js @@ -0,0 +1,20 @@ +import { deleteRecord, ActionOptions, DeleteShopifyOrderLineItemActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { DeleteShopifyOrderLineItemActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + await preventCrossShopDataAccess(params, record); + await deleteRecord(record); +}; + +/** + * @param { DeleteShopifyOrderLineItemActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "delete" }; diff --git a/product-reviews-template/api/models/shopifyOrderLineItem/actions/update.js b/product-reviews-template/api/models/shopifyOrderLineItem/actions/update.js new file mode 100755 index 00000000..052ee39b --- /dev/null +++ b/product-reviews-template/api/models/shopifyOrderLineItem/actions/update.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, UpdateShopifyOrderLineItemActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { UpdateShopifyOrderLineItemActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +/** + * @param { UpdateShopifyOrderLineItemActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "update" }; diff --git a/product-reviews-template/api/models/shopifyOrderLineItem/schema.gadget.ts b/product-reviews-template/api/models/shopifyOrderLineItem/schema.gadget.ts new file mode 100755 index 00000000..ab010367 --- /dev/null +++ b/product-reviews-template/api/models/shopifyOrderLineItem/schema.gadget.ts @@ -0,0 +1,43 @@ +import type { GadgetModel } from "gadget-server"; + +// This file describes the schema for the "shopifyOrderLineItem" model, go to https://product-reviews-template.gadget.app/edit to view/edit your model in Gadget +// For more information on how to update this file http://docs.gadget.dev + +export const schema: GadgetModel = { + type: "gadget/model-schema/v1", + storageKey: "DataModel-Shopify-OrderLineItem", + fields: {}, + shopify: { + fields: [ + "attributedStaffs", + "currentQuantity", + "discountAllocations", + "fulfillableQuantity", + "fulfillmentService", + "fulfillmentStatus", + "giftCard", + "grams", + "name", + "order", + "price", + "priceSet", + "product", + "productExists", + "properties", + "quantity", + "requiresShipping", + "shop", + "shopifyCreatedAt", + "shopifyUpdatedAt", + "sku", + "taxLines", + "taxable", + "title", + "totalDiscount", + "totalDiscountSet", + "variantInventoryManagement", + "variantTitle", + "vendor", + ], + }, +}; diff --git a/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts b/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts index 562198d4..20985072 100755 --- a/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts +++ b/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts @@ -19,6 +19,7 @@ export const schema: GadgetModel = { "category", "compareAtPriceRange", "handle", + "orderLineItems", "productCategory", "productType", "publishedAt", diff --git a/product-reviews-template/api/models/shopifyShop/actions/install.js b/product-reviews-template/api/models/shopifyShop/actions/install.js index d11f76e2..3d34a7a8 100755 --- a/product-reviews-template/api/models/shopifyShop/actions/install.js +++ b/product-reviews-template/api/models/shopifyShop/actions/install.js @@ -1,19 +1,128 @@ -import { applyParams, save, ActionOptions, InstallShopifyShopActionContext } from "gadget-server"; +import { + applyParams, + save, + ActionOptions, + InstallShopifyShopActionContext, +} from "gadget-server"; /** * @param { InstallShopifyShopActionContext } context */ export async function run({ params, record, logger, api, connections }) { applyParams(params, record); + + const shopify = connections.shopify.current; + + const reviewMetaobjectDefinitionCreateResponse = await shopify.graphql( + `mutation ($definition: MetaobjectDefinitionCreateInput!) { + metaobjectDefinitionCreate(definition: $definition) { + metaobjectDefinition { + id + } + userErrors { + message + } + } + }`, + { + definition: { + type: "review", + fieldDefinitions: [ + { + key: "anonymous", + type: "boolean", + required: true, + }, + { + key: "rating", + type: "rating", + required: true, + validations: [ + { + name: "max", + value: "5", + }, + { + name: "min", + value: "0", + }, + ], + }, + { + key: "content", + type: "multi_line_text_field", + required: true, + }, + { + key: "product", + type: "product_reference", + required: true, + }, + ], + }, + } + ); + + if ( + reviewMetaobjectDefinitionCreateResponse?.metaobjectDefinitionCreate + ?.userErrors?.length + ) + throw new Error( + reviewMetaobjectDefinitionCreateResponse.metaobjectDefinitionCreate.userErrors[0].message + ); + + record.reviewMetaobjectDefinitionId = + reviewMetaobjectDefinitionCreateResponse.metaobjectDefinitionCreate.metaobjectDefinition.id; + + const metaobjectReferenceMetafieldDefinitionCreationResponse = + await shopify.graphql( + `mutation ($definition: MetafieldDefinitionInput!) { + metafieldDefinitionCreate(definition: $definition) { + createdDefinition { + id + } + userErrors { + message + } + } + }`, + { + definition: { + name: "Reviews", + namespace: "reviews", + key: "productMetaobjects", + description: "A list of metaobjects assoicated to this product", + type: "list.metaobject_reference", + ownerType: "PRODUCT", + }, + } + ); + + if ( + metaobjectReferenceMetafieldDefinitionCreationResponse + ?.metafieldDefinitionCreate?.userErrors?.length + ) + throw new Error( + metaobjectReferenceMetafieldDefinitionCreationResponse.metafieldDefinitionCreate.userErrors[0].message + ); + + record.metaobjectReferenceMetafieldDefinitionId = + metaobjectReferenceMetafieldDefinitionCreationResponse.metafieldDefinitionCreate.createdDefinition.id; + await save(record); -}; +} /** * @param { InstallShopifyShopActionContext } context */ export async function onSuccess({ params, record, logger, api, connections }) { - // Your logic goes here -}; + await api.shopifySync.run({ + shop: { + _link: record.id, + }, + domain: record.domain, + }); +} /** @type { ActionOptions } */ export const options = { actionType: "create" }; diff --git a/product-reviews-template/api/models/shopifyShop/schema.gadget.ts b/product-reviews-template/api/models/shopifyShop/schema.gadget.ts index af1ed8d4..d3bf13d5 100755 --- a/product-reviews-template/api/models/shopifyShop/schema.gadget.ts +++ b/product-reviews-template/api/models/shopifyShop/schema.gadget.ts @@ -17,6 +17,16 @@ export const schema: GadgetModel = { }, storageKey: "V66nKdXdjiQO", }, + metaobjectReferenceMetafieldDefinitionId: { + type: "string", + validations: { unique: true }, + storageKey: "19hnN32KHdzM", + }, + reviewMetaobjectDefinitionId: { + type: "string", + validations: { unique: true }, + storageKey: "bLb7uPSnlZDw", + }, reviews: { type: "hasMany", children: { model: "review", belongsToField: "shop" }, @@ -62,6 +72,7 @@ export const schema: GadgetModel = { "multiLocationEnabled", "myshopifyDomain", "name", + "orderLineItems", "orders", "passwordEnabled", "phone", diff --git a/product-reviews-template/package.json b/product-reviews-template/package.json index c25307d3..93ff5ad3 100755 --- a/product-reviews-template/package.json +++ b/product-reviews-template/package.json @@ -22,6 +22,7 @@ "@shopify/polaris": "^13.8.0", "@shopify/polaris-icons": "^9.3.0", "gadget-server": "link:.gadget/server", + "luxon": "^3.5.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-email": "^2.1.6", diff --git a/product-reviews-template/settings.gadget.ts b/product-reviews-template/settings.gadget.ts index 2f29d507..fa1b00aa 100755 --- a/product-reviews-template/settings.gadget.ts +++ b/product-reviews-template/settings.gadget.ts @@ -10,6 +10,7 @@ export const settings: GadgetSettings = { enabledModels: [ "shopifyCustomer", "shopifyOrder", + "shopifyOrderLineItem", "shopifyProduct", ], type: "partner", @@ -18,6 +19,10 @@ export const settings: GadgetSettings = { "read_products", "read_orders", "read_customers", + "write_metaobject_definitions", + "read_metaobject_definitions", + "write_metaobjects", + "read_metaobjects", ], }, }, diff --git a/product-reviews-template/yarn.lock b/product-reviews-template/yarn.lock index e0095c8b..3d34858c 100644 --- a/product-reviews-template/yarn.lock +++ b/product-reviews-template/yarn.lock @@ -3094,6 +3094,11 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" +luxon@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.5.0.tgz#6b6f65c5cd1d61d1fd19dbf07ee87a50bf4b8e20" + integrity sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ== + marked@7.0.4: version "7.0.4" resolved "https://registry.yarnpkg.com/marked/-/marked-7.0.4.tgz#e2558ee2d535b9df6a27c6e282dc603a18388a6d" @@ -4074,6 +4079,7 @@ string_decoder@^1.1.1, string_decoder@^1.3.0: safe-buffer "~5.2.0" "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: + name strip-ansi-cjs version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== From 9fa9f10b7cfb6ccf359957b28f26a0be6a00ce1b Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Wed, 21 Aug 2024 10:12:53 -0400 Subject: [PATCH 04/43] Fixing issue with the installation --- product-reviews-template/api/actions/sendReviewRequests.js | 3 +++ .../api/models/shopifyShop/actions/install.js | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/product-reviews-template/api/actions/sendReviewRequests.js b/product-reviews-template/api/actions/sendReviewRequests.js index e91fba4e..eb688de3 100755 --- a/product-reviews-template/api/actions/sendReviewRequests.js +++ b/product-reviews-template/api/actions/sendReviewRequests.js @@ -15,6 +15,7 @@ export async function run({ params, logger, api, connections }) { }, }, select: { + id: true, lineItems: { edges: { node: { @@ -31,4 +32,6 @@ export async function run({ params, logger, api, connections }) { orders = await orders.nextPage(); allOrders = allOrders.concat(orders); } + + logger.info({ allOrders }, "All orders"); } diff --git a/product-reviews-template/api/models/shopifyShop/actions/install.js b/product-reviews-template/api/models/shopifyShop/actions/install.js index 3d34a7a8..f93d1d5e 100755 --- a/product-reviews-template/api/models/shopifyShop/actions/install.js +++ b/product-reviews-template/api/models/shopifyShop/actions/install.js @@ -39,11 +39,11 @@ export async function run({ params, record, logger, api, connections }) { required: true, validations: [ { - name: "max", + name: "scale_max", value: "5", }, { - name: "min", + name: "scale_min", value: "0", }, ], From a926be1efe901521d71068689c49d0bbe50167f3 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Wed, 21 Aug 2024 12:41:36 -0400 Subject: [PATCH 05/43] Trying to fix the install action --- .../api/models/shopifyShop/actions/install.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/product-reviews-template/api/models/shopifyShop/actions/install.js b/product-reviews-template/api/models/shopifyShop/actions/install.js index f93d1d5e..b2f8ef45 100755 --- a/product-reviews-template/api/models/shopifyShop/actions/install.js +++ b/product-reviews-template/api/models/shopifyShop/actions/install.js @@ -35,15 +35,15 @@ export async function run({ params, record, logger, api, connections }) { }, { key: "rating", - type: "rating", + type: "number_integer", required: true, validations: [ { - name: "scale_max", + name: "max", value: "5", }, { - name: "scale_min", + name: "min", value: "0", }, ], From 6373f4d6bd3b1e9f5cd8bbe06304b7e43d78e7b1 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Wed, 21 Aug 2024 13:28:13 -0400 Subject: [PATCH 06/43] Fixed issues with application installation --- .../api/models/shopifyShop/actions/install.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/product-reviews-template/api/models/shopifyShop/actions/install.js b/product-reviews-template/api/models/shopifyShop/actions/install.js index b2f8ef45..7fc224da 100755 --- a/product-reviews-template/api/models/shopifyShop/actions/install.js +++ b/product-reviews-template/api/models/shopifyShop/actions/install.js @@ -27,6 +27,9 @@ export async function run({ params, record, logger, api, connections }) { { definition: { type: "review", + access: { + storefront: "PUBLIC_READ", + }, fieldDefinitions: [ { key: "anonymous", @@ -35,15 +38,15 @@ export async function run({ params, record, logger, api, connections }) { }, { key: "rating", - type: "number_integer", + type: "rating", required: true, validations: [ { - name: "max", + name: "scale_max", value: "5", }, { - name: "min", + name: "scale_min", value: "0", }, ], @@ -89,11 +92,17 @@ export async function run({ params, record, logger, api, connections }) { { definition: { name: "Reviews", - namespace: "reviews", - key: "productMetaobjects", + namespace: "productReviews", + key: "reviewMetaobjects", description: "A list of metaobjects assoicated to this product", type: "list.metaobject_reference", ownerType: "PRODUCT", + validations: [ + { + name: "metaobject_definition_id", + value: record.reviewMetaobjectDefinitionId, + }, + ], }, } ); From cfb9ccc8b26d11abf29418714b63ab8c9b51a261 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Wed, 21 Aug 2024 16:47:23 -0400 Subject: [PATCH 07/43] In the process of adding the email enqueue chain --- .../api/actions/enqueueEmails.js | 59 +++++++++++++++++++ .../api/actions/sendReviewRequests.js | 16 ++++- 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100755 product-reviews-template/api/actions/enqueueEmails.js diff --git a/product-reviews-template/api/actions/enqueueEmails.js b/product-reviews-template/api/actions/enqueueEmails.js new file mode 100755 index 00000000..9dde15c1 --- /dev/null +++ b/product-reviews-template/api/actions/enqueueEmails.js @@ -0,0 +1,59 @@ +import { EnqueueEmailsGlobalActionContext } from "gadget-server"; + +/** + * @param { EnqueueEmailsGlobalActionContext } context + */ +export async function run({ params, logger, api, connections }) { + const { allOrders } = params; + + const orders = allOrders.splice(0, 80); + + for (const order of orders) { + const { id, lineItems } = order; + + const tempArr = []; + + for (const { node } of lineItems.edges) { + const { productId } = node; + + tempArr.push(productId); + } + + await api.enqueue(api, {}, {}); + } +} + +export const params = { + allOrders: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + lineItems: { + type: "object", + properties: { + edges: { + type: "array", + items: { + type: "object", + properties: { + node: { + type: "object", + properties: { + productId: { + type: "string", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, +}; diff --git a/product-reviews-template/api/actions/sendReviewRequests.js b/product-reviews-template/api/actions/sendReviewRequests.js index eb688de3..bec75180 100755 --- a/product-reviews-template/api/actions/sendReviewRequests.js +++ b/product-reviews-template/api/actions/sendReviewRequests.js @@ -33,5 +33,19 @@ export async function run({ params, logger, api, connections }) { allOrders = allOrders.concat(orders); } - logger.info({ allOrders }, "All orders"); + const options = { + queue: { + name: `send-wishlist-emails-${uuid()}`, + maxConcurrency: 50, + }, + retries: 1, + }; + + await api.enqueue( + api.enqueueEmails, + { allOrders: allOrders.map(({ __typeName, ...rest }) => rest) }, + { queue } + ); + + logger.info({ allOrders, date: new Date() }, "All orders"); } From 7ac21c8b43eaf8f7ee144b78404ca3ab7b2a5ac4 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Thu, 22 Aug 2024 15:48:31 -0400 Subject: [PATCH 08/43] Added email sending // Started writing reviews frontend --- .../filters/shopify/shopifyProductImage.gelly | 3 + .../accessControl/permissions.gadget.ts | 24 ++++++++ .../api/actions/enqueueEmails.js | 49 +++++++++++++-- .../api/actions/sendEmail.js | 54 +++++++++++++++++ .../api/actions/sendReviewRequests.js | 20 ++++--- .../models/shopifyProduct/schema.gadget.ts | 1 + .../shopifyProductImage/actions/create.js | 21 +++++++ .../shopifyProductImage/actions/delete.js | 20 +++++++ .../shopifyProductImage/actions/update.js | 21 +++++++ .../shopifyProductImage/schema.gadget.ts | 23 +++++++ .../api/models/shopifyShop/schema.gadget.ts | 1 + product-reviews-template/package.json | 9 ++- product-reviews-template/settings.gadget.ts | 3 +- .../web/components/App.jsx | 34 +++-------- .../web/components/ProductCard.jsx | 31 ++++++++++ .../web/components/ReviewForm.jsx | 53 ++++++++++++++++ .../web/components/index.js | 1 + product-reviews-template/web/main.jsx | 2 +- product-reviews-template/web/routes/index.js | 2 + product-reviews-template/yarn.lock | 60 ++++++++++++------- 20 files changed, 365 insertions(+), 67 deletions(-) create mode 100755 product-reviews-template/accessControl/filters/shopify/shopifyProductImage.gelly create mode 100755 product-reviews-template/api/actions/sendEmail.js create mode 100755 product-reviews-template/api/models/shopifyProductImage/actions/create.js create mode 100755 product-reviews-template/api/models/shopifyProductImage/actions/delete.js create mode 100755 product-reviews-template/api/models/shopifyProductImage/actions/update.js create mode 100755 product-reviews-template/api/models/shopifyProductImage/schema.gadget.ts create mode 100644 product-reviews-template/web/components/ProductCard.jsx create mode 100644 product-reviews-template/web/components/ReviewForm.jsx create mode 100644 product-reviews-template/web/components/index.js create mode 100644 product-reviews-template/web/routes/index.js diff --git a/product-reviews-template/accessControl/filters/shopify/shopifyProductImage.gelly b/product-reviews-template/accessControl/filters/shopify/shopifyProductImage.gelly new file mode 100755 index 00000000..f4afd0d6 --- /dev/null +++ b/product-reviews-template/accessControl/filters/shopify/shopifyProductImage.gelly @@ -0,0 +1,3 @@ +filter ($session: Session) on ShopifyProductImage [ + where shopId == $session.shopId +] diff --git a/product-reviews-template/accessControl/permissions.gadget.ts b/product-reviews-template/accessControl/permissions.gadget.ts index af75eb50..e71ae3dc 100755 --- a/product-reviews-template/accessControl/permissions.gadget.ts +++ b/product-reviews-template/accessControl/permissions.gadget.ts @@ -59,6 +59,17 @@ export const permissions: GadgetPermissions = { update: true, }, }, + shopifyProductImage: { + read: { + filter: + "accessControl/filters/shopify/shopifyProductImage.gelly", + }, + actions: { + create: true, + delete: true, + update: true, + }, + }, shopifyShop: { read: { filter: "accessControl/filters/shopify/shopifyShop.gelly", @@ -85,6 +96,19 @@ export const permissions: GadgetPermissions = { }, unauthenticated: { storageKey: "unauthenticated", + models: { + review: { + actions: { + create: true, + }, + }, + shopifyProduct: { + read: true, + }, + shopifyProductImage: { + read: true, + }, + }, }, }, }; diff --git a/product-reviews-template/api/actions/enqueueEmails.js b/product-reviews-template/api/actions/enqueueEmails.js index 9dde15c1..7b2ad1d8 100755 --- a/product-reviews-template/api/actions/enqueueEmails.js +++ b/product-reviews-template/api/actions/enqueueEmails.js @@ -9,18 +9,29 @@ export async function run({ params, logger, api, connections }) { const orders = allOrders.splice(0, 80); for (const order of orders) { - const { id, lineItems } = order; + const { + id, + lineItems, + customer: { email }, + } = order; - const tempArr = []; + const products = []; + const seen = {}; for (const { node } of lineItems.edges) { const { productId } = node; - tempArr.push(productId); + if (seen[productId]) continue; + + seen[productId] = true; + products.push(productId); } - await api.enqueue(api, {}, {}); + await api.enqueue(api.sendEmail, { id, products, email }, options); } + + if (allOrders.length) + await api.enqueue(api.enqueueEmails, { allOrders, options }, options); } export const params = { @@ -32,6 +43,9 @@ export const params = { id: { type: "string", }, + orderNumber: { + type: "number", + }, lineItems: { type: "object", properties: { @@ -53,6 +67,33 @@ export const params = { }, }, }, + customer: { + type: "object", + properties: { + email: { + type: "string", + }, + }, + }, + }, + }, + }, + options: { + type: "object", + properties: { + queue: { + type: "object", + properties: { + name: { + type: "string", + }, + maxConcurrency: { + type: "number", + }, + }, + }, + retries: { + type: "number", }, }, }, diff --git a/product-reviews-template/api/actions/sendEmail.js b/product-reviews-template/api/actions/sendEmail.js new file mode 100755 index 00000000..0ded04bf --- /dev/null +++ b/product-reviews-template/api/actions/sendEmail.js @@ -0,0 +1,54 @@ +import { SendEmailGlobalActionContext } from "gadget-server"; +import React from "react"; +import { render } from "@react-email/render"; +import { Container, Button } from "@react-email/components"; + +/** + * @param { SendEmailGlobalActionContext } context + */ +export async function run({ + params, + logger, + api, + connections, + emails, + currentAppUrl, +}) { + const { id, products, email, orderNumber } = params; + + await emails.sendMail({ + to: email, + subject: `Review your purchase${products.length > 1 ? "s" : ""}`, + html: await render( + + {/* Add more text in here */} + + + ), + }); +} + +export const params = { + id: { + type: "string", + }, + products: { + type: "array", + items: { + type: "string", + }, + }, + email: { + type: "string", + }, + orderNumber: { + type: "number", + }, +}; diff --git a/product-reviews-template/api/actions/sendReviewRequests.js b/product-reviews-template/api/actions/sendReviewRequests.js index bec75180..237adec3 100755 --- a/product-reviews-template/api/actions/sendReviewRequests.js +++ b/product-reviews-template/api/actions/sendReviewRequests.js @@ -1,4 +1,5 @@ import { SendReviewRequestsGlobalActionContext } from "gadget-server"; +import { v4 as uuidv4 } from "uuid"; /** * @param { SendReviewRequestsGlobalActionContext } context @@ -16,6 +17,7 @@ export async function run({ params, logger, api, connections }) { }, select: { id: true, + orderNumber: true, lineItems: { edges: { node: { @@ -23,6 +25,9 @@ export async function run({ params, logger, api, connections }) { }, }, }, + customer: { + email: true, + }, }, }); @@ -35,17 +40,16 @@ export async function run({ params, logger, api, connections }) { const options = { queue: { - name: `send-wishlist-emails-${uuid()}`, + name: `send-wishlist-emails-${uuidv4()}`, maxConcurrency: 50, }, retries: 1, }; - await api.enqueue( - api.enqueueEmails, - { allOrders: allOrders.map(({ __typeName, ...rest }) => rest) }, - { queue } - ); - - logger.info({ allOrders, date: new Date() }, "All orders"); + if (allOrders.length) + await api.enqueue( + api.enqueueEmails, + { allOrders: allOrders.map(({ __typeName, ...rest }) => rest), options }, + options + ); } diff --git a/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts b/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts index 20985072..e24f83ad 100755 --- a/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts +++ b/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts @@ -19,6 +19,7 @@ export const schema: GadgetModel = { "category", "compareAtPriceRange", "handle", + "images", "orderLineItems", "productCategory", "productType", diff --git a/product-reviews-template/api/models/shopifyProductImage/actions/create.js b/product-reviews-template/api/models/shopifyProductImage/actions/create.js new file mode 100755 index 00000000..8824eb40 --- /dev/null +++ b/product-reviews-template/api/models/shopifyProductImage/actions/create.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, CreateShopifyProductImageActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @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" }; diff --git a/product-reviews-template/api/models/shopifyProductImage/actions/delete.js b/product-reviews-template/api/models/shopifyProductImage/actions/delete.js new file mode 100755 index 00000000..1d2ce190 --- /dev/null +++ b/product-reviews-template/api/models/shopifyProductImage/actions/delete.js @@ -0,0 +1,20 @@ +import { deleteRecord, ActionOptions, DeleteShopifyProductImageActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @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" }; diff --git a/product-reviews-template/api/models/shopifyProductImage/actions/update.js b/product-reviews-template/api/models/shopifyProductImage/actions/update.js new file mode 100755 index 00000000..5a973983 --- /dev/null +++ b/product-reviews-template/api/models/shopifyProductImage/actions/update.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, UpdateShopifyProductImageActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @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" }; diff --git a/product-reviews-template/api/models/shopifyProductImage/schema.gadget.ts b/product-reviews-template/api/models/shopifyProductImage/schema.gadget.ts new file mode 100755 index 00000000..d6e0bcd1 --- /dev/null +++ b/product-reviews-template/api/models/shopifyProductImage/schema.gadget.ts @@ -0,0 +1,23 @@ +import type { GadgetModel } from "gadget-server"; + +// This file describes the schema for the "shopifyProductImage" model, go to https://product-reviews-template.gadget.app/edit to view/edit your model in Gadget +// For more information on how to update this file http://docs.gadget.dev + +export const schema: GadgetModel = { + type: "gadget/model-schema/v1", + storageKey: "DataModel-Shopify-ProductImage", + fields: {}, + shopify: { + fields: [ + "alt", + "height", + "position", + "product", + "shop", + "shopifyCreatedAt", + "shopifyUpdatedAt", + "source", + "width", + ], + }, +}; diff --git a/product-reviews-template/api/models/shopifyShop/schema.gadget.ts b/product-reviews-template/api/models/shopifyShop/schema.gadget.ts index d3bf13d5..e5955a0c 100755 --- a/product-reviews-template/api/models/shopifyShop/schema.gadget.ts +++ b/product-reviews-template/api/models/shopifyShop/schema.gadget.ts @@ -80,6 +80,7 @@ export const schema: GadgetModel = { "planName", "preLaunchEnabled", "primaryLocale", + "productImages", "products", "province", "provinceCode", diff --git a/product-reviews-template/package.json b/product-reviews-template/package.json index 93ff5ad3..2fa28cb2 100755 --- a/product-reviews-template/package.json +++ b/product-reviews-template/package.json @@ -15,9 +15,10 @@ }, "dependencies": { "@gadget-client/product-reviews-template": "link:.gadget/client", - "@gadgetinc/react": "^0.16.1", + "@gadgetinc/react": "^0.16.2", "@gadgetinc/react-shopify-app-bridge": "^0.16.0", "@react-email/components": "0.0.22", + "@react-email/render": "1.0.0", "@shopify/app-bridge-react": "4.0.0", "@shopify/polaris": "^13.8.0", "@shopify/polaris-icons": "^9.3.0", @@ -27,7 +28,9 @@ "react-dom": "^18.2.0", "react-email": "^2.1.6", "react-router-dom": "6.15.0", - "shopify-api-node": "^3.12.6" + "shopify-api-node": "^3.12.6", + "uuid": "^10.0.0", + "fastify": "^4.24.2" }, "devDependencies": { "@types/node": "^20.12.8", @@ -37,4 +40,4 @@ "typescript": "^5.4.5", "vite": "^5.3.5" } -} +} \ No newline at end of file diff --git a/product-reviews-template/settings.gadget.ts b/product-reviews-template/settings.gadget.ts index fa1b00aa..a48b5a75 100755 --- a/product-reviews-template/settings.gadget.ts +++ b/product-reviews-template/settings.gadget.ts @@ -2,7 +2,7 @@ import type { GadgetSettings } from "gadget-server"; export const settings: GadgetSettings = { type: "gadget/settings/v1", - frameworkVersion: "v1.2.0", + frameworkVersion: "v1.1.0", plugins: { connections: { shopify: { @@ -12,6 +12,7 @@ export const settings: GadgetSettings = { "shopifyOrder", "shopifyOrderLineItem", "shopifyProduct", + "shopifyProductImage", ], type: "partner", scopes: [ diff --git a/product-reviews-template/web/components/App.jsx b/product-reviews-template/web/components/App.jsx index b9a2a35b..a64d7f7c 100755 --- a/product-reviews-template/web/components/App.jsx +++ b/product-reviews-template/web/components/App.jsx @@ -4,7 +4,7 @@ import { useGadget, } from "@gadgetinc/react-shopify-app-bridge"; import { NavMenu } from "@shopify/app-bridge-react"; -import { Box, Card, Page, Spinner, Text } from "@shopify/polaris"; +import { Spinner } from "@shopify/polaris"; import { useEffect } from "react"; import { Link, @@ -17,9 +17,9 @@ import { useNavigate, } from "react-router-dom"; import { api } from "../api"; -import AboutPage from "../routes/about"; -import Index from "../routes/index"; +import { AboutPage, Index } from "../routes"; import "./App.css"; +import ReviewForm from "./ReviewForm"; function Error404() { const navigate = useNavigate(); @@ -36,13 +36,14 @@ function Error404() { return
404 not found
; } -function App() { +export default function () { const router = createBrowserRouter( createRoutesFromElements( }> } /> } /> } /> + } /> ) ); @@ -84,6 +85,7 @@ function AuthenticatedApp() { ); } + return isAuthenticated ? : ; } @@ -102,27 +104,5 @@ function EmbeddedApp() { } function UnauthenticatedApp() { - return ( - -
- - - App must be viewed in the Shopify Admin - - - - Edit this page:{" "} - - web/components/App.jsx - - - - -
-
- ); + return ; } - -export default App; diff --git a/product-reviews-template/web/components/ProductCard.jsx b/product-reviews-template/web/components/ProductCard.jsx new file mode 100644 index 00000000..dec7525c --- /dev/null +++ b/product-reviews-template/web/components/ProductCard.jsx @@ -0,0 +1,31 @@ +import { AutoForm } from "@gadgetinc/react/auto/polaris"; +import { Button, Card, Text } from "@shopify/polaris"; +import { ChevronDownIcon, ChevronUpIcon } from "@shopify/polaris-icons"; +import { api } from "../api"; +import { useState } from "react"; + +export default ({ id, title, orderId }) => { + const [open, setOpen] = useState(false); + + return ( + + + + {title} + + + + + ); +}; diff --git a/product-reviews-template/web/components/ReviewForm.jsx b/product-reviews-template/web/components/ReviewForm.jsx new file mode 100644 index 00000000..fe747ffd --- /dev/null +++ b/product-reviews-template/web/components/ReviewForm.jsx @@ -0,0 +1,53 @@ +import { useParams, useSearchParams } from "react-router-dom"; +import { useFindMany } from "@gadgetinc/react"; + +import { api } from "../api"; +import { BlockStack, Page } from "@shopify/polaris"; +import ProductCard from "./ProductCard"; + +export default () => { + const { orderId } = useParams(); + const [searchParams] = useSearchParams(); + + const [ + { + data: products, + fetching: fetchingProducts, + error: errorFetchingProducts, + }, + ] = useFindMany(api.shopifyProduct, { + filter: { + id: { + in: searchParams.get("products").split(","), + }, + }, + select: { + id: true, + title: true, + images: { + edges: { + node: { + source: true, + alt: true, + }, + }, + }, + }, + }); + + console.log({ + orderId, + products, + orderNumber: searchParams.get("orderNumber"), + }); + + return ( + + + {products?.map(({ id, title }) => ( + + ))} + + + ); +}; diff --git a/product-reviews-template/web/components/index.js b/product-reviews-template/web/components/index.js new file mode 100644 index 00000000..272db70d --- /dev/null +++ b/product-reviews-template/web/components/index.js @@ -0,0 +1 @@ +export { default as App } from "./App"; diff --git a/product-reviews-template/web/main.jsx b/product-reviews-template/web/main.jsx index 0f2d586e..29abc862 100755 --- a/product-reviews-template/web/main.jsx +++ b/product-reviews-template/web/main.jsx @@ -3,7 +3,7 @@ import "@shopify/polaris/build/esm/styles.css"; import enTranslations from "@shopify/polaris/locales/en.json"; import React from "react"; import ReactDOM from "react-dom/client"; -import App from "./components/App"; +import { App } from "./components"; const root = document.getElementById("root"); if (!root) throw new Error("#root element not found for booting react app"); diff --git a/product-reviews-template/web/routes/index.js b/product-reviews-template/web/routes/index.js new file mode 100644 index 00000000..77deccf5 --- /dev/null +++ b/product-reviews-template/web/routes/index.js @@ -0,0 +1,2 @@ +export { default as Index } from "./index.jsx"; +export { default as AboutPage } from "./about.jsx"; diff --git a/product-reviews-template/yarn.lock b/product-reviews-template/yarn.lock index 3d34858c..5443ad54 100644 --- a/product-reviews-template/yarn.lock +++ b/product-reviews-template/yarn.lock @@ -146,7 +146,7 @@ dependencies: "@babel/types" "^7.25.2" -"@babel/runtime@^7.21.0", "@babel/runtime@^7.23.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": +"@babel/runtime@^7.23.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": version "7.25.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.0.tgz#3af9a91c1b739c569d5d80cc917280919c544ecb" integrity sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw== @@ -522,16 +522,14 @@ crypto-js "^4.2.0" tslib "^2.6.2" -"@gadgetinc/react@^0.16.1": - version "0.16.2" - resolved "https://registry.yarnpkg.com/@gadgetinc/react/-/react-0.16.2.tgz#5170e1c19304b5bc941f606d4f054f2ec6121d69" - integrity sha512-1oVShl00miQwcVzSEWwE/DLCO+4JhZWICBveDXRjt31n7s5nrjt7N+X2FS3MdY87eS7H2fNn5asxVGtzPIMu8w== +"@gadgetinc/react@^0.16.2": + version "0.16.4" + resolved "https://registry.yarnpkg.com/@gadgetinc/react/-/react-0.16.4.tgz#5833bff9e72ef2fa151a90b470f6ca6c471f9736" + integrity sha512-QtTJX4W80y7Vvvvkb/sBEdTNvCer0hbPHrzj6LX0WLz4E1p5dGyPWaiF6JkE8yi03tpi9/Mi6q8aO+UIV3xvcw== dependencies: "@0no-co/graphql.web" "^1.0.4" "@gadgetinc/api-client-core" "^0.15.24" "@hookform/resolvers" "^3.3.1" - date-fns "^2.30.0" - date-fns-tz "^2.0.0" filesize "^10.1.2" pluralize "^8.0.0" react-fast-compare "^3.2.2" @@ -1069,6 +1067,15 @@ js-beautify "^1.14.11" react-promise-suspense "0.3.4" +"@react-email/render@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@react-email/render/-/render-1.0.0.tgz#cccde27b10018d954160264c0db6b283c3be619d" + integrity sha512-seN2p3JRUSZhwIUiymh9N6ZfhRZ14ywOraQqAokY63DkDeHZW2pA2a6nWpNc/igfOcNyt09Wsoi1Aj0esxhdzw== + dependencies: + html-to-text "9.0.5" + js-beautify "^1.14.11" + react-promise-suspense "0.3.4" + "@react-email/row@0.0.9": version "0.0.9" resolved "https://registry.yarnpkg.com/@react-email/row/-/row-0.0.9.tgz#e7816992691ca89d1d99b0e926247b9f8f23d96a" @@ -2153,18 +2160,6 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== -date-fns-tz@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/date-fns-tz/-/date-fns-tz-2.0.1.tgz#0a9b2099031c0d74120b45de9fd23192e48ea495" - integrity sha512-fJCG3Pwx8HUoLhkepdsP7Z5RsucUi+ZBOxyM5d0ZZ6c4SdYustq0VMmOu6Wf7bli+yS/Jwp91TOCqn9jMcVrUA== - -date-fns@^2.30.0: - version "2.30.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" - integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== - dependencies: - "@babel/runtime" "^7.21.0" - debounce@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/debounce/-/debounce-2.0.0.tgz#b2f914518a1481466f4edaee0b063e4d473ad549" @@ -4052,8 +4047,16 @@ streamsearch@^1.1.0: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: - name string-width-cjs +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -4078,8 +4081,14 @@ string_decoder@^1.1.1, string_decoder@^1.3.0: dependencies: safe-buffer "~5.2.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: - name strip-ansi-cjs +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -4341,6 +4350,11 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +uuid@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-10.0.0.tgz#5a95aa454e6e002725c79055fd42aaba30ca6294" + integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ== + vary@^1: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" From fd789f6a82ab786fd578b2c40772b8fcae720879 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Fri, 23 Aug 2024 11:46:20 -0400 Subject: [PATCH 09/43] Adding stars to the review card // Adding styled spinner component for loading --- .../web/components/App.jsx | 15 +--- .../web/components/ProductCard.jsx | 70 ++++++++++++++----- .../web/components/ReviewForm.jsx | 15 ++-- .../web/components/Stars.jsx | 39 +++++++++++ .../web/components/StyledSpinner.jsx | 17 +++++ 5 files changed, 119 insertions(+), 37 deletions(-) create mode 100644 product-reviews-template/web/components/Stars.jsx create mode 100644 product-reviews-template/web/components/StyledSpinner.jsx diff --git a/product-reviews-template/web/components/App.jsx b/product-reviews-template/web/components/App.jsx index a64d7f7c..53076f89 100755 --- a/product-reviews-template/web/components/App.jsx +++ b/product-reviews-template/web/components/App.jsx @@ -20,6 +20,7 @@ import { api } from "../api"; import { AboutPage, Index } from "../routes"; import "./App.css"; import ReviewForm from "./ReviewForm"; +import StyledSpinner from "./StyledSpinner"; function Error404() { const navigate = useNavigate(); @@ -71,19 +72,7 @@ function AuthenticatedApp() { // we use `isAuthenticated` to render pages once the OAuth flow is complete! const { isAuthenticated, loading } = useGadget(); if (loading) { - return ( -
- -
- ); + return ; } return isAuthenticated ? : ; diff --git a/product-reviews-template/web/components/ProductCard.jsx b/product-reviews-template/web/components/ProductCard.jsx index dec7525c..fdd116f6 100644 --- a/product-reviews-template/web/components/ProductCard.jsx +++ b/product-reviews-template/web/components/ProductCard.jsx @@ -1,31 +1,65 @@ -import { AutoForm } from "@gadgetinc/react/auto/polaris"; -import { Button, Card, Text } from "@shopify/polaris"; +import { + AutoForm, + AutoNumberInput, + AutoSubmit, + AutoTextInput, +} from "@gadgetinc/react/auto/polaris"; +import { + Button, + ButtonGroup, + Card, + Collapsible, + InlineStack, + Text, +} from "@shopify/polaris"; import { ChevronDownIcon, ChevronUpIcon } from "@shopify/polaris-icons"; import { api } from "../api"; import { useState } from "react"; +import Stars from "./Stars"; export default ({ id, title, orderId }) => { const [open, setOpen] = useState(false); + const [rating, setRating] = useState(0); + + // const controller = useNumberController() return ( - - - {title} - - - + {/* */} + + {/* */} + + + + + + + + + + + + + ); }; diff --git a/product-reviews-template/web/components/ReviewForm.jsx b/product-reviews-template/web/components/ReviewForm.jsx index fe747ffd..c30e454a 100644 --- a/product-reviews-template/web/components/ReviewForm.jsx +++ b/product-reviews-template/web/components/ReviewForm.jsx @@ -4,6 +4,7 @@ import { useFindMany } from "@gadgetinc/react"; import { api } from "../api"; import { BlockStack, Page } from "@shopify/polaris"; import ProductCard from "./ProductCard"; +import StyledSpinner from "./StyledSpinner"; export default () => { const { orderId } = useParams(); @@ -35,14 +36,16 @@ export default () => { }, }); - console.log({ - orderId, - products, - orderNumber: searchParams.get("orderNumber"), - }); + if (fetchingProducts) { + return ( + + + + ); + } return ( - + {products?.map(({ id, title }) => ( diff --git a/product-reviews-template/web/components/Stars.jsx b/product-reviews-template/web/components/Stars.jsx new file mode 100644 index 00000000..2ce842e5 --- /dev/null +++ b/product-reviews-template/web/components/Stars.jsx @@ -0,0 +1,39 @@ +import { useState } from "react"; +import { Icon, InlineStack } from "@shopify/polaris"; +import { StarFilledIcon, StarIcon } from "@shopify/polaris-icons"; + +export default ({ rating = 0, totalStars = 5, onRate }) => { + const [hoveredStar, setHoveredStar] = useState(0); + + const handleMouseEnter = (index) => { + setHoveredStar(index + 1); + }; + + const handleMouseLeave = () => { + setHoveredStar(0); + }; + + const handleClick = (index) => { + if (onRate) { + onRate(index + 1); + } + }; + + return ( + + {Array.from({ length: totalStars }, (_, index) => ( +
handleMouseEnter(index)} + onMouseLeave={handleMouseLeave} + onClick={() => handleClick(index)} + style={{ cursor: "pointer" }} + > + +
+ ))} +
+ ); +}; diff --git a/product-reviews-template/web/components/StyledSpinner.jsx b/product-reviews-template/web/components/StyledSpinner.jsx new file mode 100644 index 00000000..29db9b3d --- /dev/null +++ b/product-reviews-template/web/components/StyledSpinner.jsx @@ -0,0 +1,17 @@ +import { Spinner } from "@shopify/polaris"; + +export default () => { + return ( +
+ +
+ ); +}; From c13769c056ec36185f78fa60d51b5a6b5ec7d300 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Fri, 23 Aug 2024 12:30:56 -0400 Subject: [PATCH 10/43] Adding stars to the review card --- .../api/models/review/actions/create.js | 27 ++++++++-- .../api/models/review/actions/update.js | 16 ++++-- .../api/models/review/schema.gadget.ts | 1 + .../web/components/ProductCard.jsx | 9 +--- .../web/components/Stars.jsx | 52 +++++++++++-------- 5 files changed, 69 insertions(+), 36 deletions(-) mode change 100644 => 100755 product-reviews-template/web/components/Stars.jsx diff --git a/product-reviews-template/api/models/review/actions/create.js b/product-reviews-template/api/models/review/actions/create.js index df4bb1db..c5500dff 100755 --- a/product-reviews-template/api/models/review/actions/create.js +++ b/product-reviews-template/api/models/review/actions/create.js @@ -1,19 +1,40 @@ -import { applyParams, save, ActionOptions, CreateReviewActionContext } from "gadget-server"; +import { + applyParams, + save, + ActionOptions, + CreateReviewActionContext, +} from "gadget-server"; /** * @param { CreateReviewActionContext } context */ export async function run({ params, record, logger, api, connections }) { applyParams(params, record); + + const order = await api.shopifyOrder.findOne(record.orderId, { + select: { + shopId: true, + customerId: true, + }, + }); + + record.shop = { + _link: order.shopId, + }; + + record.customer = { + _link: order.customerId, + }; + await save(record); -}; +} /** * @param { CreateReviewActionContext } context */ export async function onSuccess({ params, record, logger, api, connections }) { // Your logic goes here -}; +} /** @type { ActionOptions } */ export const options = { diff --git a/product-reviews-template/api/models/review/actions/update.js b/product-reviews-template/api/models/review/actions/update.js index c4310745..42f020e8 100755 --- a/product-reviews-template/api/models/review/actions/update.js +++ b/product-reviews-template/api/models/review/actions/update.js @@ -1,4 +1,9 @@ -import { applyParams, save, ActionOptions, UpdateReviewActionContext } from "gadget-server"; +import { + applyParams, + save, + ActionOptions, + UpdateReviewActionContext, +} from "gadget-server"; /** * @param { UpdateReviewActionContext } context @@ -6,14 +11,17 @@ import { applyParams, save, ActionOptions, UpdateReviewActionContext } from "gad export async function run({ params, record, logger, api, connections }) { applyParams(params, record); await save(record); -}; +} /** * @param { UpdateReviewActionContext } context */ export async function onSuccess({ params, record, logger, api, connections }) { - // Add logic to create metaobject in Shopify (if approved) -}; + const approved = record.changes("approved"); + + if (approved.changed) { + } +} /** @type { ActionOptions } */ export const options = { diff --git a/product-reviews-template/api/models/review/schema.gadget.ts b/product-reviews-template/api/models/review/schema.gadget.ts index 906f5005..068c5b46 100755 --- a/product-reviews-template/api/models/review/schema.gadget.ts +++ b/product-reviews-template/api/models/review/schema.gadget.ts @@ -30,6 +30,7 @@ export const schema: GadgetModel = { }, order: { type: "belongsTo", + validations: { required: true }, parent: { model: "shopifyOrder" }, storageKey: "6cS42mJLsWyc", }, diff --git a/product-reviews-template/web/components/ProductCard.jsx b/product-reviews-template/web/components/ProductCard.jsx index fdd116f6..e22a5c31 100644 --- a/product-reviews-template/web/components/ProductCard.jsx +++ b/product-reviews-template/web/components/ProductCard.jsx @@ -1,6 +1,5 @@ import { AutoForm, - AutoNumberInput, AutoSubmit, AutoTextInput, } from "@gadgetinc/react/auto/polaris"; @@ -19,9 +18,6 @@ import Stars from "./Stars"; export default ({ id, title, orderId }) => { const [open, setOpen] = useState(false); - const [rating, setRating] = useState(0); - - // const controller = useNumberController() return ( @@ -37,10 +33,9 @@ export default ({ id, title, orderId }) => { productId: id, }} exclude={["anonymous", "approved", "customer", "order", "product"]} + onSuccess={() => setOpen(false)} > - {/* */} - - {/* */} + diff --git a/product-reviews-template/web/components/Stars.jsx b/product-reviews-template/web/components/Stars.jsx old mode 100644 new mode 100755 index 2ce842e5..f193dfd7 --- a/product-reviews-template/web/components/Stars.jsx +++ b/product-reviews-template/web/components/Stars.jsx @@ -1,10 +1,13 @@ import { useState } from "react"; import { Icon, InlineStack } from "@shopify/polaris"; import { StarFilledIcon, StarIcon } from "@shopify/polaris-icons"; +import { Controller, useFormContext } from "@gadgetinc/react"; -export default ({ rating = 0, totalStars = 5, onRate }) => { +export default ({ totalStars = 5 }) => { const [hoveredStar, setHoveredStar] = useState(0); + const { control } = useFormContext(); + const handleMouseEnter = (index) => { setHoveredStar(index + 1); }; @@ -13,27 +16,32 @@ export default ({ rating = 0, totalStars = 5, onRate }) => { setHoveredStar(0); }; - const handleClick = (index) => { - if (onRate) { - onRate(index + 1); - } - }; - return ( - - {Array.from({ length: totalStars }, (_, index) => ( -
handleMouseEnter(index)} - onMouseLeave={handleMouseLeave} - onClick={() => handleClick(index)} - style={{ cursor: "pointer" }} - > - -
- ))} -
+ ( + + {Array.from({ length: totalStars }, (_, index) => ( +
handleMouseEnter(index)} + onMouseLeave={handleMouseLeave} + onClick={() => fieldProps.onChange(index + 1)} + style={{ cursor: "pointer" }} + {...{ fieldProps }} + > + +
+ ))} +
+ )} + /> ); }; From f9374fc42141f24ab2aa280e8c3c2ed0a707265c Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Fri, 23 Aug 2024 14:03:02 -0400 Subject: [PATCH 11/43] Adding metaobject creation functionality to the reviews creation process --- .../api/models/review/actions/update.js | 18 +++-- .../api/models/review/schema.gadget.ts | 1 + product-reviews-template/package.json | 2 +- .../web/components/App.jsx | 7 +- .../web/components/ProductCard.jsx | 60 ---------------- .../web/components/ReviewCard.jsx | 71 +++++++++++++++++++ .../{ReviewForm.jsx => Reviews.jsx} | 14 +++- .../web/components/Stars.jsx | 8 +-- product-reviews-template/yarn.lock | 2 +- 9 files changed, 106 insertions(+), 77 deletions(-) delete mode 100644 product-reviews-template/web/components/ProductCard.jsx create mode 100644 product-reviews-template/web/components/ReviewCard.jsx rename product-reviews-template/web/components/{ReviewForm.jsx => Reviews.jsx} (80%) mode change 100644 => 100755 diff --git a/product-reviews-template/api/models/review/actions/update.js b/product-reviews-template/api/models/review/actions/update.js index 42f020e8..cd66d366 100755 --- a/product-reviews-template/api/models/review/actions/update.js +++ b/product-reviews-template/api/models/review/actions/update.js @@ -10,6 +10,19 @@ import { */ export async function run({ params, record, logger, api, connections }) { applyParams(params, record); + + const approved = record.changes("approved"); + + if (approved.changed) { + const shopify = connections.shopify.current; + + if (approved.current && !record.metaobjectId) { + await shopify.graphql({}); + } else if (!approved.current && record.metaobjectId) { + await shopify.graphql({}); + } + } + await save(record); } @@ -17,10 +30,7 @@ export async function run({ params, record, logger, api, connections }) { * @param { UpdateReviewActionContext } context */ export async function onSuccess({ params, record, logger, api, connections }) { - const approved = record.changes("approved"); - - if (approved.changed) { - } + // Your logic goes here } /** @type { ActionOptions } */ diff --git a/product-reviews-template/api/models/review/schema.gadget.ts b/product-reviews-template/api/models/review/schema.gadget.ts index 068c5b46..3015848d 100755 --- a/product-reviews-template/api/models/review/schema.gadget.ts +++ b/product-reviews-template/api/models/review/schema.gadget.ts @@ -28,6 +28,7 @@ export const schema: GadgetModel = { parent: { model: "shopifyCustomer" }, storageKey: "bT0Adl6mg5Lc", }, + metaobjectId: { type: "string", storageKey: "MDTelmNZFvN8" }, order: { type: "belongsTo", validations: { required: true }, diff --git a/product-reviews-template/package.json b/product-reviews-template/package.json index 2fa28cb2..eaf38c0a 100755 --- a/product-reviews-template/package.json +++ b/product-reviews-template/package.json @@ -15,7 +15,7 @@ }, "dependencies": { "@gadget-client/product-reviews-template": "link:.gadget/client", - "@gadgetinc/react": "^0.16.2", + "@gadgetinc/react": "^0.16.3", "@gadgetinc/react-shopify-app-bridge": "^0.16.0", "@react-email/components": "0.0.22", "@react-email/render": "1.0.0", diff --git a/product-reviews-template/web/components/App.jsx b/product-reviews-template/web/components/App.jsx index 53076f89..e2e8c42e 100755 --- a/product-reviews-template/web/components/App.jsx +++ b/product-reviews-template/web/components/App.jsx @@ -4,7 +4,6 @@ import { useGadget, } from "@gadgetinc/react-shopify-app-bridge"; import { NavMenu } from "@shopify/app-bridge-react"; -import { Spinner } from "@shopify/polaris"; import { useEffect } from "react"; import { Link, @@ -19,7 +18,7 @@ import { import { api } from "../api"; import { AboutPage, Index } from "../routes"; import "./App.css"; -import ReviewForm from "./ReviewForm"; +import Reviews from "./Reviews"; import StyledSpinner from "./StyledSpinner"; function Error404() { @@ -44,7 +43,7 @@ export default function () { } /> } /> } /> - } /> + } /> ) ); @@ -93,5 +92,5 @@ function EmbeddedApp() { } function UnauthenticatedApp() { - return ; + return ; } diff --git a/product-reviews-template/web/components/ProductCard.jsx b/product-reviews-template/web/components/ProductCard.jsx deleted file mode 100644 index e22a5c31..00000000 --- a/product-reviews-template/web/components/ProductCard.jsx +++ /dev/null @@ -1,60 +0,0 @@ -import { - AutoForm, - AutoSubmit, - AutoTextInput, -} from "@gadgetinc/react/auto/polaris"; -import { - Button, - ButtonGroup, - Card, - Collapsible, - InlineStack, - Text, -} from "@shopify/polaris"; -import { ChevronDownIcon, ChevronUpIcon } from "@shopify/polaris-icons"; -import { api } from "../api"; -import { useState } from "react"; -import Stars from "./Stars"; - -export default ({ id, title, orderId }) => { - const [open, setOpen] = useState(false); - - return ( - - - {title} - - - setOpen(false)} - > - - - - - - - - - - - - - - - - ); -}; diff --git a/product-reviews-template/web/components/ReviewCard.jsx b/product-reviews-template/web/components/ReviewCard.jsx new file mode 100644 index 00000000..7256a0b8 --- /dev/null +++ b/product-reviews-template/web/components/ReviewCard.jsx @@ -0,0 +1,71 @@ +import { + AutoForm, + AutoSubmit, + AutoTextInput, +} from "@gadgetinc/react/auto/polaris"; +import { + BlockStack, + Button, + ButtonGroup, + Card, + Collapsible, + InlineStack, + Text, + Thumbnail, +} from "@shopify/polaris"; +import { + ChevronDownIcon, + ChevronUpIcon, + ImageIcon, +} from "@shopify/polaris-icons"; +import { api } from "../api"; +import { useState } from "react"; +import Stars from "./Stars"; + +export default ({ id, title, orderId, images }) => { + const [open, setOpen] = useState(false); + + return ( + + + + + + {title} + + + + setOpen(false)} + > + + + + + + + + + + + + + + + + + ); +}; diff --git a/product-reviews-template/web/components/ReviewForm.jsx b/product-reviews-template/web/components/Reviews.jsx old mode 100644 new mode 100755 similarity index 80% rename from product-reviews-template/web/components/ReviewForm.jsx rename to product-reviews-template/web/components/Reviews.jsx index c30e454a..721a8a85 --- a/product-reviews-template/web/components/ReviewForm.jsx +++ b/product-reviews-template/web/components/Reviews.jsx @@ -3,7 +3,7 @@ import { useFindMany } from "@gadgetinc/react"; import { api } from "../api"; import { BlockStack, Page } from "@shopify/polaris"; -import ProductCard from "./ProductCard"; +import ReviewCard from "./ReviewCard"; import StyledSpinner from "./StyledSpinner"; export default () => { @@ -47,8 +47,16 @@ export default () => { return ( - {products?.map(({ id, title }) => ( - + {products?.map(({ id, title, images }) => ( + ))} diff --git a/product-reviews-template/web/components/Stars.jsx b/product-reviews-template/web/components/Stars.jsx index f193dfd7..990b2083 100755 --- a/product-reviews-template/web/components/Stars.jsx +++ b/product-reviews-template/web/components/Stars.jsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import { Icon, InlineStack } from "@shopify/polaris"; +import { Box, Icon, InlineStack } from "@shopify/polaris"; import { StarFilledIcon, StarIcon } from "@shopify/polaris-icons"; import { Controller, useFormContext } from "@gadgetinc/react"; @@ -23,13 +23,13 @@ export default ({ totalStars = 5 }) => { render={({ field: { ref, ...fieldProps } }) => ( {Array.from({ length: totalStars }, (_, index) => ( -
handleMouseEnter(index)} onMouseLeave={handleMouseLeave} onClick={() => fieldProps.onChange(index + 1)} style={{ cursor: "pointer" }} - {...{ fieldProps }} + fieldprops={fieldProps} > { : StarIcon } /> -
+ ))}
)} diff --git a/product-reviews-template/yarn.lock b/product-reviews-template/yarn.lock index 5443ad54..bd43c98a 100644 --- a/product-reviews-template/yarn.lock +++ b/product-reviews-template/yarn.lock @@ -522,7 +522,7 @@ crypto-js "^4.2.0" tslib "^2.6.2" -"@gadgetinc/react@^0.16.2": +"@gadgetinc/react@^0.16.3": version "0.16.4" resolved "https://registry.yarnpkg.com/@gadgetinc/react/-/react-0.16.4.tgz#5833bff9e72ef2fa151a90b470f6ca6c471f9736" integrity sha512-QtTJX4W80y7Vvvvkb/sBEdTNvCer0hbPHrzj6LX0WLz4E1p5dGyPWaiF6JkE8yi03tpi9/Mi6q8aO+UIV3xvcw== From ecf8951cf17e09eae04828a374883ac93b296292 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Mon, 26 Aug 2024 15:54:26 -0400 Subject: [PATCH 12/43] Adding metaobject creation and deletion code in the update action of review --- .../api/models/review/actions/update.js | 90 +++++++++++++++++-- 1 file changed, 84 insertions(+), 6 deletions(-) diff --git a/product-reviews-template/api/models/review/actions/update.js b/product-reviews-template/api/models/review/actions/update.js index cd66d366..1b1f9ca8 100755 --- a/product-reviews-template/api/models/review/actions/update.js +++ b/product-reviews-template/api/models/review/actions/update.js @@ -11,15 +11,93 @@ import { export async function run({ params, record, logger, api, connections }) { applyParams(params, record); - const approved = record.changes("approved"); + const { changed, current: approved } = record.changes("approved"); - if (approved.changed) { + if (changed) { const shopify = connections.shopify.current; - if (approved.current && !record.metaobjectId) { - await shopify.graphql({}); - } else if (!approved.current && record.metaobjectId) { - await shopify.graphql({}); + if (approved && !record.metaobjectId) { + const customer = await api.shopifyCustomer.maybeFindOne( + record.customerId, + { + select: { + firstName: true, + }, + } + ); + + // Create the metaobject + const metaobjectCreateResponse = await shopify.graphql( + `mutation ($metaobject: MetaobjectCreateInput!) { + metaobjectCreate(metaobject: $metaobject) { + metaobject { + id + } + userErrors { + message + } + } + }`, + { + metaobject: { + type: "review", + fields: [ + { + key: "anonymous", + value: + record.anonymous == true + ? record.anonymous.toString() + : customer?.firstName + ? "true" + : "false", + }, + { + key: "rating", + value: record.rating.toString(), + }, + { + key: "content", + value: record.content, + }, + { + key: "product", + value: `gid://shopify/Product/${record.productId}`, + }, + ], + }, + } + ); + + // Throw an error if Shopify returns an error + if (metaobjectCreateResponse?.metaobjectCreate?.userErrors?.length) + throw new Error( + metaobjectCreateResponse.metaobjectCreate.userErrors[0].message + ); + + // Set the metaobject id on the record + record.metaobjectId = + metaobjectCreateResponse.metaobjectCreate.metaobject.id; + } else if (!approved && record.metaobjectId) { + // Delete the metaobject + const metaobjectDeleteResponse = await shopify.graphql( + `mutation ($id: ID!) { + metaobjectDelete(id: $id) { + deletedId + userErrors { + message + } + } + }`, + { + id: record.metaobjectId, + } + ); + + // Throw an error if Shopify returns an error + if (metaobjectDeleteResponse?.metaobjectDelete?.userErrors?.length) + throw new Error( + metaobjectDeleteResponse.metaobjectDelete.userErrors[0].message + ); } } From 6ac2e723cf5b4af4977f516a1321a26cbe893b33 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Mon, 26 Aug 2024 16:43:05 -0400 Subject: [PATCH 13/43] Working on adding a nice table for approving and removing reviews --- product-reviews-template/web/routes/index.jsx | 68 ++++++------------- 1 file changed, 21 insertions(+), 47 deletions(-) diff --git a/product-reviews-template/web/routes/index.jsx b/product-reviews-template/web/routes/index.jsx index d8c648d7..9d95fcc9 100755 --- a/product-reviews-template/web/routes/index.jsx +++ b/product-reviews-template/web/routes/index.jsx @@ -13,55 +13,29 @@ import { api } from "../api"; export default function () { return ( - + - - - Successfully connected your Gadget app to Shopify - - - - - - - - - Edit this page:{" "} - - web/routes/index.jsx - - - - - - - - {/* use Autocomponents to build UI quickly: https://docs.gadget.dev/guides/frontend/autocomponents */} - - - - Shop records fetched from:{" "} - - api/models/shopifyShop/data - - - - + From 5ccd8f71b0adaca8f31232fbec2c40e50f9d750f Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Tue, 27 Aug 2024 08:49:47 -0400 Subject: [PATCH 14/43] Reworked the stars component to work for both static and action handling --- .../web/components/Stars.jsx | 19 ++++++++--- .../web/components/index.js | 1 + product-reviews-template/web/routes/index.jsx | 32 ++++++++++++++----- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/product-reviews-template/web/components/Stars.jsx b/product-reviews-template/web/components/Stars.jsx index 990b2083..c0c2915d 100755 --- a/product-reviews-template/web/components/Stars.jsx +++ b/product-reviews-template/web/components/Stars.jsx @@ -3,10 +3,10 @@ import { Box, Icon, InlineStack } from "@shopify/polaris"; import { StarFilledIcon, StarIcon } from "@shopify/polaris-icons"; import { Controller, useFormContext } from "@gadgetinc/react"; -export default ({ totalStars = 5 }) => { +export default ({ rating }) => { const [hoveredStar, setHoveredStar] = useState(0); - const { control } = useFormContext(); + const formContext = useFormContext(); const handleMouseEnter = (index) => { setHoveredStar(index + 1); @@ -16,13 +16,22 @@ export default ({ totalStars = 5 }) => { setHoveredStar(0); }; - return ( + // Add the non-null version here + return rating ? ( + + {Array.from({ length: 5 }, (_, index) => ( + + + + ))} + + ) : ( ( - {Array.from({ length: totalStars }, (_, index) => ( + {Array.from({ length: 5 }, (_, index) => ( handleMouseEnter(index)} diff --git a/product-reviews-template/web/components/index.js b/product-reviews-template/web/components/index.js index 272db70d..8ed7e558 100644 --- a/product-reviews-template/web/components/index.js +++ b/product-reviews-template/web/components/index.js @@ -1 +1,2 @@ export { default as App } from "./App"; +export { default as Stars } from "./Stars"; diff --git a/product-reviews-template/web/routes/index.jsx b/product-reviews-template/web/routes/index.jsx index 9d95fcc9..882b4dc1 100755 --- a/product-reviews-template/web/routes/index.jsx +++ b/product-reviews-template/web/routes/index.jsx @@ -1,4 +1,4 @@ -import { AutoTable } from "@gadgetinc/react/auto/polaris"; +import { AutoButton, AutoTable } from "@gadgetinc/react/auto/polaris"; import { Banner, BlockStack, @@ -10,6 +10,7 @@ import { Text, } from "@shopify/polaris"; import { api } from "../api"; +import { Stars } from "../components"; export default function () { return ( @@ -27,14 +28,29 @@ export default function () { }, customer: { firstName: true, lastName: true }, }} - excludeColumns={[ - "id", - "anonymous", - "metaobjectId", - "createdAt", - "updatedAt", - ]} selectable={false} + columns={[ + { field: "product.title", header: "Product" }, + { field: "content", header: "Review" }, + { field: "customer.firstName", header: "Customer" }, + { + field: "rating", + header: "Rating", + render: ({ record }) => , + }, + { + field: "approved", + header: "", + render: ({ record }) => ( + + {record.approved ? "Remove" : "Approve"} + + ), + }, + ]} /> From ef30efb82d2f536472fd69eb224f82c8c48c4eb8 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Tue, 27 Aug 2024 09:36:32 -0400 Subject: [PATCH 15/43] Fixing an issue with the rating setting for metaobjects --- .../api/models/review/actions/update.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/product-reviews-template/api/models/review/actions/update.js b/product-reviews-template/api/models/review/actions/update.js index 1b1f9ca8..b294d976 100755 --- a/product-reviews-template/api/models/review/actions/update.js +++ b/product-reviews-template/api/models/review/actions/update.js @@ -53,7 +53,11 @@ export async function run({ params, record, logger, api, connections }) { }, { key: "rating", - value: record.rating.toString(), + value: JSON.stringify({ + value: record.rating, + scale_max: "5", + scale_min: "0", + }), }, { key: "content", From d51daedfb57a04923a021df27e457b729fdc0259 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Tue, 27 Aug 2024 11:04:34 -0400 Subject: [PATCH 16/43] Adding modal and custom render to table --- .../api/models/review/actions/update.js | 2 + product-reviews-template/web/routes/index.jsx | 58 +++++++++++++++---- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/product-reviews-template/api/models/review/actions/update.js b/product-reviews-template/api/models/review/actions/update.js index b294d976..7ff4555b 100755 --- a/product-reviews-template/api/models/review/actions/update.js +++ b/product-reviews-template/api/models/review/actions/update.js @@ -102,6 +102,8 @@ export async function run({ params, record, logger, api, connections }) { throw new Error( metaobjectDeleteResponse.metaobjectDelete.userErrors[0].message ); + + record.metaobjectId = null; } } diff --git a/product-reviews-template/web/routes/index.jsx b/product-reviews-template/web/routes/index.jsx index 882b4dc1..6355d31a 100755 --- a/product-reviews-template/web/routes/index.jsx +++ b/product-reviews-template/web/routes/index.jsx @@ -1,18 +1,14 @@ import { AutoButton, AutoTable } from "@gadgetinc/react/auto/polaris"; -import { - Banner, - BlockStack, - Box, - Card, - Layout, - Link, - Page, - Text, -} from "@shopify/polaris"; +import { BlockStack, Layout, Page, Text, Tooltip } from "@shopify/polaris"; import { api } from "../api"; import { Stars } from "../components"; +import { useAppBridge } from "@shopify/app-bridge-react"; +import { useState } from "react"; export default function () { + const { toast, modal } = useAppBridge(); + const [modalContent, setModelContent] = useState(""); + return ( @@ -31,7 +27,24 @@ export default function () { selectable={false} columns={[ { field: "product.title", header: "Product" }, - { field: "content", header: "Review" }, + { + field: "content", + header: "Review", + render: ({ record: { content } }) => ( + +
{ + setModelContent(content); + modal.show("review-content-modal"); + }} + > + + {content} + +
+
+ ), + }, { field: "customer.firstName", header: "Customer" }, { field: "rating", @@ -45,6 +58,23 @@ export default function () { + toast.show( + approved + ? "Review added to store" + : "Review removed from store", + { + duration: 5000, + } + ) + } + onError={() => + toast.show("Error submitting change", { + duration: 5000, + isError: true, + }) + } > {record.approved ? "Remove" : "Approve"} @@ -53,6 +83,12 @@ export default function () { ]} /> + + + + {modalContent} + +
); From b89b83c7cc49857973383c10f2dcb06f047aed2f Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Wed, 28 Aug 2024 10:50:06 -0400 Subject: [PATCH 17/43] Moved the product-reviews code to the shopify folder --- .../product-reviews-template}/.gitignore | 0 .../product-reviews-template}/.ignore | 0 .../accessControl/filters/review/tenancy.gelly | 0 .../filters/shopify/shopifyCustomer.gelly | 0 .../filters/shopify/shopifyGdprRequest.gelly | 0 .../filters/shopify/shopifyOrder.gelly | 0 .../filters/shopify/shopifyOrderLineItem.gelly | 0 .../filters/shopify/shopifyProduct.gelly | 0 .../filters/shopify/shopifyProductImage.gelly | 0 .../accessControl/filters/shopify/shopifyShop.gelly | 0 .../accessControl/filters/shopify/shopifySync.gelly | 0 .../accessControl/permissions.gadget.ts | 0 .../api/actions/enqueueEmails.js | 0 .../api/actions/sendEmail.js | 0 .../api/actions/sendReviewRequests.js | 0 .../api/models/review/actions/create.js | 0 .../api/models/review/actions/delete.js | 0 .../api/models/review/actions/update.js | 0 .../api/models/review/schema.gadget.ts | 0 .../api/models/session/schema.gadget.ts | 0 .../api/models/shopifyCustomer/actions/create.js | 0 .../api/models/shopifyCustomer/actions/delete.js | 0 .../api/models/shopifyCustomer/actions/update.js | 0 .../api/models/shopifyCustomer/schema.gadget.ts | 0 .../api/models/shopifyGdprRequest/actions/create.js | 0 .../api/models/shopifyGdprRequest/actions/update.js | 0 .../api/models/shopifyGdprRequest/schema.gadget.ts | 0 .../api/models/shopifyOrder/actions/create.js | 0 .../api/models/shopifyOrder/actions/delete.js | 0 .../api/models/shopifyOrder/actions/update.js | 0 .../api/models/shopifyOrder/schema.gadget.ts | 0 .../models/shopifyOrderLineItem/actions/create.js | 0 .../models/shopifyOrderLineItem/actions/delete.js | 0 .../models/shopifyOrderLineItem/actions/update.js | 0 .../models/shopifyOrderLineItem/schema.gadget.ts | 0 .../api/models/shopifyProduct/actions/create.js | 0 .../api/models/shopifyProduct/actions/delete.js | 0 .../api/models/shopifyProduct/actions/update.js | 0 .../api/models/shopifyProduct/schema.gadget.ts | 0 .../models/shopifyProductImage/actions/create.js | 0 .../models/shopifyProductImage/actions/delete.js | 0 .../models/shopifyProductImage/actions/update.js | 0 .../api/models/shopifyProductImage/schema.gadget.ts | 0 .../api/models/shopifyShop/actions/install.js | 0 .../api/models/shopifyShop/actions/reinstall.js | 0 .../api/models/shopifyShop/actions/uninstall.js | 0 .../api/models/shopifyShop/actions/update.js | 0 .../api/models/shopifyShop/schema.gadget.ts | 0 .../api/models/shopifySync/actions/abort.js | 0 .../api/models/shopifySync/actions/complete.js | 0 .../api/models/shopifySync/actions/error.js | 0 .../api/models/shopifySync/actions/run.js | 0 .../api/models/shopifySync/schema.gadget.ts | 0 .../extensions/product-reviews/assets/thumbs-up.png | Bin .../product-reviews/blocks/star_rating.liquid | 0 .../product-reviews/locales/en.default.json | 0 .../product-reviews/shopify.extension.toml | 0 .../product-reviews/snippets/stars.liquid | 0 .../product-reviews-template}/index.html | 0 .../product-reviews-template}/package.json | 0 .../product-reviews-template}/settings.gadget.ts | 0 .../product-reviews-template}/vite.config.mjs | 0 .../product-reviews-template}/web/api.js | 0 .../web/components/App.css | 0 .../web/components/App.jsx | 0 .../web/components/ReviewCard.jsx | 0 .../web/components/Reviews.jsx | 0 .../web/components/Stars.jsx | 0 .../web/components/StyledSpinner.jsx | 0 .../web/components/index.js | 0 .../product-reviews-template}/web/main.jsx | 0 .../product-reviews-template}/web/routes/about.jsx | 0 .../product-reviews-template}/web/routes/index.js | 0 .../product-reviews-template}/web/routes/index.jsx | 0 .../product-reviews-template}/yarn.lock | 0 75 files changed, 0 insertions(+), 0 deletions(-) rename {product-reviews-template => shopify/product-reviews-template}/.gitignore (100%) rename {product-reviews-template => shopify/product-reviews-template}/.ignore (100%) rename {product-reviews-template => shopify/product-reviews-template}/accessControl/filters/review/tenancy.gelly (100%) rename {product-reviews-template => shopify/product-reviews-template}/accessControl/filters/shopify/shopifyCustomer.gelly (100%) rename {product-reviews-template => shopify/product-reviews-template}/accessControl/filters/shopify/shopifyGdprRequest.gelly (100%) rename {product-reviews-template => shopify/product-reviews-template}/accessControl/filters/shopify/shopifyOrder.gelly (100%) rename {product-reviews-template => shopify/product-reviews-template}/accessControl/filters/shopify/shopifyOrderLineItem.gelly (100%) rename {product-reviews-template => shopify/product-reviews-template}/accessControl/filters/shopify/shopifyProduct.gelly (100%) rename {product-reviews-template => shopify/product-reviews-template}/accessControl/filters/shopify/shopifyProductImage.gelly (100%) rename {product-reviews-template => shopify/product-reviews-template}/accessControl/filters/shopify/shopifyShop.gelly (100%) rename {product-reviews-template => shopify/product-reviews-template}/accessControl/filters/shopify/shopifySync.gelly (100%) rename {product-reviews-template => shopify/product-reviews-template}/accessControl/permissions.gadget.ts (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/actions/enqueueEmails.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/actions/sendEmail.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/actions/sendReviewRequests.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/review/actions/create.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/review/actions/delete.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/review/actions/update.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/review/schema.gadget.ts (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/session/schema.gadget.ts (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyCustomer/actions/create.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyCustomer/actions/delete.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyCustomer/actions/update.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyCustomer/schema.gadget.ts (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyGdprRequest/actions/create.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyGdprRequest/actions/update.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyGdprRequest/schema.gadget.ts (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyOrder/actions/create.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyOrder/actions/delete.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyOrder/actions/update.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyOrder/schema.gadget.ts (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyOrderLineItem/actions/create.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyOrderLineItem/actions/delete.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyOrderLineItem/actions/update.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyOrderLineItem/schema.gadget.ts (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyProduct/actions/create.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyProduct/actions/delete.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyProduct/actions/update.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyProduct/schema.gadget.ts (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyProductImage/actions/create.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyProductImage/actions/delete.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyProductImage/actions/update.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyProductImage/schema.gadget.ts (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyShop/actions/install.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyShop/actions/reinstall.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyShop/actions/uninstall.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyShop/actions/update.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifyShop/schema.gadget.ts (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifySync/actions/abort.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifySync/actions/complete.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifySync/actions/error.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifySync/actions/run.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/api/models/shopifySync/schema.gadget.ts (100%) rename {product-reviews-template => shopify/product-reviews-template}/extensions/product-reviews/assets/thumbs-up.png (100%) rename {product-reviews-template => shopify/product-reviews-template}/extensions/product-reviews/blocks/star_rating.liquid (100%) rename {product-reviews-template => shopify/product-reviews-template}/extensions/product-reviews/locales/en.default.json (100%) rename {product-reviews-template => shopify/product-reviews-template}/extensions/product-reviews/shopify.extension.toml (100%) rename {product-reviews-template => shopify/product-reviews-template}/extensions/product-reviews/snippets/stars.liquid (100%) rename {product-reviews-template => shopify/product-reviews-template}/index.html (100%) rename {product-reviews-template => shopify/product-reviews-template}/package.json (100%) rename {product-reviews-template => shopify/product-reviews-template}/settings.gadget.ts (100%) rename {product-reviews-template => shopify/product-reviews-template}/vite.config.mjs (100%) rename {product-reviews-template => shopify/product-reviews-template}/web/api.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/web/components/App.css (100%) rename {product-reviews-template => shopify/product-reviews-template}/web/components/App.jsx (100%) rename {product-reviews-template => shopify/product-reviews-template}/web/components/ReviewCard.jsx (100%) rename {product-reviews-template => shopify/product-reviews-template}/web/components/Reviews.jsx (100%) rename {product-reviews-template => shopify/product-reviews-template}/web/components/Stars.jsx (100%) rename {product-reviews-template => shopify/product-reviews-template}/web/components/StyledSpinner.jsx (100%) rename {product-reviews-template => shopify/product-reviews-template}/web/components/index.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/web/main.jsx (100%) rename {product-reviews-template => shopify/product-reviews-template}/web/routes/about.jsx (100%) rename {product-reviews-template => shopify/product-reviews-template}/web/routes/index.js (100%) rename {product-reviews-template => shopify/product-reviews-template}/web/routes/index.jsx (100%) rename {product-reviews-template => shopify/product-reviews-template}/yarn.lock (100%) diff --git a/product-reviews-template/.gitignore b/shopify/product-reviews-template/.gitignore similarity index 100% rename from product-reviews-template/.gitignore rename to shopify/product-reviews-template/.gitignore diff --git a/product-reviews-template/.ignore b/shopify/product-reviews-template/.ignore similarity index 100% rename from product-reviews-template/.ignore rename to shopify/product-reviews-template/.ignore diff --git a/product-reviews-template/accessControl/filters/review/tenancy.gelly b/shopify/product-reviews-template/accessControl/filters/review/tenancy.gelly similarity index 100% rename from product-reviews-template/accessControl/filters/review/tenancy.gelly rename to shopify/product-reviews-template/accessControl/filters/review/tenancy.gelly diff --git a/product-reviews-template/accessControl/filters/shopify/shopifyCustomer.gelly b/shopify/product-reviews-template/accessControl/filters/shopify/shopifyCustomer.gelly similarity index 100% rename from product-reviews-template/accessControl/filters/shopify/shopifyCustomer.gelly rename to shopify/product-reviews-template/accessControl/filters/shopify/shopifyCustomer.gelly diff --git a/product-reviews-template/accessControl/filters/shopify/shopifyGdprRequest.gelly b/shopify/product-reviews-template/accessControl/filters/shopify/shopifyGdprRequest.gelly similarity index 100% rename from product-reviews-template/accessControl/filters/shopify/shopifyGdprRequest.gelly rename to shopify/product-reviews-template/accessControl/filters/shopify/shopifyGdprRequest.gelly diff --git a/product-reviews-template/accessControl/filters/shopify/shopifyOrder.gelly b/shopify/product-reviews-template/accessControl/filters/shopify/shopifyOrder.gelly similarity index 100% rename from product-reviews-template/accessControl/filters/shopify/shopifyOrder.gelly rename to shopify/product-reviews-template/accessControl/filters/shopify/shopifyOrder.gelly diff --git a/product-reviews-template/accessControl/filters/shopify/shopifyOrderLineItem.gelly b/shopify/product-reviews-template/accessControl/filters/shopify/shopifyOrderLineItem.gelly similarity index 100% rename from product-reviews-template/accessControl/filters/shopify/shopifyOrderLineItem.gelly rename to shopify/product-reviews-template/accessControl/filters/shopify/shopifyOrderLineItem.gelly diff --git a/product-reviews-template/accessControl/filters/shopify/shopifyProduct.gelly b/shopify/product-reviews-template/accessControl/filters/shopify/shopifyProduct.gelly similarity index 100% rename from product-reviews-template/accessControl/filters/shopify/shopifyProduct.gelly rename to shopify/product-reviews-template/accessControl/filters/shopify/shopifyProduct.gelly diff --git a/product-reviews-template/accessControl/filters/shopify/shopifyProductImage.gelly b/shopify/product-reviews-template/accessControl/filters/shopify/shopifyProductImage.gelly similarity index 100% rename from product-reviews-template/accessControl/filters/shopify/shopifyProductImage.gelly rename to shopify/product-reviews-template/accessControl/filters/shopify/shopifyProductImage.gelly diff --git a/product-reviews-template/accessControl/filters/shopify/shopifyShop.gelly b/shopify/product-reviews-template/accessControl/filters/shopify/shopifyShop.gelly similarity index 100% rename from product-reviews-template/accessControl/filters/shopify/shopifyShop.gelly rename to shopify/product-reviews-template/accessControl/filters/shopify/shopifyShop.gelly diff --git a/product-reviews-template/accessControl/filters/shopify/shopifySync.gelly b/shopify/product-reviews-template/accessControl/filters/shopify/shopifySync.gelly similarity index 100% rename from product-reviews-template/accessControl/filters/shopify/shopifySync.gelly rename to shopify/product-reviews-template/accessControl/filters/shopify/shopifySync.gelly diff --git a/product-reviews-template/accessControl/permissions.gadget.ts b/shopify/product-reviews-template/accessControl/permissions.gadget.ts similarity index 100% rename from product-reviews-template/accessControl/permissions.gadget.ts rename to shopify/product-reviews-template/accessControl/permissions.gadget.ts diff --git a/product-reviews-template/api/actions/enqueueEmails.js b/shopify/product-reviews-template/api/actions/enqueueEmails.js similarity index 100% rename from product-reviews-template/api/actions/enqueueEmails.js rename to shopify/product-reviews-template/api/actions/enqueueEmails.js diff --git a/product-reviews-template/api/actions/sendEmail.js b/shopify/product-reviews-template/api/actions/sendEmail.js similarity index 100% rename from product-reviews-template/api/actions/sendEmail.js rename to shopify/product-reviews-template/api/actions/sendEmail.js diff --git a/product-reviews-template/api/actions/sendReviewRequests.js b/shopify/product-reviews-template/api/actions/sendReviewRequests.js similarity index 100% rename from product-reviews-template/api/actions/sendReviewRequests.js rename to shopify/product-reviews-template/api/actions/sendReviewRequests.js diff --git a/product-reviews-template/api/models/review/actions/create.js b/shopify/product-reviews-template/api/models/review/actions/create.js similarity index 100% rename from product-reviews-template/api/models/review/actions/create.js rename to shopify/product-reviews-template/api/models/review/actions/create.js diff --git a/product-reviews-template/api/models/review/actions/delete.js b/shopify/product-reviews-template/api/models/review/actions/delete.js similarity index 100% rename from product-reviews-template/api/models/review/actions/delete.js rename to shopify/product-reviews-template/api/models/review/actions/delete.js diff --git a/product-reviews-template/api/models/review/actions/update.js b/shopify/product-reviews-template/api/models/review/actions/update.js similarity index 100% rename from product-reviews-template/api/models/review/actions/update.js rename to shopify/product-reviews-template/api/models/review/actions/update.js diff --git a/product-reviews-template/api/models/review/schema.gadget.ts b/shopify/product-reviews-template/api/models/review/schema.gadget.ts similarity index 100% rename from product-reviews-template/api/models/review/schema.gadget.ts rename to shopify/product-reviews-template/api/models/review/schema.gadget.ts diff --git a/product-reviews-template/api/models/session/schema.gadget.ts b/shopify/product-reviews-template/api/models/session/schema.gadget.ts similarity index 100% rename from product-reviews-template/api/models/session/schema.gadget.ts rename to shopify/product-reviews-template/api/models/session/schema.gadget.ts diff --git a/product-reviews-template/api/models/shopifyCustomer/actions/create.js b/shopify/product-reviews-template/api/models/shopifyCustomer/actions/create.js similarity index 100% rename from product-reviews-template/api/models/shopifyCustomer/actions/create.js rename to shopify/product-reviews-template/api/models/shopifyCustomer/actions/create.js diff --git a/product-reviews-template/api/models/shopifyCustomer/actions/delete.js b/shopify/product-reviews-template/api/models/shopifyCustomer/actions/delete.js similarity index 100% rename from product-reviews-template/api/models/shopifyCustomer/actions/delete.js rename to shopify/product-reviews-template/api/models/shopifyCustomer/actions/delete.js diff --git a/product-reviews-template/api/models/shopifyCustomer/actions/update.js b/shopify/product-reviews-template/api/models/shopifyCustomer/actions/update.js similarity index 100% rename from product-reviews-template/api/models/shopifyCustomer/actions/update.js rename to shopify/product-reviews-template/api/models/shopifyCustomer/actions/update.js diff --git a/product-reviews-template/api/models/shopifyCustomer/schema.gadget.ts b/shopify/product-reviews-template/api/models/shopifyCustomer/schema.gadget.ts similarity index 100% rename from product-reviews-template/api/models/shopifyCustomer/schema.gadget.ts rename to shopify/product-reviews-template/api/models/shopifyCustomer/schema.gadget.ts diff --git a/product-reviews-template/api/models/shopifyGdprRequest/actions/create.js b/shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/create.js similarity index 100% rename from product-reviews-template/api/models/shopifyGdprRequest/actions/create.js rename to shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/create.js diff --git a/product-reviews-template/api/models/shopifyGdprRequest/actions/update.js b/shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/update.js similarity index 100% rename from product-reviews-template/api/models/shopifyGdprRequest/actions/update.js rename to shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/update.js diff --git a/product-reviews-template/api/models/shopifyGdprRequest/schema.gadget.ts b/shopify/product-reviews-template/api/models/shopifyGdprRequest/schema.gadget.ts similarity index 100% rename from product-reviews-template/api/models/shopifyGdprRequest/schema.gadget.ts rename to shopify/product-reviews-template/api/models/shopifyGdprRequest/schema.gadget.ts diff --git a/product-reviews-template/api/models/shopifyOrder/actions/create.js b/shopify/product-reviews-template/api/models/shopifyOrder/actions/create.js similarity index 100% rename from product-reviews-template/api/models/shopifyOrder/actions/create.js rename to shopify/product-reviews-template/api/models/shopifyOrder/actions/create.js diff --git a/product-reviews-template/api/models/shopifyOrder/actions/delete.js b/shopify/product-reviews-template/api/models/shopifyOrder/actions/delete.js similarity index 100% rename from product-reviews-template/api/models/shopifyOrder/actions/delete.js rename to shopify/product-reviews-template/api/models/shopifyOrder/actions/delete.js diff --git a/product-reviews-template/api/models/shopifyOrder/actions/update.js b/shopify/product-reviews-template/api/models/shopifyOrder/actions/update.js similarity index 100% rename from product-reviews-template/api/models/shopifyOrder/actions/update.js rename to shopify/product-reviews-template/api/models/shopifyOrder/actions/update.js diff --git a/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts b/shopify/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts similarity index 100% rename from product-reviews-template/api/models/shopifyOrder/schema.gadget.ts rename to shopify/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts diff --git a/product-reviews-template/api/models/shopifyOrderLineItem/actions/create.js b/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/create.js similarity index 100% rename from product-reviews-template/api/models/shopifyOrderLineItem/actions/create.js rename to shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/create.js diff --git a/product-reviews-template/api/models/shopifyOrderLineItem/actions/delete.js b/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/delete.js similarity index 100% rename from product-reviews-template/api/models/shopifyOrderLineItem/actions/delete.js rename to shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/delete.js diff --git a/product-reviews-template/api/models/shopifyOrderLineItem/actions/update.js b/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/update.js similarity index 100% rename from product-reviews-template/api/models/shopifyOrderLineItem/actions/update.js rename to shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/update.js diff --git a/product-reviews-template/api/models/shopifyOrderLineItem/schema.gadget.ts b/shopify/product-reviews-template/api/models/shopifyOrderLineItem/schema.gadget.ts similarity index 100% rename from product-reviews-template/api/models/shopifyOrderLineItem/schema.gadget.ts rename to shopify/product-reviews-template/api/models/shopifyOrderLineItem/schema.gadget.ts diff --git a/product-reviews-template/api/models/shopifyProduct/actions/create.js b/shopify/product-reviews-template/api/models/shopifyProduct/actions/create.js similarity index 100% rename from product-reviews-template/api/models/shopifyProduct/actions/create.js rename to shopify/product-reviews-template/api/models/shopifyProduct/actions/create.js diff --git a/product-reviews-template/api/models/shopifyProduct/actions/delete.js b/shopify/product-reviews-template/api/models/shopifyProduct/actions/delete.js similarity index 100% rename from product-reviews-template/api/models/shopifyProduct/actions/delete.js rename to shopify/product-reviews-template/api/models/shopifyProduct/actions/delete.js diff --git a/product-reviews-template/api/models/shopifyProduct/actions/update.js b/shopify/product-reviews-template/api/models/shopifyProduct/actions/update.js similarity index 100% rename from product-reviews-template/api/models/shopifyProduct/actions/update.js rename to shopify/product-reviews-template/api/models/shopifyProduct/actions/update.js diff --git a/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts b/shopify/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts similarity index 100% rename from product-reviews-template/api/models/shopifyProduct/schema.gadget.ts rename to shopify/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts diff --git a/product-reviews-template/api/models/shopifyProductImage/actions/create.js b/shopify/product-reviews-template/api/models/shopifyProductImage/actions/create.js similarity index 100% rename from product-reviews-template/api/models/shopifyProductImage/actions/create.js rename to shopify/product-reviews-template/api/models/shopifyProductImage/actions/create.js diff --git a/product-reviews-template/api/models/shopifyProductImage/actions/delete.js b/shopify/product-reviews-template/api/models/shopifyProductImage/actions/delete.js similarity index 100% rename from product-reviews-template/api/models/shopifyProductImage/actions/delete.js rename to shopify/product-reviews-template/api/models/shopifyProductImage/actions/delete.js diff --git a/product-reviews-template/api/models/shopifyProductImage/actions/update.js b/shopify/product-reviews-template/api/models/shopifyProductImage/actions/update.js similarity index 100% rename from product-reviews-template/api/models/shopifyProductImage/actions/update.js rename to shopify/product-reviews-template/api/models/shopifyProductImage/actions/update.js diff --git a/product-reviews-template/api/models/shopifyProductImage/schema.gadget.ts b/shopify/product-reviews-template/api/models/shopifyProductImage/schema.gadget.ts similarity index 100% rename from product-reviews-template/api/models/shopifyProductImage/schema.gadget.ts rename to shopify/product-reviews-template/api/models/shopifyProductImage/schema.gadget.ts diff --git a/product-reviews-template/api/models/shopifyShop/actions/install.js b/shopify/product-reviews-template/api/models/shopifyShop/actions/install.js similarity index 100% rename from product-reviews-template/api/models/shopifyShop/actions/install.js rename to shopify/product-reviews-template/api/models/shopifyShop/actions/install.js diff --git a/product-reviews-template/api/models/shopifyShop/actions/reinstall.js b/shopify/product-reviews-template/api/models/shopifyShop/actions/reinstall.js similarity index 100% rename from product-reviews-template/api/models/shopifyShop/actions/reinstall.js rename to shopify/product-reviews-template/api/models/shopifyShop/actions/reinstall.js diff --git a/product-reviews-template/api/models/shopifyShop/actions/uninstall.js b/shopify/product-reviews-template/api/models/shopifyShop/actions/uninstall.js similarity index 100% rename from product-reviews-template/api/models/shopifyShop/actions/uninstall.js rename to shopify/product-reviews-template/api/models/shopifyShop/actions/uninstall.js diff --git a/product-reviews-template/api/models/shopifyShop/actions/update.js b/shopify/product-reviews-template/api/models/shopifyShop/actions/update.js similarity index 100% rename from product-reviews-template/api/models/shopifyShop/actions/update.js rename to shopify/product-reviews-template/api/models/shopifyShop/actions/update.js diff --git a/product-reviews-template/api/models/shopifyShop/schema.gadget.ts b/shopify/product-reviews-template/api/models/shopifyShop/schema.gadget.ts similarity index 100% rename from product-reviews-template/api/models/shopifyShop/schema.gadget.ts rename to shopify/product-reviews-template/api/models/shopifyShop/schema.gadget.ts diff --git a/product-reviews-template/api/models/shopifySync/actions/abort.js b/shopify/product-reviews-template/api/models/shopifySync/actions/abort.js similarity index 100% rename from product-reviews-template/api/models/shopifySync/actions/abort.js rename to shopify/product-reviews-template/api/models/shopifySync/actions/abort.js diff --git a/product-reviews-template/api/models/shopifySync/actions/complete.js b/shopify/product-reviews-template/api/models/shopifySync/actions/complete.js similarity index 100% rename from product-reviews-template/api/models/shopifySync/actions/complete.js rename to shopify/product-reviews-template/api/models/shopifySync/actions/complete.js diff --git a/product-reviews-template/api/models/shopifySync/actions/error.js b/shopify/product-reviews-template/api/models/shopifySync/actions/error.js similarity index 100% rename from product-reviews-template/api/models/shopifySync/actions/error.js rename to shopify/product-reviews-template/api/models/shopifySync/actions/error.js diff --git a/product-reviews-template/api/models/shopifySync/actions/run.js b/shopify/product-reviews-template/api/models/shopifySync/actions/run.js similarity index 100% rename from product-reviews-template/api/models/shopifySync/actions/run.js rename to shopify/product-reviews-template/api/models/shopifySync/actions/run.js diff --git a/product-reviews-template/api/models/shopifySync/schema.gadget.ts b/shopify/product-reviews-template/api/models/shopifySync/schema.gadget.ts similarity index 100% rename from product-reviews-template/api/models/shopifySync/schema.gadget.ts rename to shopify/product-reviews-template/api/models/shopifySync/schema.gadget.ts diff --git a/product-reviews-template/extensions/product-reviews/assets/thumbs-up.png b/shopify/product-reviews-template/extensions/product-reviews/assets/thumbs-up.png similarity index 100% rename from product-reviews-template/extensions/product-reviews/assets/thumbs-up.png rename to shopify/product-reviews-template/extensions/product-reviews/assets/thumbs-up.png diff --git a/product-reviews-template/extensions/product-reviews/blocks/star_rating.liquid b/shopify/product-reviews-template/extensions/product-reviews/blocks/star_rating.liquid similarity index 100% rename from product-reviews-template/extensions/product-reviews/blocks/star_rating.liquid rename to shopify/product-reviews-template/extensions/product-reviews/blocks/star_rating.liquid diff --git a/product-reviews-template/extensions/product-reviews/locales/en.default.json b/shopify/product-reviews-template/extensions/product-reviews/locales/en.default.json similarity index 100% rename from product-reviews-template/extensions/product-reviews/locales/en.default.json rename to shopify/product-reviews-template/extensions/product-reviews/locales/en.default.json diff --git a/product-reviews-template/extensions/product-reviews/shopify.extension.toml b/shopify/product-reviews-template/extensions/product-reviews/shopify.extension.toml similarity index 100% rename from product-reviews-template/extensions/product-reviews/shopify.extension.toml rename to shopify/product-reviews-template/extensions/product-reviews/shopify.extension.toml diff --git a/product-reviews-template/extensions/product-reviews/snippets/stars.liquid b/shopify/product-reviews-template/extensions/product-reviews/snippets/stars.liquid similarity index 100% rename from product-reviews-template/extensions/product-reviews/snippets/stars.liquid rename to shopify/product-reviews-template/extensions/product-reviews/snippets/stars.liquid diff --git a/product-reviews-template/index.html b/shopify/product-reviews-template/index.html similarity index 100% rename from product-reviews-template/index.html rename to shopify/product-reviews-template/index.html diff --git a/product-reviews-template/package.json b/shopify/product-reviews-template/package.json similarity index 100% rename from product-reviews-template/package.json rename to shopify/product-reviews-template/package.json diff --git a/product-reviews-template/settings.gadget.ts b/shopify/product-reviews-template/settings.gadget.ts similarity index 100% rename from product-reviews-template/settings.gadget.ts rename to shopify/product-reviews-template/settings.gadget.ts diff --git a/product-reviews-template/vite.config.mjs b/shopify/product-reviews-template/vite.config.mjs similarity index 100% rename from product-reviews-template/vite.config.mjs rename to shopify/product-reviews-template/vite.config.mjs diff --git a/product-reviews-template/web/api.js b/shopify/product-reviews-template/web/api.js similarity index 100% rename from product-reviews-template/web/api.js rename to shopify/product-reviews-template/web/api.js diff --git a/product-reviews-template/web/components/App.css b/shopify/product-reviews-template/web/components/App.css similarity index 100% rename from product-reviews-template/web/components/App.css rename to shopify/product-reviews-template/web/components/App.css diff --git a/product-reviews-template/web/components/App.jsx b/shopify/product-reviews-template/web/components/App.jsx similarity index 100% rename from product-reviews-template/web/components/App.jsx rename to shopify/product-reviews-template/web/components/App.jsx diff --git a/product-reviews-template/web/components/ReviewCard.jsx b/shopify/product-reviews-template/web/components/ReviewCard.jsx similarity index 100% rename from product-reviews-template/web/components/ReviewCard.jsx rename to shopify/product-reviews-template/web/components/ReviewCard.jsx diff --git a/product-reviews-template/web/components/Reviews.jsx b/shopify/product-reviews-template/web/components/Reviews.jsx similarity index 100% rename from product-reviews-template/web/components/Reviews.jsx rename to shopify/product-reviews-template/web/components/Reviews.jsx diff --git a/product-reviews-template/web/components/Stars.jsx b/shopify/product-reviews-template/web/components/Stars.jsx similarity index 100% rename from product-reviews-template/web/components/Stars.jsx rename to shopify/product-reviews-template/web/components/Stars.jsx diff --git a/product-reviews-template/web/components/StyledSpinner.jsx b/shopify/product-reviews-template/web/components/StyledSpinner.jsx similarity index 100% rename from product-reviews-template/web/components/StyledSpinner.jsx rename to shopify/product-reviews-template/web/components/StyledSpinner.jsx diff --git a/product-reviews-template/web/components/index.js b/shopify/product-reviews-template/web/components/index.js similarity index 100% rename from product-reviews-template/web/components/index.js rename to shopify/product-reviews-template/web/components/index.js diff --git a/product-reviews-template/web/main.jsx b/shopify/product-reviews-template/web/main.jsx similarity index 100% rename from product-reviews-template/web/main.jsx rename to shopify/product-reviews-template/web/main.jsx diff --git a/product-reviews-template/web/routes/about.jsx b/shopify/product-reviews-template/web/routes/about.jsx similarity index 100% rename from product-reviews-template/web/routes/about.jsx rename to shopify/product-reviews-template/web/routes/about.jsx diff --git a/product-reviews-template/web/routes/index.js b/shopify/product-reviews-template/web/routes/index.js similarity index 100% rename from product-reviews-template/web/routes/index.js rename to shopify/product-reviews-template/web/routes/index.js diff --git a/product-reviews-template/web/routes/index.jsx b/shopify/product-reviews-template/web/routes/index.jsx similarity index 100% rename from product-reviews-template/web/routes/index.jsx rename to shopify/product-reviews-template/web/routes/index.jsx diff --git a/product-reviews-template/yarn.lock b/shopify/product-reviews-template/yarn.lock similarity index 100% rename from product-reviews-template/yarn.lock rename to shopify/product-reviews-template/yarn.lock From aa05a716287b193b4b9b0c12ff7268aa8136e71c Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Mon, 7 Oct 2024 16:44:10 -0400 Subject: [PATCH 18/43] Added a global action to fetch the order data // Made the route a one time use route // Need to push people to an error or message page when the route they are trying to hit is expired --- .../accessControl/permissions.gadget.ts | 9 +- .../api/actions/enqueueEmails.js | 51 ++---------- .../api/actions/fetchOrderData.js | 83 +++++++++++++++++++ .../api/actions/sendEmail.js | 21 ++--- .../api/actions/sendReviewRequests.js | 10 +-- .../api/models/review/actions/create.js | 2 + .../api/models/shopifyOrder/actions/create.js | 4 + .../api/models/shopifyOrder/schema.gadget.ts | 5 ++ shopify/product-reviews-template/package.json | 9 +- .../settings.gadget.ts | 2 +- .../product-reviews-template/vite.config.mjs | 12 +++ .../web/components/App.jsx | 3 +- .../web/components/ReviewCard.jsx | 12 ++- .../web/components/Reviews.jsx | 63 +++++--------- .../web/components/Stars.jsx | 2 +- shopify/product-reviews-template/yarn.lock | 46 ++++++---- 16 files changed, 191 insertions(+), 143 deletions(-) create mode 100755 shopify/product-reviews-template/api/actions/fetchOrderData.js diff --git a/shopify/product-reviews-template/accessControl/permissions.gadget.ts b/shopify/product-reviews-template/accessControl/permissions.gadget.ts index e71ae3dc..c3d27bb1 100755 --- a/shopify/product-reviews-template/accessControl/permissions.gadget.ts +++ b/shopify/product-reviews-template/accessControl/permissions.gadget.ts @@ -102,12 +102,9 @@ export const permissions: GadgetPermissions = { create: true, }, }, - shopifyProduct: { - read: true, - }, - shopifyProductImage: { - read: true, - }, + }, + actions: { + fetchOrderData: true, }, }, }, diff --git a/shopify/product-reviews-template/api/actions/enqueueEmails.js b/shopify/product-reviews-template/api/actions/enqueueEmails.js index 7b2ad1d8..9c384875 100755 --- a/shopify/product-reviews-template/api/actions/enqueueEmails.js +++ b/shopify/product-reviews-template/api/actions/enqueueEmails.js @@ -8,26 +8,11 @@ export async function run({ params, logger, api, connections }) { const orders = allOrders.splice(0, 80); - for (const order of orders) { - const { - id, - lineItems, - customer: { email }, - } = order; - - const products = []; - const seen = {}; - - for (const { node } of lineItems.edges) { - const { productId } = node; - - if (seen[productId]) continue; - - seen[productId] = true; - products.push(productId); - } - - await api.enqueue(api.sendEmail, { id, products, email }, options); + for (const { + singleUseCode, + customer: { email }, + } of orders) { + await api.enqueue(api.sendEmail, { singleUseCode, email }, options); } if (allOrders.length) @@ -40,33 +25,9 @@ export const params = { items: { type: "object", properties: { - id: { + singleUseCode: { type: "string", }, - orderNumber: { - type: "number", - }, - lineItems: { - type: "object", - properties: { - edges: { - type: "array", - items: { - type: "object", - properties: { - node: { - type: "object", - properties: { - productId: { - type: "string", - }, - }, - }, - }, - }, - }, - }, - }, customer: { type: "object", properties: { diff --git a/shopify/product-reviews-template/api/actions/fetchOrderData.js b/shopify/product-reviews-template/api/actions/fetchOrderData.js new file mode 100755 index 00000000..dc50f5c4 --- /dev/null +++ b/shopify/product-reviews-template/api/actions/fetchOrderData.js @@ -0,0 +1,83 @@ +import { FetchOrderDataGlobalActionContext } from "gadget-server"; + +/** + * @param { FetchOrderDataGlobalActionContext } context + */ +export async function run({ params, logger, api, connections }) { + logger.info({ params }, "params"); + + const order = await api.shopifyOrder.maybeFindFirst({ + filter: { + singleUseCode: { + equals: params.code, + }, + }, + select: { + id: true, + orderNumber: true, + }, + }); + + if (order) { + logger.info({ order }, "order"); + + let lineItems = await api.shopifyOrderLineItem.findMany({ + filter: { + order: { + equals: order.id, + }, + }, + select: { + id: true, + product: { + id: true, + title: true, + images: { + edges: { + node: { + source: true, + }, + }, + }, + }, + }, + }); + + let allLineItems = lineItems; + + while (lineItems.hasNextPage) { + lineItems = await lineItems.nextPage(); + allLineItems = allLineItems.concat(lineItems); + } + + const seen = {}; + const products = []; + + for (const { + product: { id, title, images }, + } of allLineItems) { + if (!seen[id]) { + seen[id] = true; + products.push({ + id: id, + title: title, + image: images.edges[0].node.source, + }); + } + } + + await api.internal.shopifyOrder.update(order.id, { + singleUseCode: null, + }); + + return { orderId: order.id, orderNumber: order.orderNumber, products }; + } else { + throw new Error(`Single use code not found: ${params.code}`); + } +} + +export const params = { + code: { + type: "string", + }, +}; diff --git a/shopify/product-reviews-template/api/actions/sendEmail.js b/shopify/product-reviews-template/api/actions/sendEmail.js index 0ded04bf..4abdd3ae 100755 --- a/shopify/product-reviews-template/api/actions/sendEmail.js +++ b/shopify/product-reviews-template/api/actions/sendEmail.js @@ -14,18 +14,16 @@ export async function run({ emails, currentAppUrl, }) { - const { id, products, email, orderNumber } = params; + const { singleUseCode, email } = params; await emails.sendMail({ to: email, - subject: `Review your purchase${products.length > 1 ? "s" : ""}`, + subject: "Review your purchase", html: await render( {/* Add more text in here */} -
-
+ {!completed && ( + + + + + + )}
); diff --git a/shopify/product-reviews-template/web/components/Reviews.jsx b/shopify/product-reviews-template/web/components/Reviews.jsx index 59fa51fe..1e7003b9 100755 --- a/shopify/product-reviews-template/web/components/Reviews.jsx +++ b/shopify/product-reviews-template/web/components/Reviews.jsx @@ -42,7 +42,7 @@ export default () => { {data?.products?.map((product) => ( - + ))} From aa716d86ffdb96f1548ebd41df0f4b9b2ab276df Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Tue, 8 Oct 2024 11:16:01 -0400 Subject: [PATCH 21/43] Removing log statement --- .../api/models/review/actions/create.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/shopify/product-reviews-template/api/models/review/actions/create.js b/shopify/product-reviews-template/api/models/review/actions/create.js index fe70b935..c5500dff 100755 --- a/shopify/product-reviews-template/api/models/review/actions/create.js +++ b/shopify/product-reviews-template/api/models/review/actions/create.js @@ -11,8 +11,6 @@ import { export async function run({ params, record, logger, api, connections }) { applyParams(params, record); - logger.info({ params }, "PARAMS") - const order = await api.shopifyOrder.findOne(record.orderId, { select: { shopId: true, From d86ca5b2259930632a07a88dbe9149066be96310 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Thu, 10 Oct 2024 13:11:08 -0400 Subject: [PATCH 22/43] Saving before moving to a new branch --- .../blocks/productReviews.liquid | 18 +++++++++ .../product-reviews/blocks/star_rating.liquid | 21 ---------- .../web/components/ApprovalButton.jsx | 40 +++++++++++++++++++ .../web/components/index.js | 1 + .../web/routes/index.jsx | 29 ++------------ 5 files changed, 63 insertions(+), 46 deletions(-) create mode 100644 shopify/product-reviews-template/extensions/product-reviews/blocks/productReviews.liquid delete mode 100644 shopify/product-reviews-template/extensions/product-reviews/blocks/star_rating.liquid create mode 100644 shopify/product-reviews-template/web/components/ApprovalButton.jsx diff --git a/shopify/product-reviews-template/extensions/product-reviews/blocks/productReviews.liquid b/shopify/product-reviews-template/extensions/product-reviews/blocks/productReviews.liquid new file mode 100644 index 00000000..dc20afba --- /dev/null +++ b/shopify/product-reviews-template/extensions/product-reviews/blocks/productReviews.liquid @@ -0,0 +1,18 @@ +{% assign revews = pro %} + + {% render 'stars', rating: avg_rating %} + +{% if avg_rating >= 4 %} + {} +{% endif %} + +{% schema %} +{ + "name": "Reviews", + "target": "section", + "settings": [ + { "type": "product", "id": "product", "label": "product", "autofill": true } + ] +} +{% endschema %} + diff --git a/shopify/product-reviews-template/extensions/product-reviews/blocks/star_rating.liquid b/shopify/product-reviews-template/extensions/product-reviews/blocks/star_rating.liquid deleted file mode 100644 index a4a67619..00000000 --- a/shopify/product-reviews-template/extensions/product-reviews/blocks/star_rating.liquid +++ /dev/null @@ -1,21 +0,0 @@ -{% assign avg_rating = block.settings.product.metafields.demo.avg_rating.value | round %} - - {% render 'stars', rating: avg_rating %} - -{% if avg_rating >= 4 %} -
- - {{ 'ratings.home.recommendationText' | t }} -{% endif %} - -{% schema %} -{ - "name": "Star Rating", - "target": "section", - "settings": [ - { "type": "product", "id": "product", "label": "product", "autofill": true }, - { "type": "color", "id": "colour", "label": "Star Colour", "default": "#ff0000" } - ] -} -{% endschema %} - diff --git a/shopify/product-reviews-template/web/components/ApprovalButton.jsx b/shopify/product-reviews-template/web/components/ApprovalButton.jsx new file mode 100644 index 00000000..e7256e74 --- /dev/null +++ b/shopify/product-reviews-template/web/components/ApprovalButton.jsx @@ -0,0 +1,40 @@ +import { Button, Text } from "@shopify/polaris"; +import { api } from "../api"; +import { useAction } from "@gadgetinc/react"; +import { useEffect } from "react"; + +export default ({ record: { id, approved }, toast }) => { + const [{ data, fetching, error }, run] = useAction(api.review.update); + + useEffect(() => { + if (!fetching && data) { + console.log(data); + + toast.show( + data.approved ? "Review added to store" : "Review removed from store", + { + duration: 5000, + } + ); + } + }, [data, fetching]); + + useEffect(() => { + if (!fetching && error) + toast.show("Error submitting change", { + duration: 5000, + isError: true, + }); + }, [error, fetching]); + + return ( + + ); +}; diff --git a/shopify/product-reviews-template/web/components/index.js b/shopify/product-reviews-template/web/components/index.js index 8ed7e558..c24f4b9d 100644 --- a/shopify/product-reviews-template/web/components/index.js +++ b/shopify/product-reviews-template/web/components/index.js @@ -1,2 +1,3 @@ export { default as App } from "./App"; export { default as Stars } from "./Stars"; +export { default as ApprovalButton } from "./ApprovalButton"; diff --git a/shopify/product-reviews-template/web/routes/index.jsx b/shopify/product-reviews-template/web/routes/index.jsx index 6355d31a..ad8cc1cd 100755 --- a/shopify/product-reviews-template/web/routes/index.jsx +++ b/shopify/product-reviews-template/web/routes/index.jsx @@ -1,7 +1,7 @@ -import { AutoButton, AutoTable } from "@gadgetinc/react/auto/polaris"; +import { AutoTable } from "@gadgetinc/react/auto/polaris"; import { BlockStack, Layout, Page, Text, Tooltip } from "@shopify/polaris"; import { api } from "../api"; -import { Stars } from "../components"; +import { ApprovalButton, Stars } from "../components"; import { useAppBridge } from "@shopify/app-bridge-react"; import { useState } from "react"; @@ -16,6 +16,7 @@ export default function () { ( - - toast.show( - approved - ? "Review added to store" - : "Review removed from store", - { - duration: 5000, - } - ) - } - onError={() => - toast.show("Error submitting change", { - duration: 5000, - isError: true, - }) - } - > - {record.approved ? "Remove" : "Approve"} - + ), }, ]} From b32773d80b0f4c5a4d0749c34f1eb664b02bc24a Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Thu, 17 Oct 2024 10:58:36 -0400 Subject: [PATCH 23/43] Working on fixing the missing metaobjects from the frontend. The issue seems to still persist with Shopify only having the ids of the metaobjects as te metafield --- .../api/actions/createReviewMetaobject.js | 78 ++++++++++++ .../api/actions/createReviewsMetafield.js | 46 +++++++ .../api/actions/updateReviewsMetafield.js | 80 ++++++++++++ .../api/models/review/actions/create.js | 19 ++- .../api/models/review/actions/update.js | 118 +++--------------- .../api/models/shopifyOrder/schema.gadget.ts | 2 + .../models/shopifyProduct/actions/create.js | 25 +++- .../models/shopifyProduct/schema.gadget.ts | 12 ++ .../api/models/shopifyShop/actions/install.js | 2 +- .../blocks/productReviews.liquid | 18 +-- .../product-reviews/snippets/stars.liquid | 10 -- .../settings.gadget.ts | 2 +- 12 files changed, 290 insertions(+), 122 deletions(-) create mode 100755 shopify/product-reviews-template/api/actions/createReviewMetaobject.js create mode 100755 shopify/product-reviews-template/api/actions/createReviewsMetafield.js create mode 100755 shopify/product-reviews-template/api/actions/updateReviewsMetafield.js delete mode 100644 shopify/product-reviews-template/extensions/product-reviews/snippets/stars.liquid diff --git a/shopify/product-reviews-template/api/actions/createReviewMetaobject.js b/shopify/product-reviews-template/api/actions/createReviewMetaobject.js new file mode 100755 index 00000000..c9b566e3 --- /dev/null +++ b/shopify/product-reviews-template/api/actions/createReviewMetaobject.js @@ -0,0 +1,78 @@ +import { CreateReviewMetaobjectGlobalActionContext } from "gadget-server"; + +/** + * @param { CreateReviewMetaobjectGlobalActionContext } context + */ +export async function run({ params, logger, api, connections }) { + const { + shopId, + review: { id, rating, content, productId }, + } = params; + + const shopify = connections.shopify.forShop(shopId); + + // Create the metaobject + const metaobjectCreateResponse = await shopify.graphql( + `mutation ($metaobject: MetaobjectCreateInput!) { + metaobjectCreate(metaobject: $metaobject) { + metaobject { + id + } + userErrors { + message + } + } + }`, + { + metaobject: { + type: "review", + fields: [ + { + key: "anonymous", + // Change later if you desire to display names of the reviewer + value: "true", + }, + { + key: "rating", + value: JSON.stringify({ + value: rating, + scale_max: "5", + scale_min: "0", + }), + }, + { + key: "content", + value: content, + }, + { + key: "product", + value: `gid://shopify/Product/${productId}`, + }, + ], + }, + } + ); + + // Throw an error if Shopify returns an error + if (metaobjectCreateResponse?.metaobjectCreate?.userErrors?.length) + throw new Error( + metaobjectCreateResponse.metaobjectCreate.userErrors[0].message + ); + + await api.internal.review.update(id, { + metaobjectId: metaobjectCreateResponse.metaobjectCreate.metaobject.id, + }); +} + +export const params = { + shopId: { type: "string" }, + review: { + type: "object", + properties: { + id: { type: "string" }, + rating: { type: "number" }, + content: { type: "string" }, + productId: { type: "string" }, + }, + }, +}; diff --git a/shopify/product-reviews-template/api/actions/createReviewsMetafield.js b/shopify/product-reviews-template/api/actions/createReviewsMetafield.js new file mode 100755 index 00000000..34480286 --- /dev/null +++ b/shopify/product-reviews-template/api/actions/createReviewsMetafield.js @@ -0,0 +1,46 @@ +import { CreateReviewsMetafieldGlobalActionContext } from "gadget-server"; + +/** + * @param { CreateReviewsMetafieldGlobalActionContext } context + */ +export async function run({ params, logger, api, connections }) { + const { shopId, productId } = params; + + const shopify = await connections.shopify.forShopId(shopId); + + const metafieldsSetResponse = await shopify.graphql( + `mutation ($metafields: [MetafieldsSetInput!]!) { + metafieldsSet(metafields: $metafields) { + metafields { + id + } + userErrors { + message + } + } + }`, + { + metafields: [ + { + key: "reviewMetaobjects", + namespace: "productReviews", + ownerId: `gid://shopify/Product/${productId}`, + type: "list.metaobject_reference", + value: "[]", + }, + ], + } + ); + + if (metafieldsSetResponse?.metafieldsSet?.userErrors?.length) + throw new Error(metafieldsSetResponse.metafieldsSet.userErrors[0].message); +} + +export const params = { + shopId: { + type: "string", + }, + productId: { + type: "string", + }, +}; diff --git a/shopify/product-reviews-template/api/actions/updateReviewsMetafield.js b/shopify/product-reviews-template/api/actions/updateReviewsMetafield.js new file mode 100755 index 00000000..ae0c6894 --- /dev/null +++ b/shopify/product-reviews-template/api/actions/updateReviewsMetafield.js @@ -0,0 +1,80 @@ +import { UpdateReviewsMetafieldGlobalActionContext } from "gadget-server"; + +/** + * @param { UpdateReviewsMetafieldGlobalActionContext } context + */ +export async function run({ params, logger, api, connections }) { + const { shopId, productId, metaobjectId, approved } = params; + + let value; + + const shopify = await connections.shopify.forShopId(shopId); + + // Build the metafield value + + const product = await api.shopifyProduct.maybeFindOne(productId, { + select: { + reviewsMetafield: true, + }, + }); + + if (!product) throw new Error("Product not found"); + + if (approved) { + product.reviewsMetafield.push(metaobjectId); + + value = JSON.stringify(product.reviewsMetafield); + } else { + const index = product.reviewsMetafield.indexOf(metaobjectId); + + if (index === -1) { + value = JSON.stringify(product.reviewsMetafield.splice(index, 1)); + } + } + + if (!value) return; + + logger.info({ value }, "VALUE"); + + const metafieldsSetResponse = await shopify.graphql( + `mutation ($metafields: [MetafieldsSetInput!]!) { + metafieldsSet(metafields: $metafields) { + metafields { + id + } + userErrors { + message + } + } + }`, + { + metafields: [ + { + key: "reviewMetaobjects", + namespace: "productReviews", + ownerId: `gid://shopify/Product/${productId}`, + type: "list.metaobject_reference", + value, + }, + ], + } + ); + + if (metafieldsSetResponse?.metafieldsSet?.userErrors?.length) + throw new Error(metafieldsSetResponse.metafieldsSet.userErrors[0].message); +} + +export const params = { + shopId: { + type: "string", + }, + productId: { + type: "string", + }, + metaobjectId: { + type: "string", + }, + approved: { + type: "boolean", + }, +}; diff --git a/shopify/product-reviews-template/api/models/review/actions/create.js b/shopify/product-reviews-template/api/models/review/actions/create.js index c5500dff..c5a202db 100755 --- a/shopify/product-reviews-template/api/models/review/actions/create.js +++ b/shopify/product-reviews-template/api/models/review/actions/create.js @@ -33,7 +33,24 @@ export async function run({ params, record, logger, api, connections }) { * @param { CreateReviewActionContext } context */ export async function onSuccess({ params, record, logger, api, connections }) { - // Your logic goes here + await api.enqueue( + api.createReviewMetaobject, + { + shopId: record.shopId, + review: { + id: record.id, + rating: record.rating, + content: record.content, + productId: record.productId, + }, + }, + { + queue: { + name: `queue-shop:${record.shopId}`, + maxConcurrency: 4, + }, + } + ); } /** @type { ActionOptions } */ diff --git a/shopify/product-reviews-template/api/models/review/actions/update.js b/shopify/product-reviews-template/api/models/review/actions/update.js index 7ff4555b..daabb943 100755 --- a/shopify/product-reviews-template/api/models/review/actions/update.js +++ b/shopify/product-reviews-template/api/models/review/actions/update.js @@ -10,103 +10,6 @@ import { */ export async function run({ params, record, logger, api, connections }) { applyParams(params, record); - - const { changed, current: approved } = record.changes("approved"); - - if (changed) { - const shopify = connections.shopify.current; - - if (approved && !record.metaobjectId) { - const customer = await api.shopifyCustomer.maybeFindOne( - record.customerId, - { - select: { - firstName: true, - }, - } - ); - - // Create the metaobject - const metaobjectCreateResponse = await shopify.graphql( - `mutation ($metaobject: MetaobjectCreateInput!) { - metaobjectCreate(metaobject: $metaobject) { - metaobject { - id - } - userErrors { - message - } - } - }`, - { - metaobject: { - type: "review", - fields: [ - { - key: "anonymous", - value: - record.anonymous == true - ? record.anonymous.toString() - : customer?.firstName - ? "true" - : "false", - }, - { - key: "rating", - value: JSON.stringify({ - value: record.rating, - scale_max: "5", - scale_min: "0", - }), - }, - { - key: "content", - value: record.content, - }, - { - key: "product", - value: `gid://shopify/Product/${record.productId}`, - }, - ], - }, - } - ); - - // Throw an error if Shopify returns an error - if (metaobjectCreateResponse?.metaobjectCreate?.userErrors?.length) - throw new Error( - metaobjectCreateResponse.metaobjectCreate.userErrors[0].message - ); - - // Set the metaobject id on the record - record.metaobjectId = - metaobjectCreateResponse.metaobjectCreate.metaobject.id; - } else if (!approved && record.metaobjectId) { - // Delete the metaobject - const metaobjectDeleteResponse = await shopify.graphql( - `mutation ($id: ID!) { - metaobjectDelete(id: $id) { - deletedId - userErrors { - message - } - } - }`, - { - id: record.metaobjectId, - } - ); - - // Throw an error if Shopify returns an error - if (metaobjectDeleteResponse?.metaobjectDelete?.userErrors?.length) - throw new Error( - metaobjectDeleteResponse.metaobjectDelete.userErrors[0].message - ); - - record.metaobjectId = null; - } - } - await save(record); } @@ -114,7 +17,26 @@ export async function run({ params, record, logger, api, connections }) { * @param { UpdateReviewActionContext } context */ export async function onSuccess({ params, record, logger, api, connections }) { - // Your logic goes here + const { changed, current: approved } = record.changes("approved"); + + if (changed) { + logger.info( + { + shopId: record.shopId, + productId: record.productId, + metaobjectId: record.metaobjectId, + approved, + }, + "HERE" + ); + + await api.enqueue(api.updateReviewsMetafield, { + shopId: record.shopId, + productId: record.productId, + metaobjectId: record.metaobjectId, + approved, + }); + } } /** @type { ActionOptions } */ diff --git a/shopify/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts b/shopify/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts index b56ea768..c813fb6e 100755 --- a/shopify/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts +++ b/shopify/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts @@ -82,6 +82,7 @@ export const schema: GadgetModel = { "sourceIdentifier", "sourceName", "sourceUrl", + "statusPageUrl", "subtotalPrice", "subtotalPriceSet", "tags", @@ -90,6 +91,7 @@ export const schema: GadgetModel = { "taxesIncluded", "test", "token", + "totalCashRoundingAdjustment", "totalDiscounts", "totalDiscountsSet", "totalLineItemsPrice", diff --git a/shopify/product-reviews-template/api/models/shopifyProduct/actions/create.js b/shopify/product-reviews-template/api/models/shopifyProduct/actions/create.js index 92ac9e7b..4ffe4d24 100755 --- a/shopify/product-reviews-template/api/models/shopifyProduct/actions/create.js +++ b/shopify/product-reviews-template/api/models/shopifyProduct/actions/create.js @@ -1,4 +1,9 @@ -import { applyParams, save, ActionOptions, CreateShopifyProductActionContext } from "gadget-server"; +import { + applyParams, + save, + ActionOptions, + CreateShopifyProductActionContext, +} from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; /** @@ -8,14 +13,26 @@ export async function run({ params, record, logger, api, connections }) { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); -}; +} /** * @param { CreateShopifyProductActionContext } context */ export async function onSuccess({ params, record, logger, api, connections }) { - // Your logic goes here -}; + await api.enqueue( + api.createReviewsMetafield, + { + shopId: record.shopId, + productId: record.id, + }, + { + queue: { + name: `queue-shop:${record.shopId}`, + maxConcurrency: 4, + }, + } + ); +} /** @type { ActionOptions } */ export const options = { actionType: "create" }; diff --git a/shopify/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts b/shopify/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts index e24f83ad..7be12e68 100755 --- a/shopify/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts +++ b/shopify/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts @@ -12,6 +12,18 @@ export const schema: GadgetModel = { children: { model: "review", belongsToField: "product" }, storageKey: "9q0TXpTv2hmS", }, + reviewsMetafield: { + type: "json", + shopifyMetafield: { + privateMetafield: false, + namespace: "productReviews", + key: "reviewMetaobjects", + metafieldType: "json", + allowMultipleEntries: false, + }, + default: [], + storageKey: "zn2QVWbMprWt", + }, }, shopify: { fields: [ diff --git a/shopify/product-reviews-template/api/models/shopifyShop/actions/install.js b/shopify/product-reviews-template/api/models/shopifyShop/actions/install.js index 7fc224da..fd039306 100755 --- a/shopify/product-reviews-template/api/models/shopifyShop/actions/install.js +++ b/shopify/product-reviews-template/api/models/shopifyShop/actions/install.js @@ -94,7 +94,7 @@ export async function run({ params, record, logger, api, connections }) { name: "Reviews", namespace: "productReviews", key: "reviewMetaobjects", - description: "A list of metaobjects assoicated to this product", + description: "A list of metaobjects associated to this product", type: "list.metaobject_reference", ownerType: "PRODUCT", validations: [ diff --git a/shopify/product-reviews-template/extensions/product-reviews/blocks/productReviews.liquid b/shopify/product-reviews-template/extensions/product-reviews/blocks/productReviews.liquid index dc20afba..29454348 100644 --- a/shopify/product-reviews-template/extensions/product-reviews/blocks/productReviews.liquid +++ b/shopify/product-reviews-template/extensions/product-reviews/blocks/productReviews.liquid @@ -1,10 +1,14 @@ -{% assign revews = pro %} - - {% render 'stars', rating: avg_rating %} - -{% if avg_rating >= 4 %} - {} -{% endif %} +{% assign reviews = product.metafields.productReviews.reviewMetaobjects.value | json %} + + + +
out
+{% for review in reviews %} +
+ Hello + {{review | json}} +
+{% endfor %} {% schema %} { diff --git a/shopify/product-reviews-template/extensions/product-reviews/snippets/stars.liquid b/shopify/product-reviews-template/extensions/product-reviews/snippets/stars.liquid deleted file mode 100644 index e98d5676..00000000 --- a/shopify/product-reviews-template/extensions/product-reviews/snippets/stars.liquid +++ /dev/null @@ -1,10 +0,0 @@ -{{ 'ratings.stars.label' | t }}: - -{%- for i in (1..rating) -%} - ★ -{%- endfor -%} -{%- assign blank_stars = 5 | minus: rating -%} -{%- for i in (1..blank_stars) -%} - ☆ -{%- endfor -%} - diff --git a/shopify/product-reviews-template/settings.gadget.ts b/shopify/product-reviews-template/settings.gadget.ts index 94f3b56d..f5934496 100755 --- a/shopify/product-reviews-template/settings.gadget.ts +++ b/shopify/product-reviews-template/settings.gadget.ts @@ -6,7 +6,7 @@ export const settings: GadgetSettings = { plugins: { connections: { shopify: { - apiVersion: "2024-07", + apiVersion: "2024-10", enabledModels: [ "shopifyCustomer", "shopifyOrder", From b4b349c5742cf31bb4baf57c51a79210f64d8aa7 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Fri, 18 Oct 2024 11:29:43 -0400 Subject: [PATCH 24/43] Updating the gadgetinc/react version and framework version --- .../api/actions/fetchOrderData.js | 2 +- .../product-reviews/assets/reviews.css | 32 +++++++++++ .../product-reviews/assets/thumbs-up.png | Bin 18051 -> 0 bytes .../blocks/productReviews.liquid | 36 ++++++------ .../snippets/star-rating.liquid | 52 ++++++++++++++++++ .../settings.gadget.ts | 2 +- 6 files changed, 105 insertions(+), 19 deletions(-) create mode 100644 shopify/product-reviews-template/extensions/product-reviews/assets/reviews.css delete mode 100644 shopify/product-reviews-template/extensions/product-reviews/assets/thumbs-up.png create mode 100644 shopify/product-reviews-template/extensions/product-reviews/snippets/star-rating.liquid diff --git a/shopify/product-reviews-template/api/actions/fetchOrderData.js b/shopify/product-reviews-template/api/actions/fetchOrderData.js index dc50f5c4..72bda81b 100755 --- a/shopify/product-reviews-template/api/actions/fetchOrderData.js +++ b/shopify/product-reviews-template/api/actions/fetchOrderData.js @@ -23,7 +23,7 @@ export async function run({ params, logger, api, connections }) { let lineItems = await api.shopifyOrderLineItem.findMany({ filter: { - order: { + orderId: { equals: order.id, }, }, diff --git a/shopify/product-reviews-template/extensions/product-reviews/assets/reviews.css b/shopify/product-reviews-template/extensions/product-reviews/assets/reviews.css new file mode 100644 index 00000000..9931d1ab --- /dev/null +++ b/shopify/product-reviews-template/extensions/product-reviews/assets/reviews.css @@ -0,0 +1,32 @@ +div#reviews { + display: flex; + flex-direction: column; + justify-content: space-around; + align-items: center; + width: 100%; +} + +div.reviewCard { + border-top: lightgrey solid 1px; + padding: 2rem 2rem; + display: flex; + flex-direction: row; + justify-content: space-around; + align-items: center; +} + +div.reviewStars { + display: flex; + align-items: start; +} + +div.reviewStars > svg { + height: 15px; + width: 15px; +} + +div.vertical-divider { + border-left: 1px solid #ccc; + height: 100%; + margin: 0 10px; +} diff --git a/shopify/product-reviews-template/extensions/product-reviews/assets/thumbs-up.png b/shopify/product-reviews-template/extensions/product-reviews/assets/thumbs-up.png deleted file mode 100644 index 6a2eb6ead214b514fd01f36ed12aef7ea12c53e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18051 zcmXtf1ymbB*ESL$L4!LaXmKqLgvzqz@YZX zYtxf?e1PYprlpLxi4CO2#d{SWGx=DBYo(#8gz@m7qo}hy9Rou-Mome51e9g? zC*xw~VM6~y&66h|BVWr$U@Bvh;$SLVge><)v)#vuWZP&?C&n$XX=`!}5K(~mAtg`N z5V0)vaYe&Ui5lh}3VJrAdS~}rvdjKmhri8Qs;b)v5HH70J9M7D)cDnT*=hd@QMCJN z>7j3ooGxbX_Ke`w-+TAv4^I9w_mnkZx93&fAA!b&#&m9UA$F~{Czl`v%C9OjYQvQD zH-7hCj-$D9ucia~mz1@--VdRe`a5;o;V0B(Q9>AOF*Gt!u19IZC-o#A4Q$^d1&Eb-_UjsoxYM= zVEOlNgc;dRmB%o3n;AoYLjnO9!BrpofWu^#UPi{wv8N zwRcqZ-^A5jPVzsgj{8x2GhtGH86O5F`&70XgEFluLl13;@9k)c9rG9NpQ(psAEO=i zZlhPDF)dp?i-w}_&u-B9C+`7B};+@eh0u?9;tF&Qc782bv zw<69l?IQ(|6xgXI^_{;L!LI8l!QY~NR&PTXw7Z#|Vt3%PsYXxJJ=9J;F4xPE%oCDy z+&B6#-6$%B88vv1YQt{FKd#E9PMxQq?l*rm6?>?qQ;~bhZ1gtpmOw(w4_J3$KOFi5 zSuCHG=DcbXROt(|<+NSsR7JkxmtB{F>Fz(dAqV57{`q!!Z_4xge7hU@N@npbaQ3SN zgMgpV09J37$2y3dk^?+Q>ji_s^kHN$*MvwI+rPCPyVc~tp{T>Linu~|Ho%v}61gk3 z;I5--=Vu*Tz!M94;TH^;#rnk-#cqt({LjH;$xlC7l9{SqS=p~=eUOS_=k60P{3gp0 ze3`tfd)&vbyIL7)%Hkg7n{-mg3wRFyx3K1?%owx5I59fbgMvrH9UJWv-f^_G; zcI~r_M(zdCV<}QTb2k*Sii+h64PMq;UHDOTz&>%iT_vbViEwS${Y^x2)exhzLc@eM zlETawSkR}7VrALyP2H5;r%mU!Scp@LomlAJ=gq7IPV_LbO$l%UzC@QuuhbvS{UZ;% z{(DBZ%1Ocy`Iaumk`Pm%5x|h1AD)aP=L4w*aK+NF7#{ClkQyaUe%lLEOZ9PCP5@Jo z$M3%O?)}9xpQpo}sup25-({ae{$id^fJP}EtV`~m7KNIuTGO(239kKg9xrfaQJ0S3 ztfxSCw`csXG3K1>a!`;{6JsrQakK(>9NCj@D-iIu9y1+S5xZ?z2k*7mAqJ_Lz~@sA zS-AoX@Wr+~V7k0da#M%&!DMewc~@-h zuP|6DqTkiLw%yYK#na3rB+M2o4cqOy*rH(j^8#5!qf3F8EpD;xaq;Man1!wBKLIPo z8@wJuSmkTc9N=1BE{P>OIPUc>ZCb@3t>fr85b>i>&co$uaExoVAdCa>CA>spI9P#f z@AmMwMF@43B`R$l0Z4nU$yA{aZxmHU^Kw0LYHeYKpsUorzp%IIRYONR_s|Abe+6-Q z1$!8ekfArg<<>e9Wbw4QE3q3T(J_Hf38le+4OrCA)pr`2uXARO-ck%NA;5-yhBw%} z0&@Ar4mIEfk7o2S1eerx+}(QgnPhJNV%gDk2qonn3+ zsG#o-kYrmeCt=!4&}S_;8t|HpV0Fnza_B5Z388y$dAhSKL#(qbIP7(kU45`)99pfEAXI!R(z|N z#xsU~*t>Yivf>xe7epn7-);Ky>zlq#9(WJt3*c;GgMeAw)u#vcbE3KUAu!@=qI!r2 z<(EhN;fvt>R-CmpepXDwuRfL$UZ#iDwwvXH)i-B}mA3nE`|y6HwUG^wL7Q>2!i}F6 z8ph%Kt(ay2i?qdhCnGhy%vPhP9taOhh-L1&8KUTWwpfL)pFq!AOl)^*Zmw9xYo#AdI51@H5XyE<9Gs7XvVhl?mzYAR>?h<>4UJLZ%Be}mY7 zcOf4BYFL=wo-m*EDHBEcZy5?kjbE|*?<3dCsLOsL%XLg z5Ul(41TR+;KVGlq>^2_FEaNg8Ce0*QkefaURh?D(@6dZrv5`#-i(xQii?Ljh_b@tZ zWoTbVhL>t`Q7@6)rnq+h+z;;QRp5i{KO10txQL`7mBa`Bd$KDq%-Ek>`iKc{E6MO?z`@v*f2j zVOVROKkpX~(aVl`56W}YyCiza-K)FP)Ejw*oPZ3*jC%~8_{SK1jyY)Wp)5*`z8I~O zl%+yMECTTc=EHQm9fk&MLe2mUH~G)`etTh)9?egC!E_0q#7FW9bXm;3$7V~{=r2wz z81mjALnf1Z)OyOp_A#gPceWb#9;Cg5Z&%87cj#d38=fn$JS}#ab8987;ydreJ8Ik*NFuB zLrEm?f2WNwdQPFU$KB76>0F>JxAX$HOEI4ZIVmETk|f>gHZZ#W>NIX1$Fd#A&hq*t{z) z3~g#O2Z(ado`u2x=>TI{rv1x*Nu>P$STJWZT1Fbzx!lC4MVaut+cr%=95l>*wZtlk zU4J}3Eq8OPYD`)idpve}U>YpiPFy}DPtm}NZWvj&GwM#KtcS~c+0{yRU?V0w%$Vqk^)iANYb zoIedvw8w#a+)$x#JRLmgdpXWHlL~sF0gMMJ`_^V3U6%}E z3zgk_&k@wuCshW==_tUzy?LwL1F|c4t%Oz3&t1R?l?la9*;MBKd(Kr!GR!ZN_g~wJ zK+Tu&EJ>QbX#N)1y!QH|(cJp##lj1=KfeuF78#@aAJTYEM!83_ ze|MwbOrxq=DGEaTlCET!6435R%?$6n``9{jkWYc+0~#gnI*btg@c*rt{QZA{gP%A} zth`gUW}X`OIV)*zeVmsgnRKb?qG57boy{_=H|-&lwv81-9T`!ObVma&zkJe6u!Iu)<>j1yDf zxpP}|mM-D6;9>k;g-h?xXrzXjS2mT*`eKSWp&mFv=J;{cg*4pVw;9Bt$EsD%LJ1Vo z4zm2;8!h9`L|^l?_V91?VQv*PPj_KdiPzA*>8LERl=g^a)J8w|9SLVS=}{)@6Y3>G zSmD4G1BM|iR#8d=w>#0h&)G4%`O@4^XG@nlOK)=R4t~Z(2e(aqc}kZwRy_Wx1HfQk zwxZj_xzRU_@(O0o!uE(gx`TjTunRbS%N2z-2}$GLv9_kh#tM+C2|(jaTb#@`i{rn(pQ*>gk8%8Uuuo^*BM`i*Vw>5l))xFc%P-rK(~0(LQO=&|AT7p$P)>0OG(Z3^S1-aip;(dpao z`76`HCDpn-&s(%V9h16n(3}8U6kb*3_lx#lN1q5`gTj}(TRP( z7Ntrz+gnXg!NdHu^BE?E)ra&CCQ%MI1hz}lA$Wrl*!MC*j!n4yZeJy@`DjEe9;)v1|5ou?O8sbAKKm|GANl1S&e*Hw%548ZI$`6dE$s$c58m3C4)eP5z zj1nVTvE}SVV2@TPB;6y{pucsccI)+!g4a5t&)R?#*W+P<{pXWTi zJ#I4_TL-SNz|k2g26gTHA(J9W!r$Gx_P}TRw%NN6!MC#>WAFbhf|n4I@zHDykIGahF)iw+@6Kw#n_oHY4(SeaszNN)^JBK)d*5FT~q-G4XM=jZ(F zP-2dfoFl^_#sx-~Ho&29gaIAKQTQkz^Hzb(Luj8BMbb>J0fgfbH~EYhoM??l27e}- zv{O{N@#L+Qjxo}WCt2$?$Cxd^-g!Nmxd>`5%%4r`}M#e@vEfMw?PCv@v zoZ^jmllUOh`)2E;LI@h|$>c>|*@w@?m(E1(R-f}l;nW$V@B-)+sMl2_5Fi?|YU*>` zr2!;n8~)kOXfbbpN_4IHrltlY+}~j1?yr>jz64vLC!uurov~=5;l|#G+j(stgIwz5j6Lgoe%F8Jj!OT0l-@(YKAtV z>q zU8hHAXa+I=K(OW;fz&fcbiH&gW2^FF=k6q{0xY0^<4LjWX zI*Ojd7vp7sG3@=6b`DjadT2*NKnm|Uy)fsvb>iL)iY3kpP0*Qf(DI4=%S-+Q5G#sb zhPFqDlIrk(Im1G-7GZ(E{Sh3f0K}}zqulkAHyQ?|)c9@a1QFQ!1)Zi~qGV+(%%}jC zyWh@G9M5k@e_za#B+q}2yH)3~)$LFBYQ(XIvS;r0yH-2uEZe=N7Jv!%03zS_ZR$ux zQ{fb%)cx0NW(5az-7;oEE$Qu)a~mH-o;T|~%Z&{Z#ajNkba(K=X{AU|uD?cWMZzRZ zTE;;$`i?Q3xc02wBuenZ80QO;VDYqZ2{}OKgQs(RlFzzHqt>XH$DpOMvws1@Te{6z z4wpsWmo=O+(@O#C-nG~wDBkMz;uQA}d{s0qZg1dLS#tHkL($eYM^bJQEH=zA6cX}- zd`{lqk1@Fklxl?*(#V>y%z}rsBMo(LXD4u7)`4Jk%#lf6C2CS?a0z4DkJJ?DStTqs z+O>4zw6pYtQUf>aIo|O30e`X1?wMKs%+>;^+5USYuBHlavKE|n6MLI*BDy{LBdha8 z;Z*KllcPuz%Y)a{qi0&r{SJ6RAVa3(mGhma0msBITT*de8Y*(SamC;iPXq|E zOTJ3o!g{E{w5DTXB!(TOMQJdfue38LMK9t#9V`ZxhqB>{)%EN&1^4lT(sXiAAI>5f zoo_;`>#(sty&N7iMXrZ%?6a7DiLnZnP+5o^q}q2HODX22k(Hw|AJ1?gw??M-T+q-D zF}R)n3Ms967i2cyI-NInW7)d~dhbCY6Zba^kh|r83$A+Y^>gwd0?e9d8 z96l(ds*-VkoD-VZ^St&LADGFjLsZK zZv+{W>ifvZAFa(}esjCRTM4f)d8-ROBF3{BJv3kl7MI+k;zzu8I?ib~mAwqRljiD9 z6XuznozO6O-+tY$|8~XgY_*O%ulRdmemISd(4_iNSF=-l`KQE)Nxcx>)OZ>eW|&Q_ zx24n3)R(<$lS3#V8*CFKOf1!dqjE>|98b89oGc_;!L<&c|k*yl90M0Erh@G8|o~q{rd;T zQs-Ytuni1#Fam7Wl>6xt&+vYrovnwQ?Zu#>u4F6(Ew|$2r%(L(JFg#e_2Nf4UWHxi z4a8+Kivbv1-D**oW+e?;s%51&78du*7*j*_bbx=&rrHPk^0J$%Jq^EkIFae9#%M-M z#H`5+ug=p;lL)C-n6>{QU&g#(s@LO?_65vi%>G?Z(&^SNejA1h9gZ&gKn>hhdbN9+ zyk3eN%?aYgfQm5_uKnS@_7Rg`2&q~&Hl&yqc==>j8AVtd=V57auN5yqg=m87vA9Ge zj65S?5|{rfd=kX<3yaj%le^kx0OVU_ije_QVj!LT@a_wK~>Qm6A2&{)b*~1~GkNI#iAZ=3D9H~%m&Yde_)S8%h zar5zjV(0YfAGIXO(+E4L1Oye%b6K(9Xiv5z9rC!t~<2QGX zBo{gNAukjfu=HT5G2 zu?m5|O6gxAA0br}1tLoXSc;~7L3ZDsMOeGOe{(~jsY zHoKvi5?ZJ@TB5%QW_kS{u^9bZz8EwnSod@VV^KRT@vg6T2_4K^>KJdS*hp6 zvbK>K9Ls5@nv>y7wAVj1l!4mW_LfcCnlj$P98BPZPwh(ivNnp`Ddv)hAH>XTENy;Q zI8)2c7zFG4HLMV!t~g0Y&A|Ql<=@kqk#M#z_QhMY1A?wO&BW>8?O^O=d{oowv; zS)AuN=d;-ub7ey&Y>W&9!TxZU*-zDBdim^E24zj24AN><&ospqbzmp~uQ#OmSHI%p zgJ~I4T6c}0?`FEp_IZ|~mwppb*C#z%)J@2VP&ivL=##$zcq&BLxc?daoubnL`K zhm?krxdY89Dy#MAC}*_?QiG$&tPdn3-=zmwj;IX)xXNNoA_-or<*bqJGUfYYIob`` zuQcdZ$4(3_fAR0Ze-T{%wEM%L{@)$7rarvr3}jf@p=_Di!O>C#y8vk%Js5FP^o<&& zE;BwGs;tzdgk_f&`tq9+_P`MQE=N#VL*#tAnFkTh{M(jW(c(HXl?8=J;NK(|ram2) z+w>eqk#TH&Et~=V0_&~nAuwW@t#UblnDRJXC(pQ&TY5iRmMqyEy=UjLXK{OqQ73PD z{Ve>~YDmDd;pklKFudgyBc4UDAUUMwxYO>859EHJC*4sQba3>upsBwd?=3PV$(F12 za3rqjuzbSl`H?JCsmCot@hR{8bR^|NyMrPMhW3iJ3-3Jn?p@$(crovgmy`ZkbIYi|<6WDZt@h!m(^qC! z3}C7YNbOGd*w)nHCw9Q+l5f;t%&_M^fNv6}ti2ZvyYKQzq!;7yQqu2QRDp1@ObUA# z_iA6AX(<723Jo9_IgGmnK=*nF5TVJ@RIvoUqpQUFL!Xu$(9E%faZUG50!>HR5N0$r z5EL$`5mx~-1)Bi*0C;uC6$tAR9&EK;UJ6#S79{^tF{xh?G3KEAE`?-5VQR|XOhIf% z4_Un4M=bhLTLpJ*Ll z{Z`g8U#M`TbamwM9&hYV|0l1dJ@UP-kE)D*i}{T4k@Wo^r20Ua9xljhSuU25Ca(@L z%0f#c>;VYL@M_>Nx%N&;xF)}~M>>?gk6O17W#u8b;=8scbUf?^I9_Q&3@|WxDmalR zZYIWRjd~gviGD0K@zsLeu|u*+RqzOI!zw2>>f1ho)}`BWOJd;4nn7Wwy{DXgYq$y) zS#D@f9+{j-{=VoiCQO1V^GC1rNtdSrfo9wny<{C_+gwhg?v~D zB3RcG6;CsP`81kX9xguaGwW!~&zwk8NUuHpHgZH$<_xCc3PG%WgsEk8j|31!@awK{ zXZ6x9i70i77mJQ2(O%$Gwn~D@)_Tqt*`Kle-xMH?lisDEmG42ueFyWc2_7mS&h}!x zBw~vwBxHW9YWYq~O#pzz;}t6+OjFA2M}KniP9(XY!&t!IrNXouIFe|q70Id)A(#Oly!4{!5s5?U(^5| zneR8*imqQVfqaZc5d!13itO~>_FQCE7*!&ZDJ$DN86DJ=8>HS@y`1v{XI+^5TwMx1)F)C1VjWXNDNr)xPGiJ+m@g=#mnatIG*k^_cCu@-lioIZwvMu@Cf_>g0|GYoM=*yd6j+G;axX_$*Arnb9Y}vWI z_3yt5u><-U@Sd_tqW@|32|ck1S0%wp%fF@l-{-o-F_%pw=4R!G=XTd@j6Oe*F0}_eEfM<>_xe!3<5(b8T;*@BPO`Gp4>_4#~1#jpyHgD zpGkURv$uDv&}!KIj`O#atWZ;fB#A)YmWo#vM#tPg&?jc26$m7oq5W${d})GL;3h{2 zy5NU94`zD2R!#g`0>?qD?2iPJw|ESx;X2n%`0X`xDkv%iyMa3fOlIjXYVybzn%QqT zE!hZ5qfye*sp#Zy5n`;;{Dw83LMSUKM$mje6-c!PPt~1k8t0{^UcP1!G_GIP4(u75 z%|m?_6sC=6ZEVj2bX?&+^MsI)g*vlYy!Uh}H7Z|NskpJlLq`^7Ky@=PgK8YdyI;M6nxxk!^wz|!0dx0k_1 zbMtME?00R(O0NF~h_KVKE|{y_!KaNGPo+myd-%#)uC;HE1Hs4O4CH5&0Lxu8_xZx8 z20&T9#VP?b%Tj{KKdWC7l(7JV6&xxo;finq?T|TAzxU$kRMz~n_^edF@>Z{ZvThE6 z1}z7RO^$7rnE5kkkOse_>6`EOyh`NtUv5?QvnXWclrNKxB#1BWwO$DtKgf6xE`$w- zERfaz0{!>r^7(E@tHVu?nZ8NLj7Y2fRxG{lT6$4o5_!?{1T&D~OP~;F_G^^7rbT1r zyKoQyiH#8Eso)&Il{~fde}i7FGuWRz!A&)<8OO{u%yZH-U6lJQqz25KMx*Udlz_kZ zr_dYGPq-G0U7r0Y2<&j2U^`D}WR2&9lZ`_FYCvIG%*m+SLb**SIV~s0C8qJT;!>V` z3BFqU74O^QuYVI#N@>=D9Lo;-X_vThwg#O8=qIaRm#RdCPthapK^u|9?{z=2m!0cn z{r)t9b6d4}7JTH$&G&0iz0c1PyKw5EutR_?&c&@QdmozG$~oL}CAv^+V=DTraf)P@ z`aGVEbb|H2-9U*3%xeXI%|?=o=tw<@9m}-E_0rzRrO8bYmZM^(C(Wnp0Zjif{)ug| zD3^va;(*Pqs+5!7DtoHVilaw??+7JulvhG;&^*Z=s<4)3q_SwNPRw?{jD^^1vWZr; zmK8FWa%7gJSGf*;_b_c!j^^ZZ{kH#=EOegM#LvD8LMgU4Q(P-?iyO!7` zbhs%`R4_oKZKzIHnS$A$^OCdCkKnI`wCUrQ7*T_Hs2r;x<95F(YI`#sYy>lAyOr z9Cv}_qb9Awa#e0W&`U=Zi(7{74-RLqT;%n7$)anC7Olv$CFis{0gc5p&kg)ya7~5u zzWm!yaTW&YW#VMud?Fo>)3Rh=d%3`e=SvK;TI+J5568ch?I)V{!P(OjaM>sq+KxCO z&@loyZ+p#-H*9K=O(U$+Cq|>>!YDRs z%_r8)i&w&%OYDYWO8cFpb?PMfi29{Z7L{~n!goy{p3f8mdp`)*TwY>l4pC#7##e?@>PzHJgw${$UMmVWqF$Du3h$j%`t# z#)+fk>p#ek;+ou9$?yd-HoR#gEkdm*$ZH$wu_u}eJiNr%N}^XmtZ-)nvQ~v19TohN zy6sdw_EkkzjlOcuUuzuDMZ>eTj3q|}+GjoaUd9XBpO56tdol@y*%IEgW}-MqXhZ{-jvenJ7j^ zdR|F>MYTyJ1A4wSE1!zFqCzX;`wKyC#n0bs>qn@euSp8AGl;f?bY|6hvsg>ifJVTl zxFA-Mv)4SuVn^A`H=zqVA)4aznhSAaK^|&X5ZTKk_z$j_O8oZ`!~R3XsX)q~Q?z&^ zH+{Bs$r92uj(6^amXMkc1MzEbPJ`gqD2ARO!5PfLh>3yafD5wwAm*tD=D;A+b0#F@ z)uSz^zhf2lFp)93WmV)fkP4+Yszc0?KBd-WipNALtmIB}X=2ZkV~xTIwV&vvY^eo( z0ama<;sv9^{b~>tWnX*LT!*DozHcI*)$4;JOi@@iZyb<2$%^mjrt9|%+h_j~uB|@J zs_1b|Z!WyLSZeBb>~xB0Ijdk?`n`xP+tG3^IQRdiT-sx(q4QPXu;IzGq4EcSYb z0wCFt>N5tU5cc8=fNo7JtCz@iQm6_6TaIYDA{mUO@Uw-PF=uoOtOefNbml;oVm zi(s|vFzYs{MiPT7p2f5=9473gu{|U6-dehHGh*)RO+7S7c4gBu?4(Q<`$w6I3M?^J ztyJ#?_){Mv)yv&|K|#z&a&VA#S36vS=)wah-Urt4C?1W&cEb92fz800@ty3#!!qed zK3!&nG6cfU{U*}WQh|F1JJXXsRYAES;5!}FH;naqYet6J1 zJZ8ES-z7}!LFt{ZCCThxzRc-DH0~E^F{7pP0l$62f|nDvyodsyY}(5zd~)&;2{r}g zcjT${?tGOlGTJI%-6qRa?&^!&6FoZ9R=Jhmyf;pC06pQR0T^04r^{F|zdDU@L_S+d z40eji?8i*4tQ5ScizdXhCwIt%!iJ<-0%sMJ{Hmq!Ftp7U7iWYDlTtFO1?vnd|0z&_S*r5kqmS z%G$iArTCo`D3ZG@YsMHp8vfP$-_55hCaLrG049kva_u+W++BkGBT0thY#;ndpu>1C z3fZsvNI>e{aWinR0M|&knYTy+Bo}+w(umMDYkSv zUZkRgVCuFypF#U~Y323pBm145$RAZY)zVz7`o$z44bqeEher%K&7BrS9XI^5kMyZ^ z+*IX!JBz3SJ3k@w}o5NA>ofHU*T8suU;E{ zHp)-8$)04TTMJO5RQrlUML!xPGe3Lh?f2B=L-N>kyYEp7R*3jsDuwVz*u7n_uL+sn z`nfMzTB_rTCs#$EFa+|r#zYj*0mSI*bp*+|Md)ra70$Mt|2V85~4c!bbE6)xVQdPWoRgfX|OhJzya>Z|MaVKYfxv>=*FR zjZR7-Ryjng`W}se^OlMWN%J$CXVLqb-lO0dn9{99s3DxSn!_bnJ3jYaT13ESxB_Uj zVjsvx4diUVTK)dFzRFmbBNRW>!1m|?0+TNfbrs_Nq?2y@lUMM~tp&=3O=DV}7XBo` z2~CpaCioH0e0o5VwZr^h@p?Pe0LW6+W_?A!A-B1`KD}+wPn&Jl945#&Ll*PL=LjdQ z+URqOxsuV*2utCNfk;b*ZMVgF8~5VTxPy&!$smw>rZ*c{sfA#(R|*2AtxX3Y^F-^NIhTwI~|3_1H{kr&fCO}l!7jf~^&1NARBllkUq zg&sq6IMLN$y{+{-Ds3EhF4>ub_r4e5&FO7Qt~H{L#pnb#C(@C(wS};YKPo&)xpVC` zLJPXucf)Tnq^nq5M;cUK0FqLt-ZgSo9uQmLs3vcjU(TsueVvb_a&yAqCv)irVjd8K zE8*X#bd4*oLZC|^p=xi}u-e&h7;I<5JN7A$?bF;hR}SG4Pn=jXb8)OyNl(G=C4HeY z?hwFdNI7-t_lGw3vAs2BWj1?ObE^6;;!&er_?2D0vQ!_Ub6Uy#4IO)u`yLht{o<@Y zXO!E2zUFdFC}bt57eTUHam!TIOLJW44?OM(;Uf~DqE^dngG};z-=l@pg4)_-)cb@u zG=Jz)7MnipIAK_3=1qdPr5H<_m6UBfb)>6tZe%pbRh=TRRupQbMNi>n2tR7Zy;vVL z1(Kby_g4qe4lhfZ_40hOf$vnBy@PjJc-8f0T6Z+`>Du!tgE0f2PN(Kg_4V!vQSn#M z5qxm+QlVDhLQLyHUzaUb?uLl*|-G8=20~%n5E`ErzhIav9$9;!5Pcdwb8Dv(j_c2e8C!0P; zgEtU)7D|4vNyu+vX_q`R=!_qQs66vZ;>hYvs?K^t)%n1ja;78eAIfRU7$DDMpM73O zSjDpXoUquc2)7WczOb6`F43V7o@xuP6KLCwe~&0q7Xnew)g3&$Xx#mf_OeuuY}G1B z?WU>TJsJDElY5@oYlj7%CTqKSz8SCM*f>&=cV|IS!N22o@ai5lruKu$kfN>-w@wY9 z0zc3z1bTOT;HmabMFyIm<`IVu(oWabm+2Z&9_qB|pd~a1>u`s8uIi%V@}3lU6D_Hg z^5r32m|g_!8v5J3@Zr%>NloMtnN2>nn7c|c#>EU2-hE4vQrlCfP_j2;?)GWupM&~% z()Jgj^l8zW?6F|y_eyxrInAltb@+)K#iu{-452qy91h>Dhh6^iZ6HyDjqlKAC5JvlwQsJf4oZH`m@sWbwkBn*7JYtD9(+N0V8^(t9apW4cQ2ZdTBkgnY-p2M;i%?Wqv>Z;!l7ce1-^dIt|7Ol#)ut!TDfJU@L@`$5!vD_NCts)?CsdE>_I##GilK zVIlIv)~&)S+}RdLmY4t1&1w9*lKZc+g-|?6N++k_hmng}M(ndu+9k()qYres*B`>^ z)CTVw1pD}oO%A}tx~si+cs8%X10-}C_$sJ^Qk@01b~OHlZRnS&sj?wa-)%`gRBZ}# z(QnU8=~X*x4T=T{c|j*eT$bmPMQN9Y$xv=AfD%%?flF02N=&BE<{hL5irUK+Rd%gg=k=u@wh{wBo*CZ-0LX+CKKfJlD|Iukn`E2o!* zYO|Q?7-%S__JtCf8gMfHV7E^2$rUo_t^wC>!YMvR>|bLg;(9iyIfHP#3Dekbs(921 zdYn#PGMY^yrjZdDGuujk7Y}pt*DcdGzgy^croe)HQm(8dn|LB#mz- zNt$+afE!M?X*^{r0tSVO;%RL!E35{S8h50+1^yb%U|vSM0^;{$6=$t~re4sbhztP* z=9XNJx#>zlB?+~Q=5*iXf8I|cMOIQ;QZ={`CwR!oKyXVY-<}?=mzENEEs){6U=$RPJ z$hwXS?QpQv=RHdTRuka(FWjpbGfaL$Ss2rSl_OW0no_%1Ixh#fB1c^ZF#x}%7G1Pp z*x=29qGvRnkk(XPvXtfC5v(IR#~I|}liSs!P*$$$2JU~8OCA!Rx+qU++;uoGCnnCx zX_VGi@*+H1`Gd7SBylo&3fpCgPX2t_UFAm#eL`{)imldri289<=d-Ah$-;l2RMr>t zM~K{;Xce70=jxQFH`;tZ6We^ZXay4g0>`M}`R&*W-d0A*HlgTRJ+_}Ho)S(A!GR-) z%M}q%EY`;*){MMoOc}VTw85UR_i95wUMk4bv83bXT#u<$&|qR7ei)fzSSEcMq1%hv z*bY@xWypz`ERR?sgu@-b0HAuqUkM1p+!utR5?N?x;*Is@4o7o-wW}vSFD@i%z%lua--(MS$XDm5%;76J^ zUCy=Jn#yL58%YfV8?c<6;S+w-?Id~!7p?dJh>hW(<-JjqltweNEq7wy?HZtTpBJuq zA6@f8x21s~+fN^fcXO8TGTePDYgL5wRoHEU6Wwm=9q28*GWx~r#AdR{TPt)sw-Xgx z=#yPfc%^8W8c>KZ+8$2qT)92oXZX#ra z;?&auT`iAU_My1-exj)5(nwb(QqN3wt|Bu|g{9AmT9@>41W4sl>2XTBLW~`s^?OSe zq1cYEZZhxa=@vaFpKPn*ZlC@|J5S|w1rfn?;fC8|KC6=;_gLy&N-Uv?W`?%in$s0{ zxgqzmW%HL5`oaS#JqZej&_T5qPCAL^z+P*g5+-`*d3-2T34dv66y@<nAdL-2L7stUxKID!#1J4Mu+3;; zpWElDnZ=1MyxOs19_|Av5p6D|rjhNPVohXPl31It#C%#*m^+_-41h|2D~|9cmCXm~ zKfC4;`!|DiWY~$bO}Msz{z-L?NRRr|+_JoveE8N3{;W5qLd{tI?9X!%4h|*B8W?bS z^KjbV5@X%VcumpL3{w@vX=~0S z1}ZK2-{324-D(MH-608MmtTt?GBuXh#Ip&G=#V8xp%xM$kxi+ej*-gCphi4RD!38& zB6~!o-YFLSmT>?J#gKA#_m=|@r4scF@>_VvquxFTBUJRN-j9I+ zM@s^wHO)1R_tyb+z@)(oeFxTL`tq97_mrwKUHNP->^*@{cH&=cwvgmSzeCcRVYeGV z7y&g6Zlk%)^HF|tgBV#D(^Toy%l8vv_-YxFCWsR|jU~4oMOwG2w;T1Vs25l{za4$M zgo^MLSn^aQ0L*pBk9*O8IBd@T2=mu(ntNvFW1qzCoOXG0Cw3C?v7K6Z?0b53R{|df z$Mi}fr_TblKnhU3S`wBFX>#t2{8%my^CIJ(1U@{Lm5&Hntf>eO0+%hheQNkqctdvP zYuz#$Y|Mq^5wThuPDw`R9qoJtJ2QMLOt3{);6pY@s5MN3zFyPS%o; zpJ%ZXp?$ldnk9&xuTcb(x-e4=UrCs{6DeW(yL|wPgZIY+vLd@^FZU+)dEGExXe=GOjl}dd}_y!|;p~6#GhE zOYGU&w=GXeme=gFcw&U?fPpcL3|dV`X}?c@^Xc0YQb*1~;b|Vj z>P#<;dmVibR#G>qIhSY9%IN|_v&UU-a1_NoS03%7kPMm?+b!m|!{f(6U zk@rrvFKI{+^Q=_Mc08}N^b1z9i?D%?VJXRe{2Kt|+=E=6Z2b_P6+3#y>`nuHi40EI zkH@7b;r}HKBYQ5gz4;0Glu&cZzqX`%#qT+Am?l)LRN7(aeYAnOX zUH-4dIO!@ARg>f*)KS3`UAVS)~1pgBGb^ z>W+(|02wpVNwFLa5}l4OhKGQ-%f{_R=85JbK%V;r#U3}0v^vkBT z<$@HfEm6@|d?2-fSa`)#Me9818CV!A_d0Mf**>x%dinUDz4UEhc|MX^;7bY#yQ%_` zqDZ*7_5THh1$z1kzmq~|J5@q=@@42{5ecZ8jbQ(B_Qq7c+(-xtg`kih_H6`tp(m4h zFiV2Kuu+k1fOpOg%awK#>9u|m>8myuD_I5c9EF^3DZHID?|G`E98D^Y3lOe1?}d5> z38j+9Wo?wVZR|r^eq|eyxCm92)FkvjN81M4M@#BdAu+d++QJDl?ZC8JLc-%_qI34g zDgqt=kR&>n)bTtJ5wS<)W#Odv zPgFd@@qq(`=m69($c&3DrB=T9R8>LCeh|Cnl`Emq=fXYG302!G&rwy;ZGEM-D?mM4 z^)I)yi)T(}g3B~lL%y1(JnZ)B|5Zi61BlnAq?(bFauX48w@5`Pm9ha@M@UFW9)D|R zHw!W0RPgBA>uk}$4SvWt$JVAqhf6ZKukaN-ZrJ$jI(|2Zs)Ba?Aa>EU*_zo>^+(66 zoNYyPtV=Ly?AqtH1Ch5L&GlQ4IF2}#>k|hNfB5s0qqL#ji1{7Fcg9dLaGqJ^(5nl9DIh&-BA7xxC5}QSSwj zRj*vhEsa(Q?Wj_rp5BWS-D$VSmfAzgZnu(83V^u|^JcENsZR(Bg`kihR#`z_d~YJ+ zJ>8$t8vKVl6bn4AE-~2~grF30t5Fsce zfOw=BNUOIY;{<27(Ea`$7c{tWURfnzn!h z#KYf3_{o?F93TCVRPYIepwI{o#D`YFgH+g&Mh(W?0Ll}nx;&)gT{Z~^`FQxY` z^I|JvqzYYPkx~&O)h=8(aLZ@gaJDz4A=Juke)oD*W?6Bsq-8F_?(B z91?M@EldR&MKVfA2a-|87$wfAA*~Kl49rs*t~DMyJ|Ffcq#Z~H=ZIeO1d+H4Avll- z4)hkn0-FxWZ&#Q#eqIfEqRaFT-8kwlzB_U8&B=xao} z9YnORK{PJgw*|i(IR7~Z&c9jr>(m~4&wC^Z*N}>yN8a!C`<`h&D%?D=F(EkE2>uy= zvconsole.log({{reviews}}) - -
out
-{% for review in reviews %} -
- Hello - {{review | json}} -
-{% endfor %} +

Reviews

+
+ {% for review in reviews%} +
+

{{ review.content}}

+
+
+ {% render "star-rating", rating: review.rating.value | plus: 0 %} +
+
+ {% endfor %} +
{% schema %} -{ - "name": "Reviews", - "target": "section", - "settings": [ - { "type": "product", "id": "product", "label": "product", "autofill": true } - ] -} + { + "name": "Reviews", + "stylesheet": "reviews.css", + "target": "section", + "settings": [] + } {% endschema %} diff --git a/shopify/product-reviews-template/extensions/product-reviews/snippets/star-rating.liquid b/shopify/product-reviews-template/extensions/product-reviews/snippets/star-rating.liquid new file mode 100644 index 00000000..39beef15 --- /dev/null +++ b/shopify/product-reviews-template/extensions/product-reviews/snippets/star-rating.liquid @@ -0,0 +1,52 @@ + +{% for iteration in (1..5) %} + {% if iteration <= rating %} + + + + + + + + {% else %} + + + + + + + + {% endif %} +{% endfor %} \ No newline at end of file diff --git a/shopify/product-reviews-template/settings.gadget.ts b/shopify/product-reviews-template/settings.gadget.ts index f5934496..e2d72ede 100755 --- a/shopify/product-reviews-template/settings.gadget.ts +++ b/shopify/product-reviews-template/settings.gadget.ts @@ -2,7 +2,7 @@ import type { GadgetSettings } from "gadget-server"; export const settings: GadgetSettings = { type: "gadget/settings/v1", - frameworkVersion: "v1.2.0", + frameworkVersion: "v1.3.0", plugins: { connections: { shopify: { From b4a27e28590f0da8e89bf3e6ecb34baf8c6af40d Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Fri, 18 Oct 2024 12:50:17 -0400 Subject: [PATCH 25/43] Updating the gadget react version --- shopify/product-reviews-template/package.json | 2 +- shopify/product-reviews-template/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/shopify/product-reviews-template/package.json b/shopify/product-reviews-template/package.json index fe883cf5..44ffdfaf 100755 --- a/shopify/product-reviews-template/package.json +++ b/shopify/product-reviews-template/package.json @@ -15,7 +15,7 @@ }, "dependencies": { "@gadget-client/product-reviews-template": "link:.gadget/client", - "@gadgetinc/react": "^0.17.2", + "@gadgetinc/react": "^0.18.0", "@gadgetinc/react-shopify-app-bridge": "^0.16.4", "@react-email/components": "0.0.22", "@react-email/render": "1.0.0", diff --git a/shopify/product-reviews-template/yarn.lock b/shopify/product-reviews-template/yarn.lock index 98685e60..757b991c 100644 --- a/shopify/product-reviews-template/yarn.lock +++ b/shopify/product-reviews-template/yarn.lock @@ -522,10 +522,10 @@ crypto-js "^4.2.0" tslib "^2.6.2" -"@gadgetinc/react@^0.17.2": - version "0.17.2" - resolved "https://registry.yarnpkg.com/@gadgetinc/react/-/react-0.17.2.tgz#4b4877faf9f181e359fbb31b9c6a9326458a28ce" - integrity sha512-y1TGXSlbtVj2ftksF5xSZTPvarXBVMJWJNr3sFeS9iWtuTHpBZvGaKNLIdfQ8bQT2SVhV3HUH+6j9BjmdQN1Lw== +"@gadgetinc/react@^0.18.0": + version "0.18.0" + resolved "https://registry.yarnpkg.com/@gadgetinc/react/-/react-0.18.0.tgz#cf27595ca5052957106a0613d7abb276539d8f05" + integrity sha512-AJsxc6OhU5A1UPXDA8UUMNIkGTppqPFvMyZLjp9590sbVn/1JS3xQmVYunDQEtSJjOe6Pt6Gjxq+ZVKqxFTkYA== dependencies: "@0no-co/graphql.web" "^1.0.4" "@gadgetinc/api-client-core" "^0.15.33" From bc13a1fad48bc9d4bf008ec4fe1bd696e94cca57 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Fri, 18 Oct 2024 14:23:54 -0400 Subject: [PATCH 26/43] Trying to fix issues with Liquid star display --- .../extensions/product-reviews/assets/reviews.css | 5 +++-- .../extensions/product-reviews/blocks/productReviews.liquid | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/shopify/product-reviews-template/extensions/product-reviews/assets/reviews.css b/shopify/product-reviews-template/extensions/product-reviews/assets/reviews.css index 9931d1ab..843f36a9 100644 --- a/shopify/product-reviews-template/extensions/product-reviews/assets/reviews.css +++ b/shopify/product-reviews-template/extensions/product-reviews/assets/reviews.css @@ -13,6 +13,7 @@ div.reviewCard { flex-direction: row; justify-content: space-around; align-items: center; + width: 100%; } div.reviewStars { @@ -25,8 +26,8 @@ div.reviewStars > svg { width: 15px; } -div.vertical-divider { - border-left: 1px solid #ccc; +span.vertical-divider { + border-left: 1px solid lightgrey; height: 100%; margin: 0 10px; } diff --git a/shopify/product-reviews-template/extensions/product-reviews/blocks/productReviews.liquid b/shopify/product-reviews-template/extensions/product-reviews/blocks/productReviews.liquid index fbf564df..7fb86bca 100644 --- a/shopify/product-reviews-template/extensions/product-reviews/blocks/productReviews.liquid +++ b/shopify/product-reviews-template/extensions/product-reviews/blocks/productReviews.liquid @@ -5,7 +5,6 @@ {% for review in reviews%}

{{ review.content}}

-
{% render "star-rating", rating: review.rating.value | plus: 0 %}
From d71285ccffa4fe8ead0a1667beda9083d1d45160 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Thu, 24 Oct 2024 10:28:10 -0400 Subject: [PATCH 27/43] Got the stars to be the correct colour by changing from Liquid to JS --- .../product-reviews/assets/reviewStars.js | 34 ++++++++++++++++ .../product-reviews/assets/reviews.css | 39 ++++++++++--------- .../blocks/productReviews.liquid | 28 ++++++++++--- 3 files changed, 78 insertions(+), 23 deletions(-) create mode 100644 shopify/product-reviews-template/extensions/product-reviews/assets/reviewStars.js diff --git a/shopify/product-reviews-template/extensions/product-reviews/assets/reviewStars.js b/shopify/product-reviews-template/extensions/product-reviews/assets/reviewStars.js new file mode 100644 index 00000000..0da93e74 --- /dev/null +++ b/shopify/product-reviews-template/extensions/product-reviews/assets/reviewStars.js @@ -0,0 +1,34 @@ +document.addEventListener("DOMContentLoaded", () => { + for (let i = 0; i < window.reviews.length; i++) { + const reviewDiv = document.getElementById(`review-${i}`); + + console.log(parseFloat(reviews[i].rating.value)); + + for (let j = 1; j <= 5; j++) { + const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + svg.setAttribute("viewBox", "-2.15 -2.15 58.17 58.17"); + svg.setAttribute("height", "18px"); + svg.setAttribute("width", "18px"); + + // Create the polygon element + const polygon = document.createElementNS( + "http://www.w3.org/2000/svg", + "polygon" + ); + polygon.setAttribute( + "fill", + `${j <= parseFloat(reviews[i].rating.value) ? "#EFCE4A" : "#808080"}` + ); + polygon.setAttribute( + "points", + "26.934,1.318 35.256,18.182 53.867,20.887 40.4,34.013 43.579,52.549 26.934,43.798 10.288,52.549 13.467,34.013 0,20.887 18.611,18.182" + ); + + // Append the polygon to the SVG + svg.appendChild(polygon); + + // Append the SVG to the div + reviewDiv.appendChild(svg); + } + } +}); diff --git a/shopify/product-reviews-template/extensions/product-reviews/assets/reviews.css b/shopify/product-reviews-template/extensions/product-reviews/assets/reviews.css index 843f36a9..20314745 100644 --- a/shopify/product-reviews-template/extensions/product-reviews/assets/reviews.css +++ b/shopify/product-reviews-template/extensions/product-reviews/assets/reviews.css @@ -1,33 +1,36 @@ div#reviews { display: flex; flex-direction: column; - justify-content: space-around; - align-items: center; width: 100%; } -div.reviewCard { - border-top: lightgrey solid 1px; - padding: 2rem 2rem; +.review-card { display: flex; - flex-direction: row; - justify-content: space-around; align-items: center; - width: 100%; + padding-top: 15px; + border-top: 1px solid #e0e0e0; + margin: 0 10px 15px 10px; } -div.reviewStars { - display: flex; - align-items: start; +.review-content { + flex-grow: 1; /* Allows the review text to take up the remaining space */ + padding: 0 15px; } -div.reviewStars > svg { - height: 15px; - width: 15px; +.vertical-divider { + border-left: 1px solid #ccc; + height: 40px; + margin: 10px 15px; +} + +.review-stars { + display: flex; + gap: 5px; + max-width: 100px; + flex-shrink: 0; /* Prevent shrinking */ } -span.vertical-divider { - border-left: 1px solid lightgrey; - height: 100%; - margin: 0 10px; +.review-stars svg { + width: 18px; /* Star size */ + height: 18px; } diff --git a/shopify/product-reviews-template/extensions/product-reviews/blocks/productReviews.liquid b/shopify/product-reviews-template/extensions/product-reviews/blocks/productReviews.liquid index 7fb86bca..dcd726f9 100644 --- a/shopify/product-reviews-template/extensions/product-reviews/blocks/productReviews.liquid +++ b/shopify/product-reviews-template/extensions/product-reviews/blocks/productReviews.liquid @@ -1,14 +1,32 @@ + +{{ 'reviews.css' | asset_url | stylesheet_tag }} + {% assign reviews = product.metafields.productReviews.reviewMetaobjects.value %} + +

Reviews

{% for review in reviews%} -
-

{{ review.content}}

-
- {% render "star-rating", rating: review.rating.value | plus: 0 %} -
+
+
+ {{ review.content }} +
+   +
+ {% comment %} The stars will be rendered here using JS {% endcomment %} +
+
+ {% else %} +
+
+ No reviews yet
+
{% endfor %}
From 4cdf9d44275f1ad99080a5c4d92cab6a3ef6cd46 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Thu, 24 Oct 2024 11:01:32 -0400 Subject: [PATCH 28/43] Changed from productImage to productMedia --- .../filters/shopify/shopifyFile.gelly | 3 ++ .../filters/shopify/shopifyProductMedia.gelly | 3 ++ .../accessControl/permissions.gadget.ts | 14 ++++++- .../api/actions/fetchOrderData.js | 20 ++++++---- .../api/actions/scheduledShopifySync.js | 33 ++++++++++++++++ .../models/shopifyCustomer/schema.gadget.ts | 1 + .../actions/create.js | 6 +-- .../api/models/shopifyFile/actions/delete.js | 20 ++++++++++ .../actions/update.js | 6 +-- .../api/models/shopifyFile/schema.gadget.ts | 39 +++++++++++++++++++ .../models/shopifyProduct/schema.gadget.ts | 4 +- .../shopifyProductMedia/actions/create.js | 21 ++++++++++ .../actions/delete.js | 6 +-- .../shopifyProductMedia/actions/update.js | 21 ++++++++++ .../schema.gadget.ts | 12 ++---- .../api/models/shopifyShop/schema.gadget.ts | 3 +- .../product-reviews/assets/reviewStars.js | 2 - .../settings.gadget.ts | 3 +- .../web/components/ReviewCard.jsx | 7 +++- 19 files changed, 191 insertions(+), 33 deletions(-) create mode 100755 shopify/product-reviews-template/accessControl/filters/shopify/shopifyFile.gelly create mode 100755 shopify/product-reviews-template/accessControl/filters/shopify/shopifyProductMedia.gelly create mode 100755 shopify/product-reviews-template/api/actions/scheduledShopifySync.js rename shopify/product-reviews-template/api/models/{shopifyProductImage => shopifyFile}/actions/create.js (66%) create mode 100755 shopify/product-reviews-template/api/models/shopifyFile/actions/delete.js rename shopify/product-reviews-template/api/models/{shopifyProductImage => shopifyFile}/actions/update.js (66%) create mode 100755 shopify/product-reviews-template/api/models/shopifyFile/schema.gadget.ts create mode 100755 shopify/product-reviews-template/api/models/shopifyProductMedia/actions/create.js rename shopify/product-reviews-template/api/models/{shopifyProductImage => shopifyProductMedia}/actions/delete.js (71%) create mode 100755 shopify/product-reviews-template/api/models/shopifyProductMedia/actions/update.js rename shopify/product-reviews-template/api/models/{shopifyProductImage => shopifyProductMedia}/schema.gadget.ts (63%) diff --git a/shopify/product-reviews-template/accessControl/filters/shopify/shopifyFile.gelly b/shopify/product-reviews-template/accessControl/filters/shopify/shopifyFile.gelly new file mode 100755 index 00000000..4c558be9 --- /dev/null +++ b/shopify/product-reviews-template/accessControl/filters/shopify/shopifyFile.gelly @@ -0,0 +1,3 @@ +filter ($session: Session) on ShopifyFile [ + where shopId == $session.shopId +] diff --git a/shopify/product-reviews-template/accessControl/filters/shopify/shopifyProductMedia.gelly b/shopify/product-reviews-template/accessControl/filters/shopify/shopifyProductMedia.gelly new file mode 100755 index 00000000..08f8a812 --- /dev/null +++ b/shopify/product-reviews-template/accessControl/filters/shopify/shopifyProductMedia.gelly @@ -0,0 +1,3 @@ +filter ($session: Session) on ShopifyProductMedia [ + where shopId == $session.shopId +] diff --git a/shopify/product-reviews-template/accessControl/permissions.gadget.ts b/shopify/product-reviews-template/accessControl/permissions.gadget.ts index c3d27bb1..ddfe812f 100755 --- a/shopify/product-reviews-template/accessControl/permissions.gadget.ts +++ b/shopify/product-reviews-template/accessControl/permissions.gadget.ts @@ -26,6 +26,16 @@ export const permissions: GadgetPermissions = { "accessControl/filters/shopify/shopifyCustomer.gelly", }, }, + shopifyFile: { + read: { + filter: "accessControl/filters/shopify/shopifyFile.gelly", + }, + actions: { + create: true, + delete: true, + update: true, + }, + }, shopifyGdprRequest: { read: { filter: @@ -59,10 +69,10 @@ export const permissions: GadgetPermissions = { update: true, }, }, - shopifyProductImage: { + shopifyProductMedia: { read: { filter: - "accessControl/filters/shopify/shopifyProductImage.gelly", + "accessControl/filters/shopify/shopifyProductMedia.gelly", }, actions: { create: true, diff --git a/shopify/product-reviews-template/api/actions/fetchOrderData.js b/shopify/product-reviews-template/api/actions/fetchOrderData.js index 72bda81b..c9fb3e1f 100755 --- a/shopify/product-reviews-template/api/actions/fetchOrderData.js +++ b/shopify/product-reviews-template/api/actions/fetchOrderData.js @@ -32,11 +32,10 @@ export async function run({ params, logger, api, connections }) { product: { id: true, title: true, - images: { - edges: { - node: { - source: true, - }, + featuredMedia: { + file: { + url: true, + alt: true, }, }, }, @@ -54,14 +53,21 @@ export async function run({ params, logger, api, connections }) { const products = []; for (const { - product: { id, title, images }, + product: { + id, + title, + featuredMedia: { + file: { alt, url }, + }, + }, } of allLineItems) { if (!seen[id]) { seen[id] = true; products.push({ id: id, title: title, - image: images.edges[0].node.source, + image: url, + alt, }); } } diff --git a/shopify/product-reviews-template/api/actions/scheduledShopifySync.js b/shopify/product-reviews-template/api/actions/scheduledShopifySync.js new file mode 100755 index 00000000..db3aa1d2 --- /dev/null +++ b/shopify/product-reviews-template/api/actions/scheduledShopifySync.js @@ -0,0 +1,33 @@ +import { ActionOptions, ScheduledShopifySyncGlobalActionContext } from "gadget-server"; +import { globalShopifySync } from "gadget-server/shopify"; + +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 + }); +}; + +/** @type { ActionOptions } */ +export const options = { + triggers: { + scheduler: [ + { + every: "day", + at: "14:21 UTC", + }, + ], + }, +}; diff --git a/shopify/product-reviews-template/api/models/shopifyCustomer/schema.gadget.ts b/shopify/product-reviews-template/api/models/shopifyCustomer/schema.gadget.ts index f8487f96..3a537a94 100755 --- a/shopify/product-reviews-template/api/models/shopifyCustomer/schema.gadget.ts +++ b/shopify/product-reviews-template/api/models/shopifyCustomer/schema.gadget.ts @@ -25,6 +25,7 @@ export const schema: GadgetModel = { "lastName", "lastOrder", "lastOrderName", + "locale", "marketingOptInLevel", "metafield", "multipassIdentifier", diff --git a/shopify/product-reviews-template/api/models/shopifyProductImage/actions/create.js b/shopify/product-reviews-template/api/models/shopifyFile/actions/create.js similarity index 66% rename from shopify/product-reviews-template/api/models/shopifyProductImage/actions/create.js rename to shopify/product-reviews-template/api/models/shopifyFile/actions/create.js index 8824eb40..62c11e60 100755 --- a/shopify/product-reviews-template/api/models/shopifyProductImage/actions/create.js +++ b/shopify/product-reviews-template/api/models/shopifyFile/actions/create.js @@ -1,8 +1,8 @@ -import { applyParams, save, ActionOptions, CreateShopifyProductImageActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions, CreateShopifyFileActionContext } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; /** - * @param { CreateShopifyProductImageActionContext } context + * @param { CreateShopifyFileActionContext } context */ export async function run({ params, record, logger, api, connections }) { applyParams(params, record); @@ -11,7 +11,7 @@ export async function run({ params, record, logger, api, connections }) { }; /** - * @param { CreateShopifyProductImageActionContext } context + * @param { CreateShopifyFileActionContext } context */ export async function onSuccess({ params, record, logger, api, connections }) { // Your logic goes here diff --git a/shopify/product-reviews-template/api/models/shopifyFile/actions/delete.js b/shopify/product-reviews-template/api/models/shopifyFile/actions/delete.js new file mode 100755 index 00000000..8e472a88 --- /dev/null +++ b/shopify/product-reviews-template/api/models/shopifyFile/actions/delete.js @@ -0,0 +1,20 @@ +import { deleteRecord, ActionOptions, DeleteShopifyFileActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { DeleteShopifyFileActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + await preventCrossShopDataAccess(params, record); + await deleteRecord(record); +}; + +/** + * @param { DeleteShopifyFileActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "delete" }; diff --git a/shopify/product-reviews-template/api/models/shopifyProductImage/actions/update.js b/shopify/product-reviews-template/api/models/shopifyFile/actions/update.js similarity index 66% rename from shopify/product-reviews-template/api/models/shopifyProductImage/actions/update.js rename to shopify/product-reviews-template/api/models/shopifyFile/actions/update.js index 5a973983..f6551468 100755 --- a/shopify/product-reviews-template/api/models/shopifyProductImage/actions/update.js +++ b/shopify/product-reviews-template/api/models/shopifyFile/actions/update.js @@ -1,8 +1,8 @@ -import { applyParams, save, ActionOptions, UpdateShopifyProductImageActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions, UpdateShopifyFileActionContext } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; /** - * @param { UpdateShopifyProductImageActionContext } context + * @param { UpdateShopifyFileActionContext } context */ export async function run({ params, record, logger, api, connections }) { applyParams(params, record); @@ -11,7 +11,7 @@ export async function run({ params, record, logger, api, connections }) { }; /** - * @param { UpdateShopifyProductImageActionContext } context + * @param { UpdateShopifyFileActionContext } context */ export async function onSuccess({ params, record, logger, api, connections }) { // Your logic goes here diff --git a/shopify/product-reviews-template/api/models/shopifyFile/schema.gadget.ts b/shopify/product-reviews-template/api/models/shopifyFile/schema.gadget.ts new file mode 100755 index 00000000..cbcde1e1 --- /dev/null +++ b/shopify/product-reviews-template/api/models/shopifyFile/schema.gadget.ts @@ -0,0 +1,39 @@ +import type { GadgetModel } from "gadget-server"; + +// This file describes the schema for the "shopifyFile" model, go to https://product-reviews-template.gadget.app/edit to view/edit your model in Gadget +// For more information on how to update this file http://docs.gadget.dev + +export const schema: GadgetModel = { + type: "gadget/model-schema/v1", + storageKey: "DataModel-Shopify-File", + fields: {}, + shopify: { + fields: [ + "alt", + "boundingBox", + "duration", + "embedUrl", + "fileErrors", + "fileStatus", + "filename", + "host", + "image", + "mediaContentType", + "mediaErrors", + "mediaWarnings", + "mimetype", + "originUrl", + "originalFileSize", + "originalSource", + "preview", + "product", + "shop", + "shopifyCreatedAt", + "shopifyUpdatedAt", + "sources", + "status", + "type", + "url", + ], + }, +}; diff --git a/shopify/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts b/shopify/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts index 7be12e68..b39cc30e 100755 --- a/shopify/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts +++ b/shopify/product-reviews-template/api/models/shopifyProduct/schema.gadget.ts @@ -30,8 +30,10 @@ export const schema: GadgetModel = { "body", "category", "compareAtPriceRange", + "featuredMedia", "handle", - "images", + "hasVariantsThatRequiresComponents", + "media", "orderLineItems", "productCategory", "productType", diff --git a/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/create.js b/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/create.js new file mode 100755 index 00000000..9f75a0f1 --- /dev/null +++ b/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/create.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, CreateShopifyProductMediaActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { CreateShopifyProductMediaActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +/** + * @param { CreateShopifyProductMediaActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "create" }; diff --git a/shopify/product-reviews-template/api/models/shopifyProductImage/actions/delete.js b/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/delete.js similarity index 71% rename from shopify/product-reviews-template/api/models/shopifyProductImage/actions/delete.js rename to shopify/product-reviews-template/api/models/shopifyProductMedia/actions/delete.js index 1d2ce190..f62ba11a 100755 --- a/shopify/product-reviews-template/api/models/shopifyProductImage/actions/delete.js +++ b/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/delete.js @@ -1,8 +1,8 @@ -import { deleteRecord, ActionOptions, DeleteShopifyProductImageActionContext } from "gadget-server"; +import { deleteRecord, ActionOptions, DeleteShopifyProductMediaActionContext } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; /** - * @param { DeleteShopifyProductImageActionContext } context + * @param { DeleteShopifyProductMediaActionContext } context */ export async function run({ params, record, logger, api, connections }) { await preventCrossShopDataAccess(params, record); @@ -10,7 +10,7 @@ export async function run({ params, record, logger, api, connections }) { }; /** - * @param { DeleteShopifyProductImageActionContext } context + * @param { DeleteShopifyProductMediaActionContext } context */ export async function onSuccess({ params, record, logger, api, connections }) { // Your logic goes here diff --git a/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/update.js b/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/update.js new file mode 100755 index 00000000..98d6de0c --- /dev/null +++ b/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/update.js @@ -0,0 +1,21 @@ +import { applyParams, save, ActionOptions, UpdateShopifyProductMediaActionContext } from "gadget-server"; +import { preventCrossShopDataAccess } from "gadget-server/shopify"; + +/** + * @param { UpdateShopifyProductMediaActionContext } context + */ +export async function run({ params, record, logger, api, connections }) { + applyParams(params, record); + await preventCrossShopDataAccess(params, record); + await save(record); +}; + +/** + * @param { UpdateShopifyProductMediaActionContext } context + */ +export async function onSuccess({ params, record, logger, api, connections }) { + // Your logic goes here +}; + +/** @type { ActionOptions } */ +export const options = { actionType: "update" }; diff --git a/shopify/product-reviews-template/api/models/shopifyProductImage/schema.gadget.ts b/shopify/product-reviews-template/api/models/shopifyProductMedia/schema.gadget.ts similarity index 63% rename from shopify/product-reviews-template/api/models/shopifyProductImage/schema.gadget.ts rename to shopify/product-reviews-template/api/models/shopifyProductMedia/schema.gadget.ts index d6e0bcd1..723e6e90 100755 --- a/shopify/product-reviews-template/api/models/shopifyProductImage/schema.gadget.ts +++ b/shopify/product-reviews-template/api/models/shopifyProductMedia/schema.gadget.ts @@ -1,23 +1,19 @@ import type { GadgetModel } from "gadget-server"; -// This file describes the schema for the "shopifyProductImage" model, go to https://product-reviews-template.gadget.app/edit to view/edit your model in Gadget +// This file describes the schema for the "shopifyProductMedia" model, go to https://product-reviews-template.gadget.app/edit to view/edit your model in Gadget // For more information on how to update this file http://docs.gadget.dev export const schema: GadgetModel = { type: "gadget/model-schema/v1", - storageKey: "DataModel-Shopify-ProductImage", + storageKey: "DataModel-Shopify-ProductMedia", fields: {}, shopify: { fields: [ - "alt", - "height", + "featuredMediaForProduct", + "file", "position", "product", "shop", - "shopifyCreatedAt", - "shopifyUpdatedAt", - "source", - "width", ], }, }; diff --git a/shopify/product-reviews-template/api/models/shopifyShop/schema.gadget.ts b/shopify/product-reviews-template/api/models/shopifyShop/schema.gadget.ts index e5955a0c..e2869285 100755 --- a/shopify/product-reviews-template/api/models/shopifyShop/schema.gadget.ts +++ b/shopify/product-reviews-template/api/models/shopifyShop/schema.gadget.ts @@ -53,6 +53,7 @@ export const schema: GadgetModel = { "eligibleForPayments", "email", "enabledPresentmentCurrencies", + "files", "finances", "forceSsl", "gdprRequests", @@ -80,7 +81,7 @@ export const schema: GadgetModel = { "planName", "preLaunchEnabled", "primaryLocale", - "productImages", + "productMedia", "products", "province", "provinceCode", diff --git a/shopify/product-reviews-template/extensions/product-reviews/assets/reviewStars.js b/shopify/product-reviews-template/extensions/product-reviews/assets/reviewStars.js index 0da93e74..cf6ec030 100644 --- a/shopify/product-reviews-template/extensions/product-reviews/assets/reviewStars.js +++ b/shopify/product-reviews-template/extensions/product-reviews/assets/reviewStars.js @@ -2,8 +2,6 @@ document.addEventListener("DOMContentLoaded", () => { for (let i = 0; i < window.reviews.length; i++) { const reviewDiv = document.getElementById(`review-${i}`); - console.log(parseFloat(reviews[i].rating.value)); - for (let j = 1; j <= 5; j++) { const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttribute("viewBox", "-2.15 -2.15 58.17 58.17"); diff --git a/shopify/product-reviews-template/settings.gadget.ts b/shopify/product-reviews-template/settings.gadget.ts index e2d72ede..0d306ddd 100755 --- a/shopify/product-reviews-template/settings.gadget.ts +++ b/shopify/product-reviews-template/settings.gadget.ts @@ -9,10 +9,11 @@ export const settings: GadgetSettings = { apiVersion: "2024-10", enabledModels: [ "shopifyCustomer", + "shopifyFile", "shopifyOrder", "shopifyOrderLineItem", "shopifyProduct", - "shopifyProductImage", + "shopifyProductMedia", ], type: "partner", scopes: [ diff --git a/shopify/product-reviews-template/web/components/ReviewCard.jsx b/shopify/product-reviews-template/web/components/ReviewCard.jsx index 518eefe9..2c3b4432 100644 --- a/shopify/product-reviews-template/web/components/ReviewCard.jsx +++ b/shopify/product-reviews-template/web/components/ReviewCard.jsx @@ -24,7 +24,7 @@ import { api } from "../api"; import { useState } from "react"; import Stars from "./Stars"; -export default ({ id: productId, title, orderId, image }) => { +export default ({ id: productId, title, orderId, image, alt }) => { const [open, setOpen] = useState(false); const [completed, setCompleted] = useState(false); @@ -33,7 +33,10 @@ export default ({ id: productId, title, orderId, image }) => { - + {title} From 10242986b3aa80f63b09d5e926d9e3c6105621f3 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Thu, 24 Oct 2024 11:06:40 -0400 Subject: [PATCH 29/43] Removing console logs --- .../api/actions/fetchOrderData.js | 4 -- .../api/actions/updateReviewsMetafield.js | 2 - .../api/models/review/actions/update.js | 10 ---- .../snippets/star-rating.liquid | 52 ------------------- .../web/components/ApprovalButton.jsx | 4 +- 5 files changed, 1 insertion(+), 71 deletions(-) delete mode 100644 shopify/product-reviews-template/extensions/product-reviews/snippets/star-rating.liquid diff --git a/shopify/product-reviews-template/api/actions/fetchOrderData.js b/shopify/product-reviews-template/api/actions/fetchOrderData.js index c9fb3e1f..6df2e98b 100755 --- a/shopify/product-reviews-template/api/actions/fetchOrderData.js +++ b/shopify/product-reviews-template/api/actions/fetchOrderData.js @@ -4,8 +4,6 @@ import { FetchOrderDataGlobalActionContext } from "gadget-server"; * @param { FetchOrderDataGlobalActionContext } context */ export async function run({ params, logger, api, connections }) { - logger.info({ params }, "params"); - const order = await api.shopifyOrder.maybeFindFirst({ filter: { singleUseCode: { @@ -19,8 +17,6 @@ export async function run({ params, logger, api, connections }) { }); if (order) { - logger.info({ order }, "order"); - let lineItems = await api.shopifyOrderLineItem.findMany({ filter: { orderId: { diff --git a/shopify/product-reviews-template/api/actions/updateReviewsMetafield.js b/shopify/product-reviews-template/api/actions/updateReviewsMetafield.js index ae0c6894..1668f3ab 100755 --- a/shopify/product-reviews-template/api/actions/updateReviewsMetafield.js +++ b/shopify/product-reviews-template/api/actions/updateReviewsMetafield.js @@ -34,8 +34,6 @@ export async function run({ params, logger, api, connections }) { if (!value) return; - logger.info({ value }, "VALUE"); - const metafieldsSetResponse = await shopify.graphql( `mutation ($metafields: [MetafieldsSetInput!]!) { metafieldsSet(metafields: $metafields) { diff --git a/shopify/product-reviews-template/api/models/review/actions/update.js b/shopify/product-reviews-template/api/models/review/actions/update.js index daabb943..2dfba8ce 100755 --- a/shopify/product-reviews-template/api/models/review/actions/update.js +++ b/shopify/product-reviews-template/api/models/review/actions/update.js @@ -20,16 +20,6 @@ export async function onSuccess({ params, record, logger, api, connections }) { const { changed, current: approved } = record.changes("approved"); if (changed) { - logger.info( - { - shopId: record.shopId, - productId: record.productId, - metaobjectId: record.metaobjectId, - approved, - }, - "HERE" - ); - await api.enqueue(api.updateReviewsMetafield, { shopId: record.shopId, productId: record.productId, diff --git a/shopify/product-reviews-template/extensions/product-reviews/snippets/star-rating.liquid b/shopify/product-reviews-template/extensions/product-reviews/snippets/star-rating.liquid deleted file mode 100644 index 39beef15..00000000 --- a/shopify/product-reviews-template/extensions/product-reviews/snippets/star-rating.liquid +++ /dev/null @@ -1,52 +0,0 @@ - -{% for iteration in (1..5) %} - {% if iteration <= rating %} - - - - - - - - {% else %} - - - - - - - - {% endif %} -{% endfor %} \ No newline at end of file diff --git a/shopify/product-reviews-template/web/components/ApprovalButton.jsx b/shopify/product-reviews-template/web/components/ApprovalButton.jsx index e7256e74..ac9d6fb5 100644 --- a/shopify/product-reviews-template/web/components/ApprovalButton.jsx +++ b/shopify/product-reviews-template/web/components/ApprovalButton.jsx @@ -1,4 +1,4 @@ -import { Button, Text } from "@shopify/polaris"; +import { Button } from "@shopify/polaris"; import { api } from "../api"; import { useAction } from "@gadgetinc/react"; import { useEffect } from "react"; @@ -8,8 +8,6 @@ export default ({ record: { id, approved }, toast }) => { useEffect(() => { if (!fetching && data) { - console.log(data); - toast.show( data.approved ? "Review added to store" : "Review removed from store", { From d4ba8991aa11068718c29aa9bb64b69b833b5f50 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Thu, 24 Oct 2024 11:28:37 -0400 Subject: [PATCH 30/43] Fixing an import issue --- .../product-reviews-template/web/components/ReviewCard.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shopify/product-reviews-template/web/components/ReviewCard.jsx b/shopify/product-reviews-template/web/components/ReviewCard.jsx index 2c3b4432..7c9da254 100644 --- a/shopify/product-reviews-template/web/components/ReviewCard.jsx +++ b/shopify/product-reviews-template/web/components/ReviewCard.jsx @@ -1,7 +1,7 @@ import { AutoForm, AutoSubmit, - AutoTextInput, + AutoStringInput, } from "@gadgetinc/react/auto/polaris"; import { BlockStack, @@ -65,7 +65,7 @@ export default ({ id: productId, title, orderId, image, alt }) => { }} > - + From 6d36b930c786f6625496b452637640d0c98b9ec9 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Thu, 24 Oct 2024 15:43:44 -0400 Subject: [PATCH 31/43] Adding all the relevant docs and readme information --- .../.github/README.md | 21 +++ .../.template/config.json | 68 ++++++++++ .../.template/docs/intro.md | 5 + .../.template/docs/setup.md | 9 ++ .../.template/webflow/content.md | 4 + .../web/routes/index.jsx | 123 +++++++++++------- 6 files changed, 182 insertions(+), 48 deletions(-) create mode 100644 shopify/product-reviews-template/.github/README.md create mode 100755 shopify/product-reviews-template/.template/config.json create mode 100755 shopify/product-reviews-template/.template/docs/intro.md create mode 100644 shopify/product-reviews-template/.template/docs/setup.md create mode 100755 shopify/product-reviews-template/.template/webflow/content.md diff --git a/shopify/product-reviews-template/.github/README.md b/shopify/product-reviews-template/.github/README.md new file mode 100644 index 00000000..77c601e1 --- /dev/null +++ b/shopify/product-reviews-template/.github/README.md @@ -0,0 +1,21 @@ +# Product reviews + +This template allows merchants to collect and manage reviews for their products, leveraging Shopify's metaobject system for storing review data. Review requests are sent a set number of days after the order is completely fulfilled. + +[![Fork template](https://img.shields.io/badge/Fork%20template-%233A0CFF?style=for-the-badge)](https://app.gadget.dev/auth/fork?domain=prodcut-reviews-template.gadget.app) + +## Key features + +- Models + - `review`: Stores customer-created reviews with fields such as `metaobjectId`, `approved`, `rating`, `content`, `product`, `order`, `customer`, and `shop`. +- Frontends + - `web/components/App.jsx`: Displays unauthorized pages. + - `web/routes/index.jsx`: Displays a table showing reviews that need to be approved. +- Actions + - `review.create`: Creates a review metaobject in Shopify when the review is first created. + - `review.update`: Updates the value of the metaobject reference metafield for the product associated with the review. +- Global Actions + - `sendEmail`: Sends an email to customers who have placed an order, linking them to the review page. + - `fetchOrderData`: Retrieves the relevant order data for the customer. + - `createReviewMetaobject`: Creates a review metaobject for a given product. + - `createReviewsMetafield`: Adds a reviews metafield (initially an empty array) when a product is created. diff --git a/shopify/product-reviews-template/.template/config.json b/shopify/product-reviews-template/.template/config.json new file mode 100755 index 00000000..f65f714f --- /dev/null +++ b/shopify/product-reviews-template/.template/config.json @@ -0,0 +1,68 @@ +{ + "version": "v1", + "setup": "docs/setup.md", + "introduction": "docs/intro.md", + "featuredGlobalActions": { + "sendEmail": { + "description": "Sends an email to the customer that placed the order, with a link to a review page." + }, + "fetchOrderData": { + "description": "Fetches data for the customer's order." + }, + "createReviewMetaobject": { + "description": "Creates a review metaobject for the given product." + }, + "createReviewsMetafield": { + "description": "Creates a reviews metafield (empty array) when a product is created." + } + }, + "featuredFrontends": { + "web/components/App.jsx": { + "description": "Modified to display unauthorized pages.", + "tags": ["edited"] + }, + "web/routes/index.jsx": { + "description": "Displays a table with reviews to be approved.", + "tags": ["edited"] + } + }, + "featuredModels": { + "review": { + "description": "Stored reviews created by customers.", + "featuredFields": [ + "metaobjectId", + "approved", + "rating", + "content", + "product", + "order", + "customer", + "shop" + ] + } + }, + "featuredActions": { + "review": { + "create": { + "description": "Creates a review metaobject in Shopify when the review is being created.", + "tags": ["edited"] + }, + "update": { + "description": "Updates the value of metaobject reference metafield for the product that the review is attached to.", + "tags": ["edited"] + } + } + }, + "webflow": { + "title": "Product reviews", + "description": "Allow merchants to get reviews for their products.", + "content": "webflow/content.md", + "mainImage": "webflow/.png", + "features": { + "shopify": true, + "frontend": true, + "models": true, + "actions": true + } + } +} diff --git a/shopify/product-reviews-template/.template/docs/intro.md b/shopify/product-reviews-template/.template/docs/intro.md new file mode 100755 index 00000000..5be352f8 --- /dev/null +++ b/shopify/product-reviews-template/.template/docs/intro.md @@ -0,0 +1,5 @@ +# Product reviews + +This template has [setup instructions](template-setup). + +This template allows merchants to collect and manage reviews for their products, leveraging Shopify's metaobject system for storing review data. Review requests are sent a set number of days after the order is completely fulfilled. diff --git a/shopify/product-reviews-template/.template/docs/setup.md b/shopify/product-reviews-template/.template/docs/setup.md new file mode 100644 index 00000000..39a820f6 --- /dev/null +++ b/shopify/product-reviews-template/.template/docs/setup.md @@ -0,0 +1,9 @@ +# Getting started + +A list of steps that you should follow: + +1. [Connect to Shopify](https://docs.gadget.dev/guides/tutorials/connecting-to-shopify#connecting-to-shopify) using our built-in Shopify plugin. + +2. Sync the code locally using `ggt` ([Gadget CLI](https://docs.gadget.dev/reference/ggt#ggt-reference)) and run `yarn dev` to test the application. Note that you're require to have a `shopify.app.toml` to run `yarn dev`. Make sure to install the [Shopify CLI](https://shopify.dev/docs/api/shopify-cli#installation) using these instructions. + +3. Install the application on a development store, and add the extension block to the product page. When testing, make sure that you're always running `yarn dev`. diff --git a/shopify/product-reviews-template/.template/webflow/content.md b/shopify/product-reviews-template/.template/webflow/content.md new file mode 100755 index 00000000..bc66df71 --- /dev/null +++ b/shopify/product-reviews-template/.template/webflow/content.md @@ -0,0 +1,4 @@ +- Allow customers to create reviews for products they've ordered +- Start with a cart transform function that respects item quantities +- _Tenancy enforced:_ App data will be unique to the store it is installed on. +- _Ready-to-Use:_ No need to start from scratch – equipped with a Shopify connection, data models, and backend logic. diff --git a/shopify/product-reviews-template/web/routes/index.jsx b/shopify/product-reviews-template/web/routes/index.jsx index ad8cc1cd..faae33a9 100755 --- a/shopify/product-reviews-template/web/routes/index.jsx +++ b/shopify/product-reviews-template/web/routes/index.jsx @@ -1,5 +1,13 @@ import { AutoTable } from "@gadgetinc/react/auto/polaris"; -import { BlockStack, Layout, Page, Text, Tooltip } from "@shopify/polaris"; +import { + BlockStack, + Box, + Card, + Layout, + Page, + Text, + Tooltip, +} from "@shopify/polaris"; import { api } from "../api"; import { ApprovalButton, Stars } from "../components"; import { useAppBridge } from "@shopify/app-bridge-react"; @@ -13,59 +21,78 @@ export default function () { - ( - -
{ - setModelContent(content); - modal.show("review-content-modal"); - }} - > + + ( + - {content} + {title} -
-
- ), - }, - { field: "customer.firstName", header: "Customer" }, - { - field: "rating", - header: "Rating", - render: ({ record }) => , - }, - { - field: "approved", - header: "", - render: ({ record }) => ( - - ), - }, - ]} - /> + + ), + }, + { + field: "content", + header: "Review", + render: ({ record: { content } }) => ( + +
{ + setModelContent(content); + modal.show("review-content-modal"); + }} + > + + {content} + +
+
+ ), + }, + { field: "customer.firstName", header: "Customer" }, + { + field: "rating", + header: "Rating", + render: ({ record }) => , + }, + { + field: "approved", + header: "", + render: ({ record }) => ( + + ), + }, + ]} + /> +
- {modalContent} + + {modalContent} +
From bd9ef090924ddd240f462e9d4b0a0ea1ef8a9bdd Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Tue, 12 Nov 2024 10:28:16 -0500 Subject: [PATCH 32/43] Moving the template to ts and fixing issues from the pr review --- ...etaobject.js => createReviewMetaobject.ts} | 25 +++++------ ...Metafield.js => createReviewsMetafield.ts} | 11 ++--- .../{enqueueEmails.js => enqueueEmails.ts} | 33 +++++++++----- .../{fetchOrderData.js => fetchOrderData.ts} | 44 ++++++++----------- .../api/actions/scheduledShopifySync.js | 33 -------------- .../api/actions/scheduledShopifySync.ts | 29 ++++++++++++ .../api/actions/sendEmail.js | 43 ------------------ .../api/actions/sendEmail.ts | 29 ++++++++++++ ...eviewRequests.js => sendReviewRequests.ts} | 10 ++--- ...Metafield.js => updateReviewsMetafield.ts} | 0 .../review/actions/{create.js => create.ts} | 0 .../review/actions/{delete.js => delete.ts} | 0 .../review/actions/{update.js => update.ts} | 0 .../actions/{create.js => create.ts} | 0 .../actions/{delete.js => delete.ts} | 0 .../actions/{update.js => update.ts} | 0 .../actions/{create.js => create.ts} | 0 .../actions/{delete.js => delete.ts} | 0 .../actions/{update.js => update.ts} | 0 .../actions/{create.js => create.ts} | 0 .../actions/{update.js => update.ts} | 0 .../actions/{create.js => create.ts} | 0 .../actions/{delete.js => delete.ts} | 0 .../actions/{update.js => update.ts} | 0 .../actions/{create.js => create.ts} | 0 .../actions/{delete.js => delete.ts} | 0 .../actions/{update.js => update.ts} | 0 .../actions/{create.js => create.ts} | 0 .../actions/{delete.js => delete.ts} | 0 .../actions/{update.js => update.ts} | 0 .../actions/{create.js => create.ts} | 0 .../actions/{delete.js => delete.ts} | 0 .../actions/{update.js => update.ts} | 0 .../actions/{install.js => install.ts} | 0 .../actions/{reinstall.js => reinstall.ts} | 0 .../actions/{uninstall.js => uninstall.ts} | 0 .../actions/{update.js => update.ts} | 0 .../actions/{abort.js => abort.ts} | 0 .../actions/{complete.js => complete.ts} | 0 .../actions/{error.js => error.ts} | 0 .../shopifySync/actions/{run.js => run.ts} | 0 .../api/utilities/renderEmail.tsx | 23 ++++++++++ shopify/product-reviews-template/index.html | 36 ++++++++------- shopify/product-reviews-template/package.json | 3 +- .../product-reviews-template/tsconfig.json | 22 ++++++++++ .../{vite.config.mjs => vite.config.mts} | 0 .../web/{api.js => api.ts} | 0 .../web/components/{App.jsx => App.tsx} | 7 +-- ...{ApprovalButton.jsx => ApprovalButton.tsx} | 0 .../components/{Invalid.jsx => Invalid.tsx} | 0 .../{ReviewCard.jsx => ReviewCard.tsx} | 0 .../components/{Reviews.jsx => Reviews.tsx} | 0 .../web/components/{Stars.jsx => Stars.tsx} | 0 .../{StyledSpinner.jsx => StyledSpinner.tsx} | 0 .../web/components/{index.js => index.ts} | 0 .../web/{main.jsx => main.tsx} | 0 ...direct.jsx => AuthenticatedOrRedirect.tsx} | 0 .../web/providers/{index.js => index.ts} | 0 .../web/routes/{about.jsx => about.tsx} | 0 .../web/routes/index.js | 2 - .../web/routes/{index.jsx => index.tsx} | 0 shopify/product-reviews-template/yarn.lock | 5 +++ 62 files changed, 190 insertions(+), 165 deletions(-) rename shopify/product-reviews-template/api/actions/{createReviewMetaobject.js => createReviewMetaobject.ts} (73%) rename shopify/product-reviews-template/api/actions/{createReviewsMetafield.js => createReviewsMetafield.ts} (80%) rename shopify/product-reviews-template/api/actions/{enqueueEmails.js => enqueueEmails.ts} (62%) rename shopify/product-reviews-template/api/actions/{fetchOrderData.js => fetchOrderData.ts} (64%) delete mode 100755 shopify/product-reviews-template/api/actions/scheduledShopifySync.js create mode 100755 shopify/product-reviews-template/api/actions/scheduledShopifySync.ts delete mode 100755 shopify/product-reviews-template/api/actions/sendEmail.js create mode 100755 shopify/product-reviews-template/api/actions/sendEmail.ts rename shopify/product-reviews-template/api/actions/{sendReviewRequests.js => sendReviewRequests.ts} (75%) rename shopify/product-reviews-template/api/actions/{updateReviewsMetafield.js => updateReviewsMetafield.ts} (100%) rename shopify/product-reviews-template/api/models/review/actions/{create.js => create.ts} (100%) rename shopify/product-reviews-template/api/models/review/actions/{delete.js => delete.ts} (100%) rename shopify/product-reviews-template/api/models/review/actions/{update.js => update.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyCustomer/actions/{create.js => create.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyCustomer/actions/{delete.js => delete.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyCustomer/actions/{update.js => update.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyFile/actions/{create.js => create.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyFile/actions/{delete.js => delete.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyFile/actions/{update.js => update.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/{create.js => create.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/{update.js => update.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyOrder/actions/{create.js => create.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyOrder/actions/{delete.js => delete.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyOrder/actions/{update.js => update.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/{create.js => create.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/{delete.js => delete.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/{update.js => update.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyProduct/actions/{create.js => create.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyProduct/actions/{delete.js => delete.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyProduct/actions/{update.js => update.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyProductMedia/actions/{create.js => create.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyProductMedia/actions/{delete.js => delete.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyProductMedia/actions/{update.js => update.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyShop/actions/{install.js => install.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyShop/actions/{reinstall.js => reinstall.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyShop/actions/{uninstall.js => uninstall.ts} (100%) rename shopify/product-reviews-template/api/models/shopifyShop/actions/{update.js => update.ts} (100%) rename shopify/product-reviews-template/api/models/shopifySync/actions/{abort.js => abort.ts} (100%) rename shopify/product-reviews-template/api/models/shopifySync/actions/{complete.js => complete.ts} (100%) rename shopify/product-reviews-template/api/models/shopifySync/actions/{error.js => error.ts} (100%) rename shopify/product-reviews-template/api/models/shopifySync/actions/{run.js => run.ts} (100%) create mode 100644 shopify/product-reviews-template/api/utilities/renderEmail.tsx create mode 100755 shopify/product-reviews-template/tsconfig.json rename shopify/product-reviews-template/{vite.config.mjs => vite.config.mts} (100%) rename shopify/product-reviews-template/web/{api.js => api.ts} (100%) rename shopify/product-reviews-template/web/components/{App.jsx => App.tsx} (91%) rename shopify/product-reviews-template/web/components/{ApprovalButton.jsx => ApprovalButton.tsx} (100%) rename shopify/product-reviews-template/web/components/{Invalid.jsx => Invalid.tsx} (100%) rename shopify/product-reviews-template/web/components/{ReviewCard.jsx => ReviewCard.tsx} (100%) rename shopify/product-reviews-template/web/components/{Reviews.jsx => Reviews.tsx} (100%) rename shopify/product-reviews-template/web/components/{Stars.jsx => Stars.tsx} (100%) rename shopify/product-reviews-template/web/components/{StyledSpinner.jsx => StyledSpinner.tsx} (100%) rename shopify/product-reviews-template/web/components/{index.js => index.ts} (100%) rename shopify/product-reviews-template/web/{main.jsx => main.tsx} (100%) rename shopify/product-reviews-template/web/providers/{AuthenticatedOrRedirect.jsx => AuthenticatedOrRedirect.tsx} (100%) rename shopify/product-reviews-template/web/providers/{index.js => index.ts} (100%) rename shopify/product-reviews-template/web/routes/{about.jsx => about.tsx} (100%) delete mode 100644 shopify/product-reviews-template/web/routes/index.js rename shopify/product-reviews-template/web/routes/{index.jsx => index.tsx} (100%) diff --git a/shopify/product-reviews-template/api/actions/createReviewMetaobject.js b/shopify/product-reviews-template/api/actions/createReviewMetaobject.ts similarity index 73% rename from shopify/product-reviews-template/api/actions/createReviewMetaobject.js rename to shopify/product-reviews-template/api/actions/createReviewMetaobject.ts index c9b566e3..874d26ca 100755 --- a/shopify/product-reviews-template/api/actions/createReviewMetaobject.js +++ b/shopify/product-reviews-template/api/actions/createReviewMetaobject.ts @@ -1,15 +1,10 @@ -import { CreateReviewMetaobjectGlobalActionContext } from "gadget-server"; +export const run: ActionRun = async ({ params, logger, api, connections }) => { + const { shopId, review } = params; -/** - * @param { CreateReviewMetaobjectGlobalActionContext } context - */ -export async function run({ params, logger, api, connections }) { - const { - shopId, - review: { id, rating, content, productId }, - } = params; + if (!shopId) throw new Error("shopId is required"); + if (!review || !review?.id) throw new Error("review is required"); - const shopify = connections.shopify.forShop(shopId); + const shopify = await connections.shopify.forShopId(shopId); // Create the metaobject const metaobjectCreateResponse = await shopify.graphql( @@ -35,18 +30,18 @@ export async function run({ params, logger, api, connections }) { { key: "rating", value: JSON.stringify({ - value: rating, + value: review.rating, scale_max: "5", scale_min: "0", }), }, { key: "content", - value: content, + value: review.content, }, { key: "product", - value: `gid://shopify/Product/${productId}`, + value: `gid://shopify/Product/${review.productId}`, }, ], }, @@ -59,10 +54,10 @@ export async function run({ params, logger, api, connections }) { metaobjectCreateResponse.metaobjectCreate.userErrors[0].message ); - await api.internal.review.update(id, { + await api.internal.review.update(review.id, { metaobjectId: metaobjectCreateResponse.metaobjectCreate.metaobject.id, }); -} +}; export const params = { shopId: { type: "string" }, diff --git a/shopify/product-reviews-template/api/actions/createReviewsMetafield.js b/shopify/product-reviews-template/api/actions/createReviewsMetafield.ts similarity index 80% rename from shopify/product-reviews-template/api/actions/createReviewsMetafield.js rename to shopify/product-reviews-template/api/actions/createReviewsMetafield.ts index 34480286..42a84239 100755 --- a/shopify/product-reviews-template/api/actions/createReviewsMetafield.js +++ b/shopify/product-reviews-template/api/actions/createReviewsMetafield.ts @@ -1,11 +1,8 @@ -import { CreateReviewsMetafieldGlobalActionContext } from "gadget-server"; - -/** - * @param { CreateReviewsMetafieldGlobalActionContext } context - */ -export async function run({ params, logger, api, connections }) { +export const run: ActionRun = async ({ params, logger, api, connections }) => { const { shopId, productId } = params; + if (!shopId) throw new Error("shopId is required"); + const shopify = await connections.shopify.forShopId(shopId); const metafieldsSetResponse = await shopify.graphql( @@ -34,7 +31,7 @@ export async function run({ params, logger, api, connections }) { if (metafieldsSetResponse?.metafieldsSet?.userErrors?.length) throw new Error(metafieldsSetResponse.metafieldsSet.userErrors[0].message); -} +}; export const params = { shopId: { diff --git a/shopify/product-reviews-template/api/actions/enqueueEmails.js b/shopify/product-reviews-template/api/actions/enqueueEmails.ts similarity index 62% rename from shopify/product-reviews-template/api/actions/enqueueEmails.js rename to shopify/product-reviews-template/api/actions/enqueueEmails.ts index 9c384875..be0d17a6 100755 --- a/shopify/product-reviews-template/api/actions/enqueueEmails.js +++ b/shopify/product-reviews-template/api/actions/enqueueEmails.ts @@ -1,23 +1,32 @@ -import { EnqueueEmailsGlobalActionContext } from "gadget-server"; - -/** - * @param { EnqueueEmailsGlobalActionContext } context - */ -export async function run({ params, logger, api, connections }) { +export const run: ActionRun = async ({ params, logger, api, connections }) => { const { allOrders } = params; + const options = { + queue: { + name: params.options?.queue?.name ?? "", + maxConcurrency: params.options?.queue?.maxConcurrency, + }, + retries: params.options?.retries, + }; + + if (!allOrders?.length) { + logger.info("No orders to process"); + return; + } + const orders = allOrders.splice(0, 80); - for (const { - singleUseCode, - customer: { email }, - } of orders) { - await api.enqueue(api.sendEmail, { singleUseCode, email }, options); + for (const { singleUseCode, customer } of orders) { + await api.enqueue( + api.sendEmail, + { singleUseCode, email: customer?.email }, + options + ); } if (allOrders.length) await api.enqueue(api.enqueueEmails, { allOrders, options }, options); -} +}; export const params = { allOrders: { diff --git a/shopify/product-reviews-template/api/actions/fetchOrderData.js b/shopify/product-reviews-template/api/actions/fetchOrderData.ts similarity index 64% rename from shopify/product-reviews-template/api/actions/fetchOrderData.js rename to shopify/product-reviews-template/api/actions/fetchOrderData.ts index 6df2e98b..56860c58 100755 --- a/shopify/product-reviews-template/api/actions/fetchOrderData.js +++ b/shopify/product-reviews-template/api/actions/fetchOrderData.ts @@ -1,9 +1,4 @@ -import { FetchOrderDataGlobalActionContext } from "gadget-server"; - -/** - * @param { FetchOrderDataGlobalActionContext } context - */ -export async function run({ params, logger, api, connections }) { +export const run: ActionRun = async ({ params, logger, api, connections }) => { const order = await api.shopifyOrder.maybeFindFirst({ filter: { singleUseCode: { @@ -42,28 +37,27 @@ export async function run({ params, logger, api, connections }) { while (lineItems.hasNextPage) { lineItems = await lineItems.nextPage(); - allLineItems = allLineItems.concat(lineItems); + allLineItems.push(...lineItems); } - const seen = {}; - const products = []; + const seen: { [key: string]: boolean } = {}; + const products: { + id: string; + title: string; + image: string; + alt: string; + }[] = []; - for (const { - product: { - id, - title, - featuredMedia: { - file: { alt, url }, - }, - }, - } of allLineItems) { - if (!seen[id]) { - seen[id] = true; + for (const { product } of allLineItems) { + if (!product?.id) continue; + + if (!seen[product?.id]) { + seen[product?.id] = true; products.push({ - id: id, - title: title, - image: url, - alt, + id: product?.id, + title: product.title ?? "", + image: product.featuredMedia?.file?.url ?? "", + alt: product.featuredMedia?.file?.alt ?? "", }); } } @@ -76,7 +70,7 @@ export async function run({ params, logger, api, connections }) { } else { throw new Error(`Single use code not found: ${params.code}`); } -} +}; export const params = { code: { diff --git a/shopify/product-reviews-template/api/actions/scheduledShopifySync.js b/shopify/product-reviews-template/api/actions/scheduledShopifySync.js deleted file mode 100755 index db3aa1d2..00000000 --- a/shopify/product-reviews-template/api/actions/scheduledShopifySync.js +++ /dev/null @@ -1,33 +0,0 @@ -import { ActionOptions, ScheduledShopifySyncGlobalActionContext } from "gadget-server"; -import { globalShopifySync } from "gadget-server/shopify"; - -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 - }); -}; - -/** @type { ActionOptions } */ -export const options = { - triggers: { - scheduler: [ - { - every: "day", - at: "14:21 UTC", - }, - ], - }, -}; diff --git a/shopify/product-reviews-template/api/actions/scheduledShopifySync.ts b/shopify/product-reviews-template/api/actions/scheduledShopifySync.ts new file mode 100755 index 00000000..9feaabec --- /dev/null +++ b/shopify/product-reviews-template/api/actions/scheduledShopifySync.ts @@ -0,0 +1,29 @@ +import { ActionOptions } from "gadget-server"; +import { globalShopifySync } from "gadget-server/shopify"; + +const HourInMs = 60 * 60 * 1000; + +export const run: ActionRun = async ({ 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: ActionOptions = { + triggers: { + scheduler: [ + { + every: "day", + at: "14:21 UTC", + }, + ], + }, +}; diff --git a/shopify/product-reviews-template/api/actions/sendEmail.js b/shopify/product-reviews-template/api/actions/sendEmail.js deleted file mode 100755 index 4abdd3ae..00000000 --- a/shopify/product-reviews-template/api/actions/sendEmail.js +++ /dev/null @@ -1,43 +0,0 @@ -import { SendEmailGlobalActionContext } from "gadget-server"; -import React from "react"; -import { render } from "@react-email/render"; -import { Container, Button } from "@react-email/components"; - -/** - * @param { SendEmailGlobalActionContext } context - */ -export async function run({ - params, - logger, - api, - connections, - emails, - currentAppUrl, -}) { - const { singleUseCode, email } = params; - - await emails.sendMail({ - to: email, - subject: "Review your purchase", - html: await render( - - {/* Add more text in here */} - - - ), - }); -} - -export const params = { - email: { - type: "string", - }, - singleUseCode: { - type: "string", - }, -}; diff --git a/shopify/product-reviews-template/api/actions/sendEmail.ts b/shopify/product-reviews-template/api/actions/sendEmail.ts new file mode 100755 index 00000000..71ebbfe4 --- /dev/null +++ b/shopify/product-reviews-template/api/actions/sendEmail.ts @@ -0,0 +1,29 @@ +import renderEmail from "../utilities/renderEmail"; + +export const run: ActionRun = async ({ + params, + logger, + api, + connections, + emails, + currentAppUrl, +}) => { + const { singleUseCode, email } = params; + + if (!email || !singleUseCode) throw new Error("Missing required params"); + + await emails.sendMail({ + to: email, + subject: "Review your purchase", + html: await renderEmail({ currentAppUrl, singleUseCode }), + }); +}; + +export const params = { + email: { + type: "string", + }, + singleUseCode: { + type: "string", + }, +}; diff --git a/shopify/product-reviews-template/api/actions/sendReviewRequests.js b/shopify/product-reviews-template/api/actions/sendReviewRequests.ts similarity index 75% rename from shopify/product-reviews-template/api/actions/sendReviewRequests.js rename to shopify/product-reviews-template/api/actions/sendReviewRequests.ts index 078f35a6..2ed1dbe3 100755 --- a/shopify/product-reviews-template/api/actions/sendReviewRequests.js +++ b/shopify/product-reviews-template/api/actions/sendReviewRequests.ts @@ -1,10 +1,6 @@ -import { SendReviewRequestsGlobalActionContext } from "gadget-server"; import { v4 as uuidv4 } from "uuid"; -/** - * @param { SendReviewRequestsGlobalActionContext } context - */ -export async function run({ params, logger, api, connections }) { +export const run: ActionRun = async ({ params, logger, api, connections }) => { let orders = await api.shopifyOrder.findMany({ first: 250, filter: { @@ -27,7 +23,7 @@ export async function run({ params, logger, api, connections }) { while (orders.hasNextPage) { orders = await orders.nextPage(); - allOrders = allOrders.concat(orders); + allOrders.push(...orders); } const options = { @@ -44,4 +40,4 @@ export async function run({ params, logger, api, connections }) { { allOrders: allOrders.map(({ __typeName, ...rest }) => rest), options }, options ); -} +}; diff --git a/shopify/product-reviews-template/api/actions/updateReviewsMetafield.js b/shopify/product-reviews-template/api/actions/updateReviewsMetafield.ts similarity index 100% rename from shopify/product-reviews-template/api/actions/updateReviewsMetafield.js rename to shopify/product-reviews-template/api/actions/updateReviewsMetafield.ts diff --git a/shopify/product-reviews-template/api/models/review/actions/create.js b/shopify/product-reviews-template/api/models/review/actions/create.ts similarity index 100% rename from shopify/product-reviews-template/api/models/review/actions/create.js rename to shopify/product-reviews-template/api/models/review/actions/create.ts diff --git a/shopify/product-reviews-template/api/models/review/actions/delete.js b/shopify/product-reviews-template/api/models/review/actions/delete.ts similarity index 100% rename from shopify/product-reviews-template/api/models/review/actions/delete.js rename to shopify/product-reviews-template/api/models/review/actions/delete.ts diff --git a/shopify/product-reviews-template/api/models/review/actions/update.js b/shopify/product-reviews-template/api/models/review/actions/update.ts similarity index 100% rename from shopify/product-reviews-template/api/models/review/actions/update.js rename to shopify/product-reviews-template/api/models/review/actions/update.ts diff --git a/shopify/product-reviews-template/api/models/shopifyCustomer/actions/create.js b/shopify/product-reviews-template/api/models/shopifyCustomer/actions/create.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyCustomer/actions/create.js rename to shopify/product-reviews-template/api/models/shopifyCustomer/actions/create.ts diff --git a/shopify/product-reviews-template/api/models/shopifyCustomer/actions/delete.js b/shopify/product-reviews-template/api/models/shopifyCustomer/actions/delete.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyCustomer/actions/delete.js rename to shopify/product-reviews-template/api/models/shopifyCustomer/actions/delete.ts diff --git a/shopify/product-reviews-template/api/models/shopifyCustomer/actions/update.js b/shopify/product-reviews-template/api/models/shopifyCustomer/actions/update.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyCustomer/actions/update.js rename to shopify/product-reviews-template/api/models/shopifyCustomer/actions/update.ts diff --git a/shopify/product-reviews-template/api/models/shopifyFile/actions/create.js b/shopify/product-reviews-template/api/models/shopifyFile/actions/create.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyFile/actions/create.js rename to shopify/product-reviews-template/api/models/shopifyFile/actions/create.ts diff --git a/shopify/product-reviews-template/api/models/shopifyFile/actions/delete.js b/shopify/product-reviews-template/api/models/shopifyFile/actions/delete.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyFile/actions/delete.js rename to shopify/product-reviews-template/api/models/shopifyFile/actions/delete.ts diff --git a/shopify/product-reviews-template/api/models/shopifyFile/actions/update.js b/shopify/product-reviews-template/api/models/shopifyFile/actions/update.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyFile/actions/update.js rename to shopify/product-reviews-template/api/models/shopifyFile/actions/update.ts diff --git a/shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/create.js b/shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/create.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/create.js rename to shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/create.ts diff --git a/shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/update.js b/shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/update.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/update.js rename to shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/update.ts diff --git a/shopify/product-reviews-template/api/models/shopifyOrder/actions/create.js b/shopify/product-reviews-template/api/models/shopifyOrder/actions/create.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyOrder/actions/create.js rename to shopify/product-reviews-template/api/models/shopifyOrder/actions/create.ts diff --git a/shopify/product-reviews-template/api/models/shopifyOrder/actions/delete.js b/shopify/product-reviews-template/api/models/shopifyOrder/actions/delete.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyOrder/actions/delete.js rename to shopify/product-reviews-template/api/models/shopifyOrder/actions/delete.ts diff --git a/shopify/product-reviews-template/api/models/shopifyOrder/actions/update.js b/shopify/product-reviews-template/api/models/shopifyOrder/actions/update.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyOrder/actions/update.js rename to shopify/product-reviews-template/api/models/shopifyOrder/actions/update.ts diff --git a/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/create.js b/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/create.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/create.js rename to shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/create.ts diff --git a/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/delete.js b/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/delete.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/delete.js rename to shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/delete.ts diff --git a/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/update.js b/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/update.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/update.js rename to shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/update.ts diff --git a/shopify/product-reviews-template/api/models/shopifyProduct/actions/create.js b/shopify/product-reviews-template/api/models/shopifyProduct/actions/create.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyProduct/actions/create.js rename to shopify/product-reviews-template/api/models/shopifyProduct/actions/create.ts diff --git a/shopify/product-reviews-template/api/models/shopifyProduct/actions/delete.js b/shopify/product-reviews-template/api/models/shopifyProduct/actions/delete.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyProduct/actions/delete.js rename to shopify/product-reviews-template/api/models/shopifyProduct/actions/delete.ts diff --git a/shopify/product-reviews-template/api/models/shopifyProduct/actions/update.js b/shopify/product-reviews-template/api/models/shopifyProduct/actions/update.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyProduct/actions/update.js rename to shopify/product-reviews-template/api/models/shopifyProduct/actions/update.ts diff --git a/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/create.js b/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/create.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyProductMedia/actions/create.js rename to shopify/product-reviews-template/api/models/shopifyProductMedia/actions/create.ts diff --git a/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/delete.js b/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/delete.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyProductMedia/actions/delete.js rename to shopify/product-reviews-template/api/models/shopifyProductMedia/actions/delete.ts diff --git a/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/update.js b/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/update.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyProductMedia/actions/update.js rename to shopify/product-reviews-template/api/models/shopifyProductMedia/actions/update.ts diff --git a/shopify/product-reviews-template/api/models/shopifyShop/actions/install.js b/shopify/product-reviews-template/api/models/shopifyShop/actions/install.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyShop/actions/install.js rename to shopify/product-reviews-template/api/models/shopifyShop/actions/install.ts diff --git a/shopify/product-reviews-template/api/models/shopifyShop/actions/reinstall.js b/shopify/product-reviews-template/api/models/shopifyShop/actions/reinstall.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyShop/actions/reinstall.js rename to shopify/product-reviews-template/api/models/shopifyShop/actions/reinstall.ts diff --git a/shopify/product-reviews-template/api/models/shopifyShop/actions/uninstall.js b/shopify/product-reviews-template/api/models/shopifyShop/actions/uninstall.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyShop/actions/uninstall.js rename to shopify/product-reviews-template/api/models/shopifyShop/actions/uninstall.ts diff --git a/shopify/product-reviews-template/api/models/shopifyShop/actions/update.js b/shopify/product-reviews-template/api/models/shopifyShop/actions/update.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifyShop/actions/update.js rename to shopify/product-reviews-template/api/models/shopifyShop/actions/update.ts diff --git a/shopify/product-reviews-template/api/models/shopifySync/actions/abort.js b/shopify/product-reviews-template/api/models/shopifySync/actions/abort.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifySync/actions/abort.js rename to shopify/product-reviews-template/api/models/shopifySync/actions/abort.ts diff --git a/shopify/product-reviews-template/api/models/shopifySync/actions/complete.js b/shopify/product-reviews-template/api/models/shopifySync/actions/complete.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifySync/actions/complete.js rename to shopify/product-reviews-template/api/models/shopifySync/actions/complete.ts diff --git a/shopify/product-reviews-template/api/models/shopifySync/actions/error.js b/shopify/product-reviews-template/api/models/shopifySync/actions/error.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifySync/actions/error.js rename to shopify/product-reviews-template/api/models/shopifySync/actions/error.ts diff --git a/shopify/product-reviews-template/api/models/shopifySync/actions/run.js b/shopify/product-reviews-template/api/models/shopifySync/actions/run.ts similarity index 100% rename from shopify/product-reviews-template/api/models/shopifySync/actions/run.js rename to shopify/product-reviews-template/api/models/shopifySync/actions/run.ts diff --git a/shopify/product-reviews-template/api/utilities/renderEmail.tsx b/shopify/product-reviews-template/api/utilities/renderEmail.tsx new file mode 100644 index 00000000..1900b37f --- /dev/null +++ b/shopify/product-reviews-template/api/utilities/renderEmail.tsx @@ -0,0 +1,23 @@ +import React from "react"; +import { render } from "@react-email/render"; +import { Container, Button } from "@react-email/components"; + +export default async ({ + singleUseCode, + currentAppUrl, +}: { + singleUseCode: string; + currentAppUrl: string; +}) => { + return await render( + + {/* Add more text in here */} + + + ); +}; diff --git a/shopify/product-reviews-template/index.html b/shopify/product-reviews-template/index.html index 67ede397..ffc6b999 100755 --- a/shopify/product-reviews-template/index.html +++ b/shopify/product-reviews-template/index.html @@ -1,19 +1,21 @@ - - - - New Gadget App Welcome Page - - - - - - - - - -
- - - + + + + New Gadget App Welcome Page + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/shopify/product-reviews-template/package.json b/shopify/product-reviews-template/package.json index 44ffdfaf..4b130511 100755 --- a/shopify/product-reviews-template/package.json +++ b/shopify/product-reviews-template/package.json @@ -34,6 +34,7 @@ "uuid": "^10.0.0" }, "devDependencies": { + "@types/uuid": "^10.0.0", "@types/node": "^20.12.8", "@types/react": "^18.0.28", "@types/react-dom": "^18.0.11", @@ -41,4 +42,4 @@ "typescript": "^5.4.5", "vite": "^5.3.5" } -} \ No newline at end of file +} diff --git a/shopify/product-reviews-template/tsconfig.json b/shopify/product-reviews-template/tsconfig.json new file mode 100755 index 00000000..be10f619 --- /dev/null +++ b/shopify/product-reviews-template/tsconfig.json @@ -0,0 +1,22 @@ +{ + "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": "/" + } +} \ No newline at end of file diff --git a/shopify/product-reviews-template/vite.config.mjs b/shopify/product-reviews-template/vite.config.mts similarity index 100% rename from shopify/product-reviews-template/vite.config.mjs rename to shopify/product-reviews-template/vite.config.mts diff --git a/shopify/product-reviews-template/web/api.js b/shopify/product-reviews-template/web/api.ts similarity index 100% rename from shopify/product-reviews-template/web/api.js rename to shopify/product-reviews-template/web/api.ts diff --git a/shopify/product-reviews-template/web/components/App.jsx b/shopify/product-reviews-template/web/components/App.tsx similarity index 91% rename from shopify/product-reviews-template/web/components/App.jsx rename to shopify/product-reviews-template/web/components/App.tsx index 4d6aa89a..c4a03728 100755 --- a/shopify/product-reviews-template/web/components/App.jsx +++ b/shopify/product-reviews-template/web/components/App.tsx @@ -16,7 +16,8 @@ import { useNavigate, } from "react-router-dom"; import { api } from "../api"; -import { AboutPage, Index } from "../routes"; +import AboutPage from "../routes/about"; +import Index from "../routes/index"; import "./App.css"; import Reviews from "./Reviews"; import StyledSpinner from "./StyledSpinner"; @@ -99,7 +100,7 @@ function AuthenticatedApp() { ); } -function EmbeddedApp({ isAuthenticated }) { +function EmbeddedApp({ isAuthenticated }: { isAuthenticated: boolean }) { return ( <> @@ -113,6 +114,6 @@ function EmbeddedApp({ isAuthenticated }) { ); } -function UnauthenticatedApp({ isAuthenticated }) { +function UnauthenticatedApp({ isAuthenticated }: { isAuthenticated: boolean }) { return ; } diff --git a/shopify/product-reviews-template/web/components/ApprovalButton.jsx b/shopify/product-reviews-template/web/components/ApprovalButton.tsx similarity index 100% rename from shopify/product-reviews-template/web/components/ApprovalButton.jsx rename to shopify/product-reviews-template/web/components/ApprovalButton.tsx diff --git a/shopify/product-reviews-template/web/components/Invalid.jsx b/shopify/product-reviews-template/web/components/Invalid.tsx similarity index 100% rename from shopify/product-reviews-template/web/components/Invalid.jsx rename to shopify/product-reviews-template/web/components/Invalid.tsx diff --git a/shopify/product-reviews-template/web/components/ReviewCard.jsx b/shopify/product-reviews-template/web/components/ReviewCard.tsx similarity index 100% rename from shopify/product-reviews-template/web/components/ReviewCard.jsx rename to shopify/product-reviews-template/web/components/ReviewCard.tsx diff --git a/shopify/product-reviews-template/web/components/Reviews.jsx b/shopify/product-reviews-template/web/components/Reviews.tsx similarity index 100% rename from shopify/product-reviews-template/web/components/Reviews.jsx rename to shopify/product-reviews-template/web/components/Reviews.tsx diff --git a/shopify/product-reviews-template/web/components/Stars.jsx b/shopify/product-reviews-template/web/components/Stars.tsx similarity index 100% rename from shopify/product-reviews-template/web/components/Stars.jsx rename to shopify/product-reviews-template/web/components/Stars.tsx diff --git a/shopify/product-reviews-template/web/components/StyledSpinner.jsx b/shopify/product-reviews-template/web/components/StyledSpinner.tsx similarity index 100% rename from shopify/product-reviews-template/web/components/StyledSpinner.jsx rename to shopify/product-reviews-template/web/components/StyledSpinner.tsx diff --git a/shopify/product-reviews-template/web/components/index.js b/shopify/product-reviews-template/web/components/index.ts similarity index 100% rename from shopify/product-reviews-template/web/components/index.js rename to shopify/product-reviews-template/web/components/index.ts diff --git a/shopify/product-reviews-template/web/main.jsx b/shopify/product-reviews-template/web/main.tsx similarity index 100% rename from shopify/product-reviews-template/web/main.jsx rename to shopify/product-reviews-template/web/main.tsx diff --git a/shopify/product-reviews-template/web/providers/AuthenticatedOrRedirect.jsx b/shopify/product-reviews-template/web/providers/AuthenticatedOrRedirect.tsx similarity index 100% rename from shopify/product-reviews-template/web/providers/AuthenticatedOrRedirect.jsx rename to shopify/product-reviews-template/web/providers/AuthenticatedOrRedirect.tsx diff --git a/shopify/product-reviews-template/web/providers/index.js b/shopify/product-reviews-template/web/providers/index.ts similarity index 100% rename from shopify/product-reviews-template/web/providers/index.js rename to shopify/product-reviews-template/web/providers/index.ts diff --git a/shopify/product-reviews-template/web/routes/about.jsx b/shopify/product-reviews-template/web/routes/about.tsx similarity index 100% rename from shopify/product-reviews-template/web/routes/about.jsx rename to shopify/product-reviews-template/web/routes/about.tsx diff --git a/shopify/product-reviews-template/web/routes/index.js b/shopify/product-reviews-template/web/routes/index.js deleted file mode 100644 index 77deccf5..00000000 --- a/shopify/product-reviews-template/web/routes/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { default as Index } from "./index.jsx"; -export { default as AboutPage } from "./about.jsx"; diff --git a/shopify/product-reviews-template/web/routes/index.jsx b/shopify/product-reviews-template/web/routes/index.tsx similarity index 100% rename from shopify/product-reviews-template/web/routes/index.jsx rename to shopify/product-reviews-template/web/routes/index.tsx diff --git a/shopify/product-reviews-template/yarn.lock b/shopify/product-reviews-template/yarn.lock index 757b991c..c63f5deb 100644 --- a/shopify/product-reviews-template/yarn.lock +++ b/shopify/product-reviews-template/yarn.lock @@ -1527,6 +1527,11 @@ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.23.0.tgz#0a6655b3e2708eaabca00b7372fafd7a792a7b09" integrity sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw== +"@types/uuid@^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-10.0.0.tgz#e9c07fe50da0f53dc24970cca94d619ff03f6f6d" + integrity sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ== + "@types/webpack@5.28.5": version "5.28.5" resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-5.28.5.tgz#0e9d9a15efa09bbda2cef41356ca4ac2031ea9a2" From 6e82df6098df6368af35c043a17e356cc005ccb4 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Tue, 12 Nov 2024 11:21:22 -0500 Subject: [PATCH 33/43] Moved more files to ts and incorporated the correct types --- .../api/actions/sendReviewRequests.ts | 6 +-- .../api/actions/updateReviewsMetafield.ts | 20 ++++----- .../api/models/review/actions/create.ts | 38 +++++++++-------- .../api/models/review/actions/delete.ts | 23 ++++------- .../api/models/review/actions/update.ts | 41 ++++++++++--------- .../models/shopifyCustomer/actions/create.ts | 27 +++++++----- .../models/shopifyCustomer/actions/delete.ts | 27 +++++++----- .../models/shopifyCustomer/actions/update.ts | 27 +++++++----- .../api/models/shopifyFile/actions/create.ts | 27 +++++++----- .../api/models/shopifyFile/actions/delete.ts | 27 +++++++----- .../api/models/shopifyFile/actions/update.ts | 27 +++++++----- .../shopifyGdprRequest/actions/create.ts | 29 +++++++------ .../shopifyGdprRequest/actions/update.ts | 27 +++++++----- .../api/models/shopifyOrder/actions/create.ts | 36 ++++++++-------- .../api/models/shopifyOrder/actions/delete.ts | 27 +++++++----- .../api/models/shopifyOrder/actions/update.ts | 41 +++++++++++-------- .../shopifyOrderLineItem/actions/create.ts | 27 +++++++----- .../shopifyOrderLineItem/actions/delete.ts | 27 +++++++----- .../shopifyOrderLineItem/actions/update.ts | 27 +++++++----- .../models/shopifyProduct/actions/create.ts | 36 ++++++++-------- .../models/shopifyProduct/actions/delete.ts | 27 +++++++----- .../models/shopifyProduct/actions/update.ts | 27 +++++++----- .../shopifyProductMedia/actions/create.ts | 27 +++++++----- .../shopifyProductMedia/actions/delete.ts | 27 +++++++----- .../shopifyProductMedia/actions/update.ts | 27 +++++++----- .../api/models/shopifyShop/actions/install.ts | 38 +++++++++-------- .../models/shopifyShop/actions/reinstall.ts | 27 +++++++----- .../models/shopifyShop/actions/uninstall.ts | 27 +++++++----- .../api/models/shopifyShop/actions/update.ts | 27 +++++++----- .../api/models/shopifySync/actions/abort.ts | 27 +++++++----- .../models/shopifySync/actions/complete.ts | 27 +++++++----- .../api/models/shopifySync/actions/error.ts | 27 +++++++----- .../api/models/shopifySync/actions/run.ts | 27 +++++++----- shopify/product-reviews-template/package.json | 3 +- .../product-reviews-template/tsconfig.json | 10 ++--- .../web/components/ApprovalButton.tsx | 14 ++++++- .../web/components/ReviewCard.tsx | 20 +++++++-- .../web/components/Reviews.tsx | 13 +++++- .../web/components/Stars.tsx | 4 +- .../web/providers/AuthenticatedOrRedirect.tsx | 4 +- .../web/routes/index.tsx | 6 ++- shopify/product-reviews-template/yarn.lock | 5 +++ 42 files changed, 585 insertions(+), 423 deletions(-) diff --git a/shopify/product-reviews-template/api/actions/sendReviewRequests.ts b/shopify/product-reviews-template/api/actions/sendReviewRequests.ts index 2ed1dbe3..38a60432 100755 --- a/shopify/product-reviews-template/api/actions/sendReviewRequests.ts +++ b/shopify/product-reviews-template/api/actions/sendReviewRequests.ts @@ -35,9 +35,5 @@ export const run: ActionRun = async ({ params, logger, api, connections }) => { }; if (allOrders.length) - await api.enqueue( - api.enqueueEmails, - { allOrders: allOrders.map(({ __typeName, ...rest }) => rest), options }, - options - ); + await api.enqueue(api.enqueueEmails, { allOrders, options }, options); }; diff --git a/shopify/product-reviews-template/api/actions/updateReviewsMetafield.ts b/shopify/product-reviews-template/api/actions/updateReviewsMetafield.ts index 1668f3ab..fa2e9174 100755 --- a/shopify/product-reviews-template/api/actions/updateReviewsMetafield.ts +++ b/shopify/product-reviews-template/api/actions/updateReviewsMetafield.ts @@ -1,11 +1,9 @@ -import { UpdateReviewsMetafieldGlobalActionContext } from "gadget-server"; - -/** - * @param { UpdateReviewsMetafieldGlobalActionContext } context - */ -export async function run({ params, logger, api, connections }) { +export const run: ActionRun = async ({ params, logger, api, connections }) => { const { shopId, productId, metaobjectId, approved } = params; + if (!shopId || !productId || !metaobjectId) + throw new Error("Missing required parameters"); + let value; const shopify = await connections.shopify.forShopId(shopId); @@ -20,15 +18,17 @@ export async function run({ params, logger, api, connections }) { if (!product) throw new Error("Product not found"); + const reviewsArray = product.reviewsMetafield as string[]; + if (approved) { - product.reviewsMetafield.push(metaobjectId); + reviewsArray.push(metaobjectId); value = JSON.stringify(product.reviewsMetafield); } else { - const index = product.reviewsMetafield.indexOf(metaobjectId); + const index = reviewsArray.indexOf(metaobjectId); if (index === -1) { - value = JSON.stringify(product.reviewsMetafield.splice(index, 1)); + value = JSON.stringify(reviewsArray.splice(index, 1)); } } @@ -60,7 +60,7 @@ export async function run({ params, logger, api, connections }) { if (metafieldsSetResponse?.metafieldsSet?.userErrors?.length) throw new Error(metafieldsSetResponse.metafieldsSet.userErrors[0].message); -} +}; export const params = { shopId: { diff --git a/shopify/product-reviews-template/api/models/review/actions/create.ts b/shopify/product-reviews-template/api/models/review/actions/create.ts index c5a202db..d44296aa 100755 --- a/shopify/product-reviews-template/api/models/review/actions/create.ts +++ b/shopify/product-reviews-template/api/models/review/actions/create.ts @@ -1,14 +1,12 @@ -import { - applyParams, - save, - ActionOptions, - CreateReviewActionContext, -} from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; -/** - * @param { CreateReviewActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); const order = await api.shopifyOrder.findOne(record.orderId, { @@ -18,21 +16,26 @@ export async function run({ params, record, logger, api, connections }) { }, }); + // @ts-ignore record.shop = { _link: order.shopId, }; + // @ts-ignore record.customer = { _link: order.customerId, }; await save(record); -} +}; -/** - * @param { CreateReviewActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { await api.enqueue( api.createReviewMetaobject, { @@ -51,9 +54,8 @@ export async function onSuccess({ params, record, logger, api, connections }) { }, } ); -} +}; -/** @type { ActionOptions } */ -export const options = { +export const options: ActionOptions = { actionType: "create", }; diff --git a/shopify/product-reviews-template/api/models/review/actions/delete.ts b/shopify/product-reviews-template/api/models/review/actions/delete.ts index 7ec089e2..4d201296 100755 --- a/shopify/product-reviews-template/api/models/review/actions/delete.ts +++ b/shopify/product-reviews-template/api/models/review/actions/delete.ts @@ -1,20 +1,15 @@ -import { deleteRecord, ActionOptions, DeleteReviewActionContext } from "gadget-server"; +import { deleteRecord, ActionOptions } from "gadget-server"; -/** - * @param { DeleteReviewActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { await deleteRecord(record); }; -/** - * @param { DeleteReviewActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { - // Your logic goes here -}; - -/** @type { ActionOptions } */ -export const options = { +export const options: ActionOptions = { actionType: "delete", }; diff --git a/shopify/product-reviews-template/api/models/review/actions/update.ts b/shopify/product-reviews-template/api/models/review/actions/update.ts index 2dfba8ce..15764900 100755 --- a/shopify/product-reviews-template/api/models/review/actions/update.ts +++ b/shopify/product-reviews-template/api/models/review/actions/update.ts @@ -1,25 +1,27 @@ -import { - applyParams, - save, - ActionOptions, - UpdateReviewActionContext, -} from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; -/** - * @param { UpdateReviewActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await save(record); -} +}; -/** - * @param { UpdateReviewActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { - const { changed, current: approved } = record.changes("approved"); +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { + const changes = record.changes("approved"); - if (changed) { + if (changes.changed) { + const approved = changes.current as boolean; await api.enqueue(api.updateReviewsMetafield, { shopId: record.shopId, productId: record.productId, @@ -27,9 +29,8 @@ export async function onSuccess({ params, record, logger, api, connections }) { approved, }); } -} +}; -/** @type { ActionOptions } */ -export const options = { +export const options: ActionOptions = { actionType: "update", }; diff --git a/shopify/product-reviews-template/api/models/shopifyCustomer/actions/create.ts b/shopify/product-reviews-template/api/models/shopifyCustomer/actions/create.ts index 2397a375..bf36848a 100755 --- a/shopify/product-reviews-template/api/models/shopifyCustomer/actions/create.ts +++ b/shopify/product-reviews-template/api/models/shopifyCustomer/actions/create.ts @@ -1,21 +1,26 @@ -import { applyParams, save, ActionOptions, CreateShopifyCustomerActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { CreateShopifyCustomerActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); }; -/** - * @param { CreateShopifyCustomerActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "create" }; +export const options: ActionOptions = { actionType: "create" }; diff --git a/shopify/product-reviews-template/api/models/shopifyCustomer/actions/delete.ts b/shopify/product-reviews-template/api/models/shopifyCustomer/actions/delete.ts index 8f4d586e..27c3f219 100755 --- a/shopify/product-reviews-template/api/models/shopifyCustomer/actions/delete.ts +++ b/shopify/product-reviews-template/api/models/shopifyCustomer/actions/delete.ts @@ -1,20 +1,25 @@ -import { deleteRecord, ActionOptions, DeleteShopifyCustomerActionContext } from "gadget-server"; +import { deleteRecord, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { DeleteShopifyCustomerActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { await preventCrossShopDataAccess(params, record); await deleteRecord(record); }; -/** - * @param { DeleteShopifyCustomerActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "delete" }; +export const options: ActionOptions = { actionType: "delete" }; diff --git a/shopify/product-reviews-template/api/models/shopifyCustomer/actions/update.ts b/shopify/product-reviews-template/api/models/shopifyCustomer/actions/update.ts index 0e97ed80..62cdbae8 100755 --- a/shopify/product-reviews-template/api/models/shopifyCustomer/actions/update.ts +++ b/shopify/product-reviews-template/api/models/shopifyCustomer/actions/update.ts @@ -1,21 +1,26 @@ -import { applyParams, save, ActionOptions, UpdateShopifyCustomerActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { UpdateShopifyCustomerActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); }; -/** - * @param { UpdateShopifyCustomerActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "update" }; +export const options: ActionOptions = { actionType: "update" }; diff --git a/shopify/product-reviews-template/api/models/shopifyFile/actions/create.ts b/shopify/product-reviews-template/api/models/shopifyFile/actions/create.ts index 62c11e60..bf36848a 100755 --- a/shopify/product-reviews-template/api/models/shopifyFile/actions/create.ts +++ b/shopify/product-reviews-template/api/models/shopifyFile/actions/create.ts @@ -1,21 +1,26 @@ -import { applyParams, save, ActionOptions, CreateShopifyFileActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { CreateShopifyFileActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); }; -/** - * @param { CreateShopifyFileActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "create" }; +export const options: ActionOptions = { actionType: "create" }; diff --git a/shopify/product-reviews-template/api/models/shopifyFile/actions/delete.ts b/shopify/product-reviews-template/api/models/shopifyFile/actions/delete.ts index 8e472a88..27c3f219 100755 --- a/shopify/product-reviews-template/api/models/shopifyFile/actions/delete.ts +++ b/shopify/product-reviews-template/api/models/shopifyFile/actions/delete.ts @@ -1,20 +1,25 @@ -import { deleteRecord, ActionOptions, DeleteShopifyFileActionContext } from "gadget-server"; +import { deleteRecord, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { DeleteShopifyFileActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { await preventCrossShopDataAccess(params, record); await deleteRecord(record); }; -/** - * @param { DeleteShopifyFileActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "delete" }; +export const options: ActionOptions = { actionType: "delete" }; diff --git a/shopify/product-reviews-template/api/models/shopifyFile/actions/update.ts b/shopify/product-reviews-template/api/models/shopifyFile/actions/update.ts index f6551468..62cdbae8 100755 --- a/shopify/product-reviews-template/api/models/shopifyFile/actions/update.ts +++ b/shopify/product-reviews-template/api/models/shopifyFile/actions/update.ts @@ -1,21 +1,26 @@ -import { applyParams, save, ActionOptions, UpdateShopifyFileActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { UpdateShopifyFileActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); }; -/** - * @param { UpdateShopifyFileActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "update" }; +export const options: ActionOptions = { actionType: "update" }; diff --git a/shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/create.ts b/shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/create.ts index bc8ee23f..7c005a1e 100755 --- a/shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/create.ts +++ b/shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/create.ts @@ -1,20 +1,26 @@ -import { applyParams, save, ActionOptions, CreateShopifyGdprRequestActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { CreateShopifyGdprRequestActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); }; -/** - * @param { CreateShopifyGdprRequestActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { - switch(record.topic) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { + 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. // See https://shopify.dev/apps/webhooks/configuration/mandatory-webhooks#customers-data_request for more information. @@ -31,5 +37,4 @@ export async function onSuccess({ params, record, logger, api, connections }) { } }; -/** @type { ActionOptions } */ -export const options = { actionType: "create" }; +export const options: ActionOptions = { actionType: "create" }; diff --git a/shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/update.ts b/shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/update.ts index a61bc466..62cdbae8 100755 --- a/shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/update.ts +++ b/shopify/product-reviews-template/api/models/shopifyGdprRequest/actions/update.ts @@ -1,21 +1,26 @@ -import { applyParams, save, ActionOptions, UpdateShopifyGdprRequestActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { UpdateShopifyGdprRequestActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); }; -/** - * @param { UpdateShopifyGdprRequestActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "update" }; +export const options: ActionOptions = { actionType: "update" }; diff --git a/shopify/product-reviews-template/api/models/shopifyOrder/actions/create.ts b/shopify/product-reviews-template/api/models/shopifyOrder/actions/create.ts index dc9b27f2..ba311428 100755 --- a/shopify/product-reviews-template/api/models/shopifyOrder/actions/create.ts +++ b/shopify/product-reviews-template/api/models/shopifyOrder/actions/create.ts @@ -1,30 +1,30 @@ -import { - applyParams, - save, - ActionOptions, - CreateShopifyOrderActionContext, -} from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; import { default as code } from "short-uuid"; -/** - * @param { CreateShopifyOrderActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); record.singleUseCode = code.generate(); await save(record); -} +}; -/** - * @param { CreateShopifyOrderActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here -} +}; -/** @type { ActionOptions } */ -export const options = { actionType: "create" }; +export const options: ActionOptions = { actionType: "create" }; diff --git a/shopify/product-reviews-template/api/models/shopifyOrder/actions/delete.ts b/shopify/product-reviews-template/api/models/shopifyOrder/actions/delete.ts index eda11bf8..27c3f219 100755 --- a/shopify/product-reviews-template/api/models/shopifyOrder/actions/delete.ts +++ b/shopify/product-reviews-template/api/models/shopifyOrder/actions/delete.ts @@ -1,20 +1,25 @@ -import { deleteRecord, ActionOptions, DeleteShopifyOrderActionContext } from "gadget-server"; +import { deleteRecord, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { DeleteShopifyOrderActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { await preventCrossShopDataAccess(params, record); await deleteRecord(record); }; -/** - * @param { DeleteShopifyOrderActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "delete" }; +export const options: ActionOptions = { actionType: "delete" }; diff --git a/shopify/product-reviews-template/api/models/shopifyOrder/actions/update.ts b/shopify/product-reviews-template/api/models/shopifyOrder/actions/update.ts index 4bcd9612..76f7b4d6 100755 --- a/shopify/product-reviews-template/api/models/shopifyOrder/actions/update.ts +++ b/shopify/product-reviews-template/api/models/shopifyOrder/actions/update.ts @@ -1,16 +1,14 @@ -import { - applyParams, - save, - ActionOptions, - UpdateShopifyOrderActionContext, -} from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; import { DateTime } from "luxon"; -/** - * @param { UpdateShopifyOrderActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); @@ -18,12 +16,17 @@ export async function run({ params, record, logger, api, connections }) { record.changed("fulfillmentStatus") && record.fulfillmentStatus === "fulfilled" ) { + if (!record.shopId) throw new Error("shopId is required"); + const shop = await api.shopifyShop.findOne(record.shopId, { select: { daysUntilReviewRequest: true, }, }); + if (!record.shopifyCreatedAt) + throw new Error("shopifyCreatedAt is required"); + record.requestReviewAfter = DateTime.fromJSDate( new Date(record.shopifyCreatedAt) ) @@ -32,14 +35,16 @@ export async function run({ params, record, logger, api, connections }) { } await save(record); -} +}; -/** - * @param { UpdateShopifyOrderActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here -} +}; -/** @type { ActionOptions } */ -export const options = { actionType: "update" }; +export const options: ActionOptions = { actionType: "update" }; diff --git a/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/create.ts b/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/create.ts index d65c01bb..bf36848a 100755 --- a/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/create.ts +++ b/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/create.ts @@ -1,21 +1,26 @@ -import { applyParams, save, ActionOptions, CreateShopifyOrderLineItemActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { CreateShopifyOrderLineItemActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); }; -/** - * @param { CreateShopifyOrderLineItemActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "create" }; +export const options: ActionOptions = { actionType: "create" }; diff --git a/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/delete.ts b/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/delete.ts index d2dd1caa..27c3f219 100755 --- a/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/delete.ts +++ b/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/delete.ts @@ -1,20 +1,25 @@ -import { deleteRecord, ActionOptions, DeleteShopifyOrderLineItemActionContext } from "gadget-server"; +import { deleteRecord, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { DeleteShopifyOrderLineItemActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { await preventCrossShopDataAccess(params, record); await deleteRecord(record); }; -/** - * @param { DeleteShopifyOrderLineItemActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "delete" }; +export const options: ActionOptions = { actionType: "delete" }; diff --git a/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/update.ts b/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/update.ts index 052ee39b..62cdbae8 100755 --- a/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/update.ts +++ b/shopify/product-reviews-template/api/models/shopifyOrderLineItem/actions/update.ts @@ -1,21 +1,26 @@ -import { applyParams, save, ActionOptions, UpdateShopifyOrderLineItemActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { UpdateShopifyOrderLineItemActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); }; -/** - * @param { UpdateShopifyOrderLineItemActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "update" }; +export const options: ActionOptions = { actionType: "update" }; diff --git a/shopify/product-reviews-template/api/models/shopifyProduct/actions/create.ts b/shopify/product-reviews-template/api/models/shopifyProduct/actions/create.ts index 4ffe4d24..721384cc 100755 --- a/shopify/product-reviews-template/api/models/shopifyProduct/actions/create.ts +++ b/shopify/product-reviews-template/api/models/shopifyProduct/actions/create.ts @@ -1,24 +1,25 @@ -import { - applyParams, - save, - ActionOptions, - CreateShopifyProductActionContext, -} from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { CreateShopifyProductActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); -} +}; -/** - * @param { CreateShopifyProductActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { await api.enqueue( api.createReviewsMetafield, { @@ -32,7 +33,6 @@ export async function onSuccess({ params, record, logger, api, connections }) { }, } ); -} +}; -/** @type { ActionOptions } */ -export const options = { actionType: "create" }; +export const options: ActionOptions = { actionType: "create" }; diff --git a/shopify/product-reviews-template/api/models/shopifyProduct/actions/delete.ts b/shopify/product-reviews-template/api/models/shopifyProduct/actions/delete.ts index 6a5f95b9..27c3f219 100755 --- a/shopify/product-reviews-template/api/models/shopifyProduct/actions/delete.ts +++ b/shopify/product-reviews-template/api/models/shopifyProduct/actions/delete.ts @@ -1,20 +1,25 @@ -import { deleteRecord, ActionOptions, DeleteShopifyProductActionContext } from "gadget-server"; +import { deleteRecord, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { DeleteShopifyProductActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { await preventCrossShopDataAccess(params, record); await deleteRecord(record); }; -/** - * @param { DeleteShopifyProductActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "delete" }; +export const options: ActionOptions = { actionType: "delete" }; diff --git a/shopify/product-reviews-template/api/models/shopifyProduct/actions/update.ts b/shopify/product-reviews-template/api/models/shopifyProduct/actions/update.ts index f3acd1ad..62cdbae8 100755 --- a/shopify/product-reviews-template/api/models/shopifyProduct/actions/update.ts +++ b/shopify/product-reviews-template/api/models/shopifyProduct/actions/update.ts @@ -1,21 +1,26 @@ -import { applyParams, save, ActionOptions, UpdateShopifyProductActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { UpdateShopifyProductActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); }; -/** - * @param { UpdateShopifyProductActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "update" }; +export const options: ActionOptions = { actionType: "update" }; diff --git a/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/create.ts b/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/create.ts index 9f75a0f1..bf36848a 100755 --- a/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/create.ts +++ b/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/create.ts @@ -1,21 +1,26 @@ -import { applyParams, save, ActionOptions, CreateShopifyProductMediaActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { CreateShopifyProductMediaActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); }; -/** - * @param { CreateShopifyProductMediaActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "create" }; +export const options: ActionOptions = { actionType: "create" }; diff --git a/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/delete.ts b/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/delete.ts index f62ba11a..27c3f219 100755 --- a/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/delete.ts +++ b/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/delete.ts @@ -1,20 +1,25 @@ -import { deleteRecord, ActionOptions, DeleteShopifyProductMediaActionContext } from "gadget-server"; +import { deleteRecord, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { DeleteShopifyProductMediaActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { await preventCrossShopDataAccess(params, record); await deleteRecord(record); }; -/** - * @param { DeleteShopifyProductMediaActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "delete" }; +export const options: ActionOptions = { actionType: "delete" }; diff --git a/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/update.ts b/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/update.ts index 98d6de0c..62cdbae8 100755 --- a/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/update.ts +++ b/shopify/product-reviews-template/api/models/shopifyProductMedia/actions/update.ts @@ -1,21 +1,26 @@ -import { applyParams, save, ActionOptions, UpdateShopifyProductMediaActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { UpdateShopifyProductMediaActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); }; -/** - * @param { UpdateShopifyProductMediaActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "update" }; +export const options: ActionOptions = { actionType: "update" }; diff --git a/shopify/product-reviews-template/api/models/shopifyShop/actions/install.ts b/shopify/product-reviews-template/api/models/shopifyShop/actions/install.ts index fd039306..a04076e6 100755 --- a/shopify/product-reviews-template/api/models/shopifyShop/actions/install.ts +++ b/shopify/product-reviews-template/api/models/shopifyShop/actions/install.ts @@ -1,18 +1,18 @@ -import { - applyParams, - save, - ActionOptions, - InstallShopifyShopActionContext, -} from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; -/** - * @param { InstallShopifyShopActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); const shopify = connections.shopify.current; + if (!shopify) throw new Error("Shopify connection not found"); + const reviewMetaobjectDefinitionCreateResponse = await shopify.graphql( `mutation ($definition: MetaobjectDefinitionCreateInput!) { metaobjectDefinitionCreate(definition: $definition) { @@ -119,19 +119,21 @@ export async function run({ params, record, logger, api, connections }) { metaobjectReferenceMetafieldDefinitionCreationResponse.metafieldDefinitionCreate.createdDefinition.id; await save(record); -} +}; -/** - * @param { InstallShopifyShopActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { await api.shopifySync.run({ shop: { _link: record.id, }, domain: record.domain, }); -} +}; -/** @type { ActionOptions } */ -export const options = { actionType: "create" }; +export const options: ActionOptions = { actionType: "create" }; diff --git a/shopify/product-reviews-template/api/models/shopifyShop/actions/reinstall.ts b/shopify/product-reviews-template/api/models/shopifyShop/actions/reinstall.ts index 8f6a5538..62cdbae8 100755 --- a/shopify/product-reviews-template/api/models/shopifyShop/actions/reinstall.ts +++ b/shopify/product-reviews-template/api/models/shopifyShop/actions/reinstall.ts @@ -1,21 +1,26 @@ -import { applyParams, save, ActionOptions, ReinstallShopifyShopActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { ReinstallShopifyShopActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); }; -/** - * @param { ReinstallShopifyShopActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "update" }; +export const options: ActionOptions = { actionType: "update" }; diff --git a/shopify/product-reviews-template/api/models/shopifyShop/actions/uninstall.ts b/shopify/product-reviews-template/api/models/shopifyShop/actions/uninstall.ts index 8edc501c..62cdbae8 100755 --- a/shopify/product-reviews-template/api/models/shopifyShop/actions/uninstall.ts +++ b/shopify/product-reviews-template/api/models/shopifyShop/actions/uninstall.ts @@ -1,21 +1,26 @@ -import { applyParams, save, ActionOptions, UninstallShopifyShopActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { UninstallShopifyShopActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); }; -/** - * @param { UninstallShopifyShopActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { actionType: "update" }; +export const options: ActionOptions = { actionType: "update" }; diff --git a/shopify/product-reviews-template/api/models/shopifyShop/actions/update.ts b/shopify/product-reviews-template/api/models/shopifyShop/actions/update.ts index a491ae74..667270a4 100755 --- a/shopify/product-reviews-template/api/models/shopifyShop/actions/update.ts +++ b/shopify/product-reviews-template/api/models/shopifyShop/actions/update.ts @@ -1,24 +1,29 @@ -import { applyParams, save, ActionOptions, UpdateShopifyShopActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { UpdateShopifyShopActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); }; -/** - * @param { UpdateShopifyShopActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { +export const options: ActionOptions = { actionType: "update", triggers: { api: true }, }; diff --git a/shopify/product-reviews-template/api/models/shopifySync/actions/abort.ts b/shopify/product-reviews-template/api/models/shopifySync/actions/abort.ts index 5e79c252..aaeed652 100755 --- a/shopify/product-reviews-template/api/models/shopifySync/actions/abort.ts +++ b/shopify/product-reviews-template/api/models/shopifySync/actions/abort.ts @@ -1,25 +1,30 @@ -import { applyParams, save, ActionOptions, AbortShopifySyncActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess, abortSync } from "gadget-server/shopify"; -/** - * @param { AbortShopifySyncActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await abortSync(params, record); await save(record); }; -/** - * @param { AbortShopifySyncActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { +export const options: ActionOptions = { actionType: "update", triggers: { api: true }, }; diff --git a/shopify/product-reviews-template/api/models/shopifySync/actions/complete.ts b/shopify/product-reviews-template/api/models/shopifySync/actions/complete.ts index d18213d9..667270a4 100755 --- a/shopify/product-reviews-template/api/models/shopifySync/actions/complete.ts +++ b/shopify/product-reviews-template/api/models/shopifySync/actions/complete.ts @@ -1,24 +1,29 @@ -import { applyParams, save, ActionOptions, CompleteShopifySyncActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { CompleteShopifySyncActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); }; -/** - * @param { CompleteShopifySyncActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { +export const options: ActionOptions = { actionType: "update", triggers: { api: true }, }; diff --git a/shopify/product-reviews-template/api/models/shopifySync/actions/error.ts b/shopify/product-reviews-template/api/models/shopifySync/actions/error.ts index fb04c884..667270a4 100755 --- a/shopify/product-reviews-template/api/models/shopifySync/actions/error.ts +++ b/shopify/product-reviews-template/api/models/shopifySync/actions/error.ts @@ -1,24 +1,29 @@ -import { applyParams, save, ActionOptions, ErrorShopifySyncActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; -/** - * @param { ErrorShopifySyncActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); await save(record); }; -/** - * @param { ErrorShopifySyncActionContext } context - */ -export async function onSuccess({ params, record, logger, api, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { +export const options: ActionOptions = { actionType: "update", triggers: { api: true }, }; diff --git a/shopify/product-reviews-template/api/models/shopifySync/actions/run.ts b/shopify/product-reviews-template/api/models/shopifySync/actions/run.ts index e74ae649..18e6ffc8 100755 --- a/shopify/product-reviews-template/api/models/shopifySync/actions/run.ts +++ b/shopify/product-reviews-template/api/models/shopifySync/actions/run.ts @@ -1,25 +1,30 @@ -import { applyParams, save, ActionOptions, RunShopifySyncActionContext } from "gadget-server"; +import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess, shopifySync } from "gadget-server/shopify"; -/** - * @param { RunShopifySyncActionContext } context - */ -export async function run({ params, record, logger, api, connections }) { +export const run: ActionRun = async ({ + params, + record, + logger, + api, + connections, +}) => { 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, connections }) { +export const onSuccess: ActionOnSuccess = async ({ + params, + record, + logger, + api, + connections, +}) => { // Your logic goes here }; -/** @type { ActionOptions } */ -export const options = { +export const options: ActionOptions = { actionType: "create", triggers: { api: true }, }; diff --git a/shopify/product-reviews-template/package.json b/shopify/product-reviews-template/package.json index 4b130511..dcda4774 100755 --- a/shopify/product-reviews-template/package.json +++ b/shopify/product-reviews-template/package.json @@ -34,10 +34,11 @@ "uuid": "^10.0.0" }, "devDependencies": { - "@types/uuid": "^10.0.0", + "@types/luxon": "^3.4.2", "@types/node": "^20.12.8", "@types/react": "^18.0.28", "@types/react-dom": "^18.0.11", + "@types/uuid": "^10.0.0", "@vitejs/plugin-react-swc": "3.2.0", "typescript": "^5.4.5", "vite": "^5.3.5" diff --git a/shopify/product-reviews-template/tsconfig.json b/shopify/product-reviews-template/tsconfig.json index be10f619..95596bbd 100755 --- a/shopify/product-reviews-template/tsconfig.json +++ b/shopify/product-reviews-template/tsconfig.json @@ -9,14 +9,12 @@ "emitDecoratorMetadata": true, "forceConsistentCasingInFileNames": true, "target": "es2020", - "lib": [ - "es2020", - "DOM" - ], + "lib": ["es2020", "DOM"], "skipLibCheck": true, "jsx": "react-jsx", "moduleResolution": "Bundler", "resolveJsonModule": true, - "baseUrl": "/" + "baseUrl": "/", + "noEmit": true } -} \ No newline at end of file +} diff --git a/shopify/product-reviews-template/web/components/ApprovalButton.tsx b/shopify/product-reviews-template/web/components/ApprovalButton.tsx index ac9d6fb5..36d0e436 100644 --- a/shopify/product-reviews-template/web/components/ApprovalButton.tsx +++ b/shopify/product-reviews-template/web/components/ApprovalButton.tsx @@ -3,7 +3,16 @@ import { api } from "../api"; import { useAction } from "@gadgetinc/react"; import { useEffect } from "react"; -export default ({ record: { id, approved }, toast }) => { +export default ({ + record: { id, approved }, + toast, +}: { + record: { id: string; approved: boolean }; + toast: { + show(message: string, opts?: any): string; + hide(id: string): void; + }; +}) => { const [{ data, fetching, error }, run] = useAction(api.review.update); useEffect(() => { @@ -30,7 +39,8 @@ export default ({ record: { id, approved }, toast }) => { onClick={() => run({ id, approved: !approved })} loading={fetching} disabled={fetching} - tone={approved ? "critical" : "primary"} + variant="primary" + tone={approved ? "critical" : undefined} > {approved ? "Remove" : "Approve"} diff --git a/shopify/product-reviews-template/web/components/ReviewCard.tsx b/shopify/product-reviews-template/web/components/ReviewCard.tsx index 7c9da254..61107e72 100644 --- a/shopify/product-reviews-template/web/components/ReviewCard.tsx +++ b/shopify/product-reviews-template/web/components/ReviewCard.tsx @@ -24,7 +24,19 @@ import { api } from "../api"; import { useState } from "react"; import Stars from "./Stars"; -export default ({ id: productId, title, orderId, image, alt }) => { +export default ({ + id: productId, + title, + orderId, + image, + alt, +}: { + id: string; + title: string; + orderId: string; + image: string; + alt: string; +}) => { const [open, setOpen] = useState(false); const [completed, setCompleted] = useState(false); @@ -44,11 +56,13 @@ export default ({ id: productId, title, orderId, image, alt }) => { {completed && ( - Review completed! + + Review completed! + )}
- + { return ( - {data?.products?.map((product) => ( + {( + data as { + orderId: string; + orderNumber: string; + products: { + id: string; + title: string; + image: string; + alt: string; + }[]; + } + )?.products?.map((product) => ( ))} diff --git a/shopify/product-reviews-template/web/components/Stars.tsx b/shopify/product-reviews-template/web/components/Stars.tsx index 994ddbaf..67e66ab4 100755 --- a/shopify/product-reviews-template/web/components/Stars.tsx +++ b/shopify/product-reviews-template/web/components/Stars.tsx @@ -3,12 +3,12 @@ import { Box, Icon, InlineStack } from "@shopify/polaris"; import { StarFilledIcon, StarIcon } from "@shopify/polaris-icons"; import { Controller, useFormContext } from "@gadgetinc/react"; -export default ({ rating }) => { +export default ({ rating }: { rating?: number }) => { const [hoveredStar, setHoveredStar] = useState(0); const formContext = useFormContext(); - const handleMouseEnter = (index) => { + const handleMouseEnter = (index: number) => { setHoveredStar(index + 1); }; diff --git a/shopify/product-reviews-template/web/providers/AuthenticatedOrRedirect.tsx b/shopify/product-reviews-template/web/providers/AuthenticatedOrRedirect.tsx index 9ea554a5..3c87587b 100644 --- a/shopify/product-reviews-template/web/providers/AuthenticatedOrRedirect.tsx +++ b/shopify/product-reviews-template/web/providers/AuthenticatedOrRedirect.tsx @@ -1,8 +1,8 @@ import { useEffect } from "react"; import { useNavigate, useOutletContext } from "react-router-dom"; -export default ({ children }) => { - const { isAuthenticated } = useOutletContext(); +export default ({ children }: { children: React.ReactNode }) => { + const { isAuthenticated } = useOutletContext<{ isAuthenticated: boolean }>(); const navigate = useNavigate(); useEffect(() => { diff --git a/shopify/product-reviews-template/web/routes/index.tsx b/shopify/product-reviews-template/web/routes/index.tsx index faae33a9..b2516337 100755 --- a/shopify/product-reviews-template/web/routes/index.tsx +++ b/shopify/product-reviews-template/web/routes/index.tsx @@ -21,7 +21,7 @@ export default function () { - + - {modalContent} + + {modalContent} +
diff --git a/shopify/product-reviews-template/yarn.lock b/shopify/product-reviews-template/yarn.lock index c63f5deb..e8af8c32 100644 --- a/shopify/product-reviews-template/yarn.lock +++ b/shopify/product-reviews-template/yarn.lock @@ -1460,6 +1460,11 @@ dependencies: "@types/node" "*" +"@types/luxon@^3.4.2": + version "3.4.2" + resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-3.4.2.tgz#e4fc7214a420173cea47739c33cdf10874694db7" + integrity sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA== + "@types/node@*", "@types/node@>=10.0.0": version "22.4.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-22.4.1.tgz#9b595d292c65b94c20923159e2ce947731b6fdce" From 9b24535f245c42566ac410e46a7862f72e8ced29 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Tue, 12 Nov 2024 13:01:26 -0500 Subject: [PATCH 34/43] Working on fixing TS issues with sendReviewRequests and Stars --- .../api/actions/scheduledShopifySync.ts | 29 ------------------- .../api/actions/sendReviewRequests.ts | 12 +++++++- .../api/actions/updateReviewsMetafield.ts | 2 +- .../api/utilities/renderEmail.tsx | 3 ++ 4 files changed, 15 insertions(+), 31 deletions(-) delete mode 100755 shopify/product-reviews-template/api/actions/scheduledShopifySync.ts diff --git a/shopify/product-reviews-template/api/actions/scheduledShopifySync.ts b/shopify/product-reviews-template/api/actions/scheduledShopifySync.ts deleted file mode 100755 index 9feaabec..00000000 --- a/shopify/product-reviews-template/api/actions/scheduledShopifySync.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { ActionOptions } from "gadget-server"; -import { globalShopifySync } from "gadget-server/shopify"; - -const HourInMs = 60 * 60 * 1000; - -export const run: ActionRun = async ({ 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: ActionOptions = { - triggers: { - scheduler: [ - { - every: "day", - at: "14:21 UTC", - }, - ], - }, -}; diff --git a/shopify/product-reviews-template/api/actions/sendReviewRequests.ts b/shopify/product-reviews-template/api/actions/sendReviewRequests.ts index 38a60432..20c4a97a 100755 --- a/shopify/product-reviews-template/api/actions/sendReviewRequests.ts +++ b/shopify/product-reviews-template/api/actions/sendReviewRequests.ts @@ -35,5 +35,15 @@ export const run: ActionRun = async ({ params, logger, api, connections }) => { }; if (allOrders.length) - await api.enqueue(api.enqueueEmails, { allOrders, options }, options); + await api.enqueue( + api.enqueueEmails, + { allOrders: allOrders.map(({ __typename, ...rest }) => rest), options }, + options + ); +}; + +export const options = { + triggers: { + scheduler: [{ every: "hour", at: "0 mins" }], + }, }; diff --git a/shopify/product-reviews-template/api/actions/updateReviewsMetafield.ts b/shopify/product-reviews-template/api/actions/updateReviewsMetafield.ts index fa2e9174..b4f182ec 100755 --- a/shopify/product-reviews-template/api/actions/updateReviewsMetafield.ts +++ b/shopify/product-reviews-template/api/actions/updateReviewsMetafield.ts @@ -6,10 +6,10 @@ export const run: ActionRun = async ({ params, logger, api, connections }) => { let value; + // eslint-disable-next-line const shopify = await connections.shopify.forShopId(shopId); // Build the metafield value - const product = await api.shopifyProduct.maybeFindOne(productId, { select: { reviewsMetafield: true, diff --git a/shopify/product-reviews-template/api/utilities/renderEmail.tsx b/shopify/product-reviews-template/api/utilities/renderEmail.tsx index 1900b37f..73547347 100644 --- a/shopify/product-reviews-template/api/utilities/renderEmail.tsx +++ b/shopify/product-reviews-template/api/utilities/renderEmail.tsx @@ -1,6 +1,7 @@ import React from "react"; import { render } from "@react-email/render"; import { Container, Button } from "@react-email/components"; +import { logger } from "gadget-server"; export default async ({ singleUseCode, @@ -9,6 +10,8 @@ export default async ({ singleUseCode: string; currentAppUrl: string; }) => { + logger.info({ singleUseCode, currentAppUrl }, "HERE"); + return await render( {/* Add more text in here */} From 5bbba9518f540445aace304c064ef0e72133b1b6 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Tue, 12 Nov 2024 13:52:46 -0500 Subject: [PATCH 35/43] Fixing final issues with types --- .../api/actions/enqueueEmails.ts | 7 +++++-- .../api/actions/sendEmail.ts | 13 +++++++++++-- .../api/actions/sendReviewRequests.ts | 12 +++++++++++- .../api/utilities/renderEmail.tsx | 2 +- .../web/components/ReviewCard.tsx | 2 +- .../web/components/Stars.tsx | 6 +++--- 6 files changed, 32 insertions(+), 10 deletions(-) diff --git a/shopify/product-reviews-template/api/actions/enqueueEmails.ts b/shopify/product-reviews-template/api/actions/enqueueEmails.ts index be0d17a6..08483a91 100755 --- a/shopify/product-reviews-template/api/actions/enqueueEmails.ts +++ b/shopify/product-reviews-template/api/actions/enqueueEmails.ts @@ -16,10 +16,10 @@ export const run: ActionRun = async ({ params, logger, api, connections }) => { const orders = allOrders.splice(0, 80); - for (const { singleUseCode, customer } of orders) { + for (const { singleUseCode, customer, id } of orders) { await api.enqueue( api.sendEmail, - { singleUseCode, email: customer?.email }, + { singleUseCode, email: customer?.email, orderId: id }, options ); } @@ -45,6 +45,9 @@ export const params = { }, }, }, + id: { + type: "string", + }, }, }, }, diff --git a/shopify/product-reviews-template/api/actions/sendEmail.ts b/shopify/product-reviews-template/api/actions/sendEmail.ts index 71ebbfe4..2db8c5ed 100755 --- a/shopify/product-reviews-template/api/actions/sendEmail.ts +++ b/shopify/product-reviews-template/api/actions/sendEmail.ts @@ -8,15 +8,21 @@ export const run: ActionRun = async ({ emails, currentAppUrl, }) => { - const { singleUseCode, email } = params; + const { singleUseCode, email, orderId } = params; - if (!email || !singleUseCode) throw new Error("Missing required params"); + if (!email || !singleUseCode || !orderId) + throw new Error("Missing required params"); await emails.sendMail({ to: email, subject: "Review your purchase", html: await renderEmail({ currentAppUrl, singleUseCode }), }); + + // Clear the field so we don't send the email again + await api.internal.shopifyOrder.update(orderId, { + requestReviewAfter: null, + }); }; export const params = { @@ -26,4 +32,7 @@ export const params = { singleUseCode: { type: "string", }, + orderId: { + type: "string", + }, }; diff --git a/shopify/product-reviews-template/api/actions/sendReviewRequests.ts b/shopify/product-reviews-template/api/actions/sendReviewRequests.ts index 20c4a97a..5e09e94d 100755 --- a/shopify/product-reviews-template/api/actions/sendReviewRequests.ts +++ b/shopify/product-reviews-template/api/actions/sendReviewRequests.ts @@ -1,3 +1,7 @@ +import { + GadgetRecordList, + ShopifyOrder, +} from "@gadget-client/product-reviews-template"; import { v4 as uuidv4 } from "uuid"; export const run: ActionRun = async ({ params, logger, api, connections }) => { @@ -12,6 +16,7 @@ export const run: ActionRun = async ({ params, logger, api, connections }) => { }, }, select: { + id: true, singleUseCode: true, customer: { email: true, @@ -37,7 +42,12 @@ export const run: ActionRun = async ({ params, logger, api, connections }) => { if (allOrders.length) await api.enqueue( api.enqueueEmails, - { allOrders: allOrders.map(({ __typename, ...rest }) => rest), options }, + { + allOrders: (allOrders as GadgetRecordList).map( + ({ __typename, ...rest }) => rest + ), + options, + }, options ); }; diff --git a/shopify/product-reviews-template/api/utilities/renderEmail.tsx b/shopify/product-reviews-template/api/utilities/renderEmail.tsx index 73547347..30673918 100644 --- a/shopify/product-reviews-template/api/utilities/renderEmail.tsx +++ b/shopify/product-reviews-template/api/utilities/renderEmail.tsx @@ -16,7 +16,7 @@ export default async ({ {/* Add more text in here */}
))} )} From 9a64e91f90db70435b59810ab1343c596e976579 Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Tue, 12 Nov 2024 14:03:42 -0500 Subject: [PATCH 36/43] Moving queue opitions to their own file --- .../api/actions/enqueueEmails.ts | 33 +++---------------- .../api/actions/sendReviewRequests.ts | 13 ++------ .../api/utilities/emailQueueOptions.ts | 9 +++++ .../web/components/ApprovalButton.tsx | 2 +- .../web/routes/index.tsx | 2 +- 5 files changed, 17 insertions(+), 42 deletions(-) create mode 100644 shopify/product-reviews-template/api/utilities/emailQueueOptions.ts diff --git a/shopify/product-reviews-template/api/actions/enqueueEmails.ts b/shopify/product-reviews-template/api/actions/enqueueEmails.ts index 08483a91..e1f55ec7 100755 --- a/shopify/product-reviews-template/api/actions/enqueueEmails.ts +++ b/shopify/product-reviews-template/api/actions/enqueueEmails.ts @@ -1,14 +1,8 @@ +import { default as queueOptions } from "../utilities/emailQueueOptions"; + export const run: ActionRun = async ({ params, logger, api, connections }) => { const { allOrders } = params; - const options = { - queue: { - name: params.options?.queue?.name ?? "", - maxConcurrency: params.options?.queue?.maxConcurrency, - }, - retries: params.options?.retries, - }; - if (!allOrders?.length) { logger.info("No orders to process"); return; @@ -20,12 +14,12 @@ export const run: ActionRun = async ({ params, logger, api, connections }) => { await api.enqueue( api.sendEmail, { singleUseCode, email: customer?.email, orderId: id }, - options + queueOptions ); } if (allOrders.length) - await api.enqueue(api.enqueueEmails, { allOrders, options }, options); + await api.enqueue(api.enqueueEmails, { allOrders }, queueOptions); }; export const params = { @@ -51,23 +45,4 @@ export const params = { }, }, }, - options: { - type: "object", - properties: { - queue: { - type: "object", - properties: { - name: { - type: "string", - }, - maxConcurrency: { - type: "number", - }, - }, - }, - retries: { - type: "number", - }, - }, - }, }; diff --git a/shopify/product-reviews-template/api/actions/sendReviewRequests.ts b/shopify/product-reviews-template/api/actions/sendReviewRequests.ts index 5e09e94d..e0fb1e24 100755 --- a/shopify/product-reviews-template/api/actions/sendReviewRequests.ts +++ b/shopify/product-reviews-template/api/actions/sendReviewRequests.ts @@ -2,7 +2,7 @@ import { GadgetRecordList, ShopifyOrder, } from "@gadget-client/product-reviews-template"; -import { v4 as uuidv4 } from "uuid"; +import { default as queueOptions } from "../utilities/emailQueueOptions"; export const run: ActionRun = async ({ params, logger, api, connections }) => { let orders = await api.shopifyOrder.findMany({ @@ -31,14 +31,6 @@ export const run: ActionRun = async ({ params, logger, api, connections }) => { allOrders.push(...orders); } - const options = { - queue: { - name: `send-wishlist-emails-${uuidv4()}`, - maxConcurrency: 50, - }, - retries: 1, - }; - if (allOrders.length) await api.enqueue( api.enqueueEmails, @@ -46,9 +38,8 @@ export const run: ActionRun = async ({ params, logger, api, connections }) => { allOrders: (allOrders as GadgetRecordList).map( ({ __typename, ...rest }) => rest ), - options, }, - options + queueOptions ); }; diff --git a/shopify/product-reviews-template/api/utilities/emailQueueOptions.ts b/shopify/product-reviews-template/api/utilities/emailQueueOptions.ts new file mode 100644 index 00000000..0df8a503 --- /dev/null +++ b/shopify/product-reviews-template/api/utilities/emailQueueOptions.ts @@ -0,0 +1,9 @@ +import { v4 as uuidv4 } from "uuid"; + +export default { + queue: { + name: `send-wishlist-emails-${uuidv4()}`, + maxConcurrency: 50, + }, + retries: 1, +}; diff --git a/shopify/product-reviews-template/web/components/ApprovalButton.tsx b/shopify/product-reviews-template/web/components/ApprovalButton.tsx index 36d0e436..00a4811d 100644 --- a/shopify/product-reviews-template/web/components/ApprovalButton.tsx +++ b/shopify/product-reviews-template/web/components/ApprovalButton.tsx @@ -39,7 +39,7 @@ export default ({ onClick={() => run({ id, approved: !approved })} loading={fetching} disabled={fetching} - variant="primary" + variant="secondary" tone={approved ? "critical" : undefined} > {approved ? "Remove" : "Approve"} diff --git a/shopify/product-reviews-template/web/routes/index.tsx b/shopify/product-reviews-template/web/routes/index.tsx index b2516337..11bc838a 100755 --- a/shopify/product-reviews-template/web/routes/index.tsx +++ b/shopify/product-reviews-template/web/routes/index.tsx @@ -18,7 +18,7 @@ export default function () { const [modalContent, setModelContent] = useState(""); return ( - + From 5ae384cbba0a39310aec9a063af3d96957d967ec Mon Sep 17 00:00:00 2001 From: Antoine Charette Date: Wed, 13 Nov 2024 11:36:54 -0500 Subject: [PATCH 37/43] Fixing issues with the way that the URL is accessed and adding more information in readme --- .../.template/docs/intro.md | 9 ++++++ .../.template/docs/setup.md | 23 ++++++++++++-- .../api/actions/fetchOrderData.ts | 12 ++++---- .../api/models/review/actions/create.ts | 23 +++++++++++++- .../api/models/review/schema.gadget.ts | 5 ++++ .../api/models/shopifyOrder/actions/create.ts | 8 +++-- .../api/models/shopifyOrder/actions/update.ts | 6 ++++ .../reviewCreationLimitReached.gelly | 3 ++ .../api/models/shopifyOrder/schema.gadget.ts | 10 +++++++ .../utilities/setReviewCreationLimit.ts | 30 +++++++++++++++++++ .../shopifyOrderLineItem/schema.gadget.ts | 9 +++++- .../api/utilities/renderEmail.tsx | 1 + .../web/components/ReviewCard.tsx | 10 +++++-- .../web/components/Reviews.tsx | 4 +++ 14 files changed, 138 insertions(+), 15 deletions(-) create mode 100755 shopify/product-reviews-template/api/models/shopifyOrder/reviewCreationLimitReached.gelly create mode 100644 shopify/product-reviews-template/api/models/shopifyOrder/utilities/setReviewCreationLimit.ts diff --git a/shopify/product-reviews-template/.template/docs/intro.md b/shopify/product-reviews-template/.template/docs/intro.md index 5be352f8..1cf01c5a 100755 --- a/shopify/product-reviews-template/.template/docs/intro.md +++ b/shopify/product-reviews-template/.template/docs/intro.md @@ -3,3 +3,12 @@ This template has [setup instructions](template-setup). This template allows merchants to collect and manage reviews for their products, leveraging Shopify's metaobject system for storing review data. Review requests are sent a set number of days after the order is completely fulfilled. + +## App flow overview + +- A customer places an order from the Shopify storefront +- Once the order is fully fulfilled, a date is set to send a review request email to the customer +- On the designated date, the email is sent +- The customer clicks a button in the email, redirecting them to a page listing their purchased products. Here, they can review each product until all have been reviewed + +Once all products are reviewed, the customer may no longer access the page. diff --git a/shopify/product-reviews-template/.template/docs/setup.md b/shopify/product-reviews-template/.template/docs/setup.md index 39a820f6..23c82984 100644 --- a/shopify/product-reviews-template/.template/docs/setup.md +++ b/shopify/product-reviews-template/.template/docs/setup.md @@ -4,6 +4,25 @@ A list of steps that you should follow: 1. [Connect to Shopify](https://docs.gadget.dev/guides/tutorials/connecting-to-shopify#connecting-to-shopify) using our built-in Shopify plugin. -2. Sync the code locally using `ggt` ([Gadget CLI](https://docs.gadget.dev/reference/ggt#ggt-reference)) and run `yarn dev` to test the application. Note that you're require to have a `shopify.app.toml` to run `yarn dev`. Make sure to install the [Shopify CLI](https://shopify.dev/docs/api/shopify-cli#installation) using these instructions. +2. Fill out the Protected Customer Data Access form in the Shopify Partner dashboard. Make usre to fill out the optional section. -3. Install the application on a development store, and add the extension block to the product page. When testing, make sure that you're always running `yarn dev`. +3. Sync the code locally using `ggt` ([Gadget CLI](https://docs.gadget.dev/reference/ggt#ggt-reference)) and run `yarn dev` to test the application. Note that you're require to have a `shopify.app.toml` to run `yarn dev`. Make sure to install the [Shopify CLI](https://shopify.dev/docs/api/shopify-cli#installation) using these instructions. + +4. Install the application on a development store, and add the extension block to the product page. When testing, make sure that you're always running `yarn dev`. + +## Testing + +### Reviews + +- Create an order + - Go to Shopify Admin and create a new order. + - Mark the order as paid and fulfilled. +- Modify the review request date + - In your Gadget app, navigate to the shopifyOrder model data viewer. + - Find the created order and manually set the review request date to the current date +- Send the review request email + - Run the sendReviewRequests action in the Gadget app using the API Playground + - The review request email will be sent to the customer’s email address +- Create review + - Open the email, and click the provided button to go to the review page + - Review each product on the page diff --git a/shopify/product-reviews-template/api/actions/fetchOrderData.ts b/shopify/product-reviews-template/api/actions/fetchOrderData.ts index 56860c58..ff2769de 100755 --- a/shopify/product-reviews-template/api/actions/fetchOrderData.ts +++ b/shopify/product-reviews-template/api/actions/fetchOrderData.ts @@ -8,6 +8,7 @@ export const run: ActionRun = async ({ params, logger, api, connections }) => { select: { id: true, orderNumber: true, + reviewCreationLimit: true, }, }); @@ -20,6 +21,7 @@ export const run: ActionRun = async ({ params, logger, api, connections }) => { }, select: { id: true, + reviewCreated: true, product: { id: true, title: true, @@ -46,9 +48,11 @@ export const run: ActionRun = async ({ params, logger, api, connections }) => { title: string; image: string; alt: string; + reviewCreated: boolean; + lineItemId: string; }[] = []; - for (const { product } of allLineItems) { + for (const { id, reviewCreated, product } of allLineItems) { if (!product?.id) continue; if (!seen[product?.id]) { @@ -58,14 +62,12 @@ export const run: ActionRun = async ({ params, logger, api, connections }) => { title: product.title ?? "", image: product.featuredMedia?.file?.url ?? "", alt: product.featuredMedia?.file?.alt ?? "", + reviewCreated: reviewCreated ?? false, + lineItemId: id, }); } } - await api.internal.shopifyOrder.update(order.id, { - singleUseCode: null, - }); - return { orderId: order.id, orderNumber: order.orderNumber, products }; } else { throw new Error(`Single use code not found: ${params.code}`); diff --git a/shopify/product-reviews-template/api/models/review/actions/create.ts b/shopify/product-reviews-template/api/models/review/actions/create.ts index d44296aa..5073c536 100755 --- a/shopify/product-reviews-template/api/models/review/actions/create.ts +++ b/shopify/product-reviews-template/api/models/review/actions/create.ts @@ -26,6 +26,12 @@ export const run: ActionRun = async ({ _link: order.customerId, }; + if (!record.lineItemId) throw new Error("Line item not provided"); + + await api.internal.shopifyOrderLineItem.update(record.lineItemId, { + reviewCreated: true, + }); + await save(record); }; @@ -39,7 +45,8 @@ export const onSuccess: ActionOnSuccess = async ({ await api.enqueue( api.createReviewMetaobject, { - shopId: record.shopId, + // @ts-ignore + shopId: record.shop, review: { id: record.id, rating: record.rating, @@ -54,6 +61,20 @@ export const onSuccess: ActionOnSuccess = async ({ }, } ); + + const order = await api.shopifyOrder.findOne(record.orderId, { + select: { + reviewCreationLimitReached: true, + }, + }); + + logger.info({ order }, "ORDER"); + + if (order?.reviewCreationLimitReached) { + await api.internal.shopifyOrder.update(record.orderId, { + singleUseCode: null, + }); + } }; export const options: ActionOptions = { diff --git a/shopify/product-reviews-template/api/models/review/schema.gadget.ts b/shopify/product-reviews-template/api/models/review/schema.gadget.ts index 3015848d..7a2c2be0 100755 --- a/shopify/product-reviews-template/api/models/review/schema.gadget.ts +++ b/shopify/product-reviews-template/api/models/review/schema.gadget.ts @@ -28,6 +28,11 @@ export const schema: GadgetModel = { parent: { model: "shopifyCustomer" }, storageKey: "bT0Adl6mg5Lc", }, + lineItem: { + type: "belongsTo", + parent: { model: "shopifyOrderLineItem" }, + storageKey: "eGLOUcOXKbyh", + }, metaobjectId: { type: "string", storageKey: "MDTelmNZFvN8" }, order: { type: "belongsTo", diff --git a/shopify/product-reviews-template/api/models/shopifyOrder/actions/create.ts b/shopify/product-reviews-template/api/models/shopifyOrder/actions/create.ts index ba311428..57dfe00b 100755 --- a/shopify/product-reviews-template/api/models/shopifyOrder/actions/create.ts +++ b/shopify/product-reviews-template/api/models/shopifyOrder/actions/create.ts @@ -1,6 +1,7 @@ import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; import { default as code } from "short-uuid"; +import setReviewCreationLimit from "../utilities/setReviewCreationLimit"; export const run: ActionRun = async ({ params, @@ -8,12 +9,15 @@ export const run: ActionRun = async ({ logger, api, connections, + trigger, }) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); record.singleUseCode = code.generate(); + setReviewCreationLimit({ record, trigger }); + await save(record); }; @@ -23,8 +27,6 @@ export const onSuccess: ActionOnSuccess = async ({ logger, api, connections, -}) => { - // Your logic goes here -}; +}) => {}; export const options: ActionOptions = { actionType: "create" }; diff --git a/shopify/product-reviews-template/api/models/shopifyOrder/actions/update.ts b/shopify/product-reviews-template/api/models/shopifyOrder/actions/update.ts index 76f7b4d6..3b84662a 100755 --- a/shopify/product-reviews-template/api/models/shopifyOrder/actions/update.ts +++ b/shopify/product-reviews-template/api/models/shopifyOrder/actions/update.ts @@ -1,6 +1,7 @@ import { applyParams, save, ActionOptions } from "gadget-server"; import { preventCrossShopDataAccess } from "gadget-server/shopify"; import { DateTime } from "luxon"; +import { default as setReviewCreationLimit } from "../utilities/setReviewCreationLimit"; export const run: ActionRun = async ({ params, @@ -8,6 +9,7 @@ export const run: ActionRun = async ({ logger, api, connections, + trigger, }) => { applyParams(params, record); await preventCrossShopDataAccess(params, record); @@ -34,6 +36,10 @@ export const run: ActionRun = async ({ .toJSDate(); } + if (record.reviewCreationLimit == null) { + setReviewCreationLimit({ record, trigger }); + } + await save(record); }; diff --git a/shopify/product-reviews-template/api/models/shopifyOrder/reviewCreationLimitReached.gelly b/shopify/product-reviews-template/api/models/shopifyOrder/reviewCreationLimitReached.gelly new file mode 100755 index 00000000..54348522 --- /dev/null +++ b/shopify/product-reviews-template/api/models/shopifyOrder/reviewCreationLimitReached.gelly @@ -0,0 +1,3 @@ +field on shopifyOrder { + count(reviews) >= reviewCreationLimit +} \ No newline at end of file diff --git a/shopify/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts b/shopify/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts index c813fb6e..9c2ec7e8 100755 --- a/shopify/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts +++ b/shopify/product-reviews-template/api/models/shopifyOrder/schema.gadget.ts @@ -12,6 +12,16 @@ export const schema: GadgetModel = { includeTime: true, storageKey: "ztIqc2_TMPaB", }, + reviewCreationLimit: { + type: "number", + storageKey: "jke-EixGFnyY", + }, + reviewCreationLimitReached: { + type: "computed", + sourceFile: + "api/models/shopifyOrder/reviewCreationLimitReached.gelly", + storageKey: "dHNhVfD1t0Hn", + }, reviews: { type: "hasMany", children: { model: "review", belongsToField: "order" }, diff --git a/shopify/product-reviews-template/api/models/shopifyOrder/utilities/setReviewCreationLimit.ts b/shopify/product-reviews-template/api/models/shopifyOrder/utilities/setReviewCreationLimit.ts new file mode 100644 index 00000000..1b3511ee --- /dev/null +++ b/shopify/product-reviews-template/api/models/shopifyOrder/utilities/setReviewCreationLimit.ts @@ -0,0 +1,30 @@ +import { ActionTrigger, CreateShopifyOrderActionContext } from "gadget-server"; + +export default ({ + trigger, + record, +}: { + trigger: ActionTrigger; + record: CreateShopifyOrderActionContext["record"]; +}) => { + if ( + trigger.type == "shopify_webhook" && + (trigger.topic == "orders/create" || trigger.topic == "orders/updated") + ) { + const products = ( + trigger.payload.line_items as { product_id: string }[] + ).reduce( + (acc: { product_id: string }[], current: { product_id: string }) => { + if ( + !acc.some((line_item) => line_item.product_id === current.product_id) + ) { + acc.push(current); + } + return acc; + }, + [] + ); + + record.reviewCreationLimit = products.length; + } +}; diff --git a/shopify/product-reviews-template/api/models/shopifyOrderLineItem/schema.gadget.ts b/shopify/product-reviews-template/api/models/shopifyOrderLineItem/schema.gadget.ts index ab010367..6952c806 100755 --- a/shopify/product-reviews-template/api/models/shopifyOrderLineItem/schema.gadget.ts +++ b/shopify/product-reviews-template/api/models/shopifyOrderLineItem/schema.gadget.ts @@ -6,7 +6,14 @@ import type { GadgetModel } from "gadget-server"; export const schema: GadgetModel = { type: "gadget/model-schema/v1", storageKey: "DataModel-Shopify-OrderLineItem", - fields: {}, + fields: { + reviewCreated: { type: "boolean", storageKey: "-rQgABflj-nA" }, + reviews: { + type: "hasMany", + children: { model: "review", belongsToField: "lineItem" }, + storageKey: "eGcGDieaLQxN", + }, + }, shopify: { fields: [ "attributedStaffs", diff --git a/shopify/product-reviews-template/api/utilities/renderEmail.tsx b/shopify/product-reviews-template/api/utilities/renderEmail.tsx index 30673918..610392f8 100644 --- a/shopify/product-reviews-template/api/utilities/renderEmail.tsx +++ b/shopify/product-reviews-template/api/utilities/renderEmail.tsx @@ -15,6 +15,7 @@ export default async ({ return await render( {/* Add more text in here */} + {/* Email written with React-Email: https://react.email/components */}