diff --git a/.changeset/lazy-ducks-add.md b/.changeset/lazy-ducks-add.md new file mode 100644 index 0000000..35afc25 --- /dev/null +++ b/.changeset/lazy-ducks-add.md @@ -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 diff --git a/docs/api-handlers.md b/docs/api-handlers.md index 7ca2b66..c49a9c1 100644 --- a/docs/api-handlers.md +++ b/docs/api-handlers.md @@ -26,11 +26,11 @@ Example usage of manifest handler in Next.js import { createManifestHandler } from "@saleor/app-sdk/handlers/next"; export default createManifestHandler({ - manifestFactory(context) { + manifestFactory({ request, appBaseUrl }) { return { name: "My Saleor App", - tokenTargetUrl: `${context.appBaseUrl}/api/register`, - appUrl: context.appBaseUrl, + tokenTargetUrl: `${appBaseUrl}/api/register`, + appUrl: appBaseUrl, permissions: [], id: "my-saleor-app", version: "1", @@ -43,10 +43,12 @@ Options provided to handler factory ```typescript 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. ### App register handler factory diff --git a/src/handlers/next/create-manifest-handler.test.ts b/src/handlers/next/create-manifest-handler.test.ts index 8455797..f9caa04 100644 --- a/src/handlers/next/create-manifest-handler.test.ts +++ b/src/handlers/next/create-manifest-handler.test.ts @@ -5,7 +5,9 @@ import { AppManifest } from "../../types"; import { createManifestHandler } from "./create-manifest-handler"; 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({ headers: { host: "some-saleor-host.cloud", @@ -15,11 +17,14 @@ describe("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 { name: "Mock name", - tokenTargetUrl: `${context.appBaseUrl}/api/register`, - appUrl: context.appBaseUrl, + tokenTargetUrl: `${appBaseUrl}/api/register`, + appUrl: appBaseUrl, permissions: [], id: "app-id", version: "1", @@ -29,7 +34,7 @@ describe("createManifestHandler", () => { await handler(req, res); - expect(res._getData()).toEqual({ + expect(res._getJSONData()).toEqual({ appUrl: "https://some-saleor-host.cloud", id: "app-id", name: "Mock name", diff --git a/src/handlers/next/create-manifest-handler.ts b/src/handlers/next/create-manifest-handler.ts index e9fbd70..fec270e 100644 --- a/src/handlers/next/create-manifest-handler.ts +++ b/src/handlers/next/create-manifest-handler.ts @@ -1,12 +1,13 @@ -import { Handler } from "retes"; -import { toNextHandler } from "retes/adapter"; -import { Response } from "retes/response"; +import { NextApiHandler, NextApiRequest } from "next"; -import { withBaseURL } from "../../middleware"; +import { getBaseUrl } from "../../headers"; import { AppManifest } from "../../types"; export type CreateManifestHandlerOptions = { - manifestFactory(context: { appBaseUrl: string }): AppManifest | Promise; + manifestFactory(context: { + appBaseUrl: string; + request: NextApiRequest; + }): AppManifest | Promise; }; /** @@ -14,16 +15,15 @@ export type CreateManifestHandlerOptions = { * implementation details if possible * In the future this will be extracted to separate sdk/next package */ -export const createManifestHandler = (options: CreateManifestHandlerOptions) => { - const baseHandler: Handler = async (request) => { - const { baseURL } = request.context; +export const createManifestHandler = + (options: CreateManifestHandlerOptions): NextApiHandler => + async (request, response) => { + const baseURL = getBaseUrl(request.headers); const manifest = await options.manifestFactory({ appBaseUrl: baseURL, + request, }); - return Response.OK(manifest); + return response.status(200).json(manifest); }; - - return toNextHandler([withBaseURL, baseHandler]); -};