diff --git a/README.md b/README.md
index a1461ad7..194efd88 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,8 @@
SDK for building [Saleor Apps](https://github.com/saleor/apps).
+Supports Saleor version 3.20+
+
[](https://www.npmjs.com/package/@saleor/app-sdk)
@@ -15,12 +17,6 @@ SDK for building [Saleor Apps](https://github.com/saleor/apps).
-## 🚨 Alpha phase
-
-App SDK is in the early stage at the moment. Every API below 1.x.x release is likely to change.
-
-Feel free to play with SDK and move its code directly to your app.
-
## Release flow
- The `main` branch is a current, latest branch.
diff --git a/package.json b/package.json
index 80c1243b..6704a4ad 100644
--- a/package.json
+++ b/package.json
@@ -84,6 +84,7 @@
"typescript": "4.9.5",
"vi-fetch": "^0.8.0",
"vite": "6.0.11 ",
+ "vite-tsconfig-paths": "^5.1.4",
"vitest": "3.0.4"
},
"peerDependenciesMeta": {
@@ -150,6 +151,11 @@
"import": "./handlers/next/index.mjs",
"require": "./handlers/next/index.js"
},
+ "./handlers/shared": {
+ "types": "./handlers/shared/index.d.ts",
+ "import": "./handlers/shared/index.mjs",
+ "require": "./handlers/shared/index.js"
+ },
"./saleor-app": {
"types": "./saleor-app.d.ts",
"import": "./saleor-app.mjs",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 43b995d9..d904039f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -147,6 +147,9 @@ importers:
vite:
specifier: '6.0.11 '
version: 6.0.11(@types/node@18.7.15)
+ vite-tsconfig-paths:
+ specifier: ^5.1.4
+ version: 5.1.4(typescript@4.9.5)(vite@6.0.11(@types/node@18.7.15))
vitest:
specifier: 3.0.4
version: 3.0.4(@types/debug@4.1.7)(@types/node@18.7.15)(jsdom@20.0.3)
@@ -3324,6 +3327,16 @@ packages:
ts-interface-checker@0.1.13:
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
+ tsconfck@3.1.4:
+ resolution: {integrity: sha512-kdqWFGVJqe+KGYvlSO9NIaWn9jT1Ny4oKVzAJsKii5eoE9snzTJzL4+MMVOMn+fikWGFmKEylcXL710V/kIPJQ==}
+ engines: {node: ^18 || >=20}
+ hasBin: true
+ peerDependencies:
+ typescript: ^5.0.0
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
tsconfig-paths@3.14.1:
resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==}
@@ -3449,6 +3462,14 @@ packages:
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
hasBin: true
+ vite-tsconfig-paths@5.1.4:
+ resolution: {integrity: sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==}
+ peerDependencies:
+ vite: '*'
+ peerDependenciesMeta:
+ vite:
+ optional: true
+
vite@6.0.11:
resolution: {integrity: sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
@@ -6863,6 +6884,10 @@ snapshots:
ts-interface-checker@0.1.13: {}
+ tsconfck@3.1.4(typescript@4.9.5):
+ optionalDependencies:
+ typescript: 4.9.5
+
tsconfig-paths@3.14.1:
dependencies:
'@types/json5': 0.0.29
@@ -7006,6 +7031,17 @@ snapshots:
- tsx
- yaml
+ vite-tsconfig-paths@5.1.4(typescript@4.9.5)(vite@6.0.11(@types/node@18.7.15)):
+ dependencies:
+ debug: 4.3.4
+ globrex: 0.1.2
+ tsconfck: 3.1.4(typescript@4.9.5)
+ optionalDependencies:
+ vite: 6.0.11(@types/node@18.7.15)
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+
vite@6.0.11(@types/node@18.7.15):
dependencies:
esbuild: 0.24.2
diff --git a/src/handlers/next/create-manifest-handler.ts b/src/handlers/next/create-manifest-handler.ts
deleted file mode 100644
index aceedd6c..00000000
--- a/src/handlers/next/create-manifest-handler.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { NextApiHandler, NextApiRequest } from "next";
-
-import { createDebug } from "../../debug";
-import { getBaseUrl, getSaleorHeaders } from "../../headers";
-import { AppManifest } from "../../types";
-
-export type CreateManifestHandlerOptions = {
- manifestFactory(context: {
- appBaseUrl: string;
- request: NextApiRequest;
- /** For Saleor < 3.15 it will be null. */
- schemaVersion: number | null;
- }): AppManifest | Promise;
-};
-
-const debug = createDebug("create-manifest-handler");
-
-/**
- * Creates API handler for Next.js. Helps with Manifest creation, hides
- * implementation details if possible
- * In the future this will be extracted to separate sdk/next package
- */
-export const createManifestHandler =
- (options: CreateManifestHandlerOptions): NextApiHandler =>
- async (request, response) => {
- const { schemaVersion } = getSaleorHeaders(request.headers);
- const baseURL = getBaseUrl(request.headers);
-
- debug("Received request with schema version \"%s\" and base URL \"%s\"", schemaVersion, baseURL);
-
- try {
- const manifest = await options.manifestFactory({
- appBaseUrl: baseURL,
- request,
- schemaVersion,
- });
-
- debug("Executed manifest file");
-
- return response.status(200).json(manifest);
- } catch (e) {
- debug("Error while resolving manifest: %O", e);
-
- return response.status(500).json({
- message: "Error resolving manifest file",
- });
- }
- };
diff --git a/src/handlers/next/create-protected-handler.ts b/src/handlers/next/create-protected-handler.ts
deleted file mode 100644
index 44027670..00000000
--- a/src/handlers/next/create-protected-handler.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import { NextApiHandler, NextApiRequest, NextApiResponse } from "next";
-
-import { APL } from "../../APL";
-import { createDebug } from "../../debug";
-import { Permission } from "../../types";
-import {
- processSaleorProtectedHandler,
- ProtectedHandlerError,
- SaleorProtectedHandlerError,
-} from "./process-protected-handler";
-import { ProtectedHandlerContext } from "./protected-handler-context";
-
-const debug = createDebug("ProtectedHandler");
-
-export const ProtectedHandlerErrorCodeMap: Record = {
- OTHER: 500,
- MISSING_HOST_HEADER: 400,
- MISSING_DOMAIN_HEADER: 400,
- MISSING_API_URL_HEADER: 400,
- NOT_REGISTERED: 401,
- JWT_VERIFICATION_FAILED: 401,
- NO_APP_ID: 401,
- MISSING_AUTHORIZATION_BEARER_HEADER: 400,
-};
-
-export type NextProtectedApiHandler = (
- req: NextApiRequest,
- res: NextApiResponse,
- ctx: ProtectedHandlerContext
-) => unknown | Promise;
-
-/**
- * Wraps provided function, to ensure incoming request comes from Saleor Dashboard.
- * Also provides additional `context` object containing request properties.
- */
-export const createProtectedHandler =
- (
- handlerFn: NextProtectedApiHandler,
- apl: APL,
- requiredPermissions?: Permission[]
- ): NextApiHandler =>
- (req, res) => {
- debug("Protected handler called");
- processSaleorProtectedHandler({
- req,
- apl,
- requiredPermissions,
- })
- .then(async (context) => {
- debug("Incoming request validated. Call handlerFn");
- return handlerFn(req, res, context);
- })
- .catch((e) => {
- debug("Unexpected error during processing the request");
-
- if (e instanceof ProtectedHandlerError) {
- debug(`Validation error: ${e.message}`);
- res.status(ProtectedHandlerErrorCodeMap[e.errorType] || 400).end();
- return;
- }
- debug("Unexpected error: %O", e);
- res.status(500).end();
- });
- };
diff --git a/src/handlers/next/create-app-register-handler.test.ts b/src/handlers/platforms/next/create-app-register-handler.test.ts
similarity index 94%
rename from src/handlers/next/create-app-register-handler.test.ts
rename to src/handlers/platforms/next/create-app-register-handler.test.ts
index 23a9bd84..582cfc03 100644
--- a/src/handlers/next/create-app-register-handler.test.ts
+++ b/src/handlers/platforms/next/create-app-register-handler.test.ts
@@ -1,20 +1,20 @@
import { createMocks } from "node-mocks-http";
import { beforeEach, describe, expect, it, Mock, vi } from "vitest";
-import { APL, AuthData } from "../../APL";
-import { MockAPL } from "../../test-utils/mock-apl";
+import { APL, AuthData } from "@/APL";
+import * as fetchRemoteJwksModule from "@/fetch-remote-jwks";
+import * as getAppIdModule from "@/get-app-id";
+import { MockAPL } from "@/test-utils/mock-apl";
+
import { createAppRegisterHandler } from "./create-app-register-handler";
const mockJwksValue = "{}";
const mockAppId = "42";
-vi.mock("../../get-app-id", () => ({
- getAppId: vi.fn().mockResolvedValue("42"), // can't use var reference, due to hoisting
-}));
-
-vi.mock("../../fetch-remote-jwks", () => ({
- fetchRemoteJwks: vi.fn().mockResolvedValue("{}"), // can't use var reference, due to hoisting
-}));
+// Cannot use vi.mock on module, due to issues with alias resolution
+// in vitest vs TypeScript: https://github.com/vitest-dev/vitest/issues/3105
+vi.spyOn(fetchRemoteJwksModule, "fetchRemoteJwks").mockResolvedValue("{}");
+vi.spyOn(getAppIdModule, "getAppId").mockResolvedValue("42");
describe("create-app-register-handler", () => {
let mockApl: APL;
diff --git a/src/handlers/next/create-app-register-handler.ts b/src/handlers/platforms/next/create-app-register-handler.ts
similarity index 93%
rename from src/handlers/next/create-app-register-handler.ts
rename to src/handlers/platforms/next/create-app-register-handler.ts
index 9b930666..70f88c33 100644
--- a/src/handlers/next/create-app-register-handler.ts
+++ b/src/handlers/platforms/next/create-app-register-handler.ts
@@ -3,22 +3,18 @@ import { toNextHandler } from "retes/adapter";
import { withMethod } from "retes/middleware";
import { Response } from "retes/response";
-import { AuthData } from "../../APL";
-import { SALEOR_API_URL_HEADER } from "../../const";
-import { createDebug } from "../../debug";
-import { fetchRemoteJwks } from "../../fetch-remote-jwks";
-import { getAppId } from "../../get-app-id";
-import { withAuthTokenRequired } from "../../middleware";
-import { HasAPL } from "../../saleor-app";
-import { validateAllowSaleorUrls } from "./validate-allow-saleor-urls";
+import { AuthData } from "@/APL";
+import { SALEOR_API_URL_HEADER } from "@/const";
+import { createDebug } from "@/debug";
+import { fetchRemoteJwks } from "@/fetch-remote-jwks";
+import { getAppId } from "@/get-app-id";
+import { HookCallbackErrorParams } from "@/handlers/shared/create-app-register-handler-types";
+import { validateAllowSaleorUrls } from "@/handlers/shared/validate-allow-saleor-urls";
+import { withAuthTokenRequired } from "@/middleware";
+import { HasAPL } from "@/saleor-app";
const debug = createDebug("createAppRegisterHandler");
-type HookCallbackErrorParams = {
- status?: number;
- message?: string;
-};
-
class RegisterCallbackError extends Error {
public status = 500;
diff --git a/src/handlers/next/create-manifest-handler.test.ts b/src/handlers/platforms/next/create-manifest-handler.test.ts
similarity index 96%
rename from src/handlers/next/create-manifest-handler.test.ts
rename to src/handlers/platforms/next/create-manifest-handler.test.ts
index f9caa04b..5fe18733 100644
--- a/src/handlers/next/create-manifest-handler.test.ts
+++ b/src/handlers/platforms/next/create-manifest-handler.test.ts
@@ -1,7 +1,8 @@
import { createMocks } from "node-mocks-http";
import { describe, expect, it } from "vitest";
-import { AppManifest } from "../../types";
+import { AppManifest } from "@/types";
+
import { createManifestHandler } from "./create-manifest-handler";
describe("createManifestHandler", () => {
diff --git a/src/handlers/platforms/next/create-manifest-handler.ts b/src/handlers/platforms/next/create-manifest-handler.ts
new file mode 100644
index 00000000..fcca4c7a
--- /dev/null
+++ b/src/handlers/platforms/next/create-manifest-handler.ts
@@ -0,0 +1,48 @@
+import { NextApiHandler, NextApiRequest } from "next";
+
+import { createDebug } from "@/debug";
+import { getBaseUrl, getSaleorHeaders } from "@/headers";
+import { AppManifest } from "@/types";
+
+export type CreateManifestHandlerOptions = {
+ manifestFactory(context: {
+ appBaseUrl: string;
+ request: NextApiRequest;
+ /** For Saleor < 3.15 it will be null. */
+ schemaVersion: number | null;
+ }): AppManifest | Promise;
+};
+
+const debug = createDebug("create-manifest-handler");
+
+/**
+ * Creates API handler for Next.js. Helps with Manifest creation, hides
+ * implementation details if possible
+ * In the future this will be extracted to separate sdk/next package
+ */
+export const createManifestHandler =
+ (options: CreateManifestHandlerOptions): NextApiHandler =>
+ async (request, response) => {
+ const { schemaVersion } = getSaleorHeaders(request.headers);
+ const baseURL = getBaseUrl(request.headers);
+
+ debug("Received request with schema version \"%s\" and base URL \"%s\"", schemaVersion, baseURL);
+
+ try {
+ const manifest = await options.manifestFactory({
+ appBaseUrl: baseURL,
+ request,
+ schemaVersion,
+ });
+
+ debug("Executed manifest file");
+
+ return response.status(200).json(manifest);
+ } catch (e) {
+ debug("Error while resolving manifest: %O", e);
+
+ return response.status(500).json({
+ message: "Error resolving manifest file",
+ });
+ }
+ };
diff --git a/src/handlers/platforms/next/create-protected-handler.ts b/src/handlers/platforms/next/create-protected-handler.ts
new file mode 100644
index 00000000..6407c878
--- /dev/null
+++ b/src/handlers/platforms/next/create-protected-handler.ts
@@ -0,0 +1,54 @@
+import { NextApiHandler, NextApiRequest, NextApiResponse } from "next";
+
+import { APL } from "@/APL";
+import { createDebug } from "@/debug";
+import { ProtectedHandlerErrorCodeMap } from "@/handlers/shared/protected-handler";
+import { Permission } from "@/types";
+
+import {
+ processSaleorProtectedHandler,
+ ProtectedHandlerError,
+} from "./process-protected-handler";
+import { ProtectedHandlerContext } from "./protected-handler-context";
+
+const debug = createDebug("ProtectedHandler");
+
+export type NextProtectedApiHandler = (
+ req: NextApiRequest,
+ res: NextApiResponse,
+ ctx: ProtectedHandlerContext
+) => unknown | Promise;
+
+/**
+ * Wraps provided function, to ensure incoming request comes from Saleor Dashboard.
+ * Also provides additional `context` object containing request properties.
+ */
+export const createProtectedHandler =
+ (
+ handlerFn: NextProtectedApiHandler,
+ apl: APL,
+ requiredPermissions?: Permission[]
+ ): NextApiHandler =>
+ (req, res) => {
+ debug("Protected handler called");
+ processSaleorProtectedHandler({
+ req,
+ apl,
+ requiredPermissions,
+ })
+ .then(async (context) => {
+ debug("Incoming request validated. Call handlerFn");
+ return handlerFn(req, res, context);
+ })
+ .catch((e) => {
+ debug("Unexpected error during processing the request");
+
+ if (e instanceof ProtectedHandlerError) {
+ debug(`Validation error: ${e.message}`);
+ res.status(ProtectedHandlerErrorCodeMap[e.errorType] || 400).end();
+ return;
+ }
+ debug("Unexpected error: %O", e);
+ res.status(500).end();
+ });
+ };
diff --git a/src/handlers/next/index.ts b/src/handlers/platforms/next/index.ts
similarity index 76%
rename from src/handlers/next/index.ts
rename to src/handlers/platforms/next/index.ts
index 23ddd049..ae894354 100644
--- a/src/handlers/next/index.ts
+++ b/src/handlers/platforms/next/index.ts
@@ -6,4 +6,6 @@ export * from "./protected-handler-context";
export * from "./saleor-webhooks/saleor-async-webhook";
export * from "./saleor-webhooks/saleor-sync-webhook";
export { NextWebhookApiHandler } from "./saleor-webhooks/saleor-webhook";
-export * from "./saleor-webhooks/sync-webhook-response-builder";
+
+// Left for compatibility
+export { buildSyncWebhookResponsePayload } from "@/handlers/shared/sync-webhook-response-builder";
diff --git a/src/handlers/next/process-protected-handler.test.ts b/src/handlers/platforms/next/process-protected-handler.test.ts
similarity index 91%
rename from src/handlers/next/process-protected-handler.test.ts
rename to src/handlers/platforms/next/process-protected-handler.test.ts
index ccc68e4f..21856c33 100644
--- a/src/handlers/next/process-protected-handler.test.ts
+++ b/src/handlers/platforms/next/process-protected-handler.test.ts
@@ -2,9 +2,12 @@ import { NextApiRequest } from "next/types";
import { createMocks } from "node-mocks-http";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
-import { getAppId } from "../../get-app-id";
-import { MockAPL } from "../../test-utils/mock-apl";
-import { verifyJWT } from "../../verify-jwt";
+import * as getAppIdModule from "@/get-app-id";
+import { getAppId } from "@/get-app-id";
+import { MockAPL } from "@/test-utils/mock-apl";
+import * as verifyJWTModule from "@/verify-jwt";
+import { verifyJWT } from "@/verify-jwt";
+
import { processSaleorProtectedHandler } from "./process-protected-handler";
const validToken =
@@ -12,15 +15,8 @@ const validToken =
const validAppId = "QXBwOjI3NQ==";
-vi.mock("./../../get-app-id", () => ({
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- getAppId: vi.fn(),
-}));
-
-vi.mock("./../../verify-jwt", () => ({
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- verifyJWT: vi.fn(),
-}));
+vi.spyOn(getAppIdModule, "getAppId");
+vi.spyOn(verifyJWTModule, "verifyJWT");
describe("processSaleorProtectedHandler", () => {
let mockRequest: NextApiRequest;
diff --git a/src/handlers/next/process-protected-handler.ts b/src/handlers/platforms/next/process-protected-handler.ts
similarity index 86%
rename from src/handlers/next/process-protected-handler.ts
rename to src/handlers/platforms/next/process-protected-handler.ts
index f3f86e3c..56138b6f 100644
--- a/src/handlers/next/process-protected-handler.ts
+++ b/src/handlers/platforms/next/process-protected-handler.ts
@@ -1,27 +1,19 @@
import { SpanKind, SpanStatusCode } from "@opentelemetry/api";
import { NextApiRequest } from "next";
-import { APL } from "../../APL";
-import { createDebug } from "../../debug";
-import { getBaseUrl, getSaleorHeaders } from "../../headers";
-import { getOtelTracer } from "../../open-telemetry";
-import { Permission } from "../../types";
-import { extractUserFromJwt } from "../../util/extract-user-from-jwt";
-import { verifyJWT } from "../../verify-jwt";
+import { APL } from "@/APL";
+import { createDebug } from "@/debug";
+import { SaleorProtectedHandlerError } from "@/handlers/shared/protected-handler";
+import { getBaseUrl, getSaleorHeaders } from "@/headers";
+import { getOtelTracer } from "@/open-telemetry";
+import { Permission } from "@/types";
+import { extractUserFromJwt } from "@/util/extract-user-from-jwt";
+import { verifyJWT } from "@/verify-jwt";
+
import { ProtectedHandlerContext } from "./protected-handler-context";
const debug = createDebug("processProtectedHandler");
-export type SaleorProtectedHandlerError =
- | "OTHER"
- | "MISSING_HOST_HEADER"
- | "MISSING_DOMAIN_HEADER"
- | "MISSING_API_URL_HEADER"
- | "MISSING_AUTHORIZATION_BEARER_HEADER"
- | "NOT_REGISTERED"
- | "JWT_VERIFICATION_FAILED"
- | "NO_APP_ID";
-
export class ProtectedHandlerError extends Error {
errorType: SaleorProtectedHandlerError = "OTHER";
diff --git a/src/handlers/next/protected-handler-context.ts b/src/handlers/platforms/next/protected-handler-context.ts
similarity index 50%
rename from src/handlers/next/protected-handler-context.ts
rename to src/handlers/platforms/next/protected-handler-context.ts
index 71bb42d3..38031889 100644
--- a/src/handlers/next/protected-handler-context.ts
+++ b/src/handlers/platforms/next/protected-handler-context.ts
@@ -1,5 +1,5 @@
-import { AuthData } from "../../APL";
-import { TokenUserPayload } from "../../util/extract-user-from-jwt";
+import { AuthData } from "@/APL";
+import { TokenUserPayload } from "@/util/extract-user-from-jwt";
export type ProtectedHandlerContext = {
baseUrl: string;
diff --git a/src/handlers/next/readme.md b/src/handlers/platforms/next/readme.md
similarity index 100%
rename from src/handlers/next/readme.md
rename to src/handlers/platforms/next/readme.md
diff --git a/src/handlers/next/saleor-webhooks/process-saleor-webhook.test.ts b/src/handlers/platforms/next/saleor-webhooks/process-saleor-webhook.test.ts
similarity index 97%
rename from src/handlers/next/saleor-webhooks/process-saleor-webhook.test.ts
rename to src/handlers/platforms/next/saleor-webhooks/process-saleor-webhook.test.ts
index a1dd35ff..4ca484b4 100644
--- a/src/handlers/next/saleor-webhooks/process-saleor-webhook.test.ts
+++ b/src/handlers/platforms/next/saleor-webhooks/process-saleor-webhook.test.ts
@@ -3,10 +3,11 @@ import { createMocks } from "node-mocks-http";
import rawBody from "raw-body";
import { beforeEach, describe, expect, it, vi } from "vitest";
-import { MockAPL } from "../../../test-utils/mock-apl";
+import { MockAPL } from "@/test-utils/mock-apl";
+
import { processSaleorWebhook } from "./process-saleor-webhook";
-vi.mock("../../../verify-signature", () => ({
+vi.mock("@/verify-signature", () => ({
// eslint-disable-next-line @typescript-eslint/no-unused-vars
verifySignature: vi.fn((domain, signature) => {
if (signature !== "mocked_signature") {
@@ -137,7 +138,7 @@ describe("processAsyncSaleorWebhook", () => {
it("Throw error on wrong signature", async () => {
mockRequest.headers["saleor-signature"] = "wrong_signature";
- vi.mock("../../../fetch-remote-jwks", () => ({
+ vi.mock("@/fetch-remote-jwks", () => ({
fetchRemoteJwks: vi.fn(async () => "wrong_signature"),
}));
diff --git a/src/handlers/next/saleor-webhooks/process-saleor-webhook.ts b/src/handlers/platforms/next/saleor-webhooks/process-saleor-webhook.ts
similarity index 81%
rename from src/handlers/next/saleor-webhooks/process-saleor-webhook.ts
rename to src/handlers/platforms/next/saleor-webhooks/process-saleor-webhook.ts
index 74f20d10..80a91289 100644
--- a/src/handlers/next/saleor-webhooks/process-saleor-webhook.ts
+++ b/src/handlers/platforms/next/saleor-webhooks/process-saleor-webhook.ts
@@ -2,53 +2,17 @@ import { SpanKind, SpanStatusCode } from "@opentelemetry/api";
import { NextApiRequest } from "next";
import getRawBody from "raw-body";
-import { APL } from "../../../APL";
-import { AuthData } from "../../../APL/apl";
-import { createDebug } from "../../../debug";
-import { fetchRemoteJwks } from "../../../fetch-remote-jwks";
-import { getBaseUrl, getSaleorHeaders } from "../../../headers";
-import { getOtelTracer } from "../../../open-telemetry";
-import { parseSchemaVersion } from "../../../util";
-import { verifySignatureWithJwks } from "../../../verify-signature";
+import { APL } from "@/APL";
+import { createDebug } from "@/debug";
+import { fetchRemoteJwks } from "@/fetch-remote-jwks";
+import { WebhookContext, WebhookError } from "@/handlers/shared/saleor-webhook";
+import { getBaseUrl, getSaleorHeaders } from "@/headers";
+import { getOtelTracer } from "@/open-telemetry";
+import { parseSchemaVersion } from "@/util";
+import { verifySignatureWithJwks } from "@/verify-signature";
const debug = createDebug("processSaleorWebhook");
-export type SaleorWebhookError =
- | "OTHER"
- | "MISSING_HOST_HEADER"
- | "MISSING_API_URL_HEADER"
- | "MISSING_EVENT_HEADER"
- | "MISSING_PAYLOAD_HEADER"
- | "MISSING_SIGNATURE_HEADER"
- | "MISSING_REQUEST_BODY"
- | "WRONG_EVENT"
- | "NOT_REGISTERED"
- | "SIGNATURE_VERIFICATION_FAILED"
- | "WRONG_METHOD"
- | "CANT_BE_PARSED"
- | "CONFIGURATION_ERROR";
-
-export class WebhookError extends Error {
- errorType: SaleorWebhookError = "OTHER";
-
- constructor(message: string, errorType: SaleorWebhookError) {
- super(message);
- if (errorType) {
- this.errorType = errorType;
- }
- Object.setPrototypeOf(this, WebhookError.prototype);
- }
-}
-
-export type WebhookContext = {
- baseUrl: string;
- event: string;
- payload: T;
- authData: AuthData;
- /** For Saleor < 3.15 it will be null. */
- schemaVersion: number | null;
-};
-
interface ProcessSaleorWebhookArgs {
req: NextApiRequest;
apl: APL;
diff --git a/src/handlers/next/saleor-webhooks/saleor-async-webhook.test.ts b/src/handlers/platforms/next/saleor-webhooks/saleor-async-webhook.test.ts
similarity index 98%
rename from src/handlers/next/saleor-webhooks/saleor-async-webhook.test.ts
rename to src/handlers/platforms/next/saleor-webhooks/saleor-async-webhook.test.ts
index 24930540..0e1d785e 100644
--- a/src/handlers/next/saleor-webhooks/saleor-async-webhook.test.ts
+++ b/src/handlers/platforms/next/saleor-webhooks/saleor-async-webhook.test.ts
@@ -2,8 +2,9 @@ import { ASTNode } from "graphql";
import { createMocks } from "node-mocks-http";
import { afterEach, describe, expect, it, vi } from "vitest";
-import { MockAPL } from "../../../test-utils/mock-apl";
-import { AsyncWebhookEventType } from "../../../types";
+import { MockAPL } from "@/test-utils/mock-apl";
+import { AsyncWebhookEventType } from "@/types";
+
import { processSaleorWebhook } from "./process-saleor-webhook";
import { SaleorAsyncWebhook } from "./saleor-async-webhook";
import { NextWebhookApiHandler, WebhookConfig } from "./saleor-webhook";
diff --git a/src/handlers/next/saleor-webhooks/saleor-async-webhook.ts b/src/handlers/platforms/next/saleor-webhooks/saleor-async-webhook.ts
similarity index 96%
rename from src/handlers/next/saleor-webhooks/saleor-async-webhook.ts
rename to src/handlers/platforms/next/saleor-webhooks/saleor-async-webhook.ts
index 8efa7a26..327a87ce 100644
--- a/src/handlers/next/saleor-webhooks/saleor-async-webhook.ts
+++ b/src/handlers/platforms/next/saleor-webhooks/saleor-async-webhook.ts
@@ -1,7 +1,8 @@
import { ASTNode } from "graphql/index";
import { NextApiHandler } from "next";
-import { AsyncWebhookEventType } from "../../../types";
+import { AsyncWebhookEventType } from "@/types";
+
import { NextWebhookApiHandler, SaleorWebhook, WebhookConfig } from "./saleor-webhook";
export class SaleorAsyncWebhook extends SaleorWebhook {
diff --git a/src/handlers/next/saleor-webhooks/saleor-sync-webhook.test.ts b/src/handlers/platforms/next/saleor-webhooks/saleor-sync-webhook.test.ts
similarity index 97%
rename from src/handlers/next/saleor-webhooks/saleor-sync-webhook.test.ts
rename to src/handlers/platforms/next/saleor-webhooks/saleor-sync-webhook.test.ts
index 282c39e4..d80f36ec 100644
--- a/src/handlers/next/saleor-webhooks/saleor-sync-webhook.test.ts
+++ b/src/handlers/platforms/next/saleor-webhooks/saleor-sync-webhook.test.ts
@@ -1,7 +1,8 @@
import { createMocks } from "node-mocks-http";
import { describe, expect, it, vi } from "vitest";
-import { MockAPL } from "../../../test-utils/mock-apl";
+import { MockAPL } from "@/test-utils/mock-apl";
+
import { processSaleorWebhook } from "./process-saleor-webhook";
import { SaleorSyncWebhook } from "./saleor-sync-webhook";
diff --git a/src/handlers/next/saleor-webhooks/saleor-sync-webhook.ts b/src/handlers/platforms/next/saleor-webhooks/saleor-sync-webhook.ts
similarity index 86%
rename from src/handlers/next/saleor-webhooks/saleor-sync-webhook.ts
rename to src/handlers/platforms/next/saleor-webhooks/saleor-sync-webhook.ts
index 3ab6b63f..9aaa216b 100644
--- a/src/handlers/next/saleor-webhooks/saleor-sync-webhook.ts
+++ b/src/handlers/platforms/next/saleor-webhooks/saleor-sync-webhook.ts
@@ -1,8 +1,9 @@
import { NextApiHandler } from "next";
-import { SyncWebhookEventType } from "../../../types";
+import { buildSyncWebhookResponsePayload } from "@/handlers/shared/sync-webhook-response-builder";
+import { SyncWebhookEventType } from "@/types";
+
import { NextWebhookApiHandler, SaleorWebhook, WebhookConfig } from "./saleor-webhook";
-import { buildSyncWebhookResponsePayload } from "./sync-webhook-response-builder";
type InjectedContext = {
buildResponse: typeof buildSyncWebhookResponsePayload;
diff --git a/src/handlers/next/saleor-webhooks/saleor-webhook.ts b/src/handlers/platforms/next/saleor-webhooks/saleor-webhook.ts
similarity index 88%
rename from src/handlers/next/saleor-webhooks/saleor-webhook.ts
rename to src/handlers/platforms/next/saleor-webhooks/saleor-webhook.ts
index 1a18527b..5a6a6fda 100644
--- a/src/handlers/next/saleor-webhooks/saleor-webhook.ts
+++ b/src/handlers/platforms/next/saleor-webhooks/saleor-webhook.ts
@@ -1,15 +1,14 @@
import { ASTNode } from "graphql";
import { NextApiHandler, NextApiRequest, NextApiResponse } from "next";
-import { APL } from "../../../APL";
-import { createDebug } from "../../../debug";
-import { gqlAstToString } from "../../../gql-ast-to-string";
-import { AsyncWebhookEventType, SyncWebhookEventType, WebhookManifest } from "../../../types";
+import { APL } from "@/APL";
+import { createDebug } from "@/debug";
+import { gqlAstToString } from "@/gql-ast-to-string";
+import { WebhookContext, WebhookError, WebhookErrorCodeMap } from "@/handlers/shared/saleor-webhook";
+import { AsyncWebhookEventType, SyncWebhookEventType, WebhookManifest } from "@/types";
+
import {
processSaleorWebhook,
- SaleorWebhookError,
- WebhookContext,
- WebhookError,
} from "./process-saleor-webhook";
const debug = createDebug("SaleorWebhook");
@@ -36,22 +35,6 @@ export interface WebhookConfig = {
- OTHER: 500,
- MISSING_HOST_HEADER: 400,
- MISSING_API_URL_HEADER: 400,
- MISSING_EVENT_HEADER: 400,
- MISSING_PAYLOAD_HEADER: 400,
- MISSING_SIGNATURE_HEADER: 400,
- MISSING_REQUEST_BODY: 400,
- WRONG_EVENT: 400,
- NOT_REGISTERED: 401,
- SIGNATURE_VERIFICATION_FAILED: 401,
- WRONG_METHOD: 405,
- CANT_BE_PARSED: 400,
- CONFIGURATION_ERROR: 500,
-};
-
export type NextWebhookApiHandler = (
req: NextApiRequest,
res: NextApiResponse,
diff --git a/src/handlers/shared/create-app-register-handler-types.ts b/src/handlers/shared/create-app-register-handler-types.ts
new file mode 100644
index 00000000..a35d369d
--- /dev/null
+++ b/src/handlers/shared/create-app-register-handler-types.ts
@@ -0,0 +1,63 @@
+import { AuthData } from "../../APL";
+import { HasAPL } from "../../saleor-app";
+
+export type HookCallbackErrorParams = {
+ status?: number;
+ message?: string;
+};
+
+export type CallbackErrorHandler = (params: HookCallbackErrorParams) => never;
+
+export type GenericCreateAppRegisterHandlerOptions = HasAPL & {
+ /**
+ * Protect app from being registered in Saleor other than specific.
+ * By default, allow everything.
+ *
+ * Provide array of either a full Saleor API URL (eg. my-shop.saleor.cloud/graphql/)
+ * or a function that receives a full Saleor API URL ad returns true/false.
+ */
+ allowedSaleorUrls?: Array boolean)>;
+ /**
+ * Run right after Saleor calls this endpoint
+ */
+ onRequestStart?(
+ request: RequestType,
+ context: {
+ authToken?: string;
+ saleorDomain?: string;
+ saleorApiUrl?: string;
+ respondWithError: CallbackErrorHandler;
+ }
+ ): Promise;
+ /**
+ * Run after all security checks
+ */
+ onRequestVerified?(
+ request: RequestType,
+ context: {
+ authData: AuthData;
+ respondWithError: CallbackErrorHandler;
+ }
+ ): Promise;
+ /**
+ * Run after APL successfully AuthData, assuming that APL.set will reject a Promise in case of error
+ */
+ onAuthAplSaved?(
+ request: RequestType,
+ context: {
+ authData: AuthData;
+ respondWithError: CallbackErrorHandler;
+ }
+ ): Promise;
+ /**
+ * Run after APL fails to set AuthData
+ */
+ onAplSetFailed?(
+ request: RequestType,
+ context: {
+ authData: AuthData;
+ error: unknown;
+ respondWithError: CallbackErrorHandler;
+ }
+ ): Promise;
+};
diff --git a/src/handlers/shared/index.ts b/src/handlers/shared/index.ts
new file mode 100644
index 00000000..35973296
--- /dev/null
+++ b/src/handlers/shared/index.ts
@@ -0,0 +1,5 @@
+export * from "./create-app-register-handler-types";
+export * from "./protected-handler";
+export * from "./saleor-webhook";
+export * from "./sync-webhook-response-builder";
+export * from "./validate-allow-saleor-urls"
diff --git a/src/handlers/shared/protected-handler.ts b/src/handlers/shared/protected-handler.ts
new file mode 100644
index 00000000..5d439081
--- /dev/null
+++ b/src/handlers/shared/protected-handler.ts
@@ -0,0 +1,18 @@
+export type SaleorProtectedHandlerError =
+ | "OTHER"
+ | "MISSING_HOST_HEADER"
+ | "MISSING_API_URL_HEADER"
+ | "MISSING_AUTHORIZATION_BEARER_HEADER"
+ | "NOT_REGISTERED"
+ | "JWT_VERIFICATION_FAILED"
+ | "NO_APP_ID";
+
+export const ProtectedHandlerErrorCodeMap: Record = {
+ OTHER: 500,
+ MISSING_HOST_HEADER: 400,
+ MISSING_API_URL_HEADER: 400,
+ NOT_REGISTERED: 401,
+ JWT_VERIFICATION_FAILED: 401,
+ NO_APP_ID: 401,
+ MISSING_AUTHORIZATION_BEARER_HEADER: 400,
+};
diff --git a/src/handlers/shared/saleor-webhook.ts b/src/handlers/shared/saleor-webhook.ts
new file mode 100644
index 00000000..fe524908
--- /dev/null
+++ b/src/handlers/shared/saleor-webhook.ts
@@ -0,0 +1,56 @@
+import { AuthData } from "../../APL";
+
+export const WebhookErrorCodeMap: Record = {
+ OTHER: 500,
+ MISSING_HOST_HEADER: 400,
+ MISSING_DOMAIN_HEADER: 400,
+ MISSING_API_URL_HEADER: 400,
+ MISSING_EVENT_HEADER: 400,
+ MISSING_PAYLOAD_HEADER: 400,
+ MISSING_SIGNATURE_HEADER: 400,
+ MISSING_REQUEST_BODY: 400,
+ WRONG_EVENT: 400,
+ NOT_REGISTERED: 401,
+ SIGNATURE_VERIFICATION_FAILED: 401,
+ WRONG_METHOD: 405,
+ CANT_BE_PARSED: 400,
+ CONFIGURATION_ERROR: 500,
+};
+
+export type SaleorWebhookError =
+ | "OTHER"
+ | "MISSING_HOST_HEADER"
+ | "MISSING_DOMAIN_HEADER"
+ | "MISSING_API_URL_HEADER"
+ | "MISSING_EVENT_HEADER"
+ | "MISSING_PAYLOAD_HEADER"
+ | "MISSING_SIGNATURE_HEADER"
+ | "MISSING_REQUEST_BODY"
+ | "WRONG_EVENT"
+ | "NOT_REGISTERED"
+ | "SIGNATURE_VERIFICATION_FAILED"
+ | "WRONG_METHOD"
+ | "CANT_BE_PARSED"
+ | "CONFIGURATION_ERROR";
+
+export class WebhookError extends Error {
+ errorType: SaleorWebhookError = "OTHER";
+
+ constructor(message: string, errorType: SaleorWebhookError) {
+ super(message);
+ if (errorType) {
+ this.errorType = errorType;
+ }
+ Object.setPrototypeOf(this, WebhookError.prototype);
+ }
+}
+
+export type WebhookContext = {
+ baseUrl: string;
+ event: string;
+ payload: TPayload;
+ authData: AuthData;
+ // TODO: Make this required
+ /** Added in Saleor 3.15 */
+ schemaVersion: number | null;
+};
diff --git a/src/handlers/next/saleor-webhooks/sync-webhook-response-builder.ts b/src/handlers/shared/sync-webhook-response-builder.ts
similarity index 98%
rename from src/handlers/next/saleor-webhooks/sync-webhook-response-builder.ts
rename to src/handlers/shared/sync-webhook-response-builder.ts
index 952e0cb7..9b690661 100644
--- a/src/handlers/next/saleor-webhooks/sync-webhook-response-builder.ts
+++ b/src/handlers/shared/sync-webhook-response-builder.ts
@@ -1,4 +1,4 @@
-import { SyncWebhookEventType } from "../../../types";
+import { SyncWebhookEventType } from "../../types";
export type SyncWebhookResponsesMap = {
CHECKOUT_CALCULATE_TAXES: {
diff --git a/src/handlers/next/validate-allow-saleor-urls.test.ts b/src/handlers/shared/validate-allow-saleor-urls.test.ts
similarity index 100%
rename from src/handlers/next/validate-allow-saleor-urls.test.ts
rename to src/handlers/shared/validate-allow-saleor-urls.test.ts
diff --git a/src/handlers/next/validate-allow-saleor-urls.ts b/src/handlers/shared/validate-allow-saleor-urls.ts
similarity index 82%
rename from src/handlers/next/validate-allow-saleor-urls.ts
rename to src/handlers/shared/validate-allow-saleor-urls.ts
index 9b7c39c5..58a91fc4 100644
--- a/src/handlers/next/validate-allow-saleor-urls.ts
+++ b/src/handlers/shared/validate-allow-saleor-urls.ts
@@ -1,4 +1,4 @@
-import { CreateAppRegisterHandlerOptions } from "./create-app-register-handler";
+import { CreateAppRegisterHandlerOptions } from "../platforms/next/create-app-register-handler";
export const validateAllowSaleorUrls = (
saleorApiUrl: string,
diff --git a/tsconfig.json b/tsconfig.json
index 504417b7..517c62b1 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,106 +1,24 @@
{
+ "$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
- /* Visit https://aka.ms/tsconfig to read more about this file */
-
- /* Projects */
- // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
- // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
- // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
- // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
- // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
- // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
-
- /* Language and Environment */
- "target": "ES2021" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
+ "target": "ES2021",
"lib": [
"dom",
"ES2021"
- ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */,
- "jsx": "react" /* Specify what JSX code is generated. */,
- // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
- // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
- // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
- // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
- // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
- // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
- // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
- // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
- // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
-
- /* Modules */
- "module": "commonjs" /* Specify what module code is generated. */,
- // "rootDir": "./", /* Specify the root folder within your source files. */
- // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
- // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
- // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
- // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
- // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
- // "types": [], /* Specify type package names to be included without being referenced in a source file. */
- // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
- // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
- "resolveJsonModule": true /* Enable importing .json files. */,
- // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
-
- /* JavaScript Support */
- // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
- // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
- // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
-
- /* Emit */
- // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
- // "declarationMap": true, /* Create sourcemaps for d.ts files. */
- // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
- // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
- // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
- // "outDir": "./", /* Specify an output folder for all emitted files. */
- // "removeComments": true, /* Disable emitting comments. */
- // "noEmit": true, /* Disable emitting files from a compilation. */
- // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
- // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
- // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
- // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
- // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
- // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
- // "newLine": "crlf", /* Set the newline character for emitting files. */
- // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
- // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
- // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
- // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
- // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
- // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
-
- /* Interop Constraints */
- // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
- // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
- "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
- // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
- "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
-
- /* Type Checking */
- "strict": true /* Enable all strict type-checking options. */,
- // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
- // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
- // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
- // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
- // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
- // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
- // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
- // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
- // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
- // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
- // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
- // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
- // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
- // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
- // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
- // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
- // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
- // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
-
- /* Completeness */
- // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
- "skipLibCheck": true /* Skip type checking all .d.ts files. */
+ ],
+ "jsx": "react",
+ "useDefineForClassFields": false,
+ "module": "commonjs",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "strict": true,
+ "skipLibCheck": true,
+ "baseUrl": ".",
+ "paths": {
+ "@/*": [
+ "src/*"
+ ]
+ }
}
}
diff --git a/tsup.config.ts b/tsup.config.ts
index f94bb74d..337cd7d8 100644
--- a/tsup.config.ts
+++ b/tsup.config.ts
@@ -1,23 +1,28 @@
import { defineConfig } from "tsup";
export default defineConfig({
- entry: [
- "src/const.ts",
- "src/types.ts",
- "src/urls.ts",
- "src/headers.ts",
- "src/saleor-app.ts",
- "src/verify-jwt.ts",
- "src/verify-signature.ts",
- "src/APL/index.ts",
- "src/APL/redis/index.ts",
- "src/APL/vercel-kv/index.ts",
- "src/app-bridge/index.ts",
- "src/app-bridge/next/index.ts",
- "src/handlers/next/index.ts",
- "src/middleware/index.ts",
- "src/settings-manager/index.ts",
- ],
+ entry: {
+ const: "src/const.ts",
+ types: "src/types.ts",
+ urls: "src/urls.ts",
+ headers: "src/headers.ts",
+ "saleor-app": "src/saleor-app.ts",
+ "verify-jwt": "src/verify-jwt.ts",
+ "verify-signature": "src/verify-signature.ts",
+ "APL/index": "src/APL/index.ts",
+ "APL/redis/index": "src/APL/redis/index.ts",
+ "APL/vercel-kv/index": "src/APL/vercel-kv/index.ts",
+ "app-bridge/index": "src/app-bridge/index.ts",
+ "app-bridge/next/index": "src/app-bridge/next/index.ts",
+ "settings-manager/index": "src/settings-manager/index.ts",
+ "handlers/shared/index": "src/handlers/shared/index.ts",
+
+ // Deprecated
+ "middleware/index": "src/middleware/index.ts",
+
+ // Mapped exports
+ "handlers/next/index": "src/handlers/platforms/next/index.ts",
+ },
dts: true,
clean: true,
format: ["esm", "cjs"],
diff --git a/vitest.config.ts b/vitest.config.mts
similarity index 74%
rename from vitest.config.ts
rename to vitest.config.mts
index 333445f5..be665089 100644
--- a/vitest.config.ts
+++ b/vitest.config.mts
@@ -1,9 +1,10 @@
import react from "@vitejs/plugin-react";
+import tsconfigPaths from "vite-tsconfig-paths"
import { defineConfig } from "vitest/config";
// https://vitejs.dev/config/
export default defineConfig({
- plugins: [react()],
+ plugins: [react(), tsconfigPaths()],
test: {
setupFiles: ["./src/setup-tests.ts"],
environment: "jsdom",