From 7559ae0ebbaffb0dce52a58af7eaa11d60c3bad8 Mon Sep 17 00:00:00 2001 From: Jack Williams <1736957+jpwilliams@users.noreply.github.com> Date: Sat, 13 May 2023 15:43:03 +0100 Subject: [PATCH 1/3] Add tests to assert event ID return when using `inngest.send()` --- src/components/Inngest.test.ts | 26 ++++++++++++++----------- src/components/InngestStepTools.test.ts | 11 +++++++++-- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/components/Inngest.test.ts b/src/components/Inngest.test.ts index d902b5f7..d63161b9 100644 --- a/src/components/Inngest.test.ts +++ b/src/components/Inngest.test.ts @@ -59,10 +59,14 @@ describe("send", () => { beforeAll(() => { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment global.fetch = jest.fn( - () => + (input: unknown) => Promise.resolve({ status: 200, - json: () => Promise.resolve({}), + json: () => + Promise.resolve({ + ids: Array.isArray(input) ? input.map((_, i) => `${i}`) : ["0"], + status: 200, + }), }) // eslint-disable-next-line @typescript-eslint/no-explicit-any ) as any; @@ -90,7 +94,7 @@ describe("send", () => { test("should succeed if event key specified at instantiation", async () => { const inngest = createClient({ name: "test", eventKey: testEventKey }); - await expect(inngest.send(testEvent)).resolves.toBeUndefined(); + await expect(inngest.send(testEvent)).resolves.toEqual(["0"]); expect(global.fetch).toHaveBeenCalledWith( expect.stringContaining(`/e/${testEventKey}`), @@ -105,7 +109,7 @@ describe("send", () => { process.env[envKeys.EventKey] = testEventKey; const inngest = createClient({ name: "test" }); - await expect(inngest.send(testEvent)).resolves.toBeUndefined(); + await expect(inngest.send(testEvent)).resolves.toEqual(["0"]); expect(global.fetch).toHaveBeenCalledWith( expect.stringContaining(`/e/${testEventKey}`), @@ -120,7 +124,7 @@ describe("send", () => { const inngest = createClient({ name: "test" }); inngest.setEventKey(testEventKey); - await expect(inngest.send(testEvent)).resolves.toBeUndefined(); + await expect(inngest.send(testEvent)).resolves.toEqual(["0"]); expect(global.fetch).toHaveBeenCalledWith( expect.stringContaining(`/e/${testEventKey}`), @@ -135,7 +139,7 @@ describe("send", () => { const inngest = createClient({ name: "test" }); inngest.setEventKey(testEventKey); - await expect(inngest.send("test", [])).resolves.toBeUndefined(); + await expect(inngest.send("test", [])).resolves.toEqual([]); expect(global.fetch).not.toHaveBeenCalled(); }); @@ -143,7 +147,7 @@ describe("send", () => { const inngest = createClient({ name: "test" }); inngest.setEventKey(testEventKey); - await expect(inngest.send([])).resolves.toBeUndefined(); + await expect(inngest.send([])).resolves.toEqual([]); expect(global.fetch).not.toHaveBeenCalled(); }); @@ -154,7 +158,7 @@ describe("send", () => { env: "foo", }); - await expect(inngest.send(testEvent)).resolves.toBeUndefined(); + await expect(inngest.send(testEvent)).resolves.toEqual(["0"]); expect(global.fetch).toHaveBeenCalledWith( expect.stringContaining(`/e/${testEventKey}`), expect.objectContaining({ @@ -175,7 +179,7 @@ describe("send", () => { eventKey: testEventKey, }); - await expect(inngest.send(testEvent)).resolves.toBeUndefined(); + await expect(inngest.send(testEvent)).resolves.toEqual(["0"]); expect(global.fetch).toHaveBeenCalledWith( expect.stringContaining(`/e/${testEventKey}`), expect.objectContaining({ @@ -197,7 +201,7 @@ describe("send", () => { env: "foo", }); - await expect(inngest.send(testEvent)).resolves.toBeUndefined(); + await expect(inngest.send(testEvent)).resolves.toEqual(["0"]); expect(global.fetch).toHaveBeenCalledWith( expect.stringContaining(`/e/${testEventKey}`), expect.objectContaining({ @@ -218,7 +222,7 @@ describe("send", () => { eventKey: testEventKey, }); - await expect(inngest.send(testEvent)).resolves.toBeUndefined(); + await expect(inngest.send(testEvent)).resolves.toEqual(["0"]); expect(global.fetch).toHaveBeenCalledWith( expect.stringContaining(`/e/${testEventKey}`), expect.objectContaining({ diff --git a/src/components/InngestStepTools.test.ts b/src/components/InngestStepTools.test.ts index 170889f2..b22e9656 100644 --- a/src/components/InngestStepTools.test.ts +++ b/src/components/InngestStepTools.test.ts @@ -244,8 +244,15 @@ describe("sleepUntil", () => { describe("sendEvent", () => { describe("runtime", () => { - const fetchMock = jest.fn(() => - Promise.resolve({ status: 200 }) + const fetchMock = jest.fn((input: unknown) => + Promise.resolve({ + status: 200, + json: () => + Promise.resolve({ + ids: Array.isArray(input) ? input.map((_, i) => `${i}`) : ["0"], + status: 200, + }), + }) ) as unknown as typeof fetch; const client = createClient({ From 825f3339c13cf899eef80e45f26b3df9bdce02b4 Mon Sep 17 00:00:00 2001 From: Jack Williams <1736957+jpwilliams@users.noreply.github.com> Date: Sat, 13 May 2023 15:43:23 +0100 Subject: [PATCH 2/3] Add returning event IDs when using `inngest.send()` and `step.sendEvent()` --- etc/inngest.api.md | 4 ++-- src/components/Inngest.ts | 34 +++++++++++++++++++++--------- src/components/InngestStepTools.ts | 8 +++---- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/etc/inngest.api.md b/etc/inngest.api.md index 9c01f3d3..96959ccf 100644 --- a/etc/inngest.api.md +++ b/etc/inngest.api.md @@ -106,9 +106,9 @@ export class Inngest = Record(name: Event, payload: SingleOrArray, "ts">>): Promise; + send(name: Event, payload: SingleOrArray, "ts">>): Promise; // Warning: (ae-forgotten-export) The symbol "SendEventPayload" needs to be exported by the entry point index.d.ts - send>(payload: Payload): Promise; + send>(payload: Payload): Promise; setEventKey( eventKey: string): void; } diff --git a/src/components/Inngest.ts b/src/components/Inngest.ts index 7aecc03c..878606c6 100644 --- a/src/components/Inngest.ts +++ b/src/components/Inngest.ts @@ -1,3 +1,4 @@ +import { z } from "zod"; import { envKeys } from "../helpers/consts"; import { devServerAvailable, devServerUrl } from "../helpers/devserver"; import { @@ -148,7 +149,7 @@ export class Inngest< /** * Given a response from Inngest, relay the error to the caller. */ - async #getResponseError(response: globalThis.Response): Promise { + #getResponseError(response: globalThis.Response, rawBody: unknown): Error { let errorMessage = "Unknown error"; switch (response.status) { case 401: @@ -164,7 +165,7 @@ export class Inngest< errorMessage = "Event key not found"; break; case 406: - errorMessage = `${JSON.stringify(await response.json())}`; + errorMessage = `${JSON.stringify(rawBody)}`; break; case 409: case 412: @@ -224,7 +225,7 @@ export class Inngest< public async send( name: Event, payload: SingleOrArray, "ts">> - ): Promise; + ): Promise; /** * Send one or many events to Inngest. Takes an entire payload (including * name) as each input. @@ -251,7 +252,7 @@ export class Inngest< */ public async send>( payload: Payload - ): Promise; + ): Promise; public async send( nameOrPayload: | Event @@ -263,7 +264,7 @@ export class Inngest< maybePayload?: SingleOrArray< PartialK, "ts"> > - ): Promise { + ): Promise { if (!this.eventKey) { throw new Error( prettyError({ @@ -306,7 +307,7 @@ export class Inngest< * happens, show a warning that this may not be intended, but don't throw. */ if (!payloads.length) { - return console.warn( + console.warn( prettyError({ type: "warn", whatHappened: "`inngest.send()` called with no events", @@ -317,6 +318,8 @@ export class Inngest< stack: true, }) ); + + return []; } // When sending events, check if the dev server is available. If so, use the @@ -339,11 +342,22 @@ export class Inngest< headers: { ...this.headers }, }); - if (response.status >= 200 && response.status < 300) { - return; - } + let rawBody: unknown; + + try { + rawBody = await response.json(); - throw await this.#getResponseError(response); + const body = await z + .object({ + ids: z.array(z.string()), + status: z.number().min(200).max(299), + }) + .parseAsync(rawBody); + + return body.ids; + } catch (err) { + throw this.#getResponseError(response, rawBody); + } } public createFunction< diff --git a/src/components/InngestStepTools.ts b/src/components/InngestStepTools.ts index b63dc27e..bfb09a46 100644 --- a/src/components/InngestStepTools.ts +++ b/src/components/InngestStepTools.ts @@ -265,15 +265,15 @@ export const createStepTools = < * Returns a promise that will resolve once the event has been sent. */ sendEvent: createTool<{ - >( - payload: Payload - ): Promise; + >(payload: Payload): ReturnType< + Inngest["send"] + >; ( name: Event, payload: SingleOrArray< PartialK, "ts"> > - ): Promise; + ): ReturnType; }>( (nameOrPayload, maybePayload) => { let payloads: ValueOf[]; From 361d7fc5432213fd3b6433b8fc9bdf7858d6343b Mon Sep 17 00:00:00 2001 From: Jack Williams Date: Sat, 13 May 2023 15:44:29 +0100 Subject: [PATCH 3/3] Create unlucky-snails-attack.md --- .changeset/unlucky-snails-attack.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/unlucky-snails-attack.md diff --git a/.changeset/unlucky-snails-attack.md b/.changeset/unlucky-snails-attack.md new file mode 100644 index 00000000..215d1c8b --- /dev/null +++ b/.changeset/unlucky-snails-attack.md @@ -0,0 +1,5 @@ +--- +"inngest": minor +--- + +Return event IDs when sending events using `inngest.send()` and `step.sendEvent()`