diff --git a/.changeset/chilly-crabs-promise.md b/.changeset/chilly-crabs-promise.md new file mode 100644 index 0000000..a7efa9f --- /dev/null +++ b/.changeset/chilly-crabs-promise.md @@ -0,0 +1,16 @@ +--- +"saleor-app-emails-and-messages": patch +"saleor-app-data-importer": patch +"saleor-app-products-feed": patch +"saleor-app-monitoring": patch +"@saleor/apps-shared": patch +"saleor-app-invoices": patch +"saleor-app-klaviyo": patch +"saleor-app-search": patch +"saleor-app-slack": patch +"saleor-app-taxes": patch +"saleor-app-cms": patch +"saleor-app-crm": patch +--- + +Added lint:fix script, so `eslint --fix` can be run deliberately diff --git a/apps/cms/package.json b/apps/cms/package.json index 99bac57..ac0fc32 100644 --- a/apps/cms/package.json +++ b/apps/cms/package.json @@ -7,6 +7,7 @@ "build": "pnpm generate && next build", "start": "next start", "lint": "next lint", + "lint:fix": "eslint --fix .", "fetch-schema": "curl https://raw.githubusercontent.com/saleor/saleor/${npm_package_saleor_schemaVersion}/saleor/graphql/schema.graphql > graphql/schema.graphql", "generate": "graphql-codegen", "test": "vitest" @@ -63,9 +64,5 @@ "prettier": "^2.7.1", "typescript": "4.9", "vitest": "^0.30.1" - }, - "lint-staged": { - "*.{js,ts,tsx}": "eslint --cache --fix", - "*.{js,ts,tsx,css,md,json}": "prettier --write" } } diff --git a/apps/crm/package.json b/apps/crm/package.json index a06cf1f..fcfec32 100644 --- a/apps/crm/package.json +++ b/apps/crm/package.json @@ -7,6 +7,7 @@ "build": "pnpm generate && next build", "start": "next start", "lint": "next lint", + "lint:fix": "eslint --fix .", "fetch-schema": "curl https://raw.githubusercontent.com/saleor/saleor/${npm_package_saleor_schemaVersion}/saleor/graphql/schema.graphql > graphql/schema.graphql", "generate": "graphql-codegen", "test": "vitest" @@ -65,9 +66,5 @@ "eslint-config-saleor": "workspace:*", "prettier": "^2.8.2", "typescript": "4.9.4" - }, - "lint-staged": { - "*.{js,ts,tsx}": "eslint --cache --fix", - "*.{js,ts,tsx,css,md,json}": "prettier --write" } } diff --git a/apps/crm/src/lib/metadata-manager.ts b/apps/crm/src/lib/metadata-manager.ts index eccded3..3ea71e1 100644 --- a/apps/crm/src/lib/metadata-manager.ts +++ b/apps/crm/src/lib/metadata-manager.ts @@ -90,9 +90,11 @@ export async function mutateMetadata( export const createSettingsManager = ( client: Pick ): SettingsManager => { - // EncryptedMetadataManager gives you interface to manipulate metadata and cache values in memory. - // We recommend it for production, because all values are encrypted. - // If your use case require plain text values, you can use MetadataManager. + /* + * EncryptedMetadataManager gives you interface to manipulate metadata and cache values in memory. + * We recommend it for production, because all values are encrypted. + * If your use case require plain text values, you can use MetadataManager. + */ return new EncryptedMetadataManager({ // Secret key should be randomly created for production and set as environment variable encryptionKey: process.env.SECRET_KEY!, diff --git a/apps/crm/src/pages/api/auth/mailchimp/callback.ts b/apps/crm/src/pages/api/auth/mailchimp/callback.ts index 8713d01..af92694 100644 --- a/apps/crm/src/pages/api/auth/mailchimp/callback.ts +++ b/apps/crm/src/pages/api/auth/mailchimp/callback.ts @@ -4,6 +4,7 @@ import { createLogger } from "../../../../lib/logger"; export const getBaseUrl = (headers: { [name: string]: string | string[] | undefined }): string => { const { host, "x-forwarded-proto": protocol = "http" } = headers; + return `${protocol}://${host}`; }; diff --git a/apps/crm/src/pages/api/auth/mailchimp/oauth.ts b/apps/crm/src/pages/api/auth/mailchimp/oauth.ts index cb69ee5..1ff8a36 100644 --- a/apps/crm/src/pages/api/auth/mailchimp/oauth.ts +++ b/apps/crm/src/pages/api/auth/mailchimp/oauth.ts @@ -6,6 +6,7 @@ import { SALEOR_API_URL_HEADER, SALEOR_AUTHORIZATION_BEARER_HEADER } from "@sale export const getBaseUrl = (headers: { [name: string]: string | string[] | undefined }): string => { const { host, "x-forwarded-proto": protocol = "http" } = headers; + return `${protocol}://${host}`; }; @@ -38,6 +39,7 @@ const handler: NextApiHandler = async (req, res) => { }); const redirectUri = `${getBaseUrl(req.headers)}/api/auth/mailchimp/callback`; + logger.debug({ redirectUri }, "Resolved redirect uri"); const qs = new URLSearchParams({ diff --git a/apps/data-importer/next.config.js b/apps/data-importer/next.config.js index 2647237..973464e 100644 --- a/apps/data-importer/next.config.js +++ b/apps/data-importer/next.config.js @@ -1,7 +1,9 @@ -// This file sets a custom webpack configuration to use your Next.js app -// with Sentry. -// https://nextjs.org/docs/api-reference/next.config.js/introduction -// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/ +/* + * This file sets a custom webpack configuration to use your Next.js app + * with Sentry. + * https://nextjs.org/docs/api-reference/next.config.js/introduction + * https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/ + */ const { withSentryConfig } = require("@sentry/nextjs"); const isSentryPropertiesInEnvironment = diff --git a/apps/data-importer/package.json b/apps/data-importer/package.json index 06ae9df..2bdef97 100644 --- a/apps/data-importer/package.json +++ b/apps/data-importer/package.json @@ -7,6 +7,7 @@ "build": "pnpm generate && next build", "start": "next start", "lint": "next lint", + "lint:fix": "eslint --fix .", "fetch-schema": "curl https://raw.githubusercontent.com/saleor/saleor/${npm_package_saleor_schemaVersion}/saleor/graphql/schema.graphql > graphql/schema.graphql", "generate": "graphql-codegen", "test": "vitest", @@ -61,9 +62,5 @@ "eslint": "^8.33.0", "eslint-config-saleor": "workspace:*", "typescript": "4.9.5" - }, - "lint-staged": { - "*.{js,ts,tsx}": "eslint --cache --fix", - "*.{js,ts,tsx,css,md,json}": "prettier --write" } } diff --git a/apps/data-importer/sentry.client.config.js b/apps/data-importer/sentry.client.config.js index d480b2d..cbc99e0 100644 --- a/apps/data-importer/sentry.client.config.js +++ b/apps/data-importer/sentry.client.config.js @@ -1,17 +1,21 @@ -// This file configures the initialization of Sentry on the browser. -// The config you add here will be used whenever a page is visited. -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ +/* + * This file configures the initialization of Sentry on the browser. + * The config you add here will be used whenever a page is visited. + * https://docs.sentry.io/platforms/javascript/guides/nextjs/ + */ import * as Sentry from "@sentry/nextjs"; -const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN; +const SENTRY_DSN = process.env.SENTRY_DSN Sentry.init({ dsn: SENTRY_DSN, // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1.0, - // ... - // Note: if you want to override the automatic release value, do not set a - // `release` value here - use the environment variable `SENTRY_RELEASE`, so - // that it will also get attached to your source maps + /* + * ... + * Note: if you want to override the automatic release value, do not set a + * `release` value here - use the environment variable `SENTRY_RELEASE`, so + * that it will also get attached to your source maps + */ }); diff --git a/apps/data-importer/sentry.edge.config.js b/apps/data-importer/sentry.edge.config.js index 1c3e861..c03243d 100644 --- a/apps/data-importer/sentry.edge.config.js +++ b/apps/data-importer/sentry.edge.config.js @@ -1,17 +1,21 @@ -// This file configures the initialization of Sentry on the server. -// The config you add here will be used whenever middleware or an Edge route handles a request. -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ +/* + * This file configures the initialization of Sentry on the server. + * The config you add here will be used whenever middleware or an Edge route handles a request. + * https://docs.sentry.io/platforms/javascript/guides/nextjs/ + */ import * as Sentry from "@sentry/nextjs"; -const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN; +const SENTRY_DSN = process.env.SENTRY_DSN Sentry.init({ dsn: SENTRY_DSN, // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1.0, - // ... - // Note: if you want to override the automatic release value, do not set a - // `release` value here - use the environment variable `SENTRY_RELEASE`, so - // that it will also get attached to your source maps + /* + * ... + * Note: if you want to override the automatic release value, do not set a + * `release` value here - use the environment variable `SENTRY_RELEASE`, so + * that it will also get attached to your source maps + */ }); diff --git a/apps/data-importer/sentry.server.config.js b/apps/data-importer/sentry.server.config.js index a7e581b..15c4c03 100644 --- a/apps/data-importer/sentry.server.config.js +++ b/apps/data-importer/sentry.server.config.js @@ -1,17 +1,21 @@ -// This file configures the initialization of Sentry on the server. -// The config you add here will be used whenever the server handles a request. -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ +/* + * This file configures the initialization of Sentry on the server. + * The config you add here will be used whenever the server handles a request. + * https://docs.sentry.io/platforms/javascript/guides/nextjs/ + */ import * as Sentry from "@sentry/nextjs"; -const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN; +const SENTRY_DSN = process.env.SENTRY_DSN Sentry.init({ dsn: SENTRY_DSN, // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1.0, - // ... - // Note: if you want to override the automatic release value, do not set a - // `release` value here - use the environment variable `SENTRY_RELEASE`, so - // that it will also get attached to your source maps + /* + * ... + * Note: if you want to override the automatic release value, do not set a + * `release` value here - use the environment variable `SENTRY_RELEASE`, so + * that it will also get attached to your source maps + */ }); diff --git a/apps/data-importer/src/modules/customers/customers-importer-nuvo/customers-columns-model.ts b/apps/data-importer/src/modules/customers/customers-importer-nuvo/customers-columns-model.ts index f0577e4..3494910 100644 --- a/apps/data-importer/src/modules/customers/customers-importer-nuvo/customers-columns-model.ts +++ b/apps/data-importer/src/modules/customers/customers-importer-nuvo/customers-columns-model.ts @@ -86,8 +86,10 @@ const generateAddressColumns = (labelNamespace: string, keyNamespace: string): C // TODO - enable address columns when mapped const allColumns: ColumnAPI[] = [ ...customerColumns, - // ...generateAddressColumns("Default Billing Address", "defaultBillingAddress"), - // ...generateAddressColumns("Default Shipping Address", "defaultShippingAddress"), + /* + * ...generateAddressColumns("Default Billing Address", "defaultBillingAddress"), + * ...generateAddressColumns("Default Shipping Address", "defaultShippingAddress"), + */ ]; export const getCustomersModelColumns = () => allColumns; @@ -116,8 +118,10 @@ export const getResultModelSchema = () => email: z.string(), note: z.string().nullish(), externalReference: z.string().nullish(), - // defaultBillingAddress: zodAddressSchema, - // defaultShippingAddress: zodAddressSchema, + /* + * defaultBillingAddress: zodAddressSchema, + * defaultShippingAddress: zodAddressSchema, + */ }), }); diff --git a/apps/data-importer/src/pages/_app.tsx b/apps/data-importer/src/pages/_app.tsx index 454ceb4..833044a 100644 --- a/apps/data-importer/src/pages/_app.tsx +++ b/apps/data-importer/src/pages/_app.tsx @@ -57,6 +57,7 @@ function NextApp({ Component, pageProps }: AppProps) { */ useEffect(() => { const jssStyles = document.querySelector("#jss-server-side"); + if (jssStyles) { jssStyles?.parentElement?.removeChild(jssStyles); } diff --git a/apps/data-importer/src/pages/_error.js b/apps/data-importer/src/pages/_error.js index 55c3486..316beec 100644 --- a/apps/data-importer/src/pages/_error.js +++ b/apps/data-importer/src/pages/_error.js @@ -20,16 +20,20 @@ import * as Sentry from "@sentry/nextjs"; import NextErrorComponent from "next/error"; const CustomErrorComponent = (props) => { - // If you're using a Nextjs version prior to 12.2.1, uncomment this to - // compensate for https://github.com/vercel/next.js/issues/8592 - // Sentry.captureUnderscoreErrorException(props); + /* + * If you're using a Nextjs version prior to 12.2.1, uncomment this to + * compensate for https://github.com/vercel/next.js/issues/8592 + * Sentry.captureUnderscoreErrorException(props); + */ return ; }; CustomErrorComponent.getInitialProps = async (contextData) => { - // In case this is running in a serverless function, await this in order to give Sentry - // time to send the error before the lambda exits + /* + * In case this is running in a serverless function, await this in order to give Sentry + * time to send the error before the lambda exits + */ await Sentry.captureUnderscoreErrorException(contextData); // This will contain the status code of the response diff --git a/apps/data-importer/turbo.json b/apps/data-importer/turbo.json index 1d0a930..cce84c4 100644 --- a/apps/data-importer/turbo.json +++ b/apps/data-importer/turbo.json @@ -16,7 +16,11 @@ "REST_APL_TOKEN", "NEXT_PUBLIC_VERCEL_ENV", "VERCEL_URL", - "PORT" + "PORT", + "SENTRY_AUTH_TOKEN", + "SENTRY_PROJECT", + "SENTRY_ORG", + "SENTRY_DSN" ] } } diff --git a/apps/emails-and-messages/package.json b/apps/emails-and-messages/package.json index 79fdf70..596a5de 100644 --- a/apps/emails-and-messages/package.json +++ b/apps/emails-and-messages/package.json @@ -6,7 +6,8 @@ "dev": "pnpm generate && NODE_OPTIONS='--inspect' next dev", "build": "pnpm generate && next build", "start": "next start", - "lint": "pnpm generate && prettier --loglevel warn --write . && eslint --fix .", + "lint": "next lint", + "lint:fix": "eslint --fix .", "fetch-schema": "curl https://raw.githubusercontent.com/saleor/saleor/${npm_package_saleor_schemaVersion}/saleor/graphql/schema.graphql > graphql/schema.graphql", "generate": "graphql-codegen", "test": "vitest" @@ -78,9 +79,5 @@ "eslint-config-saleor": "workspace:*", "prettier": "^2.8.2", "typescript": "4.9.4" - }, - "lint-staged": { - "*.{js,ts,tsx}": "eslint --cache --fix", - "*.{js,ts,tsx,css,md,json}": "prettier --write" } } diff --git a/apps/invoices/next.config.js b/apps/invoices/next.config.js index 803ba4f..d15fa73 100644 --- a/apps/invoices/next.config.js +++ b/apps/invoices/next.config.js @@ -1,7 +1,9 @@ -// This file sets a custom webpack configuration to use your Next.js app -// with Sentry. -// https://nextjs.org/docs/api-reference/next.config.js/introduction -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ +/* + * This file sets a custom webpack configuration to use your Next.js app + * with Sentry. + * https://nextjs.org/docs/api-reference/next.config.js/introduction + * https://docs.sentry.io/platforms/javascript/guides/nextjs/ + */ const { withSentryConfig } = require("@sentry/nextjs"); @@ -13,12 +15,14 @@ const isSentryPropertiesInEnvironment = */ const moduleExports = { sentry: { - // Use `hidden-source-map` rather than `source-map` as the Webpack `devtool` - // for client-side builds. (This will be the default starting in - // `@sentry/nextjs` version 8.0.0.) See - // https://webpack.js.org/configuration/devtool/ and - // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#use-hidden-source-map - // for more information. + /* + * Use `hidden-source-map` rather than `source-map` as the Webpack `devtool` + * for client-side builds. (This will be the default starting in + * `@sentry/nextjs` version 8.0.0.) See + * https://webpack.js.org/configuration/devtool/ and + * https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#use-hidden-source-map + * for more information. + */ hideSourceMaps: true, disableServerWebpackPlugin: !isSentryPropertiesInEnvironment, disableClientWebpackPlugin: !isSentryPropertiesInEnvironment, @@ -31,17 +35,23 @@ const moduleExports = { }; const sentryWebpackPluginOptions = { - // Additional config options for the Sentry Webpack plugin. Keep in mind that - // the following options are set automatically, and overriding them is not - // recommended: - // release, url, org, project, authToken, configFile, stripPrefix, - // urlPrefix, include, ignore + /* + * Additional config options for the Sentry Webpack plugin. Keep in mind that + * the following options are set automatically, and overriding them is not + * recommended: + * release, url, org, project, authToken, configFile, stripPrefix, + * urlPrefix, include, ignore + */ silent: true, // Suppresses all logs - // For all available options, see: - // https://github.com/getsentry/sentry-webpack-plugin#options. + /* + * For all available options, see: + * https://github.com/getsentry/sentry-webpack-plugin#options. + */ }; -// Make sure adding Sentry options is the last code to run before exporting, to -// ensure that your source maps include changes from all other Webpack plugins +/* + * Make sure adding Sentry options is the last code to run before exporting, to + * ensure that your source maps include changes from all other Webpack plugins + */ module.exports = withSentryConfig(moduleExports, sentryWebpackPluginOptions); diff --git a/apps/invoices/package.json b/apps/invoices/package.json index 523cb0e..eab98df 100644 --- a/apps/invoices/package.json +++ b/apps/invoices/package.json @@ -7,6 +7,7 @@ "build": "pnpm generate && next build", "start": "next start", "lint": "next lint", + "lint:fix": "eslint --fix .", "fetch-schema": "curl https://raw.githubusercontent.com/saleor/saleor/${npm_package_saleor_schemaVersion}/saleor/graphql/schema.graphql > graphql/schema.graphql", "generate": "graphql-codegen", "test": "vitest", @@ -70,10 +71,6 @@ "typescript": "4.9.5", "vite": "^4.2.1", "vitest": "^0.30.1", -"@types/semver": "^7.3.13" - }, - "lint-staged": { - "*.{js,ts,tsx}": "eslint --cache --fix", - "*.{js,ts,tsx,css,md,json}": "prettier --write" + "@types/semver": "^7.3.13" } } diff --git a/apps/invoices/sentry.client.config.js b/apps/invoices/sentry.client.config.js index d480b2d..1364019 100644 --- a/apps/invoices/sentry.client.config.js +++ b/apps/invoices/sentry.client.config.js @@ -1,17 +1,21 @@ -// This file configures the initialization of Sentry on the browser. -// The config you add here will be used whenever a page is visited. -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ +/* + * This file configures the initialization of Sentry on the browser. + * The config you add here will be used whenever a page is visited. + * https://docs.sentry.io/platforms/javascript/guides/nextjs/ + */ import * as Sentry from "@sentry/nextjs"; -const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN; +const SENTRY_DSN = process.env.SENTRY_DSN; Sentry.init({ dsn: SENTRY_DSN, // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1.0, - // ... - // Note: if you want to override the automatic release value, do not set a - // `release` value here - use the environment variable `SENTRY_RELEASE`, so - // that it will also get attached to your source maps + /* + * ... + * Note: if you want to override the automatic release value, do not set a + * `release` value here - use the environment variable `SENTRY_RELEASE`, so + * that it will also get attached to your source maps + */ }); diff --git a/apps/invoices/sentry.edge.config.js b/apps/invoices/sentry.edge.config.js index 1c3e861..c03243d 100644 --- a/apps/invoices/sentry.edge.config.js +++ b/apps/invoices/sentry.edge.config.js @@ -1,17 +1,21 @@ -// This file configures the initialization of Sentry on the server. -// The config you add here will be used whenever middleware or an Edge route handles a request. -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ +/* + * This file configures the initialization of Sentry on the server. + * The config you add here will be used whenever middleware or an Edge route handles a request. + * https://docs.sentry.io/platforms/javascript/guides/nextjs/ + */ import * as Sentry from "@sentry/nextjs"; -const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN; +const SENTRY_DSN = process.env.SENTRY_DSN Sentry.init({ dsn: SENTRY_DSN, // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1.0, - // ... - // Note: if you want to override the automatic release value, do not set a - // `release` value here - use the environment variable `SENTRY_RELEASE`, so - // that it will also get attached to your source maps + /* + * ... + * Note: if you want to override the automatic release value, do not set a + * `release` value here - use the environment variable `SENTRY_RELEASE`, so + * that it will also get attached to your source maps + */ }); diff --git a/apps/invoices/sentry.server.config.js b/apps/invoices/sentry.server.config.js index a7e581b..15c4c03 100644 --- a/apps/invoices/sentry.server.config.js +++ b/apps/invoices/sentry.server.config.js @@ -1,17 +1,21 @@ -// This file configures the initialization of Sentry on the server. -// The config you add here will be used whenever the server handles a request. -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ +/* + * This file configures the initialization of Sentry on the server. + * The config you add here will be used whenever the server handles a request. + * https://docs.sentry.io/platforms/javascript/guides/nextjs/ + */ import * as Sentry from "@sentry/nextjs"; -const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN; +const SENTRY_DSN = process.env.SENTRY_DSN Sentry.init({ dsn: SENTRY_DSN, // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1.0, - // ... - // Note: if you want to override the automatic release value, do not set a - // `release` value here - use the environment variable `SENTRY_RELEASE`, so - // that it will also get attached to your source maps + /* + * ... + * Note: if you want to override the automatic release value, do not set a + * `release` value here - use the environment variable `SENTRY_RELEASE`, so + * that it will also get attached to your source maps + */ }); diff --git a/apps/invoices/src/modules/app-configuration/metadata-manager.ts b/apps/invoices/src/modules/app-configuration/metadata-manager.ts index 65d56c2..f63ba63 100644 --- a/apps/invoices/src/modules/app-configuration/metadata-manager.ts +++ b/apps/invoices/src/modules/app-configuration/metadata-manager.ts @@ -81,9 +81,11 @@ export async function mutateMetadata(client: Client, metadata: MetadataEntry[]) } export const createSettingsManager = (client: Client) => { - // EncryptedMetadataManager gives you interface to manipulate metadata and cache values in memory. - // We recommend it for production, because all values are encrypted. - // If your use case require plain text values, you can use MetadataManager. + /* + * EncryptedMetadataManager gives you interface to manipulate metadata and cache values in memory. + * We recommend it for production, because all values are encrypted. + * If your use case require plain text values, you can use MetadataManager. + */ return new EncryptedMetadataManager({ // Secret key should be randomly created for production and set as environment variable encryptionKey: process.env.SECRET_KEY!, diff --git a/apps/invoices/src/modules/invoice-generator/microinvoice/microinvoice-invoice-generator.ts b/apps/invoices/src/modules/invoice-generator/microinvoice/microinvoice-invoice-generator.ts index 3e044fc..c57fd4f 100644 --- a/apps/invoices/src/modules/invoice-generator/microinvoice/microinvoice-invoice-generator.ts +++ b/apps/invoices/src/modules/invoice-generator/microinvoice/microinvoice-invoice-generator.ts @@ -19,13 +19,15 @@ export class MicroinvoiceInvoiceGenerator implements InvoiceGenerator { const microinvoiceInstance = new Microinvoice({ style: { - // header: { - // image: { - // path: "./examples/logo.png", - // width: 50, - // height: 19, - // }, - // }, + /* + * header: { + * image: { + * path: "./examples/logo.png", + * width: 50, + * height: 19, + * }, + * }, + */ }, data: { invoice: { @@ -60,10 +62,12 @@ export class MicroinvoiceInvoiceGenerator implements InvoiceGenerator { order.billingAddress?.country.country, ], }, - // { - // label: "Tax Identifier", - // value: "todo", - // }, + /* + * { + * label: "Tax Identifier", + * value: "todo", + * }, + */ ], seller: [ @@ -79,23 +83,27 @@ export class MicroinvoiceInvoiceGenerator implements InvoiceGenerator { companyAddressData.countryArea, ], }, - // { - // label: "Tax Identifier", - // value: "todo", - // }, + /* + * { + * label: "Tax Identifier", + * value: "todo", + * }, + */ ], legal: [ - // { - // value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit", - // weight: "bold", - // color: "primary", - // }, - // { - // value: "sed do eiusmod tempor incididunt ut labore et dolore magna.", - // weight: "bold", - // color: "secondary", - // }, + /* + * { + * value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit", + * weight: "bold", + * color: "primary", + * }, + * { + * value: "sed do eiusmod tempor incididunt ut labore et dolore magna.", + * weight: "bold", + * color: "secondary", + * }, + */ ], details: { diff --git a/apps/invoices/src/pages/_app.tsx b/apps/invoices/src/pages/_app.tsx index 08bc777..dfb65fa 100644 --- a/apps/invoices/src/pages/_app.tsx +++ b/apps/invoices/src/pages/_app.tsx @@ -22,6 +22,7 @@ function NextApp({ Component, pageProps }: AppProps) { */ useEffect(() => { const jssStyles = document.querySelector("#jss-server-side"); + if (jssStyles) { jssStyles?.parentElement?.removeChild(jssStyles); } diff --git a/apps/invoices/src/pages/_error.js b/apps/invoices/src/pages/_error.js index 49f0ea6..6e8ecdc 100644 --- a/apps/invoices/src/pages/_error.js +++ b/apps/invoices/src/pages/_error.js @@ -20,16 +20,20 @@ import * as Sentry from '@sentry/nextjs'; import NextErrorComponent from 'next/error'; const CustomErrorComponent = props => { - // If you're using a Nextjs version prior to 12.2.1, uncomment this to - // compensate for https://github.com/vercel/next.js/issues/8592 - // Sentry.captureUnderscoreErrorException(props); + /* + * If you're using a Nextjs version prior to 12.2.1, uncomment this to + * compensate for https://github.com/vercel/next.js/issues/8592 + * Sentry.captureUnderscoreErrorException(props); + */ return ; }; CustomErrorComponent.getInitialProps = async contextData => { - // In case this is running in a serverless function, await this in order to give Sentry - // time to send the error before the lambda exits + /* + * In case this is running in a serverless function, await this in order to give Sentry + * time to send the error before the lambda exits + */ await Sentry.captureUnderscoreErrorException(contextData); // This will contain the status code of the response diff --git a/apps/invoices/src/pages/api/webhooks/invoice-requested.ts b/apps/invoices/src/pages/api/webhooks/invoice-requested.ts index ae83940..20acf4e 100644 --- a/apps/invoices/src/pages/api/webhooks/invoice-requested.ts +++ b/apps/invoices/src/pages/api/webhooks/invoice-requested.ts @@ -174,6 +174,7 @@ export const handler: NextWebhookApiHandler = a ); const hashedInvoiceName = hashInvoiceFilename(invoiceName, orderId); + logger.debug({ hashedInvoiceName }); const hashedInvoiceFileName = `${hashedInvoiceName}.pdf`; diff --git a/apps/invoices/turbo.json b/apps/invoices/turbo.json index d2681ce..3ddf9cb 100644 --- a/apps/invoices/turbo.json +++ b/apps/invoices/turbo.json @@ -14,7 +14,11 @@ "ALLOWED_DOMAIN_PATTERN", "NEXT_PUBLIC_VERCEL_ENV", "REST_APL_ENDPOINT", - "REST_APL_TOKEN" + "REST_APL_TOKEN", + "SENTRY_PROJECT", + "SENTRY_DSN", + "SENTRY_ORG", + "SENTRY_AUTH_TOKEN" ] } } diff --git a/apps/klaviyo/next.config.js b/apps/klaviyo/next.config.js index a8b0016..084c10d 100644 --- a/apps/klaviyo/next.config.js +++ b/apps/klaviyo/next.config.js @@ -28,17 +28,23 @@ const nextConfig = { }; const sentryWebpackPluginOptions = { - // Additional config options for the Sentry Webpack plugin. Keep in mind that - // the following options are set automatically, and overriding them is not - // recommended: - // release, url, org, project, authToken, configFile, stripPrefix, - // urlPrefix, include, ignore + /* + * Additional config options for the Sentry Webpack plugin. Keep in mind that + * the following options are set automatically, and overriding them is not + * recommended: + * release, url, org, project, authToken, configFile, stripPrefix, + * urlPrefix, include, ignore + */ silent: true, // Suppresses all logs - // For all available options, see: - // https://github.com/getsentry/sentry-webpack-plugin#options. + /* + * For all available options, see: + * https://github.com/getsentry/sentry-webpack-plugin#options. + */ }; -// Make sure adding Sentry options is the last code to run before exporting, to -// ensure that your source maps include changes from all other Webpack plugins +/* + * Make sure adding Sentry options is the last code to run before exporting, to + * ensure that your source maps include changes from all other Webpack plugins + */ module.exports = withSentryConfig(nextConfig, sentryWebpackPluginOptions); diff --git a/apps/klaviyo/package.json b/apps/klaviyo/package.json index c8dc15a..88e4bb4 100644 --- a/apps/klaviyo/package.json +++ b/apps/klaviyo/package.json @@ -7,7 +7,8 @@ "dev": "pnpm generate && NODE_OPTIONS='--inspect' next dev", "build": "pnpm generate && next build", "start": "next start", - "lint": "pnpm generate && prettier --loglevel warn --write . && eslint --fix .", + "lint": "next lint", + "lint:fix": "eslint --fix .", "fetch-schema": "curl https://raw.githubusercontent.com/saleor/saleor/${npm_package_saleor_schemaVersion}/saleor/graphql/schema.graphql > graphql/schema.graphql", "generate": "graphql-codegen" }, diff --git a/apps/klaviyo/sentry.client.config.js b/apps/klaviyo/sentry.client.config.js index d480b2d..5834e2e 100644 --- a/apps/klaviyo/sentry.client.config.js +++ b/apps/klaviyo/sentry.client.config.js @@ -1,6 +1,8 @@ -// This file configures the initialization of Sentry on the browser. -// The config you add here will be used whenever a page is visited. -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ +/* + * This file configures the initialization of Sentry on the browser. + * The config you add here will be used whenever a page is visited. + * https://docs.sentry.io/platforms/javascript/guides/nextjs/ + */ import * as Sentry from "@sentry/nextjs"; @@ -10,8 +12,10 @@ Sentry.init({ dsn: SENTRY_DSN, // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1.0, - // ... - // Note: if you want to override the automatic release value, do not set a - // `release` value here - use the environment variable `SENTRY_RELEASE`, so - // that it will also get attached to your source maps + /* + * ... + * Note: if you want to override the automatic release value, do not set a + * `release` value here - use the environment variable `SENTRY_RELEASE`, so + * that it will also get attached to your source maps + */ }); diff --git a/apps/klaviyo/sentry.server.config.js b/apps/klaviyo/sentry.server.config.js index a7e581b..eb63769 100644 --- a/apps/klaviyo/sentry.server.config.js +++ b/apps/klaviyo/sentry.server.config.js @@ -1,6 +1,8 @@ -// This file configures the initialization of Sentry on the server. -// The config you add here will be used whenever the server handles a request. -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ +/* + * This file configures the initialization of Sentry on the server. + * The config you add here will be used whenever the server handles a request. + * https://docs.sentry.io/platforms/javascript/guides/nextjs/ + */ import * as Sentry from "@sentry/nextjs"; @@ -10,8 +12,10 @@ Sentry.init({ dsn: SENTRY_DSN, // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1.0, - // ... - // Note: if you want to override the automatic release value, do not set a - // `release` value here - use the environment variable `SENTRY_RELEASE`, so - // that it will also get attached to your source maps + /* + * ... + * Note: if you want to override the automatic release value, do not set a + * `release` value here - use the environment variable `SENTRY_RELEASE`, so + * that it will also get attached to your source maps + */ }); diff --git a/apps/klaviyo/src/hooks/useAppApi.ts b/apps/klaviyo/src/hooks/useAppApi.ts index e0a5b7f..edaac0e 100644 --- a/apps/klaviyo/src/hooks/useAppApi.ts +++ b/apps/klaviyo/src/hooks/useAppApi.ts @@ -39,6 +39,7 @@ export const useAppApi = ({ url, options, skip }: UseFetchProps) => { } const json = await res.json(); + setData(json); } catch (e) { setError(e as unknown); diff --git a/apps/klaviyo/src/lib/klaviyo.ts b/apps/klaviyo/src/lib/klaviyo.ts index 1d6e392..3ac7c77 100644 --- a/apps/klaviyo/src/lib/klaviyo.ts +++ b/apps/klaviyo/src/lib/klaviyo.ts @@ -5,6 +5,7 @@ interface EmailServiceProvider { export const Klaviyo = (token: string): EmailServiceProvider => ({ send: async (event, recipient, context) => { const formParams = new URLSearchParams(); + formParams.append( "data", JSON.stringify({ diff --git a/apps/klaviyo/src/lib/metadata.ts b/apps/klaviyo/src/lib/metadata.ts index 28def01..0b9b1e7 100644 --- a/apps/klaviyo/src/lib/metadata.ts +++ b/apps/klaviyo/src/lib/metadata.ts @@ -8,10 +8,12 @@ import { } from "../../generated/graphql"; import { settingsManagerSecretKey } from "../../saleor-app"; -// Function is using urql graphql client to fetch all available metadata. -// Before returning query result, we are transforming response to list of objects with key and value fields -// which can be used by the manager. -// Result of this query is cached by the manager. +/* + * Function is using urql graphql client to fetch all available metadata. + * Before returning query result, we are transforming response to list of objects with key and value fields + * which can be used by the manager. + * Result of this query is cached by the manager. + */ export async function fetchAllMetadata(client: Client): Promise { const { error, data } = await client .query(FetchAppDetailsDocument, {}) @@ -25,9 +27,11 @@ export async function fetchAllMetadata(client: Client): Promise return data?.app?.privateMetadata.map((md) => ({ key: md.key, value: md.value })) || []; } -// Mutate function takes urql client and metadata entries, and construct mutation to the API. -// Before data are send, additional query for required App ID is made. -// The manager will use updated entries returned by this mutation to update it's cache. +/* + * Mutate function takes urql client and metadata entries, and construct mutation to the API. + * Before data are send, additional query for required App ID is made. + * The manager will use updated entries returned by this mutation to update it's cache. + */ export async function mutateMetadata(client: Client, appId: string, metadata: MetadataEntry[]) { const { error: mutationError, data: mutationData } = await client .mutation(UpdateAppMetadataDocument, { @@ -50,9 +54,11 @@ export async function mutateMetadata(client: Client, appId: string, metadata: Me } export const createSettingsManager = (client: Client, appId: string) => - // EncryptedMetadataManager gives you interface to manipulate metadata and cache values in memory. - // We recommend it for production, because all values are encrypted. - // If your use case require plain text values, you can use MetadataManager. + /* + * EncryptedMetadataManager gives you interface to manipulate metadata and cache values in memory. + * We recommend it for production, because all values are encrypted. + * If your use case require plain text values, you can use MetadataManager. + */ new EncryptedMetadataManager({ // Secret key should be randomly created for production and set as environment variable encryptionKey: settingsManagerSecretKey, diff --git a/apps/klaviyo/src/pages/_app.tsx b/apps/klaviyo/src/pages/_app.tsx index 5e45f66..1af174f 100644 --- a/apps/klaviyo/src/pages/_app.tsx +++ b/apps/klaviyo/src/pages/_app.tsx @@ -73,6 +73,7 @@ function SaleorApp({ Component, pageProps }: AppLayoutProps) { useEffect(() => { const jssStyles = document.querySelector("#jss-server-side"); + if (jssStyles) { jssStyles?.parentElement?.removeChild(jssStyles); } diff --git a/apps/klaviyo/src/pages/_error.tsx b/apps/klaviyo/src/pages/_error.tsx index d431a7f..b6539e1 100644 --- a/apps/klaviyo/src/pages/_error.tsx +++ b/apps/klaviyo/src/pages/_error.tsx @@ -15,10 +15,12 @@ interface AppErrorProps extends ErrorProps { function MyError({ statusCode, hasGetInitialPropsRun, err }: ErrorPageProps) { if (!hasGetInitialPropsRun && err) { - // getInitialProps is not called when an exception is thrown - // at the top level of a module while it is being loaded. - // As a workaround, we pass err via _app.js so it can be captured - // Read more: https://github.com/vercel/next.js/issues/8592. + /* + * getInitialProps is not called when an exception is thrown + * at the top level of a module while it is being loaded. + * As a workaround, we pass err via _app.js so it can be captured + * Read more: https://github.com/vercel/next.js/issues/8592. + */ Sentry.captureException(err); // Flushing is not required in this case as it only happens on the client } @@ -31,8 +33,10 @@ MyError.getInitialProps = async (context: NextPageContext) => { const { res, err, asPath } = context; - // Workaround for https://github.com/vercel/next.js/issues/8592, mark when - // getInitialProps has run + /* + * Workaround for https://github.com/vercel/next.js/issues/8592, mark when + * getInitialProps has run + */ errorInitialProps.hasGetInitialPropsRun = true; // Returning early because we don't want to log 404 errors to Sentry. @@ -40,32 +44,38 @@ MyError.getInitialProps = async (context: NextPageContext) => { return errorInitialProps; } - // Running on the server, the response object (`res`) is available. - // - // Next.js will pass an err on the server if a page's data fetching methods - // threw or returned a Promise that rejected - // - // Running on the client (browser), Next.js will provide an err if: - // - // - a page's `getInitialProps` threw or returned a Promise that rejected - // - an exception was thrown somewhere in the React lifecycle (render, - // componentDidMount, etc) that was caught by Next.js's React Error - // Boundary. Read more about what types of exceptions are caught by Error - // Boundaries: https://reactjs.org/docs/error-boundaries.html + /* + * Running on the server, the response object (`res`) is available. + * + * Next.js will pass an err on the server if a page's data fetching methods + * threw or returned a Promise that rejected + * + * Running on the client (browser), Next.js will provide an err if: + * + * - a page's `getInitialProps` threw or returned a Promise that rejected + * - an exception was thrown somewhere in the React lifecycle (render, + * componentDidMount, etc) that was caught by Next.js's React Error + * Boundary. Read more about what types of exceptions are caught by Error + * Boundaries: https://reactjs.org/docs/error-boundaries.html + */ if (err) { Sentry.captureException(err); - // Flushing before returning is necessary if deploying to Vercel, see - // https://vercel.com/docs/platform/limits#streaming-responses + /* + * Flushing before returning is necessary if deploying to Vercel, see + * https://vercel.com/docs/platform/limits#streaming-responses + */ await Sentry.flush(2000); return errorInitialProps; } - // If this point is reached, getInitialProps was called without any - // information about what the error might be. This is unexpected and may - // indicate a bug introduced in Next.js, so record it in Sentry + /* + * If this point is reached, getInitialProps was called without any + * information about what the error might be. This is unexpected and may + * indicate a bug introduced in Next.js, so record it in Sentry + */ Sentry.captureException(new Error(`_error.js getInitialProps missing data at path: ${asPath}`)); await Sentry.flush(2000); diff --git a/apps/klaviyo/src/pages/api/webhooks/customer-created.ts b/apps/klaviyo/src/pages/api/webhooks/customer-created.ts index 140a702..c9cf9d7 100644 --- a/apps/klaviyo/src/pages/api/webhooks/customer-created.ts +++ b/apps/klaviyo/src/pages/api/webhooks/customer-created.ts @@ -91,6 +91,7 @@ const handler: NextWebhookApiHandler = as if (klaviyoResponse.status !== 200) { const klaviyoMessage = ` Message: ${(await klaviyoResponse.json())?.message}.` || ""; + console.debug("Klaviyo returned error: ", klaviyoMessage); return res.status(500).json({ diff --git a/apps/klaviyo/src/pages/api/webhooks/fulfillment-created.ts b/apps/klaviyo/src/pages/api/webhooks/fulfillment-created.ts index 751955d..10f5e3f 100644 --- a/apps/klaviyo/src/pages/api/webhooks/fulfillment-created.ts +++ b/apps/klaviyo/src/pages/api/webhooks/fulfillment-created.ts @@ -96,6 +96,7 @@ const handler: NextWebhookApiHandler = if (klaviyoResponse.status !== 200) { const klaviyoMessage = ` Message: ${(await klaviyoResponse.json())?.message}.` || ""; + console.debug("Klaviyo returned error: ", klaviyoMessage); return res.status(500).json({ diff --git a/apps/klaviyo/src/pages/api/webhooks/order-created.ts b/apps/klaviyo/src/pages/api/webhooks/order-created.ts index bb3fe63..9085125 100644 --- a/apps/klaviyo/src/pages/api/webhooks/order-created.ts +++ b/apps/klaviyo/src/pages/api/webhooks/order-created.ts @@ -67,6 +67,7 @@ const handler: NextWebhookApiHandler = async if (klaviyoResponse.status !== 200) { const klaviyoMessage = ` Message: ${(await klaviyoResponse.json())?.message}.` || ""; + console.debug("Klaviyo returned error: ", klaviyoMessage); return res.status(500).json({ success: false, diff --git a/apps/klaviyo/src/pages/api/webhooks/order-fully-paid.ts b/apps/klaviyo/src/pages/api/webhooks/order-fully-paid.ts index ddde85a..05d0d2e 100644 --- a/apps/klaviyo/src/pages/api/webhooks/order-fully-paid.ts +++ b/apps/klaviyo/src/pages/api/webhooks/order-fully-paid.ts @@ -67,6 +67,7 @@ const handler: NextWebhookApiHandler = asy if (klaviyoResponse.status !== 200) { const klaviyoMessage = ` Message: ${(await klaviyoResponse.json())?.message}.` || ""; + console.debug("Klaviyo returned error: ", klaviyoMessage); return res.status(500).json({ diff --git a/apps/klaviyo/src/pages/configuration.tsx b/apps/klaviyo/src/pages/configuration.tsx index b5658fe..21c5e77 100644 --- a/apps/klaviyo/src/pages/configuration.tsx +++ b/apps/klaviyo/src/pages/configuration.tsx @@ -171,6 +171,7 @@ function Configuration() { const onChange = (event: ChangeEvent) => { const { name, value } = event.target as HTMLInputElement; + setConfiguration((prev) => prev!.map((prevField) => (prevField.key === name ? { ...prevField, value } : prevField)) ); diff --git a/apps/monitoring/package.json b/apps/monitoring/package.json index e946483..51019d4 100644 --- a/apps/monitoring/package.json +++ b/apps/monitoring/package.json @@ -7,6 +7,7 @@ "build": "pnpm generate && next build", "start": "next start", "lint": "next lint", + "lint:fix": "eslint --fix .", "generate": "graphql-codegen", "test": "vitest" }, @@ -55,9 +56,5 @@ "eslint-config-saleor": "workspace:*", "prettier": "^2.8.2", "typescript": "4.9.4" - }, - "lint-staged": { - "*.{js,ts,tsx}": "eslint --cache --fix", - "*.{js,ts,tsx,css,md,json}": "prettier --write" } } diff --git a/apps/monitoring/src/pages/_app.tsx b/apps/monitoring/src/pages/_app.tsx index fa42ec3..620c9df 100644 --- a/apps/monitoring/src/pages/_app.tsx +++ b/apps/monitoring/src/pages/_app.tsx @@ -69,6 +69,7 @@ function NextApp({ Component, pageProps }: AppProps) { */ useEffect(() => { const jssStyles = document.querySelector("#jss-server-side"); + if (jssStyles) { jssStyles?.parentElement?.removeChild(jssStyles); } diff --git a/apps/products-feed/package.json b/apps/products-feed/package.json index da8e0c5..d1b90f6 100644 --- a/apps/products-feed/package.json +++ b/apps/products-feed/package.json @@ -7,6 +7,7 @@ "build": "pnpm generate && next build", "start": "next start", "lint": "next lint", + "lint:fix": "eslint --fix .", "fetch-schema": "curl https://raw.githubusercontent.com/saleor/saleor/${npm_package_saleor_schemaVersion}/saleor/graphql/schema.graphql > graphql/schema.graphql", "generate": "graphql-codegen", "test": "vitest" @@ -69,9 +70,5 @@ "eslint-config-saleor": "workspace:*", "prettier": "^2.8.2", "typescript": "4.9.4" - }, - "lint-staged": { - "*.{js,ts,tsx}": "eslint --cache --fix", - "*.{js,ts,tsx,css,md,json}": "prettier --write" } } diff --git a/apps/products-feed/src/lib/google-feed/generate-google-xml-feed.ts b/apps/products-feed/src/lib/google-feed/generate-google-xml-feed.ts index 8a0f146..f892823 100644 --- a/apps/products-feed/src/lib/google-feed/generate-google-xml-feed.ts +++ b/apps/products-feed/src/lib/google-feed/generate-google-xml-feed.ts @@ -86,5 +86,6 @@ export const generateGoogleXmlFeed = ({ }, }, ]; + return builder.build(data); }; diff --git a/apps/products-feed/src/modules/app-configuration/metadata-manager.ts b/apps/products-feed/src/modules/app-configuration/metadata-manager.ts index 65d56c2..f63ba63 100644 --- a/apps/products-feed/src/modules/app-configuration/metadata-manager.ts +++ b/apps/products-feed/src/modules/app-configuration/metadata-manager.ts @@ -81,9 +81,11 @@ export async function mutateMetadata(client: Client, metadata: MetadataEntry[]) } export const createSettingsManager = (client: Client) => { - // EncryptedMetadataManager gives you interface to manipulate metadata and cache values in memory. - // We recommend it for production, because all values are encrypted. - // If your use case require plain text values, you can use MetadataManager. + /* + * EncryptedMetadataManager gives you interface to manipulate metadata and cache values in memory. + * We recommend it for production, because all values are encrypted. + * If your use case require plain text values, you can use MetadataManager. + */ return new EncryptedMetadataManager({ // Secret key should be randomly created for production and set as environment variable encryptionKey: process.env.SECRET_KEY!, diff --git a/apps/products-feed/src/modules/app-configuration/ui/feed-preview-card.tsx b/apps/products-feed/src/modules/app-configuration/ui/feed-preview-card.tsx index b848f68..44000d1 100644 --- a/apps/products-feed/src/modules/app-configuration/ui/feed-preview-card.tsx +++ b/apps/products-feed/src/modules/app-configuration/ui/feed-preview-card.tsx @@ -36,6 +36,7 @@ export const FeedPreviewCard = ({ channelSlug }: FeedPreviewCardProps) => { const openUrlInNewTab = async (url: string) => { await appBridge?.dispatch(actions.Redirect({ to: url, newContext: true })); }; + return ( diff --git a/apps/products-feed/src/modules/app-configuration/ui/side-menu.tsx b/apps/products-feed/src/modules/app-configuration/ui/side-menu.tsx index 16578b2..378d9fa 100644 --- a/apps/products-feed/src/modules/app-configuration/ui/side-menu.tsx +++ b/apps/products-feed/src/modules/app-configuration/ui/side-menu.tsx @@ -65,6 +65,7 @@ export const SideMenu: React.FC = ({ const classes = useStyles(); const isNoItems = !items || !items.length; + return ( diff --git a/apps/products-feed/src/modules/category-mapping/category-mapping.router.ts b/apps/products-feed/src/modules/category-mapping/category-mapping.router.ts index fdda0f7..2deda61 100644 --- a/apps/products-feed/src/modules/category-mapping/category-mapping.router.ts +++ b/apps/products-feed/src/modules/category-mapping/category-mapping.router.ts @@ -38,6 +38,7 @@ export const categoryMappingRouter = router({ .input(SetCategoryMappingInputSchema) .mutation(async ({ ctx, input }) => { const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl }); + logger.debug("categoriesRouter.setCategoryMapping called"); const { error } = await ctx.apiClient .mutation(UpdateCategoryMappingDocument, { diff --git a/apps/products-feed/src/modules/ui/configuration-page-base-layout.tsx b/apps/products-feed/src/modules/ui/configuration-page-base-layout.tsx index c86ef3f..c0ae053 100644 --- a/apps/products-feed/src/modules/ui/configuration-page-base-layout.tsx +++ b/apps/products-feed/src/modules/ui/configuration-page-base-layout.tsx @@ -28,10 +28,12 @@ export const ConfigurationPageBaseLayout = ({ children }: Props) => { const navigateToTab = (value: string) => { const redirectionUrl = tabs.find((tab) => tab.key === value)?.url; + if (redirectionUrl) { router.push(redirectionUrl); } }; + return (
diff --git a/apps/products-feed/src/pages/_app.tsx b/apps/products-feed/src/pages/_app.tsx index 4c6aed2..dbb68aa 100644 --- a/apps/products-feed/src/pages/_app.tsx +++ b/apps/products-feed/src/pages/_app.tsx @@ -63,6 +63,7 @@ const generateClassName = createGenerateClassName({ * Ensure instance is a singleton. * TODO: This is React 18 issue, consider hiding this workaround inside app-sdk */ + export const appBridgeInstance = typeof window !== "undefined" ? new AppBridge() : undefined; /** @@ -78,6 +79,7 @@ function NextApp({ Component, pageProps }: AppProps) { */ useEffect(() => { const jssStyles = document.querySelector("#jss-server-side"); + if (jssStyles) { jssStyles?.parentElement?.removeChild(jssStyles); } diff --git a/apps/products-feed/src/pages/api/feed/[url]/[channel]/google.xml.ts b/apps/products-feed/src/pages/api/feed/[url]/[channel]/google.xml.ts index 8700e0f..f0cb08d 100644 --- a/apps/products-feed/src/pages/api/feed/[url]/[channel]/google.xml.ts +++ b/apps/products-feed/src/pages/api/feed/[url]/[channel]/google.xml.ts @@ -22,6 +22,7 @@ export const handler = async (req: NextApiRequest, res: NextApiResponse) => { channel, route: "api/feed/{url}/{channel}/google.xml", }); + logger.debug("Feed route visited"); if (!url.length) { @@ -59,8 +60,10 @@ export const handler = async (req: NextApiRequest, res: NextApiResponse) => { let storefrontUrl: string; let productStorefrontUrl: string; + try { const settings = await getGoogleFeedSettings({ authData, channel }); + storefrontUrl = settings.storefrontUrl; productStorefrontUrl = settings.productStorefrontUrl; } catch (error) { @@ -72,8 +75,10 @@ export const handler = async (req: NextApiRequest, res: NextApiResponse) => { let shopName: string; let shopDescription: string | undefined; + try { const shopDetails = await fetchShopData({ client, channel }); + shopName = shopDetails.shopName; shopDescription = shopDetails.shopDescription; } catch (error) { diff --git a/apps/search/next.config.js b/apps/search/next.config.js index 46516e7..8d3ee7d 100644 --- a/apps/search/next.config.js +++ b/apps/search/next.config.js @@ -1,7 +1,9 @@ -// This file sets a custom webpack configuration to use your Next.js app -// with Sentry. -// https://nextjs.org/docs/api-reference/next.config.js/introduction -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ +/* + * This file sets a custom webpack configuration to use your Next.js app + * with Sentry. + * https://nextjs.org/docs/api-reference/next.config.js/introduction + * https://docs.sentry.io/platforms/javascript/guides/nextjs/ + */ const { withSentryConfig } = require("@sentry/nextjs"); @@ -23,12 +25,14 @@ const moduleExports = { }, transpilePackages: ["@saleor/apps-shared"], sentry: { - // Use `hidden-source-map` rather than `source-map` as the Webpack `devtool` - // for client-side builds. (This will be the default starting in - // `@sentry/nextjs` version 8.0.0.) See - // https://webpack.js.org/configuration/devtool/ and - // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#use-hidden-source-map - // for more information. + /* + * Use `hidden-source-map` rather than `source-map` as the Webpack `devtool` + * for client-side builds. (This will be the default starting in + * `@sentry/nextjs` version 8.0.0.) See + * https://webpack.js.org/configuration/devtool/ and + * https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#use-hidden-source-map + * for more information. + */ hideSourceMaps: true, disableServerWebpackPlugin: !isSentryPropertiesInEnvironment, disableClientWebpackPlugin: !isSentryPropertiesInEnvironment, @@ -36,17 +40,23 @@ const moduleExports = { }; const sentryWebpackPluginOptions = { - // Additional config options for the Sentry Webpack plugin. Keep in mind that - // the following options are set automatically, and overriding them is not - // recommended: - // release, url, org, project, authToken, configFile, stripPrefix, - // urlPrefix, include, ignore + /* + * Additional config options for the Sentry Webpack plugin. Keep in mind that + * the following options are set automatically, and overriding them is not + * recommended: + * release, url, org, project, authToken, configFile, stripPrefix, + * urlPrefix, include, ignore + */ silent: true, // Suppresses all logs - // For all available options, see: - // https://github.com/getsentry/sentry-webpack-plugin#options. + /* + * For all available options, see: + * https://github.com/getsentry/sentry-webpack-plugin#options. + */ }; -// Make sure adding Sentry options is the last code to run before exporting, to -// ensure that your source maps include changes from all other Webpack plugins +/* + * Make sure adding Sentry options is the last code to run before exporting, to + * ensure that your source maps include changes from all other Webpack plugins + */ module.exports = withSentryConfig(moduleExports, sentryWebpackPluginOptions); diff --git a/apps/search/package.json b/apps/search/package.json index 011e5bc..51dce72 100644 --- a/apps/search/package.json +++ b/apps/search/package.json @@ -7,6 +7,7 @@ "build": "pnpm generate && next build", "start": "next start", "lint": "next lint", + "lint:fix": "eslint --fix .", "fetch-schema": "curl https://raw.githubusercontent.com/saleor/saleor/${npm_package_saleor_schemaVersion}/saleor/graphql/schema.graphql > graphql/schema.graphql", "generate": "graphql-codegen" }, @@ -58,9 +59,5 @@ "eslint-config-saleor": "workspace:*", "prettier": "^2.7.1", "typescript": "4.8.4" - }, - "lint-staged": { - "*.{js,ts,tsx}": "eslint --cache --fix", - "*.{js,ts,tsx,css,md,json}": "prettier --write" } } diff --git a/apps/search/sentry.client.config.js b/apps/search/sentry.client.config.js index 09f7c52..0712c2b 100644 --- a/apps/search/sentry.client.config.js +++ b/apps/search/sentry.client.config.js @@ -1,17 +1,21 @@ -// This file configures the initialization of Sentry on the browser. -// The config you add here will be used whenever a page is visited. -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ +/* + * This file configures the initialization of Sentry on the browser. + * The config you add here will be used whenever a page is visited. + * https://docs.sentry.io/platforms/javascript/guides/nextjs/ + */ import * as Sentry from '@sentry/nextjs'; -const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN; +const SENTRY_DSN = process.env.SENTRY_DSN Sentry.init({ dsn: SENTRY_DSN, // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1.0, - // ... - // Note: if you want to override the automatic release value, do not set a - // `release` value here - use the environment variable `SENTRY_RELEASE`, so - // that it will also get attached to your source maps + /* + * ... + * Note: if you want to override the automatic release value, do not set a + * `release` value here - use the environment variable `SENTRY_RELEASE`, so + * that it will also get attached to your source maps + */ }); diff --git a/apps/search/sentry.edge.config.js b/apps/search/sentry.edge.config.js index fcf9cb8..563a066 100644 --- a/apps/search/sentry.edge.config.js +++ b/apps/search/sentry.edge.config.js @@ -1,17 +1,21 @@ -// This file configures the initialization of Sentry on the server. -// The config you add here will be used whenever middleware or an Edge route handles a request. -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ +/* + * This file configures the initialization of Sentry on the server. + * The config you add here will be used whenever middleware or an Edge route handles a request. + * https://docs.sentry.io/platforms/javascript/guides/nextjs/ + */ import * as Sentry from '@sentry/nextjs'; -const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN; +const SENTRY_DSN = process.env.SENTRY_DSN Sentry.init({ dsn: SENTRY_DSN, // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1.0, - // ... - // Note: if you want to override the automatic release value, do not set a - // `release` value here - use the environment variable `SENTRY_RELEASE`, so - // that it will also get attached to your source maps + /* + * ... + * Note: if you want to override the automatic release value, do not set a + * `release` value here - use the environment variable `SENTRY_RELEASE`, so + * that it will also get attached to your source maps + */ }); diff --git a/apps/search/sentry.server.config.js b/apps/search/sentry.server.config.js index 990cf22..647606f 100644 --- a/apps/search/sentry.server.config.js +++ b/apps/search/sentry.server.config.js @@ -1,17 +1,21 @@ -// This file configures the initialization of Sentry on the server. -// The config you add here will be used whenever the server handles a request. -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ +/* + * This file configures the initialization of Sentry on the server. + * The config you add here will be used whenever the server handles a request. + * https://docs.sentry.io/platforms/javascript/guides/nextjs/ + */ import * as Sentry from '@sentry/nextjs'; -const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN; +const SENTRY_DSN = process.env.SENTRY_DSN Sentry.init({ dsn: SENTRY_DSN, // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1.0, - // ... - // Note: if you want to override the automatic release value, do not set a - // `release` value here - use the environment variable `SENTRY_RELEASE`, so - // that it will also get attached to your source maps + /* + * ... + * Note: if you want to override the automatic release value, do not set a + * `release` value here - use the environment variable `SENTRY_RELEASE`, so + * that it will also get attached to your source maps + */ }); diff --git a/apps/search/src/components/AlgoliaConfigurationCard.tsx b/apps/search/src/components/AlgoliaConfigurationCard.tsx index 72ed708..081751d 100644 --- a/apps/search/src/components/AlgoliaConfigurationCard.tsx +++ b/apps/search/src/components/AlgoliaConfigurationCard.tsx @@ -49,8 +49,10 @@ export const AlgoliaConfigurationCard = () => { }, body: JSON.stringify(conf), }); + if (resp.status >= 200 && resp.status < 300) { const data = (await resp.json()) as { data?: AlgoliaConfigurationFields }; + return data.data; } throw new Error(`Server responded with status code ${resp.status}`); diff --git a/apps/search/src/components/Hits.tsx b/apps/search/src/components/Hits.tsx index 6ad7a82..cad6a6e 100644 --- a/apps/search/src/components/Hits.tsx +++ b/apps/search/src/components/Hits.tsx @@ -20,6 +20,7 @@ function Hit(props: { hit: any }) { export function Hits() { const { hits } = useHits(); + return (
{hits.map((hit) => ( diff --git a/apps/search/src/components/SearchBox.tsx b/apps/search/src/components/SearchBox.tsx index 2bba1c6..5d6db17 100644 --- a/apps/search/src/components/SearchBox.tsx +++ b/apps/search/src/components/SearchBox.tsx @@ -10,6 +10,7 @@ export function SearchBox() { const handleChange = (e: ChangeEvent) => { refine(e.target.value); }; + return (
{ (async () => { const channels = await getChannels(); // get all products for each channel + await channels.data?.channels?.reduce(async (acc, channel) => { await acc; await getProducts(channel.slug, ""); diff --git a/apps/search/src/lib/algolia/algoliaSearchProvider.ts b/apps/search/src/lib/algolia/algoliaSearchProvider.ts index f4daad0..a4110a9 100644 --- a/apps/search/src/lib/algolia/algoliaSearchProvider.ts +++ b/apps/search/src/lib/algolia/algoliaSearchProvider.ts @@ -34,6 +34,7 @@ export class AlgoliaSearchProvider implements SearchProvider { return Promise.all( Object.entries(groupedByIndex).map(([indexName, objects]) => { const index = this.#algolia.initIndex(indexName); + return index.saveObjects(objects); }) ); @@ -45,6 +46,7 @@ export class AlgoliaSearchProvider implements SearchProvider { return Promise.all( Object.entries(groupedByIndex).map(([indexName, objects]) => { const index = this.#algolia.initIndex(indexName); + return index.deleteObjects(objects.map((o) => o.objectID)); }) ); @@ -57,6 +59,7 @@ export class AlgoliaSearchProvider implements SearchProvider { visibleInListings: true, indexNamePrefix: this.#indexNamePrefix, }); + await this.saveGroupedByIndex(groupedByIndex); } @@ -128,6 +131,7 @@ export class AlgoliaSearchProvider implements SearchProvider { visibleInListings: null, indexNamePrefix: this.#indexNamePrefix, }); + if (groupedByIndexToDelete) { await this.deleteGroupedByIndex(groupedByIndexToDelete); } @@ -157,6 +161,7 @@ const groupVariantByIndexName = ( variant: productVariant, channel: channelListing.channel.slug, }); + return { object, indexName: channelListingToAlgoliaIndexId(channelListing, indexNamePrefix), @@ -190,5 +195,6 @@ const groupProductsByIndexName = ( acc[indexName].push(...objects); return acc; }, {} as GroupedByIndex); + return groupedByIndex; }; diff --git a/apps/search/src/lib/algolia/algoliaUtils.ts b/apps/search/src/lib/algolia/algoliaUtils.ts index 9509f17..31db7c9 100644 --- a/apps/search/src/lib/algolia/algoliaUtils.ts +++ b/apps/search/src/lib/algolia/algoliaUtils.ts @@ -21,6 +21,7 @@ export function channelListingToAlgoliaIndexId( channelListing.channel.currencyCode, "products", ]; + return nameSegments.filter(isNotNil).join("."); } @@ -85,6 +86,7 @@ export function productAndVariantToAlgolia({ const attributes = { ...product.attributes.reduce((acc, attr, idx) => { const preparedAttr = mapSelectedAttributesToRecord(attr); + if (!preparedAttr) { return acc; } @@ -95,6 +97,7 @@ export function productAndVariantToAlgolia({ }, {}), ...variant.attributes.reduce((acc, attr, idx) => { const preparedAttr = mapSelectedAttributesToRecord(attr); + if (!preparedAttr) { return acc; } @@ -123,6 +126,7 @@ export function productAndVariantToAlgolia({ collections: product.collections?.map((collection) => collection.name) || [], metadata: formatMetadata(variant), }; + return document; } diff --git a/apps/search/src/lib/algolia/getAlgoliaConfiguration.ts b/apps/search/src/lib/algolia/getAlgoliaConfiguration.ts index abbb0ad..7d8d1b6 100644 --- a/apps/search/src/lib/algolia/getAlgoliaConfiguration.ts +++ b/apps/search/src/lib/algolia/getAlgoliaConfiguration.ts @@ -18,6 +18,7 @@ export const getAlgoliaConfiguration = async ({ authData }: GetAlgoliaConfigurat try { const secretKey = await settings.get("secretKey", authData.domain); + if (!secretKey?.length) { return { errors: [ @@ -30,6 +31,7 @@ export const getAlgoliaConfiguration = async ({ authData }: GetAlgoliaConfigurat } const appId = await settings.get("appId", authData.domain); + if (!appId?.length) { return { errors: [ @@ -41,6 +43,7 @@ export const getAlgoliaConfiguration = async ({ authData }: GetAlgoliaConfigurat } const indexNamePrefix = (await settings.get("indexNamePrefix", authData.domain)) || ""; + debug("Configuration fetched"); return { settings: { diff --git a/apps/search/src/lib/configuration.ts b/apps/search/src/lib/configuration.ts index 588198c..f61e5f3 100644 --- a/apps/search/src/lib/configuration.ts +++ b/apps/search/src/lib/configuration.ts @@ -9,6 +9,7 @@ export const fetchConfiguration = async (saleorApiUrl: string, token: string) => }, }); const data = (await res.json()) as { data?: AlgoliaConfigurationFields }; + return data.data; }; diff --git a/apps/search/src/lib/metadata.ts b/apps/search/src/lib/metadata.ts index ee78a65..1835fc1 100644 --- a/apps/search/src/lib/metadata.ts +++ b/apps/search/src/lib/metadata.ts @@ -8,10 +8,12 @@ import { } from "../../generated/graphql"; import { settingsManagerSecretKey } from "../../saleor-app"; -// Function is using urql graphql client to fetch all available metadata. -// Before returning query result, we are transforming response to list of objects with key and value fields -// which can be used by the manager. -// Result of this query is cached by the manager. +/* + * Function is using urql graphql client to fetch all available metadata. + * Before returning query result, we are transforming response to list of objects with key and value fields + * which can be used by the manager. + * Result of this query is cached by the manager. + */ export async function fetchAllMetadata(client: Client): Promise { const { error, data } = await client .query(FetchAppDetailsDocument, {}) @@ -25,9 +27,11 @@ export async function fetchAllMetadata(client: Client): Promise return data?.app?.privateMetadata.map((md) => ({ key: md.key, value: md.value })) || []; } -// Mutate function takes urql client and metadata entries, and construct mutation to the API. -// Before data are send, additional query for required App ID is made. -// The manager will use updated entries returned by this mutation to update it's cache. +/* + * Mutate function takes urql client and metadata entries, and construct mutation to the API. + * Before data are send, additional query for required App ID is made. + * The manager will use updated entries returned by this mutation to update it's cache. + */ export async function mutateMetadata(client: Client, metadata: MetadataEntry[]) { // to update the metadata, ID is required const { error: idQueryError, data: idQueryData } = await client @@ -69,9 +73,11 @@ export async function mutateMetadata(client: Client, metadata: MetadataEntry[]) } export const createSettingsManager = (client: Client) => { - // EncryptedMetadataManager gives you interface to manipulate metadata and cache values in memory. - // We recommend it for production, because all values are encrypted. - // If your use case require plain text values, you can use MetadataManager. + /* + * EncryptedMetadataManager gives you interface to manipulate metadata and cache values in memory. + * We recommend it for production, because all values are encrypted. + * If your use case require plain text values, you can use MetadataManager. + */ return new EncryptedMetadataManager({ // Secret key should be randomly created for production and set as environment variable encryptionKey: settingsManagerSecretKey, diff --git a/apps/search/src/pages/_app.tsx b/apps/search/src/pages/_app.tsx index cc28f2f..497922b 100644 --- a/apps/search/src/pages/_app.tsx +++ b/apps/search/src/pages/_app.tsx @@ -35,6 +35,7 @@ const queryClient = new QueryClient({ }, }, }); + type PalettesOverride = Record<"light" | "dark", SaleorThemeColors>; /** @@ -73,6 +74,7 @@ function NextApp({ Component, pageProps }: AppProps) { */ useEffect(() => { const jssStyles = document.querySelector("#jss-server-side"); + if (jssStyles) { jssStyles?.parentElement?.removeChild(jssStyles); } diff --git a/apps/search/src/pages/_error.js b/apps/search/src/pages/_error.js index 49f0ea6..6e8ecdc 100644 --- a/apps/search/src/pages/_error.js +++ b/apps/search/src/pages/_error.js @@ -20,16 +20,20 @@ import * as Sentry from '@sentry/nextjs'; import NextErrorComponent from 'next/error'; const CustomErrorComponent = props => { - // If you're using a Nextjs version prior to 12.2.1, uncomment this to - // compensate for https://github.com/vercel/next.js/issues/8592 - // Sentry.captureUnderscoreErrorException(props); + /* + * If you're using a Nextjs version prior to 12.2.1, uncomment this to + * compensate for https://github.com/vercel/next.js/issues/8592 + * Sentry.captureUnderscoreErrorException(props); + */ return ; }; CustomErrorComponent.getInitialProps = async contextData => { - // In case this is running in a serverless function, await this in order to give Sentry - // time to send the error before the lambda exits + /* + * In case this is running in a serverless function, await this in order to give Sentry + * time to send the error before the lambda exits + */ await Sentry.captureUnderscoreErrorException(contextData); // This will contain the status code of the response diff --git a/apps/search/src/pages/api/configuration.ts b/apps/search/src/pages/api/configuration.ts index e830827..ba7891e 100644 --- a/apps/search/src/pages/api/configuration.ts +++ b/apps/search/src/pages/api/configuration.ts @@ -58,6 +58,7 @@ export const handler = async ( const { appId, searchKey, secretKey, indexNamePrefix } = JSON.parse( req.body ) as AlgoliaConfigurationFields; + await settings.set([ { key: "secretKey", value: secretKey || "", domain }, { key: "searchKey", value: searchKey || "", domain }, diff --git a/apps/search/src/pages/api/webhooks/saleor/product_created.ts b/apps/search/src/pages/api/webhooks/saleor/product_created.ts index 9c5ba4a..077da25 100644 --- a/apps/search/src/pages/api/webhooks/saleor/product_created.ts +++ b/apps/search/src/pages/api/webhooks/saleor/product_created.ts @@ -22,6 +22,7 @@ export const handler: NextWebhookApiHandler = async (req, res, c const debug = createDebug(`Webhook handler - ${webhookProductCreated.event}`); const { event, authData } = context; + debug( `New event ${event} (${context.payload?.__typename}) from the ${authData.domain} domain has been received!` ); @@ -43,6 +44,7 @@ export const handler: NextWebhookApiHandler = async (req, res, c }); const { product } = context.payload; + if (product) { await searchProvider.createProduct(product); } diff --git a/apps/search/src/pages/api/webhooks/saleor/product_deleted.ts b/apps/search/src/pages/api/webhooks/saleor/product_deleted.ts index 2cb1b60..6a51a4a 100644 --- a/apps/search/src/pages/api/webhooks/saleor/product_deleted.ts +++ b/apps/search/src/pages/api/webhooks/saleor/product_deleted.ts @@ -22,6 +22,7 @@ export const handler: NextWebhookApiHandler = async (req, res, c const debug = createDebug(`Webhook handler - ${webhookProductDeleted.event}`); const { event, authData } = context; + debug( `New event ${event} (${context.payload?.__typename}) from the ${authData.domain} domain has been received!` ); @@ -43,6 +44,7 @@ export const handler: NextWebhookApiHandler = async (req, res, c }); const { product } = context.payload; + if (product) { await searchProvider.deleteProduct(product); } diff --git a/apps/search/src/pages/api/webhooks/saleor/product_updated.ts b/apps/search/src/pages/api/webhooks/saleor/product_updated.ts index e59a866..828e1a9 100644 --- a/apps/search/src/pages/api/webhooks/saleor/product_updated.ts +++ b/apps/search/src/pages/api/webhooks/saleor/product_updated.ts @@ -22,6 +22,7 @@ export const handler: NextWebhookApiHandler = async (req, res, c const debug = createDebug(`Webhook handler - ${webhookProductUpdated.event}`); const { event, authData } = context; + debug( `New event ${event} (${context.payload?.__typename}) from the ${authData.domain} domain has been received!` ); @@ -43,6 +44,7 @@ export const handler: NextWebhookApiHandler = async (req, res, c }); const { product } = context.payload; + if (product) { await searchProvider.updateProduct(product); } diff --git a/apps/search/src/pages/api/webhooks/saleor/product_variant_created.ts b/apps/search/src/pages/api/webhooks/saleor/product_variant_created.ts index aaa07ee..46edbfe 100644 --- a/apps/search/src/pages/api/webhooks/saleor/product_variant_created.ts +++ b/apps/search/src/pages/api/webhooks/saleor/product_variant_created.ts @@ -25,6 +25,7 @@ export const handler: NextWebhookApiHandler = async (req, const debug = createDebug(`Webhook handler - ${webhookProductVariantCreated.event}`); const { event, authData } = context; + debug( `New event ${event} (${context.payload?.__typename}) from the ${authData.domain} domain has been received!` ); @@ -46,6 +47,7 @@ export const handler: NextWebhookApiHandler = async (req, }); const { productVariant } = context.payload; + if (productVariant) { await searchProvider.createProductVariant(productVariant); } diff --git a/apps/search/src/pages/api/webhooks/saleor/product_variant_deleted.ts b/apps/search/src/pages/api/webhooks/saleor/product_variant_deleted.ts index 7b7ed42..65b10b2 100644 --- a/apps/search/src/pages/api/webhooks/saleor/product_variant_deleted.ts +++ b/apps/search/src/pages/api/webhooks/saleor/product_variant_deleted.ts @@ -25,6 +25,7 @@ export const handler: NextWebhookApiHandler = async (req, const debug = createDebug(`Webhook handler - ${webhookProductVariantDeleted.event}`); const { event, authData } = context; + debug( `New event ${event} (${context.payload?.__typename}) from the ${authData.domain} domain has been received!` ); @@ -46,6 +47,7 @@ export const handler: NextWebhookApiHandler = async (req, }); const { productVariant } = context.payload; + if (productVariant) { await searchProvider.deleteProductVariant(productVariant); } diff --git a/apps/search/src/pages/api/webhooks/saleor/product_variant_updated.ts b/apps/search/src/pages/api/webhooks/saleor/product_variant_updated.ts index 060455b..611b839 100644 --- a/apps/search/src/pages/api/webhooks/saleor/product_variant_updated.ts +++ b/apps/search/src/pages/api/webhooks/saleor/product_variant_updated.ts @@ -25,6 +25,7 @@ export const handler: NextWebhookApiHandler = async (req, const debug = createDebug(`Webhook handler - ${webhookProductVariantUpdated.event}`); const { event, authData } = context; + debug( `New event ${event} (${context.payload?.__typename}) from the ${authData.domain} domain has been received!` ); @@ -46,6 +47,7 @@ export const handler: NextWebhookApiHandler = async (req, }); const { productVariant } = context.payload; + if (productVariant) { await searchProvider.updateProductVariant(productVariant); } diff --git a/apps/search/turbo.json b/apps/search/turbo.json index 7bceb2c..1071973 100644 --- a/apps/search/turbo.json +++ b/apps/search/turbo.json @@ -11,6 +11,10 @@ "ALLOWED_DOMAIN_PATTERN", "REST_APL_ENDPOINT", "REST_APL_TOKEN", + "SENTRY_AUTH_TOKEN", + "SENTRY_PROJECT", + "SENTRY_DSN", + "SENTRY_ORG", "NEXT_PUBLIC_VERCEL_ENV" ] } diff --git a/apps/slack/next.config.js b/apps/slack/next.config.js index ef8d307..ec85591 100644 --- a/apps/slack/next.config.js +++ b/apps/slack/next.config.js @@ -1,7 +1,9 @@ -// This file sets a custom webpack configuration to use your Next.js app -// with Sentry. -// https://nextjs.org/docs/api-reference/next.config.js/introduction -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ +/* + * This file sets a custom webpack configuration to use your Next.js app + * with Sentry. + * https://nextjs.org/docs/api-reference/next.config.js/introduction + * https://docs.sentry.io/platforms/javascript/guides/nextjs/ + */ const { withSentryConfig } = require("@sentry/nextjs"); @@ -18,28 +20,36 @@ const moduleExports = { sentry: { disableServerWebpackPlugin: !isSentryPropertiesInEnvironment, disableClientWebpackPlugin: !isSentryPropertiesInEnvironment, - // Use `hidden-source-map` rather than `source-map` as the Webpack `devtool` - // for client-side builds. (This will be the default starting in - // `@sentry/nextjs` version 8.0.0.) See - // https://webpack.js.org/configuration/devtool/ and - // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#use-hidden-source-map - // for more information. + /* + * Use `hidden-source-map` rather than `source-map` as the Webpack `devtool` + * for client-side builds. (This will be the default starting in + * `@sentry/nextjs` version 8.0.0.) See + * https://webpack.js.org/configuration/devtool/ and + * https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#use-hidden-source-map + * for more information. + */ hideSourceMaps: true, }, }; const sentryWebpackPluginOptions = { - // Additional config options for the Sentry Webpack plugin. Keep in mind that - // the following options are set automatically, and overriding them is not - // recommended: - // release, url, org, project, authToken, configFile, stripPrefix, - // urlPrefix, include, ignore + /* + * Additional config options for the Sentry Webpack plugin. Keep in mind that + * the following options are set automatically, and overriding them is not + * recommended: + * release, url, org, project, authToken, configFile, stripPrefix, + * urlPrefix, include, ignore + */ silent: true, // Suppresses all logs - // For all available options, see: - // https://github.com/getsentry/sentry-webpack-plugin#options. + /* + * For all available options, see: + * https://github.com/getsentry/sentry-webpack-plugin#options. + */ }; -// Make sure adding Sentry options is the last code to run before exporting, to -// ensure that your source maps include changes from all other Webpack plugins +/* + * Make sure adding Sentry options is the last code to run before exporting, to + * ensure that your source maps include changes from all other Webpack plugins + */ module.exports = withSentryConfig(moduleExports, sentryWebpackPluginOptions); diff --git a/apps/slack/package.json b/apps/slack/package.json index 111312c..e05c20d 100644 --- a/apps/slack/package.json +++ b/apps/slack/package.json @@ -6,7 +6,8 @@ "dev": "pnpm generate && NODE_OPTIONS='--inspect' next dev", "build": "pnpm generate && next build", "start": "next start", - "lint": "pnpm generate && prettier --loglevel warn --write . && eslint --fix .", + "lint": "next lint", + "lint:fix": "eslint --fix .", "fetch-schema": "curl https://raw.githubusercontent.com/saleor/saleor/${npm_package_saleor_schemaVersion}/saleor/graphql/schema.graphql > graphql/schema.graphql", "generate": "graphql-codegen" }, @@ -54,9 +55,5 @@ "postcss": "^8.4.14", "pretty-quick": "^3.1.3", "typescript": "4.8.3" - }, - "lint-staged": { - "*.{js,ts,tsx}": "eslint --cache --fix", - "*.{js,ts,tsx,css,md,json}": "prettier --write" } } diff --git a/apps/slack/sentry.client.config.js b/apps/slack/sentry.client.config.js index d480b2d..5834e2e 100644 --- a/apps/slack/sentry.client.config.js +++ b/apps/slack/sentry.client.config.js @@ -1,6 +1,8 @@ -// This file configures the initialization of Sentry on the browser. -// The config you add here will be used whenever a page is visited. -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ +/* + * This file configures the initialization of Sentry on the browser. + * The config you add here will be used whenever a page is visited. + * https://docs.sentry.io/platforms/javascript/guides/nextjs/ + */ import * as Sentry from "@sentry/nextjs"; @@ -10,8 +12,10 @@ Sentry.init({ dsn: SENTRY_DSN, // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1.0, - // ... - // Note: if you want to override the automatic release value, do not set a - // `release` value here - use the environment variable `SENTRY_RELEASE`, so - // that it will also get attached to your source maps + /* + * ... + * Note: if you want to override the automatic release value, do not set a + * `release` value here - use the environment variable `SENTRY_RELEASE`, so + * that it will also get attached to your source maps + */ }); diff --git a/apps/slack/sentry.edge.config.js b/apps/slack/sentry.edge.config.js index 1c3e861..f97c794 100644 --- a/apps/slack/sentry.edge.config.js +++ b/apps/slack/sentry.edge.config.js @@ -1,6 +1,8 @@ -// This file configures the initialization of Sentry on the server. -// The config you add here will be used whenever middleware or an Edge route handles a request. -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ +/* + * This file configures the initialization of Sentry on the server. + * The config you add here will be used whenever middleware or an Edge route handles a request. + * https://docs.sentry.io/platforms/javascript/guides/nextjs/ + */ import * as Sentry from "@sentry/nextjs"; @@ -10,8 +12,10 @@ Sentry.init({ dsn: SENTRY_DSN, // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1.0, - // ... - // Note: if you want to override the automatic release value, do not set a - // `release` value here - use the environment variable `SENTRY_RELEASE`, so - // that it will also get attached to your source maps + /* + * ... + * Note: if you want to override the automatic release value, do not set a + * `release` value here - use the environment variable `SENTRY_RELEASE`, so + * that it will also get attached to your source maps + */ }); diff --git a/apps/slack/sentry.server.config.js b/apps/slack/sentry.server.config.js index a7e581b..eb63769 100644 --- a/apps/slack/sentry.server.config.js +++ b/apps/slack/sentry.server.config.js @@ -1,6 +1,8 @@ -// This file configures the initialization of Sentry on the server. -// The config you add here will be used whenever the server handles a request. -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ +/* + * This file configures the initialization of Sentry on the server. + * The config you add here will be used whenever the server handles a request. + * https://docs.sentry.io/platforms/javascript/guides/nextjs/ + */ import * as Sentry from "@sentry/nextjs"; @@ -10,8 +12,10 @@ Sentry.init({ dsn: SENTRY_DSN, // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1.0, - // ... - // Note: if you want to override the automatic release value, do not set a - // `release` value here - use the environment variable `SENTRY_RELEASE`, so - // that it will also get attached to your source maps + /* + * ... + * Note: if you want to override the automatic release value, do not set a + * `release` value here - use the environment variable `SENTRY_RELEASE`, so + * that it will also get attached to your source maps + */ }); diff --git a/apps/slack/src/hooks/theme-synchronizer.tsx b/apps/slack/src/hooks/theme-synchronizer.tsx index b07b09d..03a4dff 100644 --- a/apps/slack/src/hooks/theme-synchronizer.tsx +++ b/apps/slack/src/hooks/theme-synchronizer.tsx @@ -12,10 +12,12 @@ function _ThemeSynchronizer() { const { appBridgeState, appBridge } = useAppBridge(); const { setTheme, themeType } = useTheme(); - // todo - replace this hook to appBridge.subscribe and react only only on initial theme event - // useEffect(() =>{ - // appBridge?.subscribe('theme',console.log) - // },[appBridge]) + /* + * todo - replace this hook to appBridge.subscribe and react only only on initial theme event + * useEffect(() =>{ + * appBridge?.subscribe('theme',console.log) + * },[appBridge]) + */ useEffect(() => { if (!setTheme || !appBridgeState?.theme) { diff --git a/apps/slack/src/hooks/useAppApi.ts b/apps/slack/src/hooks/useAppApi.ts index 073e557..786bc0e 100644 --- a/apps/slack/src/hooks/useAppApi.ts +++ b/apps/slack/src/hooks/useAppApi.ts @@ -39,6 +39,7 @@ export const useAppApi = ({ url, options, skip }: UseFetchProps) => { } const json = await res.json(); + setData(json); } catch (e) { setError(e as unknown); diff --git a/apps/slack/src/lib/metadata.ts b/apps/slack/src/lib/metadata.ts index 400074c..8705a18 100644 --- a/apps/slack/src/lib/metadata.ts +++ b/apps/slack/src/lib/metadata.ts @@ -8,10 +8,12 @@ import { } from "../../generated/graphql"; import { settingsManagerSecretKey } from "./saleor-app"; -// Function is using urql graphql client to fetch all available metadata. -// Before returning query result, we are transforming response to list of objects with key and value fields -// which can be used by the manager. -// Result of this query is cached by the manager. +/* + * Function is using urql graphql client to fetch all available metadata. + * Before returning query result, we are transforming response to list of objects with key and value fields + * which can be used by the manager. + * Result of this query is cached by the manager. + */ export async function fetchAllMetadata(client: Client): Promise { const { error, data } = await client .query(FetchAppDetailsDocument, {}) @@ -25,9 +27,11 @@ export async function fetchAllMetadata(client: Client): Promise return data?.app?.privateMetadata.map((md) => ({ key: md.key, value: md.value })) || []; } -// Mutate function takes urql client and metadata entries, and construct mutation to the API. -// Before data are send, additional query for required App ID is made. -// The manager will use updated entries returned by this mutation to update it's cache. +/* + * Mutate function takes urql client and metadata entries, and construct mutation to the API. + * Before data are send, additional query for required App ID is made. + * The manager will use updated entries returned by this mutation to update it's cache. + */ export async function mutateMetadata(client: Client, appId: string, metadata: MetadataEntry[]) { const { error: mutationError, data: mutationData } = await client .mutation(UpdateAppMetadataDocument, { @@ -50,9 +54,11 @@ export async function mutateMetadata(client: Client, appId: string, metadata: Me } export const createSettingsManager = (client: Client, appId: string) => - // EncryptedMetadataManager gives you interface to manipulate metadata and cache values in memory. - // We recommend it for production, because all values are encrypted. - // If your use case require plain text values, you can use MetadataManager. + /* + * EncryptedMetadataManager gives you interface to manipulate metadata and cache values in memory. + * We recommend it for production, because all values are encrypted. + * If your use case require plain text values, you can use MetadataManager. + */ new EncryptedMetadataManager({ // Secret key should be randomly created for production and set as environment variable encryptionKey: settingsManagerSecretKey, diff --git a/apps/slack/src/lib/saleor-app.ts b/apps/slack/src/lib/saleor-app.ts index 99ee378..f6cccc8 100644 --- a/apps/slack/src/lib/saleor-app.ts +++ b/apps/slack/src/lib/saleor-app.ts @@ -10,6 +10,7 @@ import { SaleorApp } from "@saleor/app-sdk/saleor-app"; */ let apl: APL; + switch (process.env.APL) { case "upstash": // Require `UPSTASH_URL` and `UPSTASH_TOKEN` environment variables @@ -30,12 +31,14 @@ switch (process.env.APL) { apl = new FileAPL(); } -// TODO: Investigate why no-ssr-wrapper does not prevent this code from execution during the build time -// if (!process.env.SECRET_KEY && process.env.NODE_ENV === "production") { -// throw new Error( -// "For production deployment SECRET_KEY is mandatory to use EncryptedSettingsManager." -// ); -// } +/* + * TODO: Investigate why no-ssr-wrapper does not prevent this code from execution during the build time + * if (!process.env.SECRET_KEY && process.env.NODE_ENV === "production") { + * throw new Error( + * "For production deployment SECRET_KEY is mandatory to use EncryptedSettingsManager." + * ); + * } + */ // Use placeholder value for the development export const settingsManagerSecretKey = process.env.SECRET_KEY || "CHANGE_ME"; diff --git a/apps/slack/src/pages/_app.tsx b/apps/slack/src/pages/_app.tsx index ffbfca4..905be19 100644 --- a/apps/slack/src/pages/_app.tsx +++ b/apps/slack/src/pages/_app.tsx @@ -73,6 +73,7 @@ function SaleorApp({ Component, pageProps }: AppLayoutProps) { useEffect(() => { const jssStyles = document.querySelector("#jss-server-side"); + if (jssStyles) { jssStyles?.parentElement?.removeChild(jssStyles); } diff --git a/apps/slack/src/pages/_error.js b/apps/slack/src/pages/_error.js index 55c3486..316beec 100644 --- a/apps/slack/src/pages/_error.js +++ b/apps/slack/src/pages/_error.js @@ -20,16 +20,20 @@ import * as Sentry from "@sentry/nextjs"; import NextErrorComponent from "next/error"; const CustomErrorComponent = (props) => { - // If you're using a Nextjs version prior to 12.2.1, uncomment this to - // compensate for https://github.com/vercel/next.js/issues/8592 - // Sentry.captureUnderscoreErrorException(props); + /* + * If you're using a Nextjs version prior to 12.2.1, uncomment this to + * compensate for https://github.com/vercel/next.js/issues/8592 + * Sentry.captureUnderscoreErrorException(props); + */ return ; }; CustomErrorComponent.getInitialProps = async (contextData) => { - // In case this is running in a serverless function, await this in order to give Sentry - // time to send the error before the lambda exits + /* + * In case this is running in a serverless function, await this in order to give Sentry + * time to send the error before the lambda exits + */ await Sentry.captureUnderscoreErrorException(contextData); // This will contain the status code of the response diff --git a/apps/slack/src/pages/_error.tsx b/apps/slack/src/pages/_error.tsx index d431a7f..b6539e1 100644 --- a/apps/slack/src/pages/_error.tsx +++ b/apps/slack/src/pages/_error.tsx @@ -15,10 +15,12 @@ interface AppErrorProps extends ErrorProps { function MyError({ statusCode, hasGetInitialPropsRun, err }: ErrorPageProps) { if (!hasGetInitialPropsRun && err) { - // getInitialProps is not called when an exception is thrown - // at the top level of a module while it is being loaded. - // As a workaround, we pass err via _app.js so it can be captured - // Read more: https://github.com/vercel/next.js/issues/8592. + /* + * getInitialProps is not called when an exception is thrown + * at the top level of a module while it is being loaded. + * As a workaround, we pass err via _app.js so it can be captured + * Read more: https://github.com/vercel/next.js/issues/8592. + */ Sentry.captureException(err); // Flushing is not required in this case as it only happens on the client } @@ -31,8 +33,10 @@ MyError.getInitialProps = async (context: NextPageContext) => { const { res, err, asPath } = context; - // Workaround for https://github.com/vercel/next.js/issues/8592, mark when - // getInitialProps has run + /* + * Workaround for https://github.com/vercel/next.js/issues/8592, mark when + * getInitialProps has run + */ errorInitialProps.hasGetInitialPropsRun = true; // Returning early because we don't want to log 404 errors to Sentry. @@ -40,32 +44,38 @@ MyError.getInitialProps = async (context: NextPageContext) => { return errorInitialProps; } - // Running on the server, the response object (`res`) is available. - // - // Next.js will pass an err on the server if a page's data fetching methods - // threw or returned a Promise that rejected - // - // Running on the client (browser), Next.js will provide an err if: - // - // - a page's `getInitialProps` threw or returned a Promise that rejected - // - an exception was thrown somewhere in the React lifecycle (render, - // componentDidMount, etc) that was caught by Next.js's React Error - // Boundary. Read more about what types of exceptions are caught by Error - // Boundaries: https://reactjs.org/docs/error-boundaries.html + /* + * Running on the server, the response object (`res`) is available. + * + * Next.js will pass an err on the server if a page's data fetching methods + * threw or returned a Promise that rejected + * + * Running on the client (browser), Next.js will provide an err if: + * + * - a page's `getInitialProps` threw or returned a Promise that rejected + * - an exception was thrown somewhere in the React lifecycle (render, + * componentDidMount, etc) that was caught by Next.js's React Error + * Boundary. Read more about what types of exceptions are caught by Error + * Boundaries: https://reactjs.org/docs/error-boundaries.html + */ if (err) { Sentry.captureException(err); - // Flushing before returning is necessary if deploying to Vercel, see - // https://vercel.com/docs/platform/limits#streaming-responses + /* + * Flushing before returning is necessary if deploying to Vercel, see + * https://vercel.com/docs/platform/limits#streaming-responses + */ await Sentry.flush(2000); return errorInitialProps; } - // If this point is reached, getInitialProps was called without any - // information about what the error might be. This is unexpected and may - // indicate a bug introduced in Next.js, so record it in Sentry + /* + * If this point is reached, getInitialProps was called without any + * information about what the error might be. This is unexpected and may + * indicate a bug introduced in Next.js, so record it in Sentry + */ Sentry.captureException(new Error(`_error.js getInitialProps missing data at path: ${asPath}`)); await Sentry.flush(2000); diff --git a/apps/slack/src/pages/api/configuration.ts b/apps/slack/src/pages/api/configuration.ts index ebb9fa3..6f44e6e 100644 --- a/apps/slack/src/pages/api/configuration.ts +++ b/apps/slack/src/pages/api/configuration.ts @@ -34,6 +34,7 @@ export const handler = async ( case "POST": { const reqBody = req.body as PostRequestBody; const newWebhookUrl = (await reqBody.data?.find((entry) => entry.key === WEBHOOK_URL))?.value; + if (!newWebhookUrl) { console.error("New value for the webhook URL has not been found"); res.status(400).json({ diff --git a/apps/slack/src/pages/api/register.ts b/apps/slack/src/pages/api/register.ts index 4217557..6096b51 100644 --- a/apps/slack/src/pages/api/register.ts +++ b/apps/slack/src/pages/api/register.ts @@ -8,6 +8,7 @@ const handler = createAppRegisterHandler({ (url) => { if (allowedUrlsPattern) { const regex = new RegExp(allowedUrlsPattern); + if (regex.test(url)) { console.debug(`Registration from the URL ${url} has been accepted`); return true; diff --git a/apps/slack/src/pages/api/webhooks/order-created.ts b/apps/slack/src/pages/api/webhooks/order-created.ts index c6481ec..0716d7b 100644 --- a/apps/slack/src/pages/api/webhooks/order-created.ts +++ b/apps/slack/src/pages/api/webhooks/order-created.ts @@ -107,6 +107,7 @@ const handler: NextWebhookApiHandler = async if (response.status !== 200) { const errorMessage = await response.text(); + console.error(`Slack API responded with code ${response.status}: ${errorMessage}`); return res.status(500).send({ diff --git a/apps/slack/src/pages/configuration.tsx b/apps/slack/src/pages/configuration.tsx index 25eb810..7d81ad0 100644 --- a/apps/slack/src/pages/configuration.tsx +++ b/apps/slack/src/pages/configuration.tsx @@ -79,6 +79,7 @@ function Configuration() { const onChange = (event: ChangeEvent) => { const { name, value } = event.target as HTMLInputElement; + setConfiguration((prev) => prev!.map((prevField) => (prevField.key === name ? { ...prevField, value } : prevField)) ); @@ -129,6 +130,7 @@ function Instructions() { }); const slackUrl = new URL("https://api.slack.com/apps"); + slackUrl.searchParams.append("new_app", "1"); slackUrl.searchParams.append("manifest_json", JSON.stringify(data)); diff --git a/apps/taxes/package.json b/apps/taxes/package.json index bcd7af4..f828a57 100644 --- a/apps/taxes/package.json +++ b/apps/taxes/package.json @@ -7,6 +7,7 @@ "build": "pnpm generate && next build", "start": "next start", "lint": "next lint", + "lint:fix": "eslint --fix .", "fetch-schema": "curl https://raw.githubusercontent.com/saleor/saleor/${npm_package_saleor_schemaVersion}/saleor/graphql/schema.graphql > graphql/schema.graphql", "generate": "graphql-codegen", "test": "vitest" diff --git a/packages/eslint-config-saleor/index.js b/packages/eslint-config-saleor/index.js index 90eddc4..b0aad0c 100644 --- a/packages/eslint-config-saleor/index.js +++ b/packages/eslint-config-saleor/index.js @@ -20,4 +20,5 @@ module.exports = { }, }, ], + ignorePatterns: ["next-env.d.ts"], }; diff --git a/packages/shared/package.json b/packages/shared/package.json index 1b1ab8d..4047078 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -20,5 +20,8 @@ "react": "^18.2.0", "react-dom": "^18.2.0" }, + "scripts": { + "lint:fix": "eslint --fix ." + }, "main": "index.ts" } diff --git a/turbo.json b/turbo.json index a00437b..87544a0 100644 --- a/turbo.json +++ b/turbo.json @@ -24,6 +24,7 @@ }, "generate": { "outputs": ["generated/"] - } + }, + "lint:fix": {} } }