Extract logger (#439)
* Extract logger * Replace logger with shared one * Replace CRM logger with shared one * Replace E&M logger with shared one * Replace invoices logger with shared one * Replace Products Feed logger with shared one * Replace Search logger with shared one * Replace Taxes logger with shared one * Uninstall pino from apps direct dependency * Update docs * Update changeset * Bumped Klaviyo typescript version to hopefully unblock the build * Change packageManager field to pnpm 8.2.0 * removed package manager field from klaviyo package.json
This commit is contained in:
parent
b56894fa14
commit
830cfe92ce
103 changed files with 415 additions and 362 deletions
15
.changeset/heavy-pens-shop.md
Normal file
15
.changeset/heavy-pens-shop.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
"saleor-app-emails-and-messages": minor
|
||||||
|
"saleor-app-products-feed": minor
|
||||||
|
"saleor-app-invoices": minor
|
||||||
|
"saleor-app-search": minor
|
||||||
|
"saleor-app-taxes": minor
|
||||||
|
"saleor-app-cms": minor
|
||||||
|
"saleor-app-crm": minor
|
||||||
|
"saleor-app-data-importer": minor
|
||||||
|
"saleor-app-klaviyo": minor
|
||||||
|
"saleor-app-monitoring": minor
|
||||||
|
"saleor-app-slack": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Changed APP_DEBUG env to APP_LOG_LEVEL
|
11
.changeset/poor-dots-play.md
Normal file
11
.changeset/poor-dots-play.md
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
"saleor-app-emails-and-messages": patch
|
||||||
|
"saleor-app-products-feed": patch
|
||||||
|
"saleor-app-invoices": patch
|
||||||
|
"saleor-app-search": patch
|
||||||
|
"saleor-app-taxes": patch
|
||||||
|
"saleor-app-cms": patch
|
||||||
|
"saleor-app-crm": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Replaced internal logger implementation with shared logger
|
5
.changeset/six-laws-do.md
Normal file
5
.changeset/six-laws-do.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"@saleor/apps-shared": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Add Pino logger and renamed required env to be APP_LOG_LEVEL
|
5
.changeset/spicy-bottles-sort.md
Normal file
5
.changeset/spicy-bottles-sort.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"saleor-app-klaviyo": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Bumped Typescript version to 5.0.4
|
|
@ -38,14 +38,17 @@ This repository serves as a starting point in the exploration of Saleor apps.
|
||||||
|
|
||||||
In the `apps` folder, you will find the following applications:
|
In the `apps` folder, you will find the following applications:
|
||||||
|
|
||||||
|
- [crm](https://docs.saleor.io/docs/3.x/developer/app-store/apps/crm) - exports customers from Saleor to CRM.
|
||||||
|
- [cms](./apps/cms) - exports products from Saleor to CMS.
|
||||||
- [data-importer](./apps/data-importer) - import data from CSV to Saleor.
|
- [data-importer](./apps/data-importer) - import data from CSV to Saleor.
|
||||||
|
- [emails-and-messages](./apps/emails-and-messages) - notifications and email communication with customers.
|
||||||
- [invoices](./apps/invoices) - generate invoice PDF for each order.
|
- [invoices](./apps/invoices) - generate invoice PDF for each order.
|
||||||
- [klaviyo](./apps/klaviyo) - send Saleor events to Klaviyo, where you can notify the customers.
|
- [klaviyo](./apps/klaviyo) - send Saleor events to Klaviyo, where you can notify the customers.
|
||||||
- [emails-and-messages](./apps/emails-and-messages) - notifications and email communication with customers.
|
- [monitoring](./apps/monitoring) - send Saleor logs to 3rd party Monitoring services
|
||||||
|
- [products-feed](./apps/products-feed) - generate products feed XML
|
||||||
- [search](./apps/search) - connect Saleor with search engines.
|
- [search](./apps/search) - connect Saleor with search engines.
|
||||||
- [slack](./apps/slack) - get notifications on Slack channel from Saleor events.
|
- [slack](./apps/slack) - get notifications on Slack channel from Saleor events.
|
||||||
- [taxes](https://docs.saleor.io/docs/3.x/developer/app-store/apps/taxes) - calculate order and checkout taxes using external services.
|
- [taxes](https://docs.saleor.io/docs/3.x/developer/app-store/apps/taxes) - calculate order and checkout taxes using external services.
|
||||||
- [cms](./apps/cms) - exports products from Saleor to CMS.
|
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
|
|
|
@ -7,4 +7,4 @@ APL=
|
||||||
REST_APL_ENDPOINT=
|
REST_APL_ENDPOINT=
|
||||||
REST_APL_TOKEN=
|
REST_APL_TOKEN=
|
||||||
|
|
||||||
APP_DEBUG=debug # Pino logger levels
|
APP_LOG_LEVEL=info
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
"graphql": "^16.6.0",
|
"graphql": "^16.6.0",
|
||||||
"graphql-tag": "^2.12.6",
|
"graphql-tag": "^2.12.6",
|
||||||
"next": "13.3.0",
|
"next": "13.3.0",
|
||||||
"pino": "^8.8.0",
|
|
||||||
"pino-pretty": "^9.1.1",
|
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-hook-form": "^7.39.1",
|
"react-hook-form": "^7.39.1",
|
||||||
|
|
|
@ -9,14 +9,15 @@ import {
|
||||||
ProductResponseSuccess,
|
ProductResponseSuccess,
|
||||||
} from "../types";
|
} from "../types";
|
||||||
import { getCmsIdFromSaleorItem } from "./metadata";
|
import { getCmsIdFromSaleorItem } from "./metadata";
|
||||||
import { logger as pinoLogger } from "../../logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import { CMSProvider, cmsProviders } from "../providers";
|
import { CMSProvider, cmsProviders } from "../providers";
|
||||||
import { ProviderInstanceSchema, providersSchemaSet } from "../config";
|
import { ProviderInstanceSchema, providersSchemaSet } from "../config";
|
||||||
|
|
||||||
export const pingProviderInstance = async (
|
export const pingProviderInstance = async (
|
||||||
providerInstanceSettings: ProviderInstanceSchema
|
providerInstanceSettings: ProviderInstanceSchema
|
||||||
): Promise<BaseResponse> => {
|
): Promise<BaseResponse> => {
|
||||||
const logger = pinoLogger.child({ providerInstanceSettings });
|
const logger = createLogger({ providerInstanceSettings });
|
||||||
|
|
||||||
logger.debug("Ping provider instance called");
|
logger.debug("Ping provider instance called");
|
||||||
|
|
||||||
const provider = cmsProviders[
|
const provider = cmsProviders[
|
||||||
|
@ -57,7 +58,8 @@ const executeCmsClientOperation = async ({
|
||||||
cmsClient: CmsClientOperations;
|
cmsClient: CmsClientOperations;
|
||||||
productVariant: WebhookProductVariantFragment;
|
productVariant: WebhookProductVariantFragment;
|
||||||
}): Promise<CmsClientOperationResult | undefined> => {
|
}): Promise<CmsClientOperationResult | undefined> => {
|
||||||
const logger = pinoLogger.child({ cmsClient });
|
const logger = createLogger({ cmsClient });
|
||||||
|
|
||||||
logger.debug("Execute CMS client operation called");
|
logger.debug("Execute CMS client operation called");
|
||||||
|
|
||||||
const cmsId = getCmsIdFromSaleorItem(productVariant, cmsClient.cmsProviderInstanceId);
|
const cmsId = getCmsIdFromSaleorItem(productVariant, cmsClient.cmsProviderInstanceId);
|
||||||
|
@ -84,9 +86,11 @@ const executeCmsClientOperation = async ({
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await cmsClient.operations.updateProduct({
|
await cmsClient.operations.updateProduct({
|
||||||
// todo: change params of product methods because of below:
|
/*
|
||||||
// * In some CMSes, cmsId may be productId. Perhaps it's better to just pass everything as one big object
|
* todo: change params of product methods because of below:
|
||||||
// * and decide on the id on the provider level.
|
* * In some CMSes, cmsId may be productId. Perhaps it's better to just pass everything as one big object
|
||||||
|
* * and decide on the id on the provider level.
|
||||||
|
*/
|
||||||
id: cmsId,
|
id: cmsId,
|
||||||
input: {
|
input: {
|
||||||
saleorId: productVariant.id,
|
saleorId: productVariant.id,
|
||||||
|
@ -163,7 +167,8 @@ export const executeCmsClientBatchOperation = async ({
|
||||||
productVariant: WebhookProductVariantFragment
|
productVariant: WebhookProductVariantFragment
|
||||||
) => boolean;
|
) => boolean;
|
||||||
}): Promise<CmsClientBatchOperationResult | undefined> => {
|
}): Promise<CmsClientBatchOperationResult | undefined> => {
|
||||||
const logger = pinoLogger.child({ cmsClient });
|
const logger = createLogger({ cmsClient });
|
||||||
|
|
||||||
logger.debug({ operations: cmsClient.operations }, "Execute CMS client operation called");
|
logger.debug({ operations: cmsClient.operations }, "Execute CMS client operation called");
|
||||||
|
|
||||||
if (cmsClient.operationType === "createBatchProducts") {
|
if (cmsClient.operationType === "createBatchProducts") {
|
||||||
|
|
|
@ -9,9 +9,10 @@ import {
|
||||||
import { providersSchemaSet } from "../config";
|
import { providersSchemaSet } from "../config";
|
||||||
import { CMSProvider, cmsProviders } from "../providers";
|
import { CMSProvider, cmsProviders } from "../providers";
|
||||||
import { CmsClientOperations } from "../types";
|
import { CmsClientOperations } from "../types";
|
||||||
import { logger as pinoLogger } from "../../logger";
|
|
||||||
import { getCmsIdFromSaleorItemKey } from "./metadata";
|
import { getCmsIdFromSaleorItemKey } from "./metadata";
|
||||||
import { type Client } from "urql";
|
import { type Client } from "urql";
|
||||||
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
type WebhookContext = Parameters<NextWebhookApiHandler>["2"];
|
type WebhookContext = Parameters<NextWebhookApiHandler>["2"];
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ export const createCmsOperations = async ({
|
||||||
productVariantChannels: string[];
|
productVariantChannels: string[];
|
||||||
productVariantCmsKeys: string[];
|
productVariantCmsKeys: string[];
|
||||||
}) => {
|
}) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
productVariantChannels,
|
productVariantChannels,
|
||||||
productVariantCmsKeys,
|
productVariantCmsKeys,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
import { ContentfulConfig, contentfulConfigSchema } from "../config";
|
import { ContentfulConfig, contentfulConfigSchema } from "../config";
|
||||||
import { logger as pinoLogger } from "../../logger";
|
|
||||||
|
|
||||||
import { CreateOperations, ProductResponse, ProductInput } from "../types";
|
import { CreateOperations, ProductResponse, ProductInput } from "../types";
|
||||||
import { createProvider } from "./create";
|
import { createProvider } from "./create";
|
||||||
import { fetchWithRateLimit } from "../data-sync";
|
import { fetchWithRateLimit } from "../data-sync";
|
||||||
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const contentfulFetch = (endpoint: string, config: ContentfulConfig, options?: RequestInit) => {
|
const contentfulFetch = (endpoint: string, config: ContentfulConfig, options?: RequestInit) => {
|
||||||
const baseUrl = config.baseUrl || "https://api.contentful.com";
|
const baseUrl = config.baseUrl || "https://api.contentful.com";
|
||||||
|
@ -64,6 +64,7 @@ const transformInputToBody = ({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return body;
|
return body;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -95,7 +96,7 @@ const getEntryEndpoint = ({
|
||||||
}): string => `/spaces/${spaceId}/environments/${environment}/entries/${resourceId}`;
|
}): string => `/spaces/${spaceId}/environments/${environment}/entries/${resourceId}`;
|
||||||
|
|
||||||
const contentfulOperations: CreateOperations<ContentfulConfig> = (config) => {
|
const contentfulOperations: CreateOperations<ContentfulConfig> = (config) => {
|
||||||
const logger = pinoLogger.child({ cms: "strapi" });
|
const logger = createLogger({ cms: "strapi" });
|
||||||
|
|
||||||
const { environment, spaceId, contentId, locale, apiRequestsPerSecond } = config;
|
const { environment, spaceId, contentId, locale, apiRequestsPerSecond } = config;
|
||||||
|
|
||||||
|
@ -104,6 +105,7 @@ const contentfulOperations: CreateOperations<ContentfulConfig> = (config) => {
|
||||||
const pingCMS = async () => {
|
const pingCMS = async () => {
|
||||||
const endpoint = `/spaces/${spaceId}`;
|
const endpoint = `/spaces/${spaceId}`;
|
||||||
const response = await contentfulFetch(endpoint, config, { method: "GET" });
|
const response = await contentfulFetch(endpoint, config, { method: "GET" });
|
||||||
|
|
||||||
logger.debug({ response }, "pingCMS response");
|
logger.debug({ response }, "pingCMS response");
|
||||||
return {
|
return {
|
||||||
ok: response.ok,
|
ok: response.ok,
|
||||||
|
@ -126,8 +128,10 @@ const contentfulOperations: CreateOperations<ContentfulConfig> = (config) => {
|
||||||
"X-Contentful-Content-Type": contentId,
|
"X-Contentful-Content-Type": contentId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.debug({ response }, "createProduct response");
|
logger.debug({ response }, "createProduct response");
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...json,
|
...json,
|
||||||
statusCode: response.status,
|
statusCode: response.status,
|
||||||
|
@ -144,8 +148,10 @@ const contentfulOperations: CreateOperations<ContentfulConfig> = (config) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const getEntryResponse = await contentfulFetch(endpoint, config, { method: "GET" });
|
const getEntryResponse = await contentfulFetch(endpoint, config, { method: "GET" });
|
||||||
|
|
||||||
logger.debug({ getEntryResponse }, "updateProduct getEntryResponse");
|
logger.debug({ getEntryResponse }, "updateProduct getEntryResponse");
|
||||||
const entry = await getEntryResponse.json();
|
const entry = await getEntryResponse.json();
|
||||||
|
|
||||||
logger.debug({ entry }, "updateProduct entry");
|
logger.debug({ entry }, "updateProduct entry");
|
||||||
|
|
||||||
const response = await contentfulFetch(endpoint, config, {
|
const response = await contentfulFetch(endpoint, config, {
|
||||||
|
@ -155,8 +161,10 @@ const contentfulOperations: CreateOperations<ContentfulConfig> = (config) => {
|
||||||
"X-Contentful-Version": entry.sys.version,
|
"X-Contentful-Version": entry.sys.version,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.debug({ response }, "updateProduct response");
|
logger.debug({ response }, "updateProduct response");
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...json,
|
...json,
|
||||||
statusCode: response.status,
|
statusCode: response.status,
|
||||||
|
@ -178,6 +186,7 @@ const contentfulOperations: CreateOperations<ContentfulConfig> = (config) => {
|
||||||
|
|
||||||
// Retry with delay x2 if by any chance hit rate limit with HTTP 429
|
// Retry with delay x2 if by any chance hit rate limit with HTTP 429
|
||||||
let secondResults: ContentfulResponse[] = [];
|
let secondResults: ContentfulResponse[] = [];
|
||||||
|
|
||||||
if (failedWithLimitResults.length > 0) {
|
if (failedWithLimitResults.length > 0) {
|
||||||
logger.debug("createBatchProductsInCMS retrying failed by rate limit with delay x2");
|
logger.debug("createBatchProductsInCMS retrying failed by rate limit with delay x2");
|
||||||
secondResults = await fetchWithRateLimit(
|
secondResults = await fetchWithRateLimit(
|
||||||
|
@ -199,6 +208,7 @@ const contentfulOperations: CreateOperations<ContentfulConfig> = (config) => {
|
||||||
|
|
||||||
// Retry with delay x2 if by any chance hit rate limit with HTTP 429
|
// Retry with delay x2 if by any chance hit rate limit with HTTP 429
|
||||||
let secondResults: Response[] = [];
|
let secondResults: Response[] = [];
|
||||||
|
|
||||||
if (failedWithLimitResults.length > 0) {
|
if (failedWithLimitResults.length > 0) {
|
||||||
logger.debug("deleteBatchProductsInCMS retrying failed by rate limit with delay x2");
|
logger.debug("deleteBatchProductsInCMS retrying failed by rate limit with delay x2");
|
||||||
secondResults = await fetchWithRateLimit(
|
secondResults = await fetchWithRateLimit(
|
||||||
|
@ -214,36 +224,42 @@ const contentfulOperations: CreateOperations<ContentfulConfig> = (config) => {
|
||||||
return {
|
return {
|
||||||
ping: async () => {
|
ping: async () => {
|
||||||
const response = await pingCMS();
|
const response = await pingCMS();
|
||||||
|
|
||||||
logger.debug({ response }, "ping response");
|
logger.debug({ response }, "ping response");
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
createProduct: async ({ input }) => {
|
createProduct: async ({ input }) => {
|
||||||
const result = await createProductInCMS(input);
|
const result = await createProductInCMS(input);
|
||||||
|
|
||||||
logger.debug({ result }, "createProduct result");
|
logger.debug({ result }, "createProduct result");
|
||||||
|
|
||||||
return transformCreateProductResponse(result);
|
return transformCreateProductResponse(result);
|
||||||
},
|
},
|
||||||
updateProduct: async ({ id, input }) => {
|
updateProduct: async ({ id, input }) => {
|
||||||
const result = await updateProductInCMS(id, input);
|
const result = await updateProductInCMS(id, input);
|
||||||
|
|
||||||
logger.debug({ result }, "updateProduct result");
|
logger.debug({ result }, "updateProduct result");
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
deleteProduct: async ({ id }) => {
|
deleteProduct: async ({ id }) => {
|
||||||
const response = await deleteProductInCMS(id);
|
const response = await deleteProductInCMS(id);
|
||||||
|
|
||||||
logger.debug({ response }, "deleteProduct response");
|
logger.debug({ response }, "deleteProduct response");
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
createBatchProducts: async ({ input }) => {
|
createBatchProducts: async ({ input }) => {
|
||||||
const results = await createBatchProductsInCMS(input);
|
const results = await createBatchProductsInCMS(input);
|
||||||
|
|
||||||
logger.debug({ results }, "createBatchProducts results");
|
logger.debug({ results }, "createBatchProducts results");
|
||||||
|
|
||||||
return results.map((result) => transformCreateProductResponse(result));
|
return results.map((result) => transformCreateProductResponse(result));
|
||||||
},
|
},
|
||||||
deleteBatchProducts: async ({ ids }) => {
|
deleteBatchProducts: async ({ ids }) => {
|
||||||
const results = await deleteBatchProductsInCMS(ids);
|
const results = await deleteBatchProductsInCMS(ids);
|
||||||
|
|
||||||
logger.debug({ results }, "deleteBatchProducts results");
|
logger.debug({ results }, "deleteBatchProducts results");
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { createProvider } from "./create";
|
import { createProvider } from "./create";
|
||||||
import { CreateOperations, ProductInput, ProductResponse } from "../types";
|
import { CreateOperations, ProductInput, ProductResponse } from "../types";
|
||||||
import { logger as pinoLogger } from "../../logger";
|
|
||||||
|
|
||||||
import { ApiError, buildClient, SimpleSchemaTypes } from "@datocms/cma-client-node";
|
import { ApiError, buildClient, SimpleSchemaTypes } from "@datocms/cma-client-node";
|
||||||
import { DatocmsConfig, datocmsConfigSchema } from "../config";
|
import { DatocmsConfig, datocmsConfigSchema } from "../config";
|
||||||
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const datocmsClient = (config: DatocmsConfig, options?: RequestInit) => {
|
const datocmsClient = (config: DatocmsConfig, options?: RequestInit) => {
|
||||||
const { baseUrl, token, environment } = config;
|
const { baseUrl, token, environment } = config;
|
||||||
|
@ -46,7 +46,7 @@ const transformResponseItem = (
|
||||||
};
|
};
|
||||||
|
|
||||||
const datocmsOperations: CreateOperations<DatocmsConfig> = (config) => {
|
const datocmsOperations: CreateOperations<DatocmsConfig> = (config) => {
|
||||||
const logger = pinoLogger.child({ cms: "strapi" });
|
const logger = createLogger({ cms: "strapi" });
|
||||||
|
|
||||||
const client = datocmsClient(config);
|
const client = datocmsClient(config);
|
||||||
|
|
||||||
|
@ -96,6 +96,7 @@ const datocmsOperations: CreateOperations<DatocmsConfig> = (config) => {
|
||||||
ping: async () => {
|
ping: async () => {
|
||||||
try {
|
try {
|
||||||
const response = await pingCMS();
|
const response = await pingCMS();
|
||||||
|
|
||||||
logger.debug({ response }, "ping response");
|
logger.debug({ response }, "ping response");
|
||||||
|
|
||||||
if (!response.id) {
|
if (!response.id) {
|
||||||
|
@ -110,6 +111,7 @@ const datocmsOperations: CreateOperations<DatocmsConfig> = (config) => {
|
||||||
createProduct: async ({ input }) => {
|
createProduct: async ({ input }) => {
|
||||||
try {
|
try {
|
||||||
const item = await createProductInCMS(input);
|
const item = await createProductInCMS(input);
|
||||||
|
|
||||||
logger.debug({ item }, "createProduct response");
|
logger.debug({ item }, "createProduct response");
|
||||||
|
|
||||||
return transformResponseItem(item, input);
|
return transformResponseItem(item, input);
|
||||||
|
@ -119,20 +121,24 @@ const datocmsOperations: CreateOperations<DatocmsConfig> = (config) => {
|
||||||
},
|
},
|
||||||
updateProduct: async ({ id, input }) => {
|
updateProduct: async ({ id, input }) => {
|
||||||
const item = await updateProductInCMS(id, input);
|
const item = await updateProductInCMS(id, input);
|
||||||
|
|
||||||
logger.debug({ item }, "updateProduct response");
|
logger.debug({ item }, "updateProduct response");
|
||||||
},
|
},
|
||||||
deleteProduct: async ({ id }) => {
|
deleteProduct: async ({ id }) => {
|
||||||
const item = await deleteProductInCMS(id);
|
const item = await deleteProductInCMS(id);
|
||||||
|
|
||||||
logger.debug({ item }, "deleteProduct response");
|
logger.debug({ item }, "deleteProduct response");
|
||||||
},
|
},
|
||||||
createBatchProducts: async ({ input }) => {
|
createBatchProducts: async ({ input }) => {
|
||||||
const items = await createBatchProductsInCMS(input);
|
const items = await createBatchProductsInCMS(input);
|
||||||
|
|
||||||
logger.debug({ items }, "createBatchProducts response");
|
logger.debug({ items }, "createBatchProducts response");
|
||||||
|
|
||||||
return items.map((item) => transformResponseItem(item.id, item.input));
|
return items.map((item) => transformResponseItem(item.id, item.input));
|
||||||
},
|
},
|
||||||
deleteBatchProducts: async ({ ids }) => {
|
deleteBatchProducts: async ({ ids }) => {
|
||||||
const items = await deleteBatchProductsInCMS(ids);
|
const items = await deleteBatchProductsInCMS(ids);
|
||||||
|
|
||||||
logger.debug({ items }, "deleteBatchProducts response");
|
logger.debug({ items }, "deleteBatchProducts response");
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { StrapiConfig, strapiConfigSchema } from "../config";
|
import { StrapiConfig, strapiConfigSchema } from "../config";
|
||||||
import { CreateOperations, ProductResponse, ProductInput } from "../types";
|
import { CreateOperations, ProductResponse, ProductInput } from "../types";
|
||||||
import { createProvider } from "./create";
|
import { createProvider } from "./create";
|
||||||
import { logger as pinoLogger } from "../../logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const strapiFetch = async (endpoint: string, config: StrapiConfig, options?: RequestInit) => {
|
const strapiFetch = async (endpoint: string, config: StrapiConfig, options?: RequestInit) => {
|
||||||
const { baseUrl, token } = config;
|
const { baseUrl, token } = config;
|
||||||
|
@ -31,6 +31,7 @@ const transformInputToBody = (input: ProductInput): StrapiBody => {
|
||||||
product_slug: input.productSlug,
|
product_slug: input.productSlug,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return body;
|
return body;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -78,7 +79,7 @@ const transformCreateProductResponse = (
|
||||||
type CreateStrapiOperations = CreateOperations<StrapiConfig>;
|
type CreateStrapiOperations = CreateOperations<StrapiConfig>;
|
||||||
|
|
||||||
export const strapiOperations: CreateStrapiOperations = (config) => {
|
export const strapiOperations: CreateStrapiOperations = (config) => {
|
||||||
const logger = pinoLogger.child({ cms: "strapi" });
|
const logger = createLogger({ cms: "strapi" });
|
||||||
|
|
||||||
const { contentTypeId } = config;
|
const { contentTypeId } = config;
|
||||||
|
|
||||||
|
@ -86,6 +87,7 @@ export const strapiOperations: CreateStrapiOperations = (config) => {
|
||||||
const response = await strapiFetch(`/${contentTypeId}`, config, {
|
const response = await strapiFetch(`/${contentTypeId}`, config, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.debug({ response }, "pingCMS response");
|
logger.debug({ response }, "pingCMS response");
|
||||||
return { ok: response.ok };
|
return { ok: response.ok };
|
||||||
};
|
};
|
||||||
|
@ -96,12 +98,14 @@ export const strapiOperations: CreateStrapiOperations = (config) => {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.debug({ response }, "createProduct response");
|
logger.debug({ response }, "createProduct response");
|
||||||
return await response.json();
|
return await response.json();
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateProductInCMS = async (id: string, input: ProductInput) => {
|
const updateProductInCMS = async (id: string, input: ProductInput) => {
|
||||||
const body = transformInputToBody(input);
|
const body = transformInputToBody(input);
|
||||||
|
|
||||||
return await strapiFetch(`/${contentTypeId}/${id}`, config, {
|
return await strapiFetch(`/${contentTypeId}/${id}`, config, {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
|
@ -130,36 +134,42 @@ export const strapiOperations: CreateStrapiOperations = (config) => {
|
||||||
return {
|
return {
|
||||||
ping: async () => {
|
ping: async () => {
|
||||||
const response = await pingCMS();
|
const response = await pingCMS();
|
||||||
|
|
||||||
logger.debug({ response }, "ping response");
|
logger.debug({ response }, "ping response");
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
createProduct: async ({ input }) => {
|
createProduct: async ({ input }) => {
|
||||||
const result = await createProductInCMS(input);
|
const result = await createProductInCMS(input);
|
||||||
|
|
||||||
logger.debug({ result }, "createProduct result");
|
logger.debug({ result }, "createProduct result");
|
||||||
|
|
||||||
return transformCreateProductResponse(result, input);
|
return transformCreateProductResponse(result, input);
|
||||||
},
|
},
|
||||||
updateProduct: async ({ id, input }) => {
|
updateProduct: async ({ id, input }) => {
|
||||||
const response = await updateProductInCMS(id, input);
|
const response = await updateProductInCMS(id, input);
|
||||||
|
|
||||||
logger.debug({ response }, "updateProduct response");
|
logger.debug({ response }, "updateProduct response");
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
deleteProduct: async ({ id }) => {
|
deleteProduct: async ({ id }) => {
|
||||||
const response = await deleteProductInCMS(id);
|
const response = await deleteProductInCMS(id);
|
||||||
|
|
||||||
logger.debug({ response }, "deleteProduct response");
|
logger.debug({ response }, "deleteProduct response");
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
createBatchProducts: async ({ input }) => {
|
createBatchProducts: async ({ input }) => {
|
||||||
const results = await createBatchProductsInCMS(input);
|
const results = await createBatchProductsInCMS(input);
|
||||||
|
|
||||||
logger.debug({ results }, "createBatchProducts results");
|
logger.debug({ results }, "createBatchProducts results");
|
||||||
|
|
||||||
return results.map((result) => transformCreateProductResponse(result.response, result.input));
|
return results.map((result) => transformCreateProductResponse(result.response, result.input));
|
||||||
},
|
},
|
||||||
deleteBatchProducts: async ({ ids }) => {
|
deleteBatchProducts: async ({ ids }) => {
|
||||||
const responses = await deleteBatchProductsInCMS(ids);
|
const responses = await deleteBatchProductsInCMS(ids);
|
||||||
|
|
||||||
logger.debug({ responses }, "deleteBatchProducts responses");
|
logger.debug({ responses }, "deleteBatchProducts responses");
|
||||||
|
|
||||||
return responses;
|
return responses;
|
||||||
|
|
|
@ -8,14 +8,16 @@ import {
|
||||||
FetchProductVariantMetadataQuery,
|
FetchProductVariantMetadataQuery,
|
||||||
UpdateAppMetadataDocument,
|
UpdateAppMetadataDocument,
|
||||||
} from "../../generated/graphql";
|
} from "../../generated/graphql";
|
||||||
import { logger as pinoLogger } from "../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
// 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
|
* Function is using urql graphql client to fetch all available metadata.
|
||||||
// which can be used by the manager.
|
* Before returning query result, we are transforming response to list of objects with key and value fields
|
||||||
// Result of this query is cached by the manager.
|
* which can be used by the manager.
|
||||||
|
* Result of this query is cached by the manager.
|
||||||
|
*/
|
||||||
export async function fetchAllMetadata(client: Client): Promise<MetadataEntry[]> {
|
export async function fetchAllMetadata(client: Client): Promise<MetadataEntry[]> {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
function: "fetchAllMetadata",
|
function: "fetchAllMetadata",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -31,11 +33,13 @@ export async function fetchAllMetadata(client: Client): Promise<MetadataEntry[]>
|
||||||
return data?.app?.privateMetadata.map((md) => ({ key: md.key, value: md.value })) || [];
|
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.
|
* Mutate function takes urql client and metadata entries, and construct mutation to the API.
|
||||||
// The manager will use updated entries returned by this mutation to update it's cache.
|
* 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[]) {
|
export async function mutateMetadata(client: Client, metadata: MetadataEntry[]) {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
function: "mutateMetadata",
|
function: "mutateMetadata",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -79,9 +83,11 @@ export async function mutateMetadata(client: Client, metadata: MetadataEntry[])
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createSettingsManager = (client: Client) => {
|
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.
|
* EncryptedMetadataManager gives you interface to manipulate metadata and cache values in memory.
|
||||||
// If your use case require plain text values, you can use MetadataManager.
|
* 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({
|
return new EncryptedMetadataManager({
|
||||||
// Secret key should be randomly created for production and set as environment variable
|
// Secret key should be randomly created for production and set as environment variable
|
||||||
encryptionKey: process.env.SECRET_KEY!,
|
encryptionKey: process.env.SECRET_KEY!,
|
||||||
|
@ -94,7 +100,7 @@ export async function fetchProductVariantMetadata(
|
||||||
client: Client,
|
client: Client,
|
||||||
productId: string
|
productId: string
|
||||||
): Promise<MetadataEntry[]> {
|
): Promise<MetadataEntry[]> {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
function: "fetchProductVariantMetadata",
|
function: "fetchProductVariantMetadata",
|
||||||
productId,
|
productId,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import { NextProtectedApiHandler, createProtectedHandler } from "@saleor/app-sdk/handlers/next";
|
import { NextProtectedApiHandler, createProtectedHandler } from "@saleor/app-sdk/handlers/next";
|
||||||
import { saleorApp } from "../../../saleor-app";
|
import { saleorApp } from "../../../saleor-app";
|
||||||
import type { NextApiRequest, NextApiResponse } from "next";
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
|
||||||
import { createClient } from "../../lib/graphql";
|
import { createClient } from "../../lib/graphql";
|
||||||
import { createSettingsManager } from "../../lib/metadata";
|
import { createSettingsManager } from "../../lib/metadata";
|
||||||
import { getProviderInstancesSettings } from "../../lib/cms/client/settings";
|
import { getProviderInstancesSettings } from "../../lib/cms/client/settings";
|
||||||
import { pingProviderInstance } from "../../lib/cms/client/clients-execution";
|
import { pingProviderInstance } from "../../lib/cms/client/clients-execution";
|
||||||
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
export interface ProviderInstancePingApiPayload {
|
export interface ProviderInstancePingApiPayload {
|
||||||
providerInstanceId: string;
|
providerInstanceId: string;
|
||||||
|
@ -23,9 +24,10 @@ const handler: NextProtectedApiHandler = async (
|
||||||
const { authData } = context;
|
const { authData } = context;
|
||||||
const { providerInstanceId } = req.body as ProviderInstancePingApiPayload;
|
const { providerInstanceId } = req.body as ProviderInstancePingApiPayload;
|
||||||
|
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
endpoint: "ping-provider-instance",
|
endpoint: "ping-provider-instance",
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.debug({ providerInstanceId }, "Called endpoint ping-provider-instance");
|
logger.debug({ providerInstanceId }, "Called endpoint ping-provider-instance");
|
||||||
|
|
||||||
if (req.method !== "POST") {
|
if (req.method !== "POST") {
|
||||||
|
|
|
@ -6,11 +6,12 @@ import { executeCmsClientBatchOperation } from "../../lib/cms/client/clients-exe
|
||||||
import { getChannelsSettings, getProviderInstancesSettings } from "../../lib/cms/client/settings";
|
import { getChannelsSettings, getProviderInstancesSettings } from "../../lib/cms/client/settings";
|
||||||
import { providersSchemaSet } from "../../lib/cms/config/providers";
|
import { providersSchemaSet } from "../../lib/cms/config/providers";
|
||||||
import { cmsProviders, CMSProvider } from "../../lib/cms/providers";
|
import { cmsProviders, CMSProvider } from "../../lib/cms/providers";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
|
||||||
import { createClient } from "../../lib/graphql";
|
import { createClient } from "../../lib/graphql";
|
||||||
import { createSettingsManager } from "../../lib/metadata";
|
import { createSettingsManager } from "../../lib/metadata";
|
||||||
import { batchUpdateMetadata, MetadataRecord } from "../../lib/cms/client/metadata-execution";
|
import { batchUpdateMetadata, MetadataRecord } from "../../lib/cms/client/metadata-execution";
|
||||||
import { CmsBatchOperations } from "../../lib/cms/types";
|
import { CmsBatchOperations } from "../../lib/cms/types";
|
||||||
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
export interface SyncProductsVariantsApiPayload {
|
export interface SyncProductsVariantsApiPayload {
|
||||||
channelSlug: string;
|
channelSlug: string;
|
||||||
|
@ -35,7 +36,7 @@ const handler: NextProtectedApiHandler = async (
|
||||||
) => {
|
) => {
|
||||||
const { authData } = context;
|
const { authData } = context;
|
||||||
|
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
endpoint: "sync-products-variants",
|
endpoint: "sync-products-variants",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,11 @@ import { saleorApp } from "../../../../saleor-app";
|
||||||
import { getCmsKeysFromSaleorItem } from "../../../lib/cms/client/metadata";
|
import { getCmsKeysFromSaleorItem } from "../../../lib/cms/client/metadata";
|
||||||
import { getChannelsSlugsFromSaleorItem } from "../../../lib/cms/client/channels";
|
import { getChannelsSlugsFromSaleorItem } from "../../../lib/cms/client/channels";
|
||||||
import { createCmsOperations, executeCmsOperations, updateMetadata } from "../../../lib/cms/client";
|
import { createCmsOperations, executeCmsOperations, updateMetadata } from "../../../lib/cms/client";
|
||||||
import { logger as pinoLogger } from "../../../lib/logger";
|
|
||||||
import { createClient } from "../../../lib/graphql";
|
import { createClient } from "../../../lib/graphql";
|
||||||
import { fetchProductVariantMetadata } from "../../../lib/metadata";
|
import { fetchProductVariantMetadata } from "../../../lib/metadata";
|
||||||
import { isAppWebhookIssuer } from "./_utils";
|
import { isAppWebhookIssuer } from "./_utils";
|
||||||
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
api: {
|
api: {
|
||||||
|
@ -58,9 +59,10 @@ export const handler: NextWebhookApiHandler<ProductUpdatedWebhookPayloadFragment
|
||||||
const { product, issuingPrincipal } = context.payload;
|
const { product, issuingPrincipal } = context.payload;
|
||||||
const { saleorApiUrl, token, appId } = context.authData;
|
const { saleorApiUrl, token, appId } = context.authData;
|
||||||
|
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
product,
|
product,
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.debug("Called webhook PRODUCT_UPDATED");
|
logger.debug("Called webhook PRODUCT_UPDATED");
|
||||||
logger.debug({ issuingPrincipal }, "Issuing principal");
|
logger.debug({ issuingPrincipal }, "Issuing principal");
|
||||||
|
|
||||||
|
@ -99,9 +101,11 @@ export const handler: NextWebhookApiHandler<ProductUpdatedWebhookPayloadFragment
|
||||||
productVariantChannels: productVariantChannels,
|
productVariantChannels: productVariantChannels,
|
||||||
productVariantCmsKeys: productVariantCmsKeys,
|
productVariantCmsKeys: productVariantCmsKeys,
|
||||||
});
|
});
|
||||||
// Do not touch product variants which are not created or should be deleted.
|
/*
|
||||||
// These operations should and will be performed by PRODUCT_VARIANT_CREATED and PRODUCT_VARIANT_DELETED webhooks.
|
* Do not touch product variants which are not created or should be deleted.
|
||||||
// Otherwise we will end up with duplicated product variants in CMS providers! (or failed variant delete operations).
|
* These operations should and will be performed by PRODUCT_VARIANT_CREATED and PRODUCT_VARIANT_DELETED webhooks.
|
||||||
|
* Otherwise we will end up with duplicated product variants in CMS providers! (or failed variant delete operations).
|
||||||
|
*/
|
||||||
const cmsUpdateOperations = cmsOperations.filter(
|
const cmsUpdateOperations = cmsOperations.filter(
|
||||||
(operation) => operation.operationType === "updateProduct"
|
(operation) => operation.operationType === "updateProduct"
|
||||||
);
|
);
|
||||||
|
|
|
@ -7,10 +7,11 @@ import {
|
||||||
import { saleorApp } from "../../../../saleor-app";
|
import { saleorApp } from "../../../../saleor-app";
|
||||||
import { getChannelsSlugsFromSaleorItem } from "../../../lib/cms/client/channels";
|
import { getChannelsSlugsFromSaleorItem } from "../../../lib/cms/client/channels";
|
||||||
import { createCmsOperations, executeCmsOperations, updateMetadata } from "../../../lib/cms/client";
|
import { createCmsOperations, executeCmsOperations, updateMetadata } from "../../../lib/cms/client";
|
||||||
import { logger as pinoLogger } from "../../../lib/logger";
|
|
||||||
import { createClient } from "../../../lib/graphql";
|
import { createClient } from "../../../lib/graphql";
|
||||||
import { fetchProductVariantMetadata } from "../../../lib/metadata";
|
import { fetchProductVariantMetadata } from "../../../lib/metadata";
|
||||||
import { getCmsKeysFromSaleorItem } from "../../../lib/cms/client/metadata";
|
import { getCmsKeysFromSaleorItem } from "../../../lib/cms/client/metadata";
|
||||||
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
api: {
|
api: {
|
||||||
|
@ -53,9 +54,10 @@ export const handler: NextWebhookApiHandler<ProductVariantCreatedWebhookPayloadF
|
||||||
const { productVariant } = context.payload;
|
const { productVariant } = context.payload;
|
||||||
const { saleorApiUrl, token } = context.authData;
|
const { saleorApiUrl, token } = context.authData;
|
||||||
|
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
productVariant,
|
productVariant,
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.debug("Called webhook PRODUCT_VARIANT_CREATED");
|
logger.debug("Called webhook PRODUCT_VARIANT_CREATED");
|
||||||
|
|
||||||
if (!productVariant) {
|
if (!productVariant) {
|
||||||
|
|
|
@ -7,8 +7,9 @@ import {
|
||||||
import { saleorApp } from "../../../../saleor-app";
|
import { saleorApp } from "../../../../saleor-app";
|
||||||
import { getCmsKeysFromSaleorItem } from "../../../lib/cms/client/metadata";
|
import { getCmsKeysFromSaleorItem } from "../../../lib/cms/client/metadata";
|
||||||
import { createCmsOperations, executeCmsOperations, updateMetadata } from "../../../lib/cms/client";
|
import { createCmsOperations, executeCmsOperations, updateMetadata } from "../../../lib/cms/client";
|
||||||
import { logger as pinoLogger } from "../../../lib/logger";
|
|
||||||
import { createClient } from "../../../lib/graphql";
|
import { createClient } from "../../../lib/graphql";
|
||||||
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
api: {
|
api: {
|
||||||
|
@ -51,9 +52,10 @@ export const handler: NextWebhookApiHandler<ProductVariantDeletedWebhookPayloadF
|
||||||
const { productVariant } = context.payload;
|
const { productVariant } = context.payload;
|
||||||
const { saleorApiUrl, token } = context.authData;
|
const { saleorApiUrl, token } = context.authData;
|
||||||
|
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
productVariant,
|
productVariant,
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.debug("Called webhook PRODUCT_VARIANT_DELETED");
|
logger.debug("Called webhook PRODUCT_VARIANT_DELETED");
|
||||||
|
|
||||||
if (!productVariant) {
|
if (!productVariant) {
|
||||||
|
|
|
@ -8,10 +8,11 @@ import { saleorApp } from "../../../../saleor-app";
|
||||||
import { getCmsKeysFromSaleorItem } from "../../../lib/cms/client/metadata";
|
import { getCmsKeysFromSaleorItem } from "../../../lib/cms/client/metadata";
|
||||||
import { getChannelsSlugsFromSaleorItem } from "../../../lib/cms/client/channels";
|
import { getChannelsSlugsFromSaleorItem } from "../../../lib/cms/client/channels";
|
||||||
import { createCmsOperations, executeCmsOperations, updateMetadata } from "../../../lib/cms/client";
|
import { createCmsOperations, executeCmsOperations, updateMetadata } from "../../../lib/cms/client";
|
||||||
import { logger as pinoLogger } from "../../../lib/logger";
|
|
||||||
import { createClient } from "../../../lib/graphql";
|
import { createClient } from "../../../lib/graphql";
|
||||||
import { fetchProductVariantMetadata } from "../../../lib/metadata";
|
import { fetchProductVariantMetadata } from "../../../lib/metadata";
|
||||||
import { isAppWebhookIssuer } from "./_utils";
|
import { isAppWebhookIssuer } from "./_utils";
|
||||||
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
api: {
|
api: {
|
||||||
|
@ -59,9 +60,10 @@ export const handler: NextWebhookApiHandler<ProductVariantUpdatedWebhookPayloadF
|
||||||
const { productVariant, issuingPrincipal } = context.payload;
|
const { productVariant, issuingPrincipal } = context.payload;
|
||||||
const { saleorApiUrl, token, appId } = context.authData;
|
const { saleorApiUrl, token, appId } = context.authData;
|
||||||
|
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
productVariant,
|
productVariant,
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.debug("Called webhook PRODUCT_VARIANT_UPDATED");
|
logger.debug("Called webhook PRODUCT_VARIANT_UPDATED");
|
||||||
logger.debug({ issuingPrincipal }, "Issuing principal");
|
logger.debug({ issuingPrincipal }, "Issuing principal");
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"build": {
|
"build": {
|
||||||
"env": [
|
"env": [
|
||||||
"APL",
|
"APL",
|
||||||
"APP_DEBUG",
|
"APP_LOG_LEVEL",
|
||||||
"NODE_ENV",
|
"NODE_ENV",
|
||||||
"SECRET_KEY",
|
"SECRET_KEY",
|
||||||
"PORT",
|
"PORT",
|
||||||
|
|
|
@ -9,4 +9,4 @@ REST_APL_TOKEN=
|
||||||
MAILCHIMP_CLIENT_ID=
|
MAILCHIMP_CLIENT_ID=
|
||||||
MAILCHIMP_CLIENT_SECRET=
|
MAILCHIMP_CLIENT_SECRET=
|
||||||
|
|
||||||
APP_DEBUG=info
|
APP_LOG_LEVEL=debug
|
|
@ -33,8 +33,6 @@
|
||||||
"jsdom": "^20.0.3",
|
"jsdom": "^20.0.3",
|
||||||
"next": "13.3.0",
|
"next": "13.3.0",
|
||||||
"next-urql": "^4.0.2",
|
"next-urql": "^4.0.2",
|
||||||
"pino": "^8.8.0",
|
|
||||||
"pino-pretty": "^9.1.1",
|
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-hook-form": "^7.43.0",
|
"react-hook-form": "^7.43.0",
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
import pino from "pino";
|
|
||||||
|
|
||||||
export const logger = pino({
|
|
||||||
level: "debug",
|
|
||||||
redact: ["token"],
|
|
||||||
transport:
|
|
||||||
process.env.NODE_ENV === "development"
|
|
||||||
? {
|
|
||||||
target: "pino-pretty",
|
|
||||||
options: {
|
|
||||||
colorize: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const createLogger = logger.child.bind(logger);
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { router } from "../trpc/trpc-server";
|
import { router } from "../trpc/trpc-server";
|
||||||
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
||||||
import { createLogger } from "../../lib/logger";
|
|
||||||
import { MailchimpClientOAuth } from "./mailchimp-client";
|
import { MailchimpClientOAuth } from "./mailchimp-client";
|
||||||
import { MailchimpConfigSettingsManager } from "./mailchimp-config-settings-manager";
|
import { MailchimpConfigSettingsManager } from "./mailchimp-config-settings-manager";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const AddContactSchema = z.object({
|
const AddContactSchema = z.object({
|
||||||
listId: z.string().min(1),
|
listId: z.string().min(1),
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Client } from "urql";
|
||||||
import { createSettingsManager } from "../../lib/metadata-manager";
|
import { createSettingsManager } from "../../lib/metadata-manager";
|
||||||
import { SettingsManager } from "@saleor/app-sdk/settings-manager";
|
import { SettingsManager } from "@saleor/app-sdk/settings-manager";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { createLogger } from "../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
export const CustomerCreatedEventConfig = z
|
export const CustomerCreatedEventConfig = z
|
||||||
.object({
|
.object({
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { router } from "../trpc/trpc-server";
|
import { router } from "../trpc/trpc-server";
|
||||||
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
||||||
import { createLogger } from "../../lib/logger";
|
|
||||||
import { MailchimpClientOAuth } from "./mailchimp-client";
|
import { MailchimpClientOAuth } from "./mailchimp-client";
|
||||||
import {
|
import {
|
||||||
CustomerCreatedEventConfig,
|
CustomerCreatedEventConfig,
|
||||||
|
@ -9,6 +9,7 @@ import {
|
||||||
} from "./mailchimp-config-settings-manager";
|
} from "./mailchimp-config-settings-manager";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const setTokenInput = MailchimpConfig;
|
const setTokenInput = MailchimpConfig;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { MailchimpAuthFrame } from "../../auth/mailchimp-auth-frame/mailchimp-auth-frame";
|
import { MailchimpAuthFrame } from "../../auth/mailchimp-auth-frame/mailchimp-auth-frame";
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { trpcClient } from "../../../trpc/trpc-client";
|
import { trpcClient } from "../../../trpc/trpc-client";
|
||||||
import { createLogger } from "../../../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const logger = createLogger({});
|
const logger = createLogger({});
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,11 @@ import { middleware, procedure } from "./trpc-server";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { ProtectedHandlerError } from "@saleor/app-sdk/handlers/next";
|
import { ProtectedHandlerError } from "@saleor/app-sdk/handlers/next";
|
||||||
import { saleorApp } from "../../saleor-app";
|
import { saleorApp } from "../../saleor-app";
|
||||||
import { logger } from "../../lib/logger";
|
|
||||||
import { createClient } from "../../lib/create-graphq-client";
|
import { createClient } from "../../lib/create-graphq-client";
|
||||||
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
|
const logger = createLogger({ service: "protected-client-procedure" });
|
||||||
|
|
||||||
const attachAppToken = middleware(async ({ ctx, next }) => {
|
const attachAppToken = middleware(async ({ ctx, next }) => {
|
||||||
logger.debug("attachAppToken middleware");
|
logger.debug("attachAppToken middleware");
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { NextApiHandler } from "next";
|
import { NextApiHandler } from "next";
|
||||||
import { MailchimpClientOAuth } from "../../../../modules/mailchimp/mailchimp-client";
|
import { MailchimpClientOAuth } from "../../../../modules/mailchimp/mailchimp-client";
|
||||||
import { createLogger } from "../../../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
export const getBaseUrl = (headers: { [name: string]: string | string[] | undefined }): string => {
|
export const getBaseUrl = (headers: { [name: string]: string | string[] | undefined }): string => {
|
||||||
const { host, "x-forwarded-proto": protocol = "http" } = headers;
|
const { host, "x-forwarded-proto": protocol = "http" } = headers;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { NextApiHandler } from "next";
|
import { NextApiHandler } from "next";
|
||||||
import { createLogger } from "../../../../lib/logger";
|
|
||||||
import { processSaleorProtectedHandler } from "@saleor/app-sdk/handlers/next";
|
import { processSaleorProtectedHandler } from "@saleor/app-sdk/handlers/next";
|
||||||
import { saleorApp } from "../../../../saleor-app";
|
import { saleorApp } from "../../../../saleor-app";
|
||||||
import { SALEOR_API_URL_HEADER, SALEOR_AUTHORIZATION_BEARER_HEADER } from "@saleor/app-sdk/const";
|
import { SALEOR_API_URL_HEADER, SALEOR_AUTHORIZATION_BEARER_HEADER } from "@saleor/app-sdk/const";
|
||||||
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
export const getBaseUrl = (headers: { [name: string]: string | string[] | undefined }): string => {
|
export const getBaseUrl = (headers: { [name: string]: string | string[] | undefined }): string => {
|
||||||
const { host, "x-forwarded-proto": protocol = "http" } = headers;
|
const { host, "x-forwarded-proto": protocol = "http" } = headers;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
||||||
import { saleorApp } from "../../../saleor-app";
|
import { saleorApp } from "../../../saleor-app";
|
||||||
import { logger as pinoLogger } from "../../../lib/logger";
|
|
||||||
import {
|
import {
|
||||||
CustomerCreatedDocument,
|
CustomerCreatedDocument,
|
||||||
CustomerCreatedPayloadFragment,
|
CustomerCreatedPayloadFragment,
|
||||||
|
@ -9,6 +8,7 @@ import { createClient } from "../../../lib/create-graphq-client";
|
||||||
import { MailchimpConfigSettingsManager } from "../../../modules/mailchimp/mailchimp-config-settings-manager";
|
import { MailchimpConfigSettingsManager } from "../../../modules/mailchimp/mailchimp-config-settings-manager";
|
||||||
import { MailchimpClientOAuth } from "../../../modules/mailchimp/mailchimp-client";
|
import { MailchimpClientOAuth } from "../../../modules/mailchimp/mailchimp-client";
|
||||||
import { metadataToMailchimpTags } from "../../../modules/saleor-customers-sync/metadata-to-mailchimp-tags";
|
import { metadataToMailchimpTags } from "../../../modules/saleor-customers-sync/metadata-to-mailchimp-tags";
|
||||||
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
export const customerCreatedWebhook = new SaleorAsyncWebhook<CustomerCreatedPayloadFragment>({
|
export const customerCreatedWebhook = new SaleorAsyncWebhook<CustomerCreatedPayloadFragment>({
|
||||||
name: "Customer Created in Saleor",
|
name: "Customer Created in Saleor",
|
||||||
|
@ -24,7 +24,7 @@ export const customerCreatedHandler: NextWebhookApiHandler<CustomerCreatedPayloa
|
||||||
res,
|
res,
|
||||||
context
|
context
|
||||||
) => {
|
) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
webhook: customerCreatedWebhook.name,
|
webhook: customerCreatedWebhook.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
||||||
import { saleorApp } from "../../../saleor-app";
|
import { saleorApp } from "../../../saleor-app";
|
||||||
import { logger as pinoLogger } from "../../../lib/logger";
|
|
||||||
import {
|
import {
|
||||||
CustomerUpdatedDocument,
|
CustomerUpdatedDocument,
|
||||||
CustomerUpdatedPayloadFragment,
|
CustomerUpdatedPayloadFragment,
|
||||||
|
@ -9,6 +9,7 @@ import { createClient } from "../../../lib/create-graphq-client";
|
||||||
import { MailchimpConfigSettingsManager } from "../../../modules/mailchimp/mailchimp-config-settings-manager";
|
import { MailchimpConfigSettingsManager } from "../../../modules/mailchimp/mailchimp-config-settings-manager";
|
||||||
import { MailchimpClientOAuth } from "../../../modules/mailchimp/mailchimp-client";
|
import { MailchimpClientOAuth } from "../../../modules/mailchimp/mailchimp-client";
|
||||||
import { metadataToMailchimpTags } from "../../../modules/saleor-customers-sync/metadata-to-mailchimp-tags";
|
import { metadataToMailchimpTags } from "../../../modules/saleor-customers-sync/metadata-to-mailchimp-tags";
|
||||||
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
export const customerMetadataUpdatedWebhook =
|
export const customerMetadataUpdatedWebhook =
|
||||||
new SaleorAsyncWebhook<CustomerUpdatedPayloadFragment>({
|
new SaleorAsyncWebhook<CustomerUpdatedPayloadFragment>({
|
||||||
|
@ -24,7 +25,7 @@ const handler: NextWebhookApiHandler<CustomerUpdatedPayloadFragment> = async (
|
||||||
res,
|
res,
|
||||||
context
|
context
|
||||||
) => {
|
) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
webhook: customerMetadataUpdatedWebhook.name,
|
webhook: customerMetadataUpdatedWebhook.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -42,8 +42,6 @@
|
||||||
"next": "13.3.0",
|
"next": "13.3.0",
|
||||||
"next-urql": "^4.0.3",
|
"next-urql": "^4.0.3",
|
||||||
"nodemailer": "^6.9.1",
|
"nodemailer": "^6.9.1",
|
||||||
"pino": "^8.8.0",
|
|
||||||
"pino-pretty": "^9.1.1",
|
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-hook-form": "^7.43.0",
|
"react-hook-form": "^7.43.0",
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
import pino from "pino";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO Set up log drain etc
|
|
||||||
*/
|
|
||||||
export const logger = pino({
|
|
||||||
level: "debug",
|
|
||||||
transport:
|
|
||||||
process.env.NODE_ENV === "development"
|
|
||||||
? {
|
|
||||||
target: "pino-pretty",
|
|
||||||
options: {
|
|
||||||
colorize: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const createLogger = logger.child.bind(logger);
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import {
|
import {
|
||||||
appChannelConfigurationInputSchema,
|
appChannelConfigurationInputSchema,
|
||||||
appConfigInputSchema,
|
appConfigInputSchema,
|
||||||
|
@ -8,8 +8,10 @@ import { router } from "../trpc/trpc-server";
|
||||||
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
// Allow access only for the dashboard users and attaches the
|
/*
|
||||||
// configuration service to the context
|
* Allow access only for the dashboard users and attaches the
|
||||||
|
* configuration service to the context
|
||||||
|
*/
|
||||||
const protectedWithConfigurationService = protectedClientProcedure.use(({ next, ctx }) =>
|
const protectedWithConfigurationService = protectedClientProcedure.use(({ next, ctx }) =>
|
||||||
next({
|
next({
|
||||||
ctx: {
|
ctx: {
|
||||||
|
@ -26,7 +28,8 @@ export const appConfigurationRouter = router({
|
||||||
getChannelConfiguration: protectedWithConfigurationService
|
getChannelConfiguration: protectedWithConfigurationService
|
||||||
.input(z.object({ channelSlug: z.string() }))
|
.input(z.object({ channelSlug: z.string() }))
|
||||||
.query(async ({ ctx, input }) => {
|
.query(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug("Get Channel Configuration called");
|
logger.debug("Get Channel Configuration called");
|
||||||
|
|
||||||
return await ctx.configurationService.getChannelConfiguration(input.channelSlug);
|
return await ctx.configurationService.getChannelConfiguration(input.channelSlug);
|
||||||
|
@ -36,13 +39,14 @@ export const appConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(appChannelConfigurationInputSchema)
|
.input(appChannelConfigurationInputSchema)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug("Set channel configuration called");
|
logger.debug("Set channel configuration called");
|
||||||
|
|
||||||
await ctx.configurationService.setChannelConfiguration(input);
|
await ctx.configurationService.setChannelConfiguration(input);
|
||||||
}),
|
}),
|
||||||
fetch: protectedWithConfigurationService.query(async ({ ctx, input }) => {
|
fetch: protectedWithConfigurationService.query(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug("appConfigurationRouter.fetch called");
|
logger.debug("appConfigurationRouter.fetch called");
|
||||||
|
|
||||||
|
@ -55,7 +59,7 @@ export const appConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(appConfigInputSchema)
|
.input(appConfigInputSchema)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "appConfigurationRouter.setAndReplace called with input");
|
logger.debug(input, "appConfigurationRouter.setAndReplace called with input");
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { PrivateMetadataAppConfigurator } from "./app-configurator";
|
import { PrivateMetadataAppConfigurator } from "./app-configurator";
|
||||||
import { Client } from "urql";
|
import { Client } from "urql";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import { AppConfig, AppConfigurationPerChannel } from "./app-config";
|
import { AppConfig, AppConfigurationPerChannel } from "./app-config";
|
||||||
import { getDefaultEmptyAppConfiguration } from "./app-config-container";
|
import { getDefaultEmptyAppConfiguration } from "./app-config-container";
|
||||||
import { createSettingsManager } from "../../lib/metadata-manager";
|
import { createSettingsManager } from "../../lib/metadata-manager";
|
||||||
|
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
service: "AppConfigurationService",
|
service: "AppConfigurationService",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ export class AppConfigurationService {
|
||||||
logger.debug("Fetch configuration from Saleor API");
|
logger.debug("Fetch configuration from Saleor API");
|
||||||
|
|
||||||
const config = await this.metadataConfigurator.getConfig();
|
const config = await this.metadataConfigurator.getConfig();
|
||||||
|
|
||||||
this.configurationData = config;
|
this.configurationData = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,11 +65,13 @@ export class AppConfigurationService {
|
||||||
async getChannelConfiguration(channel: string) {
|
async getChannelConfiguration(channel: string) {
|
||||||
logger.debug("Get channel configuration");
|
logger.debug("Get channel configuration");
|
||||||
const configurations = await this.getConfiguration();
|
const configurations = await this.getConfiguration();
|
||||||
|
|
||||||
if (!configurations) {
|
if (!configurations) {
|
||||||
return getDefaultEmptyAppConfiguration();
|
return getDefaultEmptyAppConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
const channelConfiguration = configurations.configurationsPerChannel[channel];
|
const channelConfiguration = configurations.configurationsPerChannel[channel];
|
||||||
|
|
||||||
return channelConfiguration || getDefaultEmptyAppConfiguration();
|
return channelConfiguration || getDefaultEmptyAppConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +84,7 @@ export class AppConfigurationService {
|
||||||
}) {
|
}) {
|
||||||
logger.debug("Set channel configuration");
|
logger.debug("Set channel configuration");
|
||||||
let configurations = await this.getConfiguration();
|
let configurations = await this.getConfiguration();
|
||||||
|
|
||||||
if (!configurations) {
|
if (!configurations) {
|
||||||
configurations = { configurationsPerChannel: {} };
|
configurations = { configurationsPerChannel: {} };
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { AuthData } from "@saleor/app-sdk/APL";
|
import { AuthData } from "@saleor/app-sdk/APL";
|
||||||
import { Client } from "urql";
|
import { Client } from "urql";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import { AppConfigurationService } from "../app-configuration/get-app-configuration.service";
|
import { AppConfigurationService } from "../app-configuration/get-app-configuration.service";
|
||||||
import { MjmlConfigurationService } from "../mjml/configuration/get-mjml-configuration.service";
|
import { MjmlConfigurationService } from "../mjml/configuration/get-mjml-configuration.service";
|
||||||
import { sendMjml } from "../mjml/send-mjml";
|
import { sendMjml } from "../mjml/send-mjml";
|
||||||
|
@ -25,7 +25,7 @@ export const sendEventMessages = async ({
|
||||||
payload,
|
payload,
|
||||||
client,
|
client,
|
||||||
}: SendEventMessagesArgs) => {
|
}: SendEventMessagesArgs) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
fn: "sendEventMessages",
|
fn: "sendEventMessages",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -60,6 +60,7 @@ export const sendEventMessages = async ({
|
||||||
const mjmlConfiguration = await mjmlConfigurationService.getConfiguration({
|
const mjmlConfiguration = await mjmlConfigurationService.getConfiguration({
|
||||||
id: channelAppConfiguration.mjmlConfigurationId,
|
id: channelAppConfiguration.mjmlConfigurationId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (mjmlConfiguration) {
|
if (mjmlConfiguration) {
|
||||||
const mjmlStatus = await sendMjml({
|
const mjmlStatus = await sendMjml({
|
||||||
event,
|
event,
|
||||||
|
@ -86,6 +87,7 @@ export const sendEventMessages = async ({
|
||||||
const sendgridConfiguration = await sendgridConfigurationService.getConfiguration({
|
const sendgridConfiguration = await sendgridConfigurationService.getConfiguration({
|
||||||
id: channelAppConfiguration.sendgridConfigurationId,
|
id: channelAppConfiguration.sendgridConfigurationId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (sendgridConfiguration) {
|
if (sendgridConfiguration) {
|
||||||
const sendgridStatus = await sendSendgrid({
|
const sendgridStatus = await sendSendgrid({
|
||||||
event,
|
event,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import Handlebars from "handlebars";
|
import Handlebars from "handlebars";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
fn: "compileHandlebarsTemplate",
|
fn: "compileHandlebarsTemplate",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ export const compileHandlebarsTemplate = (template: string, variables: any) => {
|
||||||
try {
|
try {
|
||||||
const templateDelegate = Handlebars.compile(template);
|
const templateDelegate = Handlebars.compile(template);
|
||||||
const htmlTemplate = templateDelegate(variables);
|
const htmlTemplate = templateDelegate(variables);
|
||||||
|
|
||||||
logger.debug("Template successfully compiled");
|
logger.debug("Template successfully compiled");
|
||||||
return {
|
return {
|
||||||
template: htmlTemplate,
|
template: htmlTemplate,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import mjml2html from "mjml";
|
import mjml2html from "mjml";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
fn: "compileMjml",
|
fn: "compileMjml",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { MjmlConfigurator, PrivateMetadataMjmlConfigurator } from "./mjml-configurator";
|
import { MjmlConfigurator, PrivateMetadataMjmlConfigurator } from "./mjml-configurator";
|
||||||
import { Client } from "urql";
|
import { Client } from "urql";
|
||||||
import { logger as pinoLogger } from "../../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import { MjmlConfig, MjmlConfiguration } from "./mjml-config";
|
import { MjmlConfig, MjmlConfiguration } from "./mjml-config";
|
||||||
import { FilterConfigurationsArgs, MjmlConfigContainer } from "./mjml-config-container";
|
import { FilterConfigurationsArgs, MjmlConfigContainer } from "./mjml-config-container";
|
||||||
import { createSettingsManager } from "../../../lib/metadata-manager";
|
import { createSettingsManager } from "../../../lib/metadata-manager";
|
||||||
|
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
service: "MjmlConfigurationService",
|
service: "MjmlConfigurationService",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ export class MjmlConfigurationService {
|
||||||
logger.debug("Fetch configuration from Saleor API");
|
logger.debug("Fetch configuration from Saleor API");
|
||||||
|
|
||||||
const config = await this.metadataConfigurator.getConfig();
|
const config = await this.metadataConfigurator.getConfig();
|
||||||
|
|
||||||
this.configurationData = config;
|
this.configurationData = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +83,7 @@ export class MjmlConfigurationService {
|
||||||
const updatedConfigurationRoot = MjmlConfigContainer.createConfiguration(
|
const updatedConfigurationRoot = MjmlConfigContainer.createConfiguration(
|
||||||
await this.getConfigurationRoot()
|
await this.getConfigurationRoot()
|
||||||
)(config);
|
)(config);
|
||||||
|
|
||||||
await this.setConfigurationRoot(updatedConfigurationRoot);
|
await this.setConfigurationRoot(updatedConfigurationRoot);
|
||||||
|
|
||||||
return updatedConfigurationRoot.configurations[
|
return updatedConfigurationRoot.configurations[
|
||||||
|
@ -94,6 +96,7 @@ export class MjmlConfigurationService {
|
||||||
const updatedConfigurationRoot = MjmlConfigContainer.updateConfiguration(
|
const updatedConfigurationRoot = MjmlConfigContainer.updateConfiguration(
|
||||||
await this.getConfigurationRoot()
|
await this.getConfigurationRoot()
|
||||||
)(config);
|
)(config);
|
||||||
|
|
||||||
this.setConfigurationRoot(updatedConfigurationRoot);
|
this.setConfigurationRoot(updatedConfigurationRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +105,7 @@ export class MjmlConfigurationService {
|
||||||
const updatedConfigurationRoot = MjmlConfigContainer.deleteConfiguration(
|
const updatedConfigurationRoot = MjmlConfigContainer.deleteConfiguration(
|
||||||
await this.getConfigurationRoot()
|
await this.getConfigurationRoot()
|
||||||
)({ id });
|
)({ id });
|
||||||
|
|
||||||
this.setConfigurationRoot(updatedConfigurationRoot);
|
this.setConfigurationRoot(updatedConfigurationRoot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { logger as pinoLogger } from "../../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import {
|
import {
|
||||||
mjmlCreateConfigurationSchema,
|
mjmlCreateConfigurationSchema,
|
||||||
mjmlDeleteConfigurationInputSchema,
|
mjmlDeleteConfigurationInputSchema,
|
||||||
|
@ -16,8 +16,10 @@ import { compileMjml } from "../compile-mjml";
|
||||||
import Handlebars from "handlebars";
|
import Handlebars from "handlebars";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
|
|
||||||
// Allow access only for the dashboard users and attaches the
|
/*
|
||||||
// configuration service to the context
|
* Allow access only for the dashboard users and attaches the
|
||||||
|
* configuration service to the context
|
||||||
|
*/
|
||||||
const protectedWithConfigurationService = protectedClientProcedure.use(({ next, ctx }) =>
|
const protectedWithConfigurationService = protectedClientProcedure.use(({ next, ctx }) =>
|
||||||
next({
|
next({
|
||||||
ctx: {
|
ctx: {
|
||||||
|
@ -32,7 +34,8 @@ const protectedWithConfigurationService = protectedClientProcedure.use(({ next,
|
||||||
|
|
||||||
export const mjmlConfigurationRouter = router({
|
export const mjmlConfigurationRouter = router({
|
||||||
fetch: protectedWithConfigurationService.query(async ({ ctx }) => {
|
fetch: protectedWithConfigurationService.query(async ({ ctx }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug("mjmlConfigurationRouter.fetch called");
|
logger.debug("mjmlConfigurationRouter.fetch called");
|
||||||
return ctx.configurationService.getConfigurationRoot();
|
return ctx.configurationService.getConfigurationRoot();
|
||||||
}),
|
}),
|
||||||
|
@ -40,7 +43,8 @@ export const mjmlConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(mjmlGetConfigurationInputSchema)
|
.input(mjmlGetConfigurationInputSchema)
|
||||||
.query(async ({ ctx, input }) => {
|
.query(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "mjmlConfigurationRouter.get called");
|
logger.debug(input, "mjmlConfigurationRouter.get called");
|
||||||
return ctx.configurationService.getConfiguration(input);
|
return ctx.configurationService.getConfiguration(input);
|
||||||
}),
|
}),
|
||||||
|
@ -48,7 +52,8 @@ export const mjmlConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(mjmlGetConfigurationsInputSchema)
|
.input(mjmlGetConfigurationsInputSchema)
|
||||||
.query(async ({ ctx, input }) => {
|
.query(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "mjmlConfigurationRouter.getConfigurations called");
|
logger.debug(input, "mjmlConfigurationRouter.getConfigurations called");
|
||||||
return ctx.configurationService.getConfigurations(input);
|
return ctx.configurationService.getConfigurations(input);
|
||||||
}),
|
}),
|
||||||
|
@ -56,7 +61,8 @@ export const mjmlConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(mjmlCreateConfigurationSchema)
|
.input(mjmlCreateConfigurationSchema)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "mjmlConfigurationRouter.create called");
|
logger.debug(input, "mjmlConfigurationRouter.create called");
|
||||||
return await ctx.configurationService.createConfiguration(input);
|
return await ctx.configurationService.createConfiguration(input);
|
||||||
}),
|
}),
|
||||||
|
@ -64,9 +70,11 @@ export const mjmlConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(mjmlDeleteConfigurationInputSchema)
|
.input(mjmlDeleteConfigurationInputSchema)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "mjmlConfigurationRouter.delete called");
|
logger.debug(input, "mjmlConfigurationRouter.delete called");
|
||||||
const existingConfiguration = await ctx.configurationService.getConfiguration(input);
|
const existingConfiguration = await ctx.configurationService.getConfiguration(input);
|
||||||
|
|
||||||
if (!existingConfiguration) {
|
if (!existingConfiguration) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
|
@ -80,14 +88,17 @@ export const mjmlConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(mjmlUpdateOrCreateConfigurationSchema)
|
.input(mjmlUpdateOrCreateConfigurationSchema)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "mjmlConfigurationRouter.update or create called");
|
logger.debug(input, "mjmlConfigurationRouter.update or create called");
|
||||||
|
|
||||||
const { id } = input;
|
const { id } = input;
|
||||||
|
|
||||||
if (!id) {
|
if (!id) {
|
||||||
return await ctx.configurationService.createConfiguration(input);
|
return await ctx.configurationService.createConfiguration(input);
|
||||||
} else {
|
} else {
|
||||||
const existingConfiguration = await ctx.configurationService.getConfiguration({ id });
|
const existingConfiguration = await ctx.configurationService.getConfiguration({ id });
|
||||||
|
|
||||||
if (!existingConfiguration) {
|
if (!existingConfiguration) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
|
@ -99,6 +110,7 @@ export const mjmlConfigurationRouter = router({
|
||||||
...input,
|
...input,
|
||||||
events: existingConfiguration.events,
|
events: existingConfiguration.events,
|
||||||
};
|
};
|
||||||
|
|
||||||
await ctx.configurationService.updateConfiguration(configuration);
|
await ctx.configurationService.updateConfiguration(configuration);
|
||||||
return configuration;
|
return configuration;
|
||||||
}
|
}
|
||||||
|
@ -107,7 +119,7 @@ export const mjmlConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(mjmlGetEventConfigurationInputSchema)
|
.input(mjmlGetEventConfigurationInputSchema)
|
||||||
.query(async ({ ctx, input }) => {
|
.query(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "mjmlConfigurationRouter.getEventConfiguration or create called");
|
logger.debug(input, "mjmlConfigurationRouter.getEventConfiguration or create called");
|
||||||
|
|
||||||
|
@ -123,6 +135,7 @@ export const mjmlConfigurationRouter = router({
|
||||||
}
|
}
|
||||||
|
|
||||||
const event = configuration.events.find((e) => e.eventType === input.eventType);
|
const event = configuration.events.find((e) => e.eventType === input.eventType);
|
||||||
|
|
||||||
if (!event) {
|
if (!event) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
|
@ -135,7 +148,7 @@ export const mjmlConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(mjmlUpdateEventConfigurationInputSchema)
|
.input(mjmlUpdateEventConfigurationInputSchema)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "mjmlConfigurationRouter.updateEventConfiguration or create called");
|
logger.debug(input, "mjmlConfigurationRouter.updateEventConfiguration or create called");
|
||||||
|
|
||||||
|
@ -151,6 +164,7 @@ export const mjmlConfigurationRouter = router({
|
||||||
}
|
}
|
||||||
|
|
||||||
const eventIndex = configuration.events.findIndex((e) => e.eventType === input.eventType);
|
const eventIndex = configuration.events.findIndex((e) => e.eventType === input.eventType);
|
||||||
|
|
||||||
configuration.events[eventIndex] = {
|
configuration.events[eventIndex] = {
|
||||||
active: input.active,
|
active: input.active,
|
||||||
eventType: input.eventType,
|
eventType: input.eventType,
|
||||||
|
@ -171,7 +185,8 @@ export const mjmlConfigurationRouter = router({
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "mjmlConfigurationRouter.renderTemplate called");
|
logger.debug(input, "mjmlConfigurationRouter.renderTemplate called");
|
||||||
|
|
||||||
let renderedSubject = "";
|
let renderedSubject = "";
|
||||||
|
@ -180,16 +195,19 @@ export const mjmlConfigurationRouter = router({
|
||||||
|
|
||||||
if (input.subject) {
|
if (input.subject) {
|
||||||
const compiledSubjectTemplate = Handlebars.compile(input.subject);
|
const compiledSubjectTemplate = Handlebars.compile(input.subject);
|
||||||
|
|
||||||
logger.warn("subject part");
|
logger.warn("subject part");
|
||||||
renderedSubject = compiledSubjectTemplate(payload);
|
renderedSubject = compiledSubjectTemplate(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
let renderedEmail = "";
|
let renderedEmail = "";
|
||||||
|
|
||||||
if (input.template) {
|
if (input.template) {
|
||||||
const compiledSubjectTemplate = Handlebars.compile(input.template);
|
const compiledSubjectTemplate = Handlebars.compile(input.template);
|
||||||
const templatedEmail = compiledSubjectTemplate(payload);
|
const templatedEmail = compiledSubjectTemplate(payload);
|
||||||
|
|
||||||
const { html: rawHtml } = compileMjml(templatedEmail);
|
const { html: rawHtml } = compileMjml(templatedEmail);
|
||||||
|
|
||||||
if (rawHtml) {
|
if (rawHtml) {
|
||||||
renderedEmail = rawHtml;
|
renderedEmail = rawHtml;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { convert } from "html-to-text";
|
import { convert } from "html-to-text";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
fn: "htmlToPlaintext",
|
fn: "htmlToPlaintext",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ export const htmlToPlaintext = (html: string) => {
|
||||||
logger.debug("Converting HTML template to plaintext");
|
logger.debug("Converting HTML template to plaintext");
|
||||||
try {
|
try {
|
||||||
const plaintext = convert(html);
|
const plaintext = convert(html);
|
||||||
|
|
||||||
logger.debug("Converted successfully");
|
logger.debug("Converted successfully");
|
||||||
return {
|
return {
|
||||||
plaintext,
|
plaintext,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import nodemailer from "nodemailer";
|
import nodemailer from "nodemailer";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
fn: "sendEmailWithSmtp",
|
fn: "sendEmailWithSmtp",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ export const sendEmailWithSmtp = async ({ smtpSettings, mailData }: SendMailArgs
|
||||||
const response = await transporter.sendMail({
|
const response = await transporter.sendMail({
|
||||||
...mailData,
|
...mailData,
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.debug("An email has been sent");
|
logger.debug("An email has been sent");
|
||||||
return { response };
|
return { response };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import { compileMjml } from "./compile-mjml";
|
import { compileMjml } from "./compile-mjml";
|
||||||
import { compileHandlebarsTemplate } from "./compile-handlebars-template";
|
import { compileHandlebarsTemplate } from "./compile-handlebars-template";
|
||||||
import { sendEmailWithSmtp, SendMailArgs } from "./send-email-with-smtp";
|
import { sendEmailWithSmtp, SendMailArgs } from "./send-email-with-smtp";
|
||||||
|
@ -26,12 +26,13 @@ export const sendMjml = async ({
|
||||||
event,
|
event,
|
||||||
mjmlConfiguration,
|
mjmlConfiguration,
|
||||||
}: SendMjmlArgs) => {
|
}: SendMjmlArgs) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
fn: "sendMjml",
|
fn: "sendMjml",
|
||||||
event,
|
event,
|
||||||
});
|
});
|
||||||
|
|
||||||
const eventSettings = mjmlConfiguration.events.find((e) => e.eventType === event);
|
const eventSettings = mjmlConfiguration.events.find((e) => e.eventType === event);
|
||||||
|
|
||||||
if (!eventSettings) {
|
if (!eventSettings) {
|
||||||
logger.debug("No active settings for this event, skipping");
|
logger.debug("No active settings for this event, skipping");
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { SendgridConfigurator, PrivateMetadataSendgridConfigurator } from "./sendgrid-configurator";
|
import { SendgridConfigurator, PrivateMetadataSendgridConfigurator } from "./sendgrid-configurator";
|
||||||
import { Client } from "urql";
|
import { Client } from "urql";
|
||||||
import { logger as pinoLogger } from "../../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import { SendgridConfig, SendgridConfiguration } from "./sendgrid-config";
|
import { SendgridConfig, SendgridConfiguration } from "./sendgrid-config";
|
||||||
import { FilterConfigurationsArgs, SendgridConfigContainer } from "./sendgrid-config-container";
|
import { FilterConfigurationsArgs, SendgridConfigContainer } from "./sendgrid-config-container";
|
||||||
import { createSettingsManager } from "../../../lib/metadata-manager";
|
import { createSettingsManager } from "../../../lib/metadata-manager";
|
||||||
|
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
service: "SendgridConfigurationService",
|
service: "SendgridConfigurationService",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ export class SendgridConfigurationService {
|
||||||
logger.debug("Fetch configuration from Saleor API");
|
logger.debug("Fetch configuration from Saleor API");
|
||||||
|
|
||||||
const config = await this.metadataConfigurator.getConfig();
|
const config = await this.metadataConfigurator.getConfig();
|
||||||
|
|
||||||
this.configurationData = config;
|
this.configurationData = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +83,7 @@ export class SendgridConfigurationService {
|
||||||
const updatedConfigurationRoot = SendgridConfigContainer.createConfiguration(
|
const updatedConfigurationRoot = SendgridConfigContainer.createConfiguration(
|
||||||
await this.getConfigurationRoot()
|
await this.getConfigurationRoot()
|
||||||
)(config);
|
)(config);
|
||||||
|
|
||||||
await this.setConfigurationRoot(updatedConfigurationRoot);
|
await this.setConfigurationRoot(updatedConfigurationRoot);
|
||||||
|
|
||||||
return updatedConfigurationRoot.configurations[
|
return updatedConfigurationRoot.configurations[
|
||||||
|
@ -94,6 +96,7 @@ export class SendgridConfigurationService {
|
||||||
const updatedConfigurationRoot = SendgridConfigContainer.updateConfiguration(
|
const updatedConfigurationRoot = SendgridConfigContainer.updateConfiguration(
|
||||||
await this.getConfigurationRoot()
|
await this.getConfigurationRoot()
|
||||||
)(config);
|
)(config);
|
||||||
|
|
||||||
this.setConfigurationRoot(updatedConfigurationRoot);
|
this.setConfigurationRoot(updatedConfigurationRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +105,7 @@ export class SendgridConfigurationService {
|
||||||
const updatedConfigurationRoot = SendgridConfigContainer.deleteConfiguration(
|
const updatedConfigurationRoot = SendgridConfigContainer.deleteConfiguration(
|
||||||
await this.getConfigurationRoot()
|
await this.getConfigurationRoot()
|
||||||
)({ id });
|
)({ id });
|
||||||
|
|
||||||
this.setConfigurationRoot(updatedConfigurationRoot);
|
this.setConfigurationRoot(updatedConfigurationRoot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { logger as pinoLogger } from "../../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import {
|
import {
|
||||||
sendgridCreateConfigurationSchema,
|
sendgridCreateConfigurationSchema,
|
||||||
sendgridDeleteConfigurationInputSchema,
|
sendgridDeleteConfigurationInputSchema,
|
||||||
|
@ -13,8 +13,10 @@ import { router } from "../../trpc/trpc-server";
|
||||||
import { protectedClientProcedure } from "../../trpc/protected-client-procedure";
|
import { protectedClientProcedure } from "../../trpc/protected-client-procedure";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
|
|
||||||
// Allow access only for the dashboard users and attaches the
|
/*
|
||||||
// configuration service to the context
|
* Allow access only for the dashboard users and attaches the
|
||||||
|
* configuration service to the context
|
||||||
|
*/
|
||||||
const protectedWithConfigurationService = protectedClientProcedure.use(({ next, ctx }) =>
|
const protectedWithConfigurationService = protectedClientProcedure.use(({ next, ctx }) =>
|
||||||
next({
|
next({
|
||||||
ctx: {
|
ctx: {
|
||||||
|
@ -29,7 +31,8 @@ const protectedWithConfigurationService = protectedClientProcedure.use(({ next,
|
||||||
|
|
||||||
export const sendgridConfigurationRouter = router({
|
export const sendgridConfigurationRouter = router({
|
||||||
fetch: protectedWithConfigurationService.query(async ({ ctx }) => {
|
fetch: protectedWithConfigurationService.query(async ({ ctx }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug("sendgridConfigurationRouter.fetch called");
|
logger.debug("sendgridConfigurationRouter.fetch called");
|
||||||
return ctx.configurationService.getConfigurationRoot();
|
return ctx.configurationService.getConfigurationRoot();
|
||||||
}),
|
}),
|
||||||
|
@ -37,7 +40,8 @@ export const sendgridConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(sendgridGetConfigurationInputSchema)
|
.input(sendgridGetConfigurationInputSchema)
|
||||||
.query(async ({ ctx, input }) => {
|
.query(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "sendgridConfigurationRouter.get called");
|
logger.debug(input, "sendgridConfigurationRouter.get called");
|
||||||
return ctx.configurationService.getConfiguration(input);
|
return ctx.configurationService.getConfiguration(input);
|
||||||
}),
|
}),
|
||||||
|
@ -45,7 +49,8 @@ export const sendgridConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(sendgridGetConfigurationsInputSchema)
|
.input(sendgridGetConfigurationsInputSchema)
|
||||||
.query(async ({ ctx, input }) => {
|
.query(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "sendgridConfigurationRouter.getConfigurations called");
|
logger.debug(input, "sendgridConfigurationRouter.getConfigurations called");
|
||||||
return ctx.configurationService.getConfigurations(input);
|
return ctx.configurationService.getConfigurations(input);
|
||||||
}),
|
}),
|
||||||
|
@ -53,7 +58,8 @@ export const sendgridConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(sendgridCreateConfigurationSchema)
|
.input(sendgridCreateConfigurationSchema)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "sendgridConfigurationRouter.create called");
|
logger.debug(input, "sendgridConfigurationRouter.create called");
|
||||||
return await ctx.configurationService.createConfiguration(input);
|
return await ctx.configurationService.createConfiguration(input);
|
||||||
}),
|
}),
|
||||||
|
@ -61,9 +67,11 @@ export const sendgridConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(sendgridDeleteConfigurationInputSchema)
|
.input(sendgridDeleteConfigurationInputSchema)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "sendgridConfigurationRouter.delete called");
|
logger.debug(input, "sendgridConfigurationRouter.delete called");
|
||||||
const existingConfiguration = await ctx.configurationService.getConfiguration(input);
|
const existingConfiguration = await ctx.configurationService.getConfiguration(input);
|
||||||
|
|
||||||
if (!existingConfiguration) {
|
if (!existingConfiguration) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
|
@ -77,14 +85,17 @@ export const sendgridConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(sendgridUpdateOrCreateConfigurationSchema)
|
.input(sendgridUpdateOrCreateConfigurationSchema)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "sendgridConfigurationRouter.update or create called");
|
logger.debug(input, "sendgridConfigurationRouter.update or create called");
|
||||||
|
|
||||||
const { id } = input;
|
const { id } = input;
|
||||||
|
|
||||||
if (!id) {
|
if (!id) {
|
||||||
return await ctx.configurationService.createConfiguration(input);
|
return await ctx.configurationService.createConfiguration(input);
|
||||||
} else {
|
} else {
|
||||||
const existingConfiguration = await ctx.configurationService.getConfiguration({ id });
|
const existingConfiguration = await ctx.configurationService.getConfiguration({ id });
|
||||||
|
|
||||||
if (!existingConfiguration) {
|
if (!existingConfiguration) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
|
@ -96,6 +107,7 @@ export const sendgridConfigurationRouter = router({
|
||||||
...input,
|
...input,
|
||||||
events: existingConfiguration.events,
|
events: existingConfiguration.events,
|
||||||
};
|
};
|
||||||
|
|
||||||
await ctx.configurationService.updateConfiguration(configuration);
|
await ctx.configurationService.updateConfiguration(configuration);
|
||||||
return configuration;
|
return configuration;
|
||||||
}
|
}
|
||||||
|
@ -104,7 +116,7 @@ export const sendgridConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(sendgridGetEventConfigurationInputSchema)
|
.input(sendgridGetEventConfigurationInputSchema)
|
||||||
.query(async ({ ctx, input }) => {
|
.query(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "sendgridConfigurationRouter.getEventConfiguration or create called");
|
logger.debug(input, "sendgridConfigurationRouter.getEventConfiguration or create called");
|
||||||
|
|
||||||
|
@ -120,6 +132,7 @@ export const sendgridConfigurationRouter = router({
|
||||||
}
|
}
|
||||||
|
|
||||||
const event = configuration.events.find((e) => e.eventType === input.eventType);
|
const event = configuration.events.find((e) => e.eventType === input.eventType);
|
||||||
|
|
||||||
if (!event) {
|
if (!event) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
|
@ -132,7 +145,7 @@ export const sendgridConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(sendgridUpdateEventConfigurationInputSchema)
|
.input(sendgridUpdateEventConfigurationInputSchema)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "sendgridConfigurationRouter.updateEventConfiguration or create called");
|
logger.debug(input, "sendgridConfigurationRouter.updateEventConfiguration or create called");
|
||||||
|
|
||||||
|
@ -148,6 +161,7 @@ export const sendgridConfigurationRouter = router({
|
||||||
}
|
}
|
||||||
|
|
||||||
const eventIndex = configuration.events.findIndex((e) => e.eventType === input.eventType);
|
const eventIndex = configuration.events.findIndex((e) => e.eventType === input.eventType);
|
||||||
|
|
||||||
configuration.events[eventIndex] = {
|
configuration.events[eventIndex] = {
|
||||||
active: input.active,
|
active: input.active,
|
||||||
eventType: input.eventType,
|
eventType: input.eventType,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import { SendgridConfiguration } from "./configuration/sendgrid-config";
|
import { SendgridConfiguration } from "./configuration/sendgrid-config";
|
||||||
import { MailService } from "@sendgrid/mail";
|
import { MailService } from "@sendgrid/mail";
|
||||||
import { MessageEventTypes } from "../event-handlers/message-event-types";
|
import { MessageEventTypes } from "../event-handlers/message-event-types";
|
||||||
|
@ -23,10 +23,11 @@ export const sendSendgrid = async ({
|
||||||
event,
|
event,
|
||||||
sendgridConfiguration,
|
sendgridConfiguration,
|
||||||
}: SendSendgridArgs) => {
|
}: SendSendgridArgs) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
fn: "sendSendgrid",
|
fn: "sendSendgrid",
|
||||||
event,
|
event,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!sendgridConfiguration.senderEmail) {
|
if (!sendgridConfiguration.senderEmail) {
|
||||||
logger.debug("Sender email has not been specified, skipping");
|
logger.debug("Sender email has not been specified, skipping");
|
||||||
return {
|
return {
|
||||||
|
@ -39,6 +40,7 @@ export const sendSendgrid = async ({
|
||||||
}
|
}
|
||||||
|
|
||||||
const eventSettings = sendgridConfiguration.events.find((e) => e.eventType === event);
|
const eventSettings = sendgridConfiguration.events.find((e) => e.eventType === event);
|
||||||
|
|
||||||
if (!eventSettings) {
|
if (!eventSettings) {
|
||||||
logger.debug("No active settings for this event, skipping");
|
logger.debug("No active settings for this event, skipping");
|
||||||
return {
|
return {
|
||||||
|
@ -74,6 +76,7 @@ export const sendSendgrid = async ({
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const mailService = new MailService();
|
const mailService = new MailService();
|
||||||
|
|
||||||
mailService.setApiKey(sendgridConfiguration.apiKey);
|
mailService.setApiKey(sendgridConfiguration.apiKey);
|
||||||
|
|
||||||
await mailService.send({
|
await mailService.send({
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { middleware, procedure } from "./trpc-server";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { ProtectedHandlerError } from "@saleor/app-sdk/handlers/next";
|
import { ProtectedHandlerError } from "@saleor/app-sdk/handlers/next";
|
||||||
import { saleorApp } from "../../saleor-app";
|
import { saleorApp } from "../../saleor-app";
|
||||||
import { logger } from "../../lib/logger";
|
import { logger } from "@saleor/apps-shared";
|
||||||
import { createClient } from "../../lib/create-graphql-client";
|
import { createClient } from "../../lib/create-graphql-client";
|
||||||
|
|
||||||
const attachAppToken = middleware(async ({ ctx, next }) => {
|
const attachAppToken = middleware(async ({ ctx, next }) => {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { createAppRegisterHandler } from "@saleor/app-sdk/handlers/next";
|
||||||
|
|
||||||
import { saleorApp } from "../../saleor-app";
|
import { saleorApp } from "../../saleor-app";
|
||||||
import { createClient } from "../../lib/create-graphql-client";
|
import { createClient } from "../../lib/create-graphql-client";
|
||||||
import { logger } from "../../lib/logger";
|
import { logger } from "@saleor/apps-shared";
|
||||||
import { getBaseUrl } from "../../lib/get-base-url";
|
import { getBaseUrl } from "../../lib/get-base-url";
|
||||||
import { registerNotifyWebhook } from "../../lib/register-notify-webhook";
|
import { registerNotifyWebhook } from "../../lib/register-notify-webhook";
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ export default createAppRegisterHandler({
|
||||||
const client = createClient(ctx.authData.saleorApiUrl, async () =>
|
const client = createClient(ctx.authData.saleorApiUrl, async () =>
|
||||||
Promise.resolve({ token: ctx.authData.token })
|
Promise.resolve({ token: ctx.authData.token })
|
||||||
);
|
);
|
||||||
|
|
||||||
await registerNotifyWebhook({
|
await registerNotifyWebhook({
|
||||||
client: client,
|
client: client,
|
||||||
baseUrl: baseUrl,
|
baseUrl: baseUrl,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
||||||
import { gql } from "urql";
|
import { gql } from "urql";
|
||||||
import { saleorApp } from "../../../saleor-app";
|
import { saleorApp } from "../../../saleor-app";
|
||||||
import { logger as pinoLogger } from "../../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import {
|
import {
|
||||||
InvoiceSentWebhookPayloadFragment,
|
InvoiceSentWebhookPayloadFragment,
|
||||||
OrderDetailsFragmentDoc,
|
OrderDetailsFragmentDoc,
|
||||||
|
@ -49,7 +49,7 @@ const handler: NextWebhookApiHandler<InvoiceSentWebhookPayloadFragment> = async
|
||||||
res,
|
res,
|
||||||
context
|
context
|
||||||
) => {
|
) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
webhook: invoiceSentWebhook.name,
|
webhook: invoiceSentWebhook.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ const handler: NextWebhookApiHandler<InvoiceSentWebhookPayloadFragment> = async
|
||||||
}
|
}
|
||||||
|
|
||||||
const recipientEmail = order.userEmail || order.user?.email;
|
const recipientEmail = order.userEmail || order.user?.email;
|
||||||
|
|
||||||
if (!recipientEmail?.length) {
|
if (!recipientEmail?.length) {
|
||||||
logger.error(`The order ${order.number} had no email recipient set. Aborting.`);
|
logger.error(`The order ${order.number} had no email recipient set. Aborting.`);
|
||||||
return res
|
return res
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
||||||
import { saleorApp } from "../../../saleor-app";
|
import { saleorApp } from "../../../saleor-app";
|
||||||
import { logger as pinoLogger } from "../../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import { sendEventMessages } from "../../../modules/event-handlers/send-event-messages";
|
import { sendEventMessages } from "../../../modules/event-handlers/send-event-messages";
|
||||||
import { createClient } from "../../../lib/create-graphql-client";
|
import { createClient } from "../../../lib/create-graphql-client";
|
||||||
import { MessageEventTypes } from "../../../modules/event-handlers/message-event-types";
|
import { MessageEventTypes } from "../../../modules/event-handlers/message-event-types";
|
||||||
|
|
||||||
// Notify event handles multiple event types which are recognized based on payload field `notify_event`.
|
/*
|
||||||
// Handler recognizes if event is one of the supported typed and sends appropriate message.
|
* Notify event handles multiple event types which are recognized based on payload field `notify_event`.
|
||||||
|
* Handler recognizes if event is one of the supported typed and sends appropriate message.
|
||||||
|
*/
|
||||||
|
|
||||||
interface NotifySubscriptionPayload {
|
interface NotifySubscriptionPayload {
|
||||||
notify_event: string;
|
notify_event: string;
|
||||||
|
@ -62,7 +64,7 @@ export const notifyWebhook = new SaleorAsyncWebhook<NotifySubscriptionPayload>({
|
||||||
});
|
});
|
||||||
|
|
||||||
const handler: NextWebhookApiHandler<NotifySubscriptionPayload> = async (req, res, context) => {
|
const handler: NextWebhookApiHandler<NotifySubscriptionPayload> = async (req, res, context) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
webhook: notifyWebhook.name,
|
webhook: notifyWebhook.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -89,6 +91,7 @@ const handler: NextWebhookApiHandler<NotifySubscriptionPayload> = async (req, re
|
||||||
};
|
};
|
||||||
|
|
||||||
const event = notifyEventMapping[payload.notify_event];
|
const event = notifyEventMapping[payload.notify_event];
|
||||||
|
|
||||||
if (!event) {
|
if (!event) {
|
||||||
logger.error(`The type of received notify event (${payload.notify_event}) is not supported.`);
|
logger.error(`The type of received notify event (${payload.notify_event}) is not supported.`);
|
||||||
return res
|
return res
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
||||||
import { gql } from "urql";
|
import { gql } from "urql";
|
||||||
import { saleorApp } from "../../../saleor-app";
|
import { saleorApp } from "../../../saleor-app";
|
||||||
import { logger as pinoLogger } from "../../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import {
|
import {
|
||||||
OrderCancelledWebhookPayloadFragment,
|
OrderCancelledWebhookPayloadFragment,
|
||||||
OrderDetailsFragmentDoc,
|
OrderDetailsFragmentDoc,
|
||||||
|
@ -40,7 +40,7 @@ const handler: NextWebhookApiHandler<OrderCancelledWebhookPayloadFragment> = asy
|
||||||
res,
|
res,
|
||||||
context
|
context
|
||||||
) => {
|
) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
webhook: orderCancelledWebhook.name,
|
webhook: orderCancelledWebhook.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ const handler: NextWebhookApiHandler<OrderCancelledWebhookPayloadFragment> = asy
|
||||||
}
|
}
|
||||||
|
|
||||||
const recipientEmail = order.userEmail || order.user?.email;
|
const recipientEmail = order.userEmail || order.user?.email;
|
||||||
|
|
||||||
if (!recipientEmail?.length) {
|
if (!recipientEmail?.length) {
|
||||||
logger.error(`The order ${order.number} had no email recipient set. Aborting.`);
|
logger.error(`The order ${order.number} had no email recipient set. Aborting.`);
|
||||||
return res
|
return res
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
||||||
import { gql } from "urql";
|
import { gql } from "urql";
|
||||||
import { saleorApp } from "../../../saleor-app";
|
import { saleorApp } from "../../../saleor-app";
|
||||||
import { logger as pinoLogger } from "../../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import {
|
import {
|
||||||
OrderConfirmedWebhookPayloadFragment,
|
OrderConfirmedWebhookPayloadFragment,
|
||||||
OrderDetailsFragmentDoc,
|
OrderDetailsFragmentDoc,
|
||||||
|
@ -41,7 +41,7 @@ const handler: NextWebhookApiHandler<OrderConfirmedWebhookPayloadFragment> = asy
|
||||||
res,
|
res,
|
||||||
context
|
context
|
||||||
) => {
|
) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
webhook: orderConfirmedWebhook.name,
|
webhook: orderConfirmedWebhook.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ const handler: NextWebhookApiHandler<OrderConfirmedWebhookPayloadFragment> = asy
|
||||||
}
|
}
|
||||||
|
|
||||||
const recipientEmail = order.userEmail || order.user?.email;
|
const recipientEmail = order.userEmail || order.user?.email;
|
||||||
|
|
||||||
if (!recipientEmail?.length) {
|
if (!recipientEmail?.length) {
|
||||||
logger.error(`The order ${order.number} had no email recipient set. Aborting.`);
|
logger.error(`The order ${order.number} had no email recipient set. Aborting.`);
|
||||||
return res
|
return res
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { OrderDetailsFragmentDoc } from "./../../../../generated/graphql";
|
||||||
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
||||||
import { gql } from "urql";
|
import { gql } from "urql";
|
||||||
import { saleorApp } from "../../../saleor-app";
|
import { saleorApp } from "../../../saleor-app";
|
||||||
import { logger as pinoLogger } from "../../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import { OrderCreatedWebhookPayloadFragment } from "../../../../generated/graphql";
|
import { OrderCreatedWebhookPayloadFragment } from "../../../../generated/graphql";
|
||||||
import { sendEventMessages } from "../../../modules/event-handlers/send-event-messages";
|
import { sendEventMessages } from "../../../modules/event-handlers/send-event-messages";
|
||||||
import { createClient } from "../../../lib/create-graphql-client";
|
import { createClient } from "../../../lib/create-graphql-client";
|
||||||
|
@ -38,7 +38,7 @@ const handler: NextWebhookApiHandler<OrderCreatedWebhookPayloadFragment> = async
|
||||||
res,
|
res,
|
||||||
context
|
context
|
||||||
) => {
|
) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
webhook: orderCreatedWebhook.name,
|
webhook: orderCreatedWebhook.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ const handler: NextWebhookApiHandler<OrderCreatedWebhookPayloadFragment> = async
|
||||||
}
|
}
|
||||||
|
|
||||||
const recipientEmail = order.userEmail || order.user?.email;
|
const recipientEmail = order.userEmail || order.user?.email;
|
||||||
|
|
||||||
if (!recipientEmail?.length) {
|
if (!recipientEmail?.length) {
|
||||||
logger.error(`The order ${order.number} had no email recipient set. Aborting.`);
|
logger.error(`The order ${order.number} had no email recipient set. Aborting.`);
|
||||||
return res
|
return res
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
||||||
import { gql } from "urql";
|
import { gql } from "urql";
|
||||||
import { saleorApp } from "../../../saleor-app";
|
import { saleorApp } from "../../../saleor-app";
|
||||||
import { logger as pinoLogger } from "../../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import {
|
import {
|
||||||
OrderDetailsFragmentDoc,
|
OrderDetailsFragmentDoc,
|
||||||
OrderFulfilledWebhookPayloadFragment,
|
OrderFulfilledWebhookPayloadFragment,
|
||||||
|
@ -41,7 +41,7 @@ const handler: NextWebhookApiHandler<OrderFulfilledWebhookPayloadFragment> = asy
|
||||||
res,
|
res,
|
||||||
context
|
context
|
||||||
) => {
|
) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
webhook: orderFulfilledWebhook.name,
|
webhook: orderFulfilledWebhook.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ const handler: NextWebhookApiHandler<OrderFulfilledWebhookPayloadFragment> = asy
|
||||||
}
|
}
|
||||||
|
|
||||||
const recipientEmail = order.userEmail || order.user?.email;
|
const recipientEmail = order.userEmail || order.user?.email;
|
||||||
|
|
||||||
if (!recipientEmail?.length) {
|
if (!recipientEmail?.length) {
|
||||||
logger.error(`The order ${order.number} had no email recipient set. Aborting.`);
|
logger.error(`The order ${order.number} had no email recipient set. Aborting.`);
|
||||||
return res
|
return res
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
|
||||||
import { gql } from "urql";
|
import { gql } from "urql";
|
||||||
import { saleorApp } from "../../../saleor-app";
|
import { saleorApp } from "../../../saleor-app";
|
||||||
import { logger as pinoLogger } from "../../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import {
|
import {
|
||||||
OrderDetailsFragmentDoc,
|
OrderDetailsFragmentDoc,
|
||||||
OrderFullyPaidWebhookPayloadFragment,
|
OrderFullyPaidWebhookPayloadFragment,
|
||||||
|
@ -41,7 +41,7 @@ const handler: NextWebhookApiHandler<OrderFullyPaidWebhookPayloadFragment> = asy
|
||||||
res,
|
res,
|
||||||
context
|
context
|
||||||
) => {
|
) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
webhook: orderFullyPaidWebhook.name,
|
webhook: orderFullyPaidWebhook.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ const handler: NextWebhookApiHandler<OrderFullyPaidWebhookPayloadFragment> = asy
|
||||||
}
|
}
|
||||||
|
|
||||||
const recipientEmail = order.userEmail || order.user?.email;
|
const recipientEmail = order.userEmail || order.user?.email;
|
||||||
|
|
||||||
if (!recipientEmail?.length) {
|
if (!recipientEmail?.length) {
|
||||||
logger.error(`The order ${order.number} had no email recipient set. Aborting.`);
|
logger.error(`The order ${order.number} had no email recipient set. Aborting.`);
|
||||||
return res
|
return res
|
||||||
|
|
|
@ -37,8 +37,6 @@
|
||||||
"graphql-tag": "^2.12.6",
|
"graphql-tag": "^2.12.6",
|
||||||
"microinvoice": "^1.0.6",
|
"microinvoice": "^1.0.6",
|
||||||
"next": "13.3.0",
|
"next": "13.3.0",
|
||||||
"pino": "^8.8.0",
|
|
||||||
"pino-pretty": "^9.1.1",
|
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-hook-form": "^7.41.0",
|
"react-hook-form": "^7.41.0",
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
import pino from "pino";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO Set up log drain etc
|
|
||||||
*/
|
|
||||||
export const logger = pino({
|
|
||||||
level: process.env.APP_DEBUG ?? "silent",
|
|
||||||
transport:
|
|
||||||
process.env.NODE_ENV === "development"
|
|
||||||
? {
|
|
||||||
target: "pino-pretty",
|
|
||||||
options: {
|
|
||||||
colorize: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const createLogger = logger.child.bind(logger);
|
|
|
@ -2,13 +2,13 @@ import { router } from "../trpc/trpc-server";
|
||||||
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
||||||
import { PrivateMetadataAppConfigurator } from "./app-configurator";
|
import { PrivateMetadataAppConfigurator } from "./app-configurator";
|
||||||
import { createSettingsManager } from "./metadata-manager";
|
import { createSettingsManager } from "./metadata-manager";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import { appConfigInputSchema } from "./app-config-input-schema";
|
import { appConfigInputSchema } from "./app-config-input-schema";
|
||||||
import { GetAppConfigurationService } from "./get-app-configuration.service";
|
import { GetAppConfigurationService } from "./get-app-configuration.service";
|
||||||
|
|
||||||
export const appConfigurationRouter = router({
|
export const appConfigurationRouter = router({
|
||||||
fetch: protectedClientProcedure.query(async ({ ctx, input }) => {
|
fetch: protectedClientProcedure.query(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug("appConfigurationRouter.fetch called");
|
logger.debug("appConfigurationRouter.fetch called");
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ export const appConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(appConfigInputSchema)
|
.input(appConfigInputSchema)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "appConfigurationRouter.setAndReplace called with input");
|
logger.debug(input, "appConfigurationRouter.setAndReplace called with input");
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { ChannelsFetcher } from "../channels/channels-fetcher";
|
||||||
import { ShopInfoFetcher } from "../shop-info/shop-info-fetcher";
|
import { ShopInfoFetcher } from "../shop-info/shop-info-fetcher";
|
||||||
import { FallbackAppConfig } from "./fallback-app-config";
|
import { FallbackAppConfig } from "./fallback-app-config";
|
||||||
import { Client } from "urql";
|
import { Client } from "urql";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
// todo test
|
// todo test
|
||||||
export class GetAppConfigurationService {
|
export class GetAppConfigurationService {
|
||||||
|
@ -16,7 +16,7 @@ export class GetAppConfigurationService {
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async getConfiguration() {
|
async getConfiguration() {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
service: "GetAppConfigurationService",
|
service: "GetAppConfigurationService",
|
||||||
saleorApiUrl: this.settings.saleorApiUrl,
|
saleorApiUrl: this.settings.saleorApiUrl,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Client, gql } from "urql";
|
import { Client, gql } from "urql";
|
||||||
import { InvoiceCreateDocument } from "../../../generated/graphql";
|
import { InvoiceCreateDocument } from "../../../generated/graphql";
|
||||||
import { logger } from "../../lib/logger";
|
import { logger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
gql`
|
gql`
|
||||||
mutation InvoiceCreate($orderId: ID!, $invoiceInput: InvoiceCreateInput!) {
|
mutation InvoiceCreate($orderId: ID!, $invoiceInput: InvoiceCreateInput!) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import invariant from "tiny-invariant";
|
import invariant from "tiny-invariant";
|
||||||
import { mkdir, access, constants } from "fs/promises";
|
import { mkdir, access, constants } from "fs/promises";
|
||||||
import { logger } from "../../lib/logger";
|
import { logger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Path will be relative to built file, in dev its inside .next/server
|
* Path will be relative to built file, in dev its inside .next/server
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { FileUploadMutation } from "../../../generated/graphql";
|
||||||
* Use File instead of Blob so Saleor can understand name
|
* Use File instead of Blob so Saleor can understand name
|
||||||
*/
|
*/
|
||||||
import { File } from "@web-std/file";
|
import { File } from "@web-std/file";
|
||||||
import { logger } from "../../lib/logger";
|
import { logger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const fileUpload = gql`
|
const fileUpload = gql`
|
||||||
mutation FileUpload($file: Upload!) {
|
mutation FileUpload($file: Upload!) {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { middleware, procedure } from "./trpc-server";
|
||||||
import { saleorApp } from "../../saleor-app";
|
import { saleorApp } from "../../saleor-app";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { ProtectedHandlerError } from "@saleor/app-sdk/handlers/next";
|
import { ProtectedHandlerError } from "@saleor/app-sdk/handlers/next";
|
||||||
import { logger } from "../../lib/logger";
|
import { logger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const attachAppToken = middleware(async ({ ctx, next }) => {
|
const attachAppToken = middleware(async ({ ctx, next }) => {
|
||||||
logger.debug("attachAppToken middleware");
|
logger.debug("attachAppToken middleware");
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { gql } from "urql";
|
||||||
import { createClient } from "../../lib/graphql";
|
import { createClient } from "../../lib/graphql";
|
||||||
import { SaleorVersionQuery } from "../../../generated/graphql";
|
import { SaleorVersionQuery } from "../../../generated/graphql";
|
||||||
|
|
||||||
import { createLogger } from "../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import { SaleorVersionCompatibilityValidator } from "../../lib/saleor-version-compatibility-validator";
|
import { SaleorVersionCompatibilityValidator } from "../../lib/saleor-version-compatibility-validator";
|
||||||
|
|
||||||
const allowedUrlsPattern = process.env.ALLOWED_DOMAIN_PATTERN;
|
const allowedUrlsPattern = process.env.ALLOWED_DOMAIN_PATTERN;
|
||||||
|
|
|
@ -15,7 +15,7 @@ import {
|
||||||
import { MicroinvoiceInvoiceGenerator } from "../../../modules/invoice-generator/microinvoice/microinvoice-invoice-generator";
|
import { MicroinvoiceInvoiceGenerator } from "../../../modules/invoice-generator/microinvoice/microinvoice-invoice-generator";
|
||||||
import { hashInvoiceFilename } from "../../../modules/invoice-file-name/hash-invoice-filename";
|
import { hashInvoiceFilename } from "../../../modules/invoice-file-name/hash-invoice-filename";
|
||||||
import { resolveTempPdfFileLocation } from "../../../modules/invoice-file-name/resolve-temp-pdf-file-location";
|
import { resolveTempPdfFileLocation } from "../../../modules/invoice-file-name/resolve-temp-pdf-file-location";
|
||||||
import { createLogger } from "../../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import { GetAppConfigurationService } from "../../../modules/app-configuration/get-app-configuration.service";
|
import { GetAppConfigurationService } from "../../../modules/app-configuration/get-app-configuration.service";
|
||||||
import { SALEOR_API_URL_HEADER } from "@saleor/app-sdk/const";
|
import { SALEOR_API_URL_HEADER } from "@saleor/app-sdk/const";
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
"name": "saleor-app-klaviyo",
|
"name": "saleor-app-klaviyo",
|
||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"packageManager": "pnpm@7.18.1",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "pnpm generate && NODE_OPTIONS='--inspect' next dev",
|
"dev": "pnpm generate && NODE_OPTIONS='--inspect' next dev",
|
||||||
"build": "pnpm generate && next build",
|
"build": "pnpm generate && next build",
|
||||||
|
@ -57,6 +56,6 @@
|
||||||
"postcss": "^8.4.14",
|
"postcss": "^8.4.14",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.7.1",
|
||||||
"pretty-quick": "^3.1.3",
|
"pretty-quick": "^3.1.3",
|
||||||
"typescript": "4.9.5"
|
"typescript": "5.0.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,6 @@
|
||||||
"jsdom": "^20.0.3",
|
"jsdom": "^20.0.3",
|
||||||
"next": "13.3.0",
|
"next": "13.3.0",
|
||||||
"next-urql": "^4.0.2",
|
"next-urql": "^4.0.2",
|
||||||
"pino": "^8.8.0",
|
|
||||||
"pino-pretty": "^9.1.1",
|
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-hook-form": "^7.43.0",
|
"react-hook-form": "^7.43.0",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { url } from "inspector";
|
import { url } from "inspector";
|
||||||
import { Client } from "urql";
|
import { Client } from "urql";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import {
|
import {
|
||||||
FetchProductDataForFeedDocument,
|
FetchProductDataForFeedDocument,
|
||||||
GoogleFeedProductVariantFragment,
|
GoogleFeedProductVariantFragment,
|
||||||
|
@ -12,7 +12,7 @@ interface FetchProductDataArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchProductData = async ({ client, channel }: FetchProductDataArgs) => {
|
export const fetchProductData = async ({ client, channel }: FetchProductDataArgs) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: url, channel, route: "Google Product Feed" });
|
const logger = createLogger({ saleorApiUrl: url, channel, route: "Google Product Feed" });
|
||||||
|
|
||||||
let result = await client
|
let result = await client
|
||||||
.query(FetchProductDataForFeedDocument, { channel: channel as string, first: 100 })
|
.query(FetchProductDataForFeedDocument, { channel: channel as string, first: 100 })
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { url } from "inspector";
|
import { url } from "inspector";
|
||||||
import { Client } from "urql";
|
import { Client } from "urql";
|
||||||
import { logger as pinoLogger } from "../logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import { ShopDetailsDocument } from "../../../generated/graphql";
|
import { ShopDetailsDocument } from "../../../generated/graphql";
|
||||||
|
|
||||||
interface FetchShopDataArgs {
|
interface FetchShopDataArgs {
|
||||||
|
@ -9,7 +9,7 @@ interface FetchShopDataArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchShopData = async ({ client, channel }: FetchShopDataArgs) => {
|
export const fetchShopData = async ({ client, channel }: FetchShopDataArgs) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: url, channel, route: "Google Product Feed" });
|
const logger = createLogger({ saleorApiUrl: url, channel, route: "Google Product Feed" });
|
||||||
|
|
||||||
const result = await client.query(ShopDetailsDocument, {}).toPromise();
|
const result = await client.query(ShopDetailsDocument, {}).toPromise();
|
||||||
const shopDetails = result.data?.shop;
|
const shopDetails = result.data?.shop;
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
import pino from "pino";
|
|
||||||
|
|
||||||
export const logger = pino({
|
|
||||||
level: process.env.APP_DEBUG ?? "silent",
|
|
||||||
transport:
|
|
||||||
process.env.NODE_ENV === "development"
|
|
||||||
? {
|
|
||||||
target: "pino-pretty",
|
|
||||||
options: {
|
|
||||||
colorize: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const createLogger = logger.child.bind(logger);
|
|
|
@ -2,13 +2,13 @@ import { router } from "../trpc/trpc-server";
|
||||||
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
||||||
import { PrivateMetadataAppConfigurator } from "./app-configurator";
|
import { PrivateMetadataAppConfigurator } from "./app-configurator";
|
||||||
import { createSettingsManager } from "./metadata-manager";
|
import { createSettingsManager } from "./metadata-manager";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import { appConfigInputSchema } from "./app-config-input-schema";
|
import { appConfigInputSchema } from "./app-config-input-schema";
|
||||||
import { GetAppConfigurationService } from "./get-app-configuration.service";
|
import { GetAppConfigurationService } from "./get-app-configuration.service";
|
||||||
|
|
||||||
export const appConfigurationRouter = router({
|
export const appConfigurationRouter = router({
|
||||||
fetch: protectedClientProcedure.query(async ({ ctx, input }) => {
|
fetch: protectedClientProcedure.query(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug("appConfigurationRouter.fetch called");
|
logger.debug("appConfigurationRouter.fetch called");
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ export const appConfigurationRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(appConfigInputSchema)
|
.input(appConfigInputSchema)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug(input, "appConfigurationRouter.setAndReplace called with input");
|
logger.debug(input, "appConfigurationRouter.setAndReplace called with input");
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { ChannelsFetcher } from "../channels/channels-fetcher";
|
||||||
import { ShopInfoFetcher } from "../shop-info/shop-info-fetcher";
|
import { ShopInfoFetcher } from "../shop-info/shop-info-fetcher";
|
||||||
import { FallbackAppConfig } from "./fallback-app-config";
|
import { FallbackAppConfig } from "./fallback-app-config";
|
||||||
import { Client } from "urql";
|
import { Client } from "urql";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
export class GetAppConfigurationService {
|
export class GetAppConfigurationService {
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -15,7 +15,7 @@ export class GetAppConfigurationService {
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async getConfiguration() {
|
async getConfiguration() {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
service: "GetAppConfigurationService",
|
service: "GetAppConfigurationService",
|
||||||
saleorApiUrl: this.settings.saleorApiUrl,
|
saleorApiUrl: this.settings.saleorApiUrl,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { router } from "../trpc/trpc-server";
|
import { router } from "../trpc/trpc-server";
|
||||||
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import { SetCategoryMappingInputSchema } from "./category-mapping-input-schema";
|
import { SetCategoryMappingInputSchema } from "./category-mapping-input-schema";
|
||||||
import {
|
import {
|
||||||
FetchCategoriesWithMappingDocument,
|
FetchCategoriesWithMappingDocument,
|
||||||
|
@ -13,7 +13,7 @@ export const categoryMappingRouter = router({
|
||||||
* Get all the category mappings to Google categories from its public metadata
|
* Get all the category mappings to Google categories from its public metadata
|
||||||
*/
|
*/
|
||||||
getCategoryMappings: protectedClientProcedure.query(async ({ ctx, input }) => {
|
getCategoryMappings: protectedClientProcedure.query(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug("categoriesRouter.getCategoryMappings called");
|
logger.debug("categoriesRouter.getCategoryMappings called");
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ export const categoryMappingRouter = router({
|
||||||
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
||||||
.input(SetCategoryMappingInputSchema)
|
.input(SetCategoryMappingInputSchema)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
|
||||||
|
|
||||||
logger.debug("categoriesRouter.setCategoryMapping called");
|
logger.debug("categoriesRouter.setCategoryMapping called");
|
||||||
const { error } = await ctx.apiClient
|
const { error } = await ctx.apiClient
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { middleware, procedure } from "./trpc-server";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { ProtectedHandlerError } from "@saleor/app-sdk/handlers/next";
|
import { ProtectedHandlerError } from "@saleor/app-sdk/handlers/next";
|
||||||
import { saleorApp } from "../../saleor-app";
|
import { saleorApp } from "../../saleor-app";
|
||||||
import { logger } from "../../lib/logger";
|
import { logger } from "@saleor/apps-shared";
|
||||||
import { createClient } from "../../lib/create-graphq-client";
|
import { createClient } from "../../lib/create-graphq-client";
|
||||||
|
|
||||||
const attachAppToken = middleware(async ({ ctx, next }) => {
|
const attachAppToken = middleware(async ({ ctx, next }) => {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
import { initUrqlClient } from "next-urql";
|
import { initUrqlClient } from "next-urql";
|
||||||
import { GoogleFeedProductVariantFragment } from "../../../../../../generated/graphql";
|
import { GoogleFeedProductVariantFragment } from "../../../../../../generated/graphql";
|
||||||
import { apl } from "../../../../../saleor-app";
|
import { apl } from "../../../../../saleor-app";
|
||||||
import { logger as pinoLogger } from "../../../../../lib/logger";
|
import { createLogger } from "@saleor/apps-shared";
|
||||||
import { fetchProductData } from "../../../../../lib/google-feed/fetch-product-data";
|
import { fetchProductData } from "../../../../../lib/google-feed/fetch-product-data";
|
||||||
import { getGoogleFeedSettings } from "../../../../../lib/google-feed/get-google-feed-settings";
|
import { getGoogleFeedSettings } from "../../../../../lib/google-feed/get-google-feed-settings";
|
||||||
import { generateGoogleXmlFeed } from "../../../../../lib/google-feed/generate-google-xml-feed";
|
import { generateGoogleXmlFeed } from "../../../../../lib/google-feed/generate-google-xml-feed";
|
||||||
|
@ -17,7 +17,7 @@ export const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||||
const url = req.query.url as string;
|
const url = req.query.url as string;
|
||||||
const channel = req.query.channel as string;
|
const channel = req.query.channel as string;
|
||||||
|
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
saleorApiUrl: url,
|
saleorApiUrl: url,
|
||||||
channel,
|
channel,
|
||||||
route: "api/feed/{url}/{channel}/google.xml",
|
route: "api/feed/{url}/{channel}/google.xml",
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
"graphql-tag": "^2.12.6",
|
"graphql-tag": "^2.12.6",
|
||||||
"next": "13.3.0",
|
"next": "13.3.0",
|
||||||
"next-urql": "4.0.0",
|
"next-urql": "4.0.0",
|
||||||
"pino": "^8.8.0",
|
|
||||||
"pino-pretty": "^9.1.1",
|
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
|
|
|
@ -1,17 +1,10 @@
|
||||||
import pino from "pino";
|
import { createLogger as _createLogger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
export const logger = pino({
|
/**
|
||||||
level: "debug",
|
* Extend factory to add more settings specific for the app
|
||||||
|
*/
|
||||||
|
export const logger = _createLogger({
|
||||||
redact: ["token", "secretKey"],
|
redact: ["token", "secretKey"],
|
||||||
transport:
|
|
||||||
process.env.NODE_ENV === "development"
|
|
||||||
? {
|
|
||||||
target: "pino-pretty",
|
|
||||||
options: {
|
|
||||||
colorize: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const createLogger = logger.child.bind(logger);
|
export const createLogger = logger.child.bind(logger);
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { ProductUpdated, ProductUpdatedDocument } from "../../../../../generated
|
||||||
import { saleorApp } from "../../../../../saleor-app";
|
import { saleorApp } from "../../../../../saleor-app";
|
||||||
import { AlgoliaSearchProvider } from "../../../../lib/algolia/algoliaSearchProvider";
|
import { AlgoliaSearchProvider } from "../../../../lib/algolia/algoliaSearchProvider";
|
||||||
import { getAlgoliaConfiguration } from "../../../../lib/algolia/getAlgoliaConfiguration";
|
import { getAlgoliaConfiguration } from "../../../../lib/algolia/getAlgoliaConfiguration";
|
||||||
import { createDebug } from "../../../../lib/debug";
|
|
||||||
import { WebhookActivityTogglerService } from "../../../../domain/WebhookActivityToggler.service";
|
import { WebhookActivityTogglerService } from "../../../../domain/WebhookActivityToggler.service";
|
||||||
import { createClient } from "../../../../lib/graphql";
|
import { createClient } from "../../../../lib/graphql";
|
||||||
import { createLogger } from "../../../../lib/logger";
|
import { createLogger } from "../../../../lib/logger";
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
"jotai": "^2.0.0",
|
"jotai": "^2.0.0",
|
||||||
"jsdom": "^20.0.3",
|
"jsdom": "^20.0.3",
|
||||||
"next": "13.3.0",
|
"next": "13.3.0",
|
||||||
"pino": "^8.8.0",
|
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-hook-form": "^7.42.1",
|
"react-hook-form": "^7.42.1",
|
||||||
|
@ -69,7 +68,6 @@
|
||||||
"eslint-config-next": "12.3.1",
|
"eslint-config-next": "12.3.1",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint-config-prettier": "^8.5.0",
|
||||||
"eslint-config-saleor": "workspace:*",
|
"eslint-config-saleor": "workspace:*",
|
||||||
"pino-pretty": "^9.1.1",
|
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.7.1",
|
||||||
"typescript": "4.8.4"
|
"typescript": "4.8.4"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,6 @@
|
||||||
import pino from "pino";
|
import { createLogger as _createLogger, Logger } from "@saleor/apps-shared";
|
||||||
|
|
||||||
export const logger = pino({
|
export const logger = _createLogger({
|
||||||
level: process.env.APP_DEBUG ?? "silent",
|
|
||||||
transport:
|
|
||||||
process.env.NODE_ENV === "development"
|
|
||||||
? {
|
|
||||||
target: "pino-pretty",
|
|
||||||
options: {
|
|
||||||
colorize: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
redact: [
|
redact: [
|
||||||
"metadata",
|
"metadata",
|
||||||
"providerInstance.config.username",
|
"providerInstance.config.username",
|
||||||
|
@ -20,3 +10,5 @@ export const logger = pino({
|
||||||
});
|
});
|
||||||
|
|
||||||
export const createLogger = logger.child.bind(logger);
|
export const createLogger = logger.child.bind(logger);
|
||||||
|
|
||||||
|
export type { Logger };
|
||||||
|
|
|
@ -5,10 +5,10 @@ import {
|
||||||
FetchAppDetailsQuery,
|
FetchAppDetailsQuery,
|
||||||
UpdateMetadataDocument,
|
UpdateMetadataDocument,
|
||||||
} from "../../../generated/graphql";
|
} from "../../../generated/graphql";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "../../lib/logger";
|
||||||
|
|
||||||
export async function fetchAllMetadata(client: Client): Promise<MetadataEntry[]> {
|
export async function fetchAllMetadata(client: Client): Promise<MetadataEntry[]> {
|
||||||
const logger = pinoLogger.child({ service: "fetchAllMetadata" });
|
const logger = createLogger({ service: "fetchAllMetadata" });
|
||||||
|
|
||||||
logger.debug("Fetching metadata from Saleor");
|
logger.debug("Fetching metadata from Saleor");
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ export async function fetchAllMetadata(client: Client): Promise<MetadataEntry[]>
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function mutateMetadata(client: Client, metadata: MetadataEntry[]) {
|
export async function mutateMetadata(client: Client, metadata: MetadataEntry[]) {
|
||||||
const logger = pinoLogger.child({ service: "mutateMetadata" });
|
const logger = createLogger({ service: "mutateMetadata" });
|
||||||
|
|
||||||
logger.debug({ metadata }, "Mutating metadata");
|
logger.debug({ metadata }, "Mutating metadata");
|
||||||
// to update the metadata, ID is required
|
// to update the metadata, ID is required
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { NextApiResponse } from "next";
|
import { NextApiResponse } from "next";
|
||||||
import { Logger } from "pino";
|
|
||||||
import { createLogger } from "../../lib/logger";
|
import { createLogger, Logger } from "../../lib/logger";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* idea: distinguish between async and sync webhooks
|
* idea: distinguish between async and sync webhooks
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import Avatax from "avatax";
|
import Avatax from "avatax";
|
||||||
import { CreateTransactionModel } from "avatax/lib/models/CreateTransactionModel";
|
import { CreateTransactionModel } from "avatax/lib/models/CreateTransactionModel";
|
||||||
import pino from "pino";
|
|
||||||
import packageJson from "../../../package.json";
|
import packageJson from "../../../package.json";
|
||||||
import { createLogger } from "../../lib/logger";
|
import { createLogger, Logger } from "../../lib/logger";
|
||||||
import { AvataxConfig } from "./avatax-config";
|
import { AvataxConfig } from "./avatax-config";
|
||||||
import { CommitTransactionModel } from "avatax/lib/models/CommitTransactionModel";
|
import { CommitTransactionModel } from "avatax/lib/models/CommitTransactionModel";
|
||||||
import { DocumentType } from "avatax/lib/enums/DocumentType";
|
import { DocumentType } from "avatax/lib/enums/DocumentType";
|
||||||
|
@ -55,7 +54,7 @@ export type ValidateAddressArgs = {
|
||||||
|
|
||||||
export class AvataxClient {
|
export class AvataxClient {
|
||||||
private client: Avatax;
|
private client: Avatax;
|
||||||
private logger: pino.Logger;
|
private logger: Logger;
|
||||||
|
|
||||||
constructor(config: AvataxConfig) {
|
constructor(config: AvataxConfig) {
|
||||||
this.logger = createLogger({ service: "AvataxClient" });
|
this.logger = createLogger({ service: "AvataxClient" });
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "../../lib/logger";
|
||||||
import { isObfuscated } from "../../lib/utils";
|
import { isObfuscated } from "../../lib/utils";
|
||||||
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
||||||
import { router } from "../trpc/trpc-server";
|
import { router } from "../trpc/trpc-server";
|
||||||
|
@ -33,7 +33,7 @@ const postInputSchema = z.object({
|
||||||
|
|
||||||
export const avataxConfigurationRouter = router({
|
export const avataxConfigurationRouter = router({
|
||||||
get: protectedClientProcedure.input(getInputSchema).query(async ({ ctx, input }) => {
|
get: protectedClientProcedure.input(getInputSchema).query(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
saleorApiUrl: ctx.saleorApiUrl,
|
saleorApiUrl: ctx.saleorApiUrl,
|
||||||
procedure: "avataxConfigurationRouter.get",
|
procedure: "avataxConfigurationRouter.get",
|
||||||
});
|
});
|
||||||
|
@ -51,7 +51,7 @@ export const avataxConfigurationRouter = router({
|
||||||
return { ...result, config: obfuscateAvataxConfig(result.config) };
|
return { ...result, config: obfuscateAvataxConfig(result.config) };
|
||||||
}),
|
}),
|
||||||
post: protectedClientProcedure.input(postInputSchema).mutation(async ({ ctx, input }) => {
|
post: protectedClientProcedure.input(postInputSchema).mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
saleorApiUrl: ctx.saleorApiUrl,
|
saleorApiUrl: ctx.saleorApiUrl,
|
||||||
procedure: "avataxConfigurationRouter.post",
|
procedure: "avataxConfigurationRouter.post",
|
||||||
});
|
});
|
||||||
|
@ -68,7 +68,7 @@ export const avataxConfigurationRouter = router({
|
||||||
return result;
|
return result;
|
||||||
}),
|
}),
|
||||||
delete: protectedClientProcedure.input(deleteInputSchema).mutation(async ({ ctx, input }) => {
|
delete: protectedClientProcedure.input(deleteInputSchema).mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
saleorApiUrl: ctx.saleorApiUrl,
|
saleorApiUrl: ctx.saleorApiUrl,
|
||||||
procedure: "avataxConfigurationRouter.delete",
|
procedure: "avataxConfigurationRouter.delete",
|
||||||
});
|
});
|
||||||
|
@ -85,7 +85,7 @@ export const avataxConfigurationRouter = router({
|
||||||
return result;
|
return result;
|
||||||
}),
|
}),
|
||||||
patch: protectedClientProcedure.input(patchInputSchema).mutation(async ({ ctx, input }) => {
|
patch: protectedClientProcedure.input(patchInputSchema).mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
saleorApiUrl: ctx.saleorApiUrl,
|
saleorApiUrl: ctx.saleorApiUrl,
|
||||||
procedure: "avataxConfigurationRouter.patch",
|
procedure: "avataxConfigurationRouter.patch",
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import pino from "pino";
|
|
||||||
import { Client } from "urql";
|
import { Client } from "urql";
|
||||||
import { createLogger } from "../../lib/logger";
|
import { createLogger, Logger } from "../../lib/logger";
|
||||||
import { createSettingsManager } from "../app/metadata-manager";
|
import { createSettingsManager } from "../app/metadata-manager";
|
||||||
import { CrudSettingsManager } from "../crud-settings/crud-settings.service";
|
import { CrudSettingsManager } from "../crud-settings/crud-settings.service";
|
||||||
import { providersSchema } from "../providers-configuration/providers-config";
|
import { providersSchema } from "../providers-configuration/providers-config";
|
||||||
|
@ -12,7 +11,7 @@ const getSchema = avataxInstanceConfigSchema;
|
||||||
|
|
||||||
export class AvataxConfigurationService {
|
export class AvataxConfigurationService {
|
||||||
private crudSettingsManager: CrudSettingsManager;
|
private crudSettingsManager: CrudSettingsManager;
|
||||||
private logger: pino.Logger;
|
private logger: Logger;
|
||||||
constructor(client: Client, saleorApiUrl: string) {
|
constructor(client: Client, saleorApiUrl: string) {
|
||||||
const settingsManager = createSettingsManager(client);
|
const settingsManager = createSettingsManager(client);
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import pino from "pino";
|
|
||||||
import {
|
import {
|
||||||
OrderCreatedSubscriptionFragment,
|
OrderCreatedSubscriptionFragment,
|
||||||
OrderFulfilledSubscriptionFragment,
|
OrderFulfilledSubscriptionFragment,
|
||||||
TaxBaseFragment,
|
TaxBaseFragment,
|
||||||
} from "../../../generated/graphql";
|
} from "../../../generated/graphql";
|
||||||
import { createLogger } from "../../lib/logger";
|
import { createLogger, Logger } from "../../lib/logger";
|
||||||
import { ChannelConfig } from "../channels-configuration/channels-config";
|
import { ChannelConfig } from "../channels-configuration/channels-config";
|
||||||
import { ProviderWebhookService } from "../taxes/tax-provider-webhook";
|
import { ProviderWebhookService } from "../taxes/tax-provider-webhook";
|
||||||
import { avataxCalculateTaxesMaps } from "./maps/avatax-calculate-taxes-map";
|
import { avataxCalculateTaxesMaps } from "./maps/avatax-calculate-taxes-map";
|
||||||
|
@ -16,7 +15,7 @@ import { avataxOrderFulfilledMaps } from "./maps/avatax-order-fulfilled-map";
|
||||||
export class AvataxWebhookService implements ProviderWebhookService {
|
export class AvataxWebhookService implements ProviderWebhookService {
|
||||||
config = defaultAvataxConfig;
|
config = defaultAvataxConfig;
|
||||||
client: AvataxClient;
|
client: AvataxClient;
|
||||||
private logger: pino.Logger;
|
private logger: Logger;
|
||||||
|
|
||||||
constructor(config: AvataxConfig) {
|
constructor(config: AvataxConfig) {
|
||||||
this.logger = createLogger({
|
this.logger = createLogger({
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "../../lib/logger";
|
||||||
import { createSettingsManager } from "../app/metadata-manager";
|
import { createSettingsManager } from "../app/metadata-manager";
|
||||||
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
||||||
import { router } from "../trpc/trpc-server";
|
import { router } from "../trpc/trpc-server";
|
||||||
|
@ -10,7 +10,7 @@ import { GetChannelsConfigurationService } from "./get-channels-configuration.se
|
||||||
// todo: refactor with crud-settings
|
// todo: refactor with crud-settings
|
||||||
export const channelsConfigurationRouter = router({
|
export const channelsConfigurationRouter = router({
|
||||||
fetch: protectedClientProcedure.query(async ({ ctx, input }) => {
|
fetch: protectedClientProcedure.query(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
saleorApiUrl: ctx.saleorApiUrl,
|
saleorApiUrl: ctx.saleorApiUrl,
|
||||||
procedure: "channelsConfigurationRouter.fetch",
|
procedure: "channelsConfigurationRouter.fetch",
|
||||||
});
|
});
|
||||||
|
@ -25,7 +25,7 @@ export const channelsConfigurationRouter = router({
|
||||||
upsert: protectedClientProcedure
|
upsert: protectedClientProcedure
|
||||||
.input(setAndReplaceChannelsInputSchema)
|
.input(setAndReplaceChannelsInputSchema)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
saleorApiUrl: ctx.saleorApiUrl,
|
saleorApiUrl: ctx.saleorApiUrl,
|
||||||
procedure: "channelsConfigurationRouter.upsert",
|
procedure: "channelsConfigurationRouter.upsert",
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Client } from "urql";
|
import { Client } from "urql";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "../../lib/logger";
|
||||||
import { createSettingsManager } from "../app/metadata-manager";
|
import { createSettingsManager } from "../app/metadata-manager";
|
||||||
import { TaxChannelsConfigurator } from "./channels-configurator";
|
import { TaxChannelsConfigurator } from "./channels-configurator";
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ export class GetChannelsConfigurationService {
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async getConfiguration() {
|
async getConfiguration() {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
service: "GetChannelsConfigurationService",
|
service: "GetChannelsConfigurationService",
|
||||||
saleorApiUrl: this.settings.saleorApiUrl,
|
saleorApiUrl: this.settings.saleorApiUrl,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import { SettingsManager } from "@saleor/app-sdk/settings-manager";
|
import { SettingsManager } from "@saleor/app-sdk/settings-manager";
|
||||||
import pino from "pino";
|
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { createLogger } from "../../lib/logger";
|
import { createLogger, Logger } from "../../lib/logger";
|
||||||
import { createId } from "../../lib/utils";
|
import { createId } from "../../lib/utils";
|
||||||
|
|
||||||
const settingSchema = z.record(z.any()).and(z.object({ id: z.string() }));
|
const settingSchema = z.record(z.any()).and(z.object({ id: z.string() }));
|
||||||
const settingsSchema = z.array(settingSchema);
|
const settingsSchema = z.array(settingSchema);
|
||||||
|
|
||||||
export class CrudSettingsManager {
|
export class CrudSettingsManager {
|
||||||
private logger: pino.Logger;
|
private logger: Logger;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private metadataManager: SettingsManager,
|
private metadataManager: SettingsManager,
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "../../lib/logger";
|
||||||
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
||||||
import { router } from "../trpc/trpc-server";
|
import { router } from "../trpc/trpc-server";
|
||||||
import { PublicTaxProvidersConfigurationService } from "./public-providers-configuration-service";
|
import { PublicTaxProvidersConfigurationService } from "./public-providers-configuration-service";
|
||||||
|
|
||||||
export const providersConfigurationRouter = router({
|
export const providersConfigurationRouter = router({
|
||||||
getAll: protectedClientProcedure.query(async ({ ctx }) => {
|
getAll: protectedClientProcedure.query(async ({ ctx }) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
saleorApiUrl: ctx.saleorApiUrl,
|
saleorApiUrl: ctx.saleorApiUrl,
|
||||||
procedure: "providersConfigurationRouter.getAll",
|
procedure: "providersConfigurationRouter.getAll",
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import pino from "pino";
|
|
||||||
import { Client } from "urql";
|
import { Client } from "urql";
|
||||||
import { createLogger } from "../../lib/logger";
|
import { createLogger, Logger } from "../../lib/logger";
|
||||||
import { obfuscateAvataxInstances } from "../avatax/avatax-config";
|
import { obfuscateAvataxInstances } from "../avatax/avatax-config";
|
||||||
import { AvataxConfigurationService } from "../avatax/avatax-configuration.service";
|
import { AvataxConfigurationService } from "../avatax/avatax-configuration.service";
|
||||||
import { obfuscateTaxJarInstances } from "../taxjar/taxjar-config";
|
import { obfuscateTaxJarInstances } from "../taxjar/taxjar-config";
|
||||||
|
@ -11,7 +10,7 @@ export const TAX_PROVIDER_KEY = "tax-providers";
|
||||||
export class PublicTaxProvidersConfigurationService {
|
export class PublicTaxProvidersConfigurationService {
|
||||||
private avataxConfigurationService: AvataxConfigurationService;
|
private avataxConfigurationService: AvataxConfigurationService;
|
||||||
private taxJarConfigurationService: TaxJarConfigurationService;
|
private taxJarConfigurationService: TaxJarConfigurationService;
|
||||||
private logger: pino.Logger;
|
private logger: Logger;
|
||||||
constructor(client: Client, saleorApiUrl: string) {
|
constructor(client: Client, saleorApiUrl: string) {
|
||||||
this.avataxConfigurationService = new AvataxConfigurationService(client, saleorApiUrl);
|
this.avataxConfigurationService = new AvataxConfigurationService(client, saleorApiUrl);
|
||||||
this.taxJarConfigurationService = new TaxJarConfigurationService(client, saleorApiUrl);
|
this.taxJarConfigurationService = new TaxJarConfigurationService(client, saleorApiUrl);
|
||||||
|
|
|
@ -4,14 +4,14 @@ import {
|
||||||
OrderFulfilledSubscriptionFragment,
|
OrderFulfilledSubscriptionFragment,
|
||||||
TaxBaseFragment,
|
TaxBaseFragment,
|
||||||
} from "../../../generated/graphql";
|
} from "../../../generated/graphql";
|
||||||
import { createLogger } from "../../lib/logger";
|
import { createLogger, Logger } from "../../lib/logger";
|
||||||
import { ChannelConfig } from "../channels-configuration/channels-config";
|
import { ChannelConfig } from "../channels-configuration/channels-config";
|
||||||
import { ProviderConfig } from "../providers-configuration/providers-config";
|
import { ProviderConfig } from "../providers-configuration/providers-config";
|
||||||
import { AvataxWebhookService } from "../avatax/avatax-webhook.service";
|
import { AvataxWebhookService } from "../avatax/avatax-webhook.service";
|
||||||
import { TaxJarWebhookService } from "../taxjar/taxjar-webhook.service";
|
import { TaxJarWebhookService } from "../taxjar/taxjar-webhook.service";
|
||||||
import { ProviderWebhookService } from "./tax-provider-webhook";
|
import { ProviderWebhookService } from "./tax-provider-webhook";
|
||||||
import { TaxProviderError } from "./tax-provider-error";
|
import { TaxProviderError } from "./tax-provider-error";
|
||||||
import pino from "pino";
|
|
||||||
import { getAppConfig } from "../app/get-app-config";
|
import { getAppConfig } from "../app/get-app-config";
|
||||||
|
|
||||||
type ActiveTaxProviderResult = { ok: true; data: ActiveTaxProvider } | { ok: false; error: string };
|
type ActiveTaxProviderResult = { ok: true; data: ActiveTaxProvider } | { ok: false; error: string };
|
||||||
|
@ -63,7 +63,7 @@ export function getActiveTaxProvider(
|
||||||
// todo: refactor to a factory
|
// todo: refactor to a factory
|
||||||
export class ActiveTaxProvider implements ProviderWebhookService {
|
export class ActiveTaxProvider implements ProviderWebhookService {
|
||||||
private client: ProviderWebhookService;
|
private client: ProviderWebhookService;
|
||||||
private logger: pino.Logger;
|
private logger: Logger;
|
||||||
private channel: ChannelConfig;
|
private channel: ChannelConfig;
|
||||||
|
|
||||||
constructor(providerInstance: ProviderConfig, channelConfig: ChannelConfig) {
|
constructor(providerInstance: ProviderConfig, channelConfig: ChannelConfig) {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import pino from "pino";
|
|
||||||
import TaxJar from "taxjar";
|
import TaxJar from "taxjar";
|
||||||
import { AddressParams, Config, CreateOrderParams, TaxParams } from "taxjar/dist/util/types";
|
import { AddressParams, Config, CreateOrderParams, TaxParams } from "taxjar/dist/util/types";
|
||||||
import { createLogger } from "../../lib/logger";
|
import { createLogger, Logger } from "../../lib/logger";
|
||||||
import { TaxJarConfig } from "./taxjar-config";
|
import { TaxJarConfig } from "./taxjar-config";
|
||||||
|
|
||||||
const createTaxJarSettings = (config: TaxJarConfig): Config => {
|
const createTaxJarSettings = (config: TaxJarConfig): Config => {
|
||||||
|
@ -27,7 +26,7 @@ export type ValidateAddressArgs = {
|
||||||
|
|
||||||
export class TaxJarClient {
|
export class TaxJarClient {
|
||||||
private client: TaxJar;
|
private client: TaxJar;
|
||||||
private logger: pino.Logger;
|
private logger: Logger;
|
||||||
|
|
||||||
constructor(providerConfig: TaxJarConfig) {
|
constructor(providerConfig: TaxJarConfig) {
|
||||||
this.logger = createLogger({ service: "TaxJarClient" });
|
this.logger = createLogger({ service: "TaxJarClient" });
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { logger as pinoLogger } from "../../lib/logger";
|
import { createLogger } from "../../lib/logger";
|
||||||
import { isObfuscated } from "../../lib/utils";
|
import { isObfuscated } from "../../lib/utils";
|
||||||
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
import { protectedClientProcedure } from "../trpc/protected-client-procedure";
|
||||||
import { router } from "../trpc/trpc-server";
|
import { router } from "../trpc/trpc-server";
|
||||||
|
@ -32,7 +32,7 @@ const postInputSchema = z.object({
|
||||||
|
|
||||||
export const taxjarConfigurationRouter = router({
|
export const taxjarConfigurationRouter = router({
|
||||||
get: protectedClientProcedure.input(getInputSchema).query(async ({ ctx, input }) => {
|
get: protectedClientProcedure.input(getInputSchema).query(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
saleorApiUrl: ctx.saleorApiUrl,
|
saleorApiUrl: ctx.saleorApiUrl,
|
||||||
procedure: "taxjarConfigurationRouter.get",
|
procedure: "taxjarConfigurationRouter.get",
|
||||||
});
|
});
|
||||||
|
@ -49,7 +49,7 @@ export const taxjarConfigurationRouter = router({
|
||||||
return { ...result, config: obfuscateTaxJarConfig(result.config) };
|
return { ...result, config: obfuscateTaxJarConfig(result.config) };
|
||||||
}),
|
}),
|
||||||
post: protectedClientProcedure.input(postInputSchema).mutation(async ({ ctx, input }) => {
|
post: protectedClientProcedure.input(postInputSchema).mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
saleorApiUrl: ctx.saleorApiUrl,
|
saleorApiUrl: ctx.saleorApiUrl,
|
||||||
procedure: "taxjarConfigurationRouter.post",
|
procedure: "taxjarConfigurationRouter.post",
|
||||||
});
|
});
|
||||||
|
@ -66,7 +66,7 @@ export const taxjarConfigurationRouter = router({
|
||||||
return result;
|
return result;
|
||||||
}),
|
}),
|
||||||
delete: protectedClientProcedure.input(deleteInputSchema).mutation(async ({ ctx, input }) => {
|
delete: protectedClientProcedure.input(deleteInputSchema).mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
saleorApiUrl: ctx.saleorApiUrl,
|
saleorApiUrl: ctx.saleorApiUrl,
|
||||||
procedure: "taxjarConfigurationRouter.delete",
|
procedure: "taxjarConfigurationRouter.delete",
|
||||||
});
|
});
|
||||||
|
@ -83,7 +83,7 @@ export const taxjarConfigurationRouter = router({
|
||||||
return result;
|
return result;
|
||||||
}),
|
}),
|
||||||
patch: protectedClientProcedure.input(patchInputSchema).mutation(async ({ ctx, input }) => {
|
patch: protectedClientProcedure.input(patchInputSchema).mutation(async ({ ctx, input }) => {
|
||||||
const logger = pinoLogger.child({
|
const logger = createLogger({
|
||||||
saleorApiUrl: ctx.saleorApiUrl,
|
saleorApiUrl: ctx.saleorApiUrl,
|
||||||
procedure: "taxjarConfigurationRouter.patch",
|
procedure: "taxjarConfigurationRouter.patch",
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import pino from "pino";
|
|
||||||
import { Client } from "urql";
|
import { Client } from "urql";
|
||||||
import { createLogger } from "../../lib/logger";
|
import { createLogger, Logger } from "../../lib/logger";
|
||||||
import { createSettingsManager } from "../app/metadata-manager";
|
import { createSettingsManager } from "../app/metadata-manager";
|
||||||
import { CrudSettingsManager } from "../crud-settings/crud-settings.service";
|
import { CrudSettingsManager } from "../crud-settings/crud-settings.service";
|
||||||
import { providersSchema } from "../providers-configuration/providers-config";
|
import { providersSchema } from "../providers-configuration/providers-config";
|
||||||
|
@ -12,7 +11,7 @@ const getSchema = taxJarInstanceConfigSchema;
|
||||||
|
|
||||||
export class TaxJarConfigurationService {
|
export class TaxJarConfigurationService {
|
||||||
private crudSettingsManager: CrudSettingsManager;
|
private crudSettingsManager: CrudSettingsManager;
|
||||||
private logger: pino.Logger;
|
private logger: Logger;
|
||||||
constructor(client: Client, saleorApiUrl: string) {
|
constructor(client: Client, saleorApiUrl: string) {
|
||||||
const settingsManager = createSettingsManager(client);
|
const settingsManager = createSettingsManager(client);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import pino from "pino";
|
|
||||||
import { OrderCreatedSubscriptionFragment, TaxBaseFragment } from "../../../generated/graphql";
|
import { OrderCreatedSubscriptionFragment, TaxBaseFragment } from "../../../generated/graphql";
|
||||||
import { createLogger } from "../../lib/logger";
|
import { createLogger, Logger } from "../../lib/logger";
|
||||||
import { ChannelConfig } from "../channels-configuration/channels-config";
|
import { ChannelConfig } from "../channels-configuration/channels-config";
|
||||||
import { ProviderWebhookService } from "../taxes/tax-provider-webhook";
|
import { ProviderWebhookService } from "../taxes/tax-provider-webhook";
|
||||||
import { TaxJarClient } from "./taxjar-client";
|
import { TaxJarClient } from "./taxjar-client";
|
||||||
|
@ -10,7 +9,7 @@ import { taxJarOrderCreatedMaps } from "./maps/taxjar-order-created-map";
|
||||||
|
|
||||||
export class TaxJarWebhookService implements ProviderWebhookService {
|
export class TaxJarWebhookService implements ProviderWebhookService {
|
||||||
client: TaxJarClient;
|
client: TaxJarClient;
|
||||||
private logger: pino.Logger;
|
private logger: Logger;
|
||||||
|
|
||||||
constructor(config: TaxJarConfig) {
|
constructor(config: TaxJarConfig) {
|
||||||
const avataxClient = new TaxJarClient(config);
|
const avataxClient = new TaxJarClient(config);
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@7.29.1",
|
"packageManager": "pnpm@8.2.0",
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.{js,ts,tsx}": "eslint --cache --fix",
|
"*.{js,ts,tsx}": "eslint --cache --fix",
|
||||||
"*.{ts,tsx,md}": "prettier --write"
|
"*.{ts,tsx,md}": "prettier --write"
|
||||||
|
|
|
@ -2,3 +2,4 @@ export * from "./src/is-in-iframe";
|
||||||
export * from "./src/macaw-theme-provider/macaw-theme-provider";
|
export * from "./src/macaw-theme-provider/macaw-theme-provider";
|
||||||
export * from "./src/no-ssr-wrapper";
|
export * from "./src/no-ssr-wrapper";
|
||||||
export * from "./src/use-dashboard-notification";
|
export * from "./src/use-dashboard-notification";
|
||||||
|
export * from "./src/logger";
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
{
|
{
|
||||||
"name": "@saleor/apps-shared",
|
"name": "@saleor/apps-shared",
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
|
"dependencies": {
|
||||||
|
"pino": "^8.8.0",
|
||||||
|
"pino-pretty": "^9.1.1"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@material-ui/core": "^4.12.4",
|
"@material-ui/core": "^4.12.4",
|
||||||
"@material-ui/icons": "^4.11.3",
|
"@material-ui/icons": "^4.11.3",
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue