diff --git a/turbo/generators/templates/job/job.test.ts.hbs b/turbo/generators/templates/job/job.test.ts.hbs new file mode 100644 index 0000000..12c49ff --- /dev/null +++ b/turbo/generators/templates/job/job.test.ts.hbs @@ -0,0 +1,23 @@ +// packages/{{kebabCase feature}}/src/jobs/{{kebabCase job}}.job.test.ts +import { describe, it, expect } from "vitest"; +import { {{camelCase job}}Job, {{camelCase job}}InputSchema } from "@/jobs/{{kebabCase job}}.job"; + +describe("{{camelCase job}}Job", () => { + it("validates input via the schema", async () => { + const job = {{camelCase job}}Job(); + await expect(job({ unexpectedField: 1 } as never)).rejects.toThrow(); + }); + + it("accepts valid input", async () => { + const job = {{camelCase job}}Job(); + {{#if (eq inputShape "typed")}} + await expect(job({ exampleField: "x" })).resolves.toBeUndefined(); + {{else}} + await expect(job({})).resolves.toBeUndefined(); + {{/if}} + }); + + it("references its input schema", () => { + expect({{camelCase job}}InputSchema).toBeDefined(); + }); +}); diff --git a/turbo/generators/templates/job/job.ts.hbs b/turbo/generators/templates/job/job.ts.hbs new file mode 100644 index 0000000..2db9299 --- /dev/null +++ b/turbo/generators/templates/job/job.ts.hbs @@ -0,0 +1,20 @@ +// packages/{{kebabCase feature}}/src/jobs/{{kebabCase job}}.job.ts +import { z } from "zod"; + +{{#if (eq inputShape "typed")}} +export const {{camelCase job}}InputSchema = z + .object({ exampleField: z.string() }) + .strict(); +{{else}} +export const {{camelCase job}}InputSchema = z.object({}).strict(); +{{/if}} + +export type {{pascalCase job}}Input = z.infer; +export type I{{pascalCase job}}Job = ReturnType; + +export const {{camelCase job}}Job = + () => + async (input: {{pascalCase job}}Input): Promise => { + {{camelCase job}}InputSchema.parse(input); + // TODO: implement the job. Inject dependencies via the factory's constructor. + }; diff --git a/turbo/generators/templates/job/task.ts.hbs b/turbo/generators/templates/job/task.ts.hbs new file mode 100644 index 0000000..b204e61 --- /dev/null +++ b/turbo/generators/templates/job/task.ts.hbs @@ -0,0 +1,18 @@ +// packages/{{kebabCase feature}}/src/integrations/cms/jobs/{{kebabCase job}}.task.ts +import type { TaskConfig } from "payload"; +import { {{camelCase feature}}Container } from "../../../di/container"; +import { {{constantCase feature}}_SYMBOLS } from "../../../di/symbols"; +import type { I{{pascalCase job}}Job } from "../../../jobs/{{kebabCase job}}.job"; + +export const {{camelCase job}}Task: TaskConfig<"{{kebabCase feature}}.{{kebabCase job}}"> = { + slug: "{{kebabCase feature}}.{{kebabCase job}}", + inputSchema: [], + retries: { attempts: 3, backoff: { type: "exponential", delay: 1000 } }, + handler: async ({ input }) => { + const job = {{camelCase feature}}Container.get( + {{constantCase feature}}_SYMBOLS.I{{pascalCase job}}Job, + ); + await job(input as never); + return { output: {} }; + }, +};