Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new Adapter and Action interfaces, add new Next.js handler implementation, remove middlewares #401

Merged
merged 46 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
09ed14b
Add actions
witoszekdev Jan 28, 2025
3dc2417
Add adapter, new shared classes
witoszekdev Jan 28, 2025
e1b4a7e
Add next.js platform adapter
witoszekdev Jan 28, 2025
9ba5562
Add new implementation for next.js handlers
witoszekdev Jan 28, 2025
0d7d3c6
Replace domain validation with saleorApiUrl
witoszekdev Jan 28, 2025
d0bf8b1
Remove deprecated exports
witoszekdev Jan 28, 2025
6aa3e56
Remove deprecated exports, add missing export, fix imports
witoszekdev Jan 28, 2025
56a404d
Fix broken imports
witoszekdev Jan 28, 2025
a70c440
Remove middlewares
witoszekdev Jan 28, 2025
ab24ad3
Remove usage of Saleor-Domain header
witoszekdev Jan 28, 2025
238ed0e
Make saleorSchemaVersion required, dropping support for Saleor < 3.15
witoszekdev Jan 29, 2025
7586dc4
Make action types more strict, allow passing generic
witoszekdev Jan 29, 2025
4a3743c
Add register error codes type
witoszekdev Jan 29, 2025
5529ec6
Add register handler tests
witoszekdev Jan 29, 2025
3067970
Add more tests, fix broken jwks handling
witoszekdev Jan 29, 2025
5a3682a
Preffer http over other protocols when https is not present
witoszekdev Jan 29, 2025
d4e2a8b
Add tests for platform adapter
witoszekdev Jan 29, 2025
6354c56
Add missing export
witoszekdev Jan 29, 2025
2744e5b
Adapter middleware headers - always return undefined for missing values
witoszekdev Jan 29, 2025
07ace44
Add tests for adapter middleware
witoszekdev Jan 29, 2025
b3aac1b
Add tests for protected action validator
witoszekdev Jan 29, 2025
e959a73
Add tests for create-protected-handler
witoszekdev Jan 31, 2025
b79b8da
Remove unused code
witoszekdev Jan 31, 2025
2c0adce
Fix tests
witoszekdev Jan 31, 2025
e6e3d6a
Add method validation to manifest action
witoszekdev Jan 31, 2025
7e1a180
Fix TS error
witoszekdev Jan 31, 2025
3bca89d
Remove assertion to fix tsup build
witoszekdev Jan 31, 2025
e5c8cfe
Remove assertion to fix prettier
witoszekdev Jan 31, 2025
af80f55
Remove retes
witoszekdev Jan 31, 2025
1c66ca9
Remove deprecated webhook fields
witoszekdev Jan 31, 2025
4d9ebfe
Rewrite saleor-async-webhook tests
witoszekdev Jan 31, 2025
6f922eb
Add changesets
witoszekdev Jan 31, 2025
a3c50b2
Remove duplicated changeset
witoszekdev Jan 31, 2025
602971b
Add missing coverage
witoszekdev Feb 3, 2025
922e3e8
Add tests for re-fetching jwks
witoszekdev Feb 3, 2025
4ace1e0
Fix TS error
witoszekdev Feb 3, 2025
7e70deb
Add missing test case
witoszekdev Feb 3, 2025
f9ddb84
Make fields required on SaleorAsyncWebhook
witoszekdev Feb 3, 2025
8c2f4a5
Add more tests for sync webhook
witoszekdev Feb 3, 2025
fdeea53
Improve changeset description
witoszekdev Feb 3, 2025
418c4a2
Rename adapter middleware -> saleor request processor
witoszekdev Feb 3, 2025
d88bc88
Remove debug backwards compatibility
witoszekdev Feb 3, 2025
32a31e7
CR
witoszekdev Feb 3, 2025
1d1ff8f
Update changeset
witoszekdev Feb 3, 2025
6565ca4
Remove actions from export
witoszekdev Feb 3, 2025
2e0b09d
Remove externals export
witoszekdev Feb 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/hip-queens-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@saleor/app-sdk": patch
---

Removed `/middlewares`, you should use `/handlers` instead.
9 changes: 9 additions & 0 deletions .changeset/kind-zoos-raise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@saleor/app-sdk": major
---

Removed deprecated fields fields and methods in `/handlers`:

- `SaleorAsyncWebhook` and `SaleorSyncWebhook` - removed `asyncEvent` and `subscriptionQueryAst`
- Removed `processSaleorWebhook` and `processProtectedHandler` methods
- Some types were moved from `/next` to `/shared`
7 changes: 7 additions & 0 deletions .changeset/sixty-taxis-glow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@saleor/app-sdk": patch
---

Added abstract `PlatformAdapterInterface` and `ActionHandlerInterface` to enable cross-framework handler implementations.

Next.js handlers were rewritten to use the new interface.
2 changes: 1 addition & 1 deletion .changeset/tough-socks-tease.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"@saleor/app-sdk": major
---

Breaking change: Remove checking "domain" header from Saleor requests. It should be replaced with the "saleor-api-url" header.
Breaking change: SDK will no longer check `saleor-domain` header when validating Saleor requests, instead it will check `saleor-api-url` header.
6 changes: 0 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
"debug": "4.3.4",
"jose": "4.14.4",
"raw-body": "2.5.2",
"retes": "0.33.0",
"uuid": "9.0.0"
},
"devDependencies": {
Expand Down Expand Up @@ -126,11 +125,6 @@
"import": "./settings-manager/index.mjs",
"require": "./settings-manager/index.js"
},
"./middleware": {
"types": "./middleware/index.d.ts",
"import": "./middleware/index.mjs",
"require": "./middleware/index.js"
},
"./urls": {
"types": "./urls.d.ts",
"import": "./urls.mjs",
Expand Down
30 changes: 0 additions & 30 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

81 changes: 81 additions & 0 deletions src/handlers/actions/manifest-action-handler.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { beforeEach, describe, expect, it, vi } from "vitest";

import { SALEOR_SCHEMA_VERSION } from "@/const";
import { MockAdapter } from "@/test-utils/mock-adapter";
import { AppManifest } from "@/types";

import { ManifestActionHandler } from "./manifest-action-handler";

describe("ManifestActionHandler", () => {
const mockManifest: AppManifest = {
id: "test-app",
name: "Test Application",
version: "1.0.0",
appUrl: "http://example.com",
permissions: [],
tokenTargetUrl: "http://example.com/token",
};

let adapter: MockAdapter;

beforeEach(() => {
adapter = new MockAdapter({
mockHeaders: {
[SALEOR_SCHEMA_VERSION]: "3.20",
},
baseUrl: "http://example.com",
});
adapter.method = "GET";
});

it("should call manifest factory and return 200 status when it resolves", async () => {
const handler = new ManifestActionHandler(adapter);
const manifestFactory = vi.fn().mockResolvedValue(mockManifest);

const result = await handler.handleAction({ manifestFactory });

expect(result.status).toBe(200);
expect(result.body).toEqual(mockManifest);
expect(manifestFactory).toHaveBeenCalledWith({
appBaseUrl: "http://example.com",
request: {},
schemaVersion: 3.20,
});
});

it("should call manifest factory and return 500 when it throws an error", async () => {
const handler = new ManifestActionHandler(adapter);
const manifestFactory = vi.fn().mockRejectedValue(new Error("Test error"));

const result = await handler.handleAction({ manifestFactory });

expect(result.status).toBe(500);
expect(result.body).toBe("Error resolving manifest file.");
});

it("should return 405 when not called using HTTP GET method", async () => {
adapter.method = "POST";
const handler = new ManifestActionHandler(adapter);

const manifestFactory = vi.fn().mockResolvedValue(mockManifest);

const result = await handler.handleAction({ manifestFactory });

expect(result.status).toBe(405);
expect(result.body).toBe("Method not allowed");
expect(manifestFactory).not.toHaveBeenCalled();
})

it("should return 400 when receives null schema version header from unsupported legacy Saleor version", async () => {
adapter.getHeader = vi.fn().mockReturnValue(null);
const handler = new ManifestActionHandler(adapter);

const manifestFactory = vi.fn().mockResolvedValue(mockManifest);

const result = await handler.handleAction({ manifestFactory });

expect(result.status).toBe(400);
expect(result.body).toBe("Missing schema version header");
expect(manifestFactory).not.toHaveBeenCalled();
});
});
71 changes: 71 additions & 0 deletions src/handlers/actions/manifest-action-handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { createDebug } from "@/debug";
import { AppManifest } from "@/types";

import {
ActionHandlerInterface,
ActionHandlerResult,
PlatformAdapterInterface,
} from "../shared/generic-adapter-use-case-types";
import { SaleorRequestProcessor } from "../shared/saleor-request-processor";

const debug = createDebug("create-manifest-handler");

export type CreateManifestHandlerOptions<T> = {
manifestFactory(context: {
appBaseUrl: string;
request: T;
/** Added in Saleor 3.15 */
schemaVersion: number;
}): AppManifest | Promise<AppManifest>;
};

export class ManifestActionHandler<I> implements ActionHandlerInterface {
constructor(private adapter: PlatformAdapterInterface<I>) {}

private requestProcessor = new SaleorRequestProcessor(this.adapter);

async handleAction(options: CreateManifestHandlerOptions<I>): Promise<ActionHandlerResult> {
const { schemaVersion } = this.requestProcessor.getSaleorHeaders();
const baseURL = this.adapter.getBaseUrl();

debug("Received request with schema version \"%s\" and base URL \"%s\"", schemaVersion, baseURL);

const invalidMethodResponse = this.requestProcessor.withMethod(["GET"]);

if (invalidMethodResponse) {
return invalidMethodResponse;
}

if (!schemaVersion) {
return {
status: 400,
bodyType: "string",
body: "Missing schema version header",
};
}

try {
const manifest = await options.manifestFactory({
appBaseUrl: baseURL,
request: this.adapter.request,
schemaVersion,
});

debug("Executed manifest file");

return {
status: 200,
bodyType: "json",
body: manifest,
};
} catch (e) {
debug("Error while resolving manifest: %O", e);

return {
status: 500,
bodyType: "string",
body: "Error resolving manifest file.",
};
}
}
}
Loading