diff --git a/package.json b/package.json index cca714f3..1af40358 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "db:push": "pnpm -F db push", "db:studio": "pnpm -F db studio", "dev": "turbo dev --parallel", + "gen:action": "turbo gen next-action", "gen:package": "turbo gen init", "gen:story": "turbo gen story", "gen:ui": "turbo gen component", diff --git a/packages/validators/src/actions/index.ts b/packages/validators/src/actions/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/packages/validators/src/index.ts b/packages/validators/src/index.ts index d7637445..de4597b9 100644 --- a/packages/validators/src/index.ts +++ b/packages/validators/src/index.ts @@ -4,3 +4,5 @@ export const CreatePostSchema = z.object({ title: z.string().min(1), content: z.string().min(1), }); + +export * from "./actions"; diff --git a/turbo/generators/config.ts b/turbo/generators/config.ts index c7d80876..73f46daf 100644 --- a/turbo/generators/config.ts +++ b/turbo/generators/config.ts @@ -1,9 +1,10 @@ import type { PlopTypes } from "@turbo/gen"; -import { component, init, story } from "./generators"; +import { component, init, nextAction, story } from "./generators"; export default function generator(plop: PlopTypes.NodePlopAPI): void { plop.setGenerator("init", init); plop.setGenerator("component", component); + plop.setGenerator("next-action", nextAction); plop.setGenerator("story", story); } diff --git a/turbo/generators/generators/action.ts b/turbo/generators/generators/action.ts new file mode 100644 index 00000000..91d27bab --- /dev/null +++ b/turbo/generators/generators/action.ts @@ -0,0 +1,50 @@ +import type { PlopTypes } from "@turbo/gen"; + +export const nextAction = { + description: "Nextjs Server Action", + prompts: [ + { + type: "input", + name: "app", + message: "📁 Which app do you want to add to?", + default: "nextjs", + validate: (value) => !!value || `App name is required`, + }, + { + type: "input", + name: "name", + message: "🐫 Action Name:", + default: "create action", + validate: (value) => !!value || `Action name is required`, + }, + ], + actions: [ + { + type: "add", + path: "apps/{{app}}/actions/index.ts", + skipIfExists: true, + }, + { + type: "add", + path: "apps/{{app}}/actions/{{dashCase name}}.ts", + templateFile: "templates/action/index.ts.hbs", + abortOnFail: true, + }, + { + type: "append", + path: "apps/{{app}}/actions/index.ts", + template: 'export * from "./{{dashCase name}}"', + }, + { + type: "add", + path: "packages/validators/src/actions/{{dashCase name}}.ts", + templateFile: "templates/action/schema.ts.hbs", + abortOnFail: true, + }, + { + type: "append", + path: "packages/validators/src/actions/index.ts", + template: 'export * from "./{{dashCase name}}"', + }, + ], +} satisfies PlopTypes.PlopGeneratorConfig; diff --git a/turbo/generators/generators/index.ts b/turbo/generators/generators/index.ts index a07cf7c1..eb7b4945 100644 --- a/turbo/generators/generators/index.ts +++ b/turbo/generators/generators/index.ts @@ -1,3 +1,4 @@ +export * from "./action"; export * from "./component"; export * from "./init"; export * from "./story"; diff --git a/turbo/generators/templates/action/index.ts.hbs b/turbo/generators/templates/action/index.ts.hbs new file mode 100644 index 00000000..17bee3d9 --- /dev/null +++ b/turbo/generators/templates/action/index.ts.hbs @@ -0,0 +1,26 @@ +"use server" + +import { worxpace } from "@acme/prisma"; +import { type ActionHandler, createSafeAction } from "@acme/ui/lib"; +import { {{pascalCase name}}, type {{pascalCase name}}Input } from "@acme/validators"; + +import { UnauthorizedError, fetchClient } from "~/lib"; + +const handler: ActionHandler<{{pascalCase name}}Input, any> = async (data) => { + let result; + const {} = data; + + try { + const { clientId } = fetchClient(); + } catch (error) { + if (error instanceof UnauthorizedError) + return { error: "Unauthorized" }; + console.log(`ERROR`, error); + return { error: "Failed to {{lowerCase name}}." }; + } + + return { data: result }; +}; + +export const {{camelCase name}} = createSafeAction({{pascalCase name}}, handler); + diff --git a/turbo/generators/templates/action/schema.ts.hbs b/turbo/generators/templates/action/schema.ts.hbs new file mode 100644 index 00000000..c615db99 --- /dev/null +++ b/turbo/generators/templates/action/schema.ts.hbs @@ -0,0 +1,5 @@ +import { z } from "zod"; + +export const {{pascalCase name}} = z.object({}); + +export type {{pascalCase name}}Input = z.infer; \ No newline at end of file