add request to createManifestHandler context (#258)

This commit is contained in:
Lukasz Ostrowski 2023-06-22 11:32:11 +02:00 committed by GitHub
parent 989810fbc6
commit 86d963e1e4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 21 deletions

View file

@ -0,0 +1,5 @@
---
"@saleor/app-sdk": minor
---
Added NextApiRequest to context of createManifestHandler. Now you can read native request to construct more specific manifest based on request params

View file

@ -26,11 +26,11 @@ Example usage of manifest handler in Next.js
import { createManifestHandler } from "@saleor/app-sdk/handlers/next"; import { createManifestHandler } from "@saleor/app-sdk/handlers/next";
export default createManifestHandler({ export default createManifestHandler({
manifestFactory(context) { manifestFactory({ request, appBaseUrl }) {
return { return {
name: "My Saleor App", name: "My Saleor App",
tokenTargetUrl: `${context.appBaseUrl}/api/register`, tokenTargetUrl: `${appBaseUrl}/api/register`,
appUrl: context.appBaseUrl, appUrl: appBaseUrl,
permissions: [], permissions: [],
id: "my-saleor-app", id: "my-saleor-app",
version: "1", version: "1",
@ -43,10 +43,12 @@ Options provided to handler factory
```typescript ```typescript
type CreateManifestHandlerOptions = { type CreateManifestHandlerOptions = {
manifestFactory(context: { appBaseUrl: string }): AppManifest; manifestFactory(context: { appBaseUrl: string; request: NextApiRequest }): AppManifest;
}; };
``` ```
You can use NextApiRequest to read additional params from request. For example read Saleor version to enable or disabled some features, depending on their support.
See [source](./src/handlers/next/create-manifest-handler.ts) for more details. See [manifest](../src/types.ts) too. See [source](./src/handlers/next/create-manifest-handler.ts) for more details. See [manifest](../src/types.ts) too.
### App register handler factory ### App register handler factory

View file

@ -5,7 +5,9 @@ import { AppManifest } from "../../types";
import { createManifestHandler } from "./create-manifest-handler"; import { createManifestHandler } from "./create-manifest-handler";
describe("createManifestHandler", () => { describe("createManifestHandler", () => {
it("Creates a handler that responds with Manifest", async () => { it("Creates a handler that responds with Manifest. Includes request in context", async () => {
expect.assertions(3);
const { res, req } = createMocks({ const { res, req } = createMocks({
headers: { headers: {
host: "some-saleor-host.cloud", host: "some-saleor-host.cloud",
@ -15,11 +17,14 @@ describe("createManifestHandler", () => {
}); });
const handler = createManifestHandler({ const handler = createManifestHandler({
manifestFactory(context: { appBaseUrl: string }): AppManifest { manifestFactory({ appBaseUrl, request }): AppManifest {
expect(request).toBeDefined();
expect(request.headers.host).toBe("some-saleor-host.cloud");
return { return {
name: "Mock name", name: "Mock name",
tokenTargetUrl: `${context.appBaseUrl}/api/register`, tokenTargetUrl: `${appBaseUrl}/api/register`,
appUrl: context.appBaseUrl, appUrl: appBaseUrl,
permissions: [], permissions: [],
id: "app-id", id: "app-id",
version: "1", version: "1",
@ -29,7 +34,7 @@ describe("createManifestHandler", () => {
await handler(req, res); await handler(req, res);
expect(res._getData()).toEqual({ expect(res._getJSONData()).toEqual({
appUrl: "https://some-saleor-host.cloud", appUrl: "https://some-saleor-host.cloud",
id: "app-id", id: "app-id",
name: "Mock name", name: "Mock name",

View file

@ -1,12 +1,13 @@
import { Handler } from "retes"; import { NextApiHandler, NextApiRequest } from "next";
import { toNextHandler } from "retes/adapter";
import { Response } from "retes/response";
import { withBaseURL } from "../../middleware"; import { getBaseUrl } from "../../headers";
import { AppManifest } from "../../types"; import { AppManifest } from "../../types";
export type CreateManifestHandlerOptions = { export type CreateManifestHandlerOptions = {
manifestFactory(context: { appBaseUrl: string }): AppManifest | Promise<AppManifest>; manifestFactory(context: {
appBaseUrl: string;
request: NextApiRequest;
}): AppManifest | Promise<AppManifest>;
}; };
/** /**
@ -14,16 +15,15 @@ export type CreateManifestHandlerOptions = {
* implementation details if possible * implementation details if possible
* In the future this will be extracted to separate sdk/next package * In the future this will be extracted to separate sdk/next package
*/ */
export const createManifestHandler = (options: CreateManifestHandlerOptions) => { export const createManifestHandler =
const baseHandler: Handler = async (request) => { (options: CreateManifestHandlerOptions): NextApiHandler =>
const { baseURL } = request.context; async (request, response) => {
const baseURL = getBaseUrl(request.headers);
const manifest = await options.manifestFactory({ const manifest = await options.manifestFactory({
appBaseUrl: baseURL, appBaseUrl: baseURL,
request,
}); });
return Response.OK(manifest); return response.status(200).json(manifest);
}; };
return toNextHandler([withBaseURL, baseHandler]);
};