@stryke/prisma-trpc-generator 0.4.8 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2631,6 +2631,12 @@ function normalizeString(path6, allowAboveRoot) {
2631
2631
  }
2632
2632
  __name(normalizeString, "normalizeString");
2633
2633
 
2634
+ // ../string-format/src/lower-case-first.ts
2635
+ init_cjs_shims();
2636
+ var lowerCaseFirst = /* @__PURE__ */ __name((input) => {
2637
+ return input ? input.charAt(0).toLowerCase() + input.slice(1) : input;
2638
+ }, "lowerCaseFirst");
2639
+
2634
2640
  // src/prisma-generator.ts
2635
2641
  var import_node_path6 = __toESM(require("node:path"), 1);
2636
2642
  var import_pluralize = __toESM(require_pluralize(), 1);
@@ -6886,8 +6892,9 @@ var configSchema = z.object({
6886
6892
  withShield: configShield.default("true"),
6887
6893
  withZod: configBoolean.default("true"),
6888
6894
  contextPath: z.string().default("../src/trpc/context"),
6889
- trpcOptionsPath: z.string().optional(),
6895
+ trpcOptions: z.boolean().or(z.string()).optional(),
6890
6896
  showModelNameInProcedure: configBoolean.default("true"),
6897
+ useTRPCNext: configBoolean.default("false"),
6891
6898
  generateModelActions: z.string().default(Object.values(ModelAction).join(",")).transform((arg) => {
6892
6899
  return arg.split(",").map((action) => modelActionEnum.parse(action.trim()));
6893
6900
  })
@@ -6896,12 +6903,6 @@ var configSchema = z.object({
6896
6903
  // src/helpers.ts
6897
6904
  init_cjs_shims();
6898
6905
 
6899
- // ../string-format/src/lower-case-first.ts
6900
- init_cjs_shims();
6901
- var lowerCaseFirst = /* @__PURE__ */ __name((input) => {
6902
- return input ? input.charAt(0).toLowerCase() + input.slice(1) : input;
6903
- }, "lowerCaseFirst");
6904
-
6905
6906
  // src/utils/get-prisma-internals.ts
6906
6907
  init_cjs_shims();
6907
6908
 
@@ -7646,24 +7647,35 @@ var generateRouterImport = /* @__PURE__ */ __name((sourceFile, modelNamePlural,
7646
7647
  async function generateBaseRouter(sourceFile, config, options) {
7647
7648
  const internals = await getPrismaInternals();
7648
7649
  const outputDir = internals.parseEnvValue(options.generator.output);
7650
+ const relativeContextPath = getRelativePath(outputDir, config.contextPath, true, options.schemaPath);
7649
7651
  sourceFile.addStatements(
7650
7652
  /* ts */
7651
7653
  `
7652
- import type { Context } from '${getRelativePath(outputDir, config.contextPath, true, options.schemaPath)}';
7654
+ import type { Context } from '${relativeContextPath}';
7653
7655
  `
7654
7656
  );
7655
- if (config.trpcOptionsPath) {
7657
+ if (config.trpcOptions) {
7656
7658
  sourceFile.addStatements(
7657
7659
  /* ts */
7658
7660
  `
7659
- import trpcOptions from '${getRelativePath(outputDir, config.trpcOptionsPath, true, options.schemaPath)}';
7661
+ import trpcOptions from '${getRelativePath(outputDir, typeof config.trpcOptions === "boolean" ? joinPaths(outputDir, "options") : config.trpcOptions, true, options.schemaPath)}';
7660
7662
  `
7661
7663
  );
7662
7664
  }
7665
+ if (config.useTRPCNext) {
7666
+ sourceFile.addStatements(
7667
+ /* ts */
7668
+ `
7669
+ import { createContext } from '${relativeContextPath}';
7670
+ import { initTRPC, TRPCError } from '@trpc/server';
7671
+ import { createTRPCServerActionHandler } from '@stryke/trpc-next/action-handler';
7672
+ `
7673
+ );
7674
+ }
7663
7675
  sourceFile.addStatements(
7664
7676
  /* ts */
7665
7677
  `
7666
- export const t = trpc.initTRPC.context<Context>().create(${config.trpcOptionsPath ? "trpcOptions" : ""});
7678
+ export const t = trpc.initTRPC.context<Context>().create(${config.trpcOptions ? "trpcOptions" : ""});
7667
7679
  `
7668
7680
  );
7669
7681
  const middlewares = [];
@@ -7719,11 +7731,44 @@ async function generateBaseRouter(sourceFile, config, options) {
7719
7731
  )
7720
7732
  });
7721
7733
  }
7734
+ sourceFile.addStatements(
7735
+ /* ts */
7736
+ `
7737
+ /**
7738
+ * Create a server-side caller
7739
+ * @see https://trpc.io/docs/server/server-side-calls
7740
+ */
7741
+ export const createCallerFactory = t.createCallerFactory;`
7742
+ );
7722
7743
  sourceFile.addStatements(
7723
7744
  /* ts */
7724
7745
  `
7725
7746
  export const publicProcedure = t.procedure; `
7726
7747
  );
7748
+ if (config.useTRPCNext) {
7749
+ sourceFile.addStatements(
7750
+ /* ts */
7751
+ `
7752
+ export const protectedProcedure = publicProcedure.use((opts) => {
7753
+ const { session } = opts.ctx;
7754
+
7755
+ if (!session?.user) {
7756
+ throw new TRPCError({
7757
+ code: 'UNAUTHORIZED',
7758
+ });
7759
+ }
7760
+
7761
+ return opts.next({ ctx: { session } });
7762
+ });
7763
+ `
7764
+ );
7765
+ sourceFile.addStatements(
7766
+ /* ts */
7767
+ `
7768
+ export const createAction = createTRPCServerActionHandler(t, createContext);
7769
+ `
7770
+ );
7771
+ }
7727
7772
  if (middlewares.length > 0) {
7728
7773
  const procName = getProcedureName(config);
7729
7774
  middlewares.forEach((middleware, i) => {
@@ -7945,7 +7990,9 @@ var constructShield = /* @__PURE__ */ __name(async ({ queries, mutations, subscr
7945
7990
  })},`;
7946
7991
  rootItems += subscriptionLinesWrapped;
7947
7992
  }
7948
- if (rootItems.length === 0) return "";
7993
+ if (rootItems.length === 0) {
7994
+ return "";
7995
+ }
7949
7996
  let shieldText = getImports("trpc-shield");
7950
7997
  const internals = await getPrismaInternals();
7951
7998
  const outputDir = internals.parseEnvValue(options.generator.output);
@@ -11612,6 +11659,27 @@ async function generate(options) {
11612
11659
  consoleLog("Skipping tRPC Shield generation");
11613
11660
  }
11614
11661
  consoleLog(`Generating tRPC source code for ${models.length} models`);
11662
+ if (config.trpcOptions && typeof config.trpcOptions === "boolean") {
11663
+ const trpcOptionsOutputPath = joinPaths(outputDir, "options.ts");
11664
+ consoleLog("Generating tRPC options source file");
11665
+ await writeFileSafely(trpcOptionsOutputPath, `import { ZodError } from 'zod';${config.useTRPCNext ? '\nimport { transformer } from "@stryke/trpc-next/shared";' : ""}
11666
+
11667
+ export default {${config.useTRPCNext ? "\n transformer," : ""}
11668
+ errorFormatter({ shape, error }) {
11669
+ return {
11670
+ ...shape,
11671
+ data: {
11672
+ ...shape.data,
11673
+ zodError:
11674
+ error.code === 'BAD_REQUEST' && error.cause instanceof ZodError
11675
+ ? error.cause.flatten()
11676
+ : null,
11677
+ },
11678
+ };
11679
+ },
11680
+ };
11681
+ `);
11682
+ }
11615
11683
  resolveModelsComments(models, hiddenModels);
11616
11684
  const createRouter = project.createSourceFile(import_node_path6.default.resolve(outputDir, "routers", "helpers", "createRouter.ts"), void 0, {
11617
11685
  overwrite: true
@@ -11640,6 +11708,10 @@ async function generate(options) {
11640
11708
  consoleLog(`Skipping model ${model} as it is hidden`);
11641
11709
  continue;
11642
11710
  }
11711
+ if (!model) {
11712
+ consoleLog(`Skipping model ${model} as it is not defined`);
11713
+ continue;
11714
+ }
11643
11715
  const modelActions = Object.keys(operations).filter((opType) => (
11644
11716
  // eslint-disable-next-line unicorn/prefer-includes
11645
11717
  config.generateModelActions.some((generateModelAction) => generateModelAction === opType.replace("One", ""))
@@ -11648,7 +11720,7 @@ async function generate(options) {
11648
11720
  consoleLog(`Skipping model ${model} as it has no actions to generate`);
11649
11721
  continue;
11650
11722
  }
11651
- const plural = (0, import_pluralize.default)(model.toLowerCase());
11723
+ const plural = (0, import_pluralize.default)(lowerCaseFirst(model));
11652
11724
  consoleLog(`Generating tRPC router for model ${model}`);
11653
11725
  generateRouterImport(appRouter, plural, model);
11654
11726
  const modelRouter = project.createSourceFile(import_node_path6.default.resolve(outputDir, "routers", `${model}.router.ts`), void 0, {
package/dist/generator.js CHANGED
@@ -2636,6 +2636,12 @@ function normalizeString(path6, allowAboveRoot) {
2636
2636
  }
2637
2637
  __name(normalizeString, "normalizeString");
2638
2638
 
2639
+ // ../string-format/src/lower-case-first.ts
2640
+ init_esm_shims();
2641
+ var lowerCaseFirst = /* @__PURE__ */ __name((input) => {
2642
+ return input ? input.charAt(0).toLowerCase() + input.slice(1) : input;
2643
+ }, "lowerCaseFirst");
2644
+
2639
2645
  // src/prisma-generator.ts
2640
2646
  var import_pluralize = __toESM(require_pluralize(), 1);
2641
2647
  import path5 from "node:path";
@@ -6891,8 +6897,9 @@ var configSchema = z.object({
6891
6897
  withShield: configShield.default("true"),
6892
6898
  withZod: configBoolean.default("true"),
6893
6899
  contextPath: z.string().default("../src/trpc/context"),
6894
- trpcOptionsPath: z.string().optional(),
6900
+ trpcOptions: z.boolean().or(z.string()).optional(),
6895
6901
  showModelNameInProcedure: configBoolean.default("true"),
6902
+ useTRPCNext: configBoolean.default("false"),
6896
6903
  generateModelActions: z.string().default(Object.values(ModelAction).join(",")).transform((arg) => {
6897
6904
  return arg.split(",").map((action) => modelActionEnum.parse(action.trim()));
6898
6905
  })
@@ -6901,12 +6908,6 @@ var configSchema = z.object({
6901
6908
  // src/helpers.ts
6902
6909
  init_esm_shims();
6903
6910
 
6904
- // ../string-format/src/lower-case-first.ts
6905
- init_esm_shims();
6906
- var lowerCaseFirst = /* @__PURE__ */ __name((input) => {
6907
- return input ? input.charAt(0).toLowerCase() + input.slice(1) : input;
6908
- }, "lowerCaseFirst");
6909
-
6910
6911
  // src/utils/get-prisma-internals.ts
6911
6912
  init_esm_shims();
6912
6913
 
@@ -7651,24 +7652,35 @@ var generateRouterImport = /* @__PURE__ */ __name((sourceFile, modelNamePlural,
7651
7652
  async function generateBaseRouter(sourceFile, config, options) {
7652
7653
  const internals = await getPrismaInternals();
7653
7654
  const outputDir = internals.parseEnvValue(options.generator.output);
7655
+ const relativeContextPath = getRelativePath(outputDir, config.contextPath, true, options.schemaPath);
7654
7656
  sourceFile.addStatements(
7655
7657
  /* ts */
7656
7658
  `
7657
- import type { Context } from '${getRelativePath(outputDir, config.contextPath, true, options.schemaPath)}';
7659
+ import type { Context } from '${relativeContextPath}';
7658
7660
  `
7659
7661
  );
7660
- if (config.trpcOptionsPath) {
7662
+ if (config.trpcOptions) {
7661
7663
  sourceFile.addStatements(
7662
7664
  /* ts */
7663
7665
  `
7664
- import trpcOptions from '${getRelativePath(outputDir, config.trpcOptionsPath, true, options.schemaPath)}';
7666
+ import trpcOptions from '${getRelativePath(outputDir, typeof config.trpcOptions === "boolean" ? joinPaths(outputDir, "options") : config.trpcOptions, true, options.schemaPath)}';
7665
7667
  `
7666
7668
  );
7667
7669
  }
7670
+ if (config.useTRPCNext) {
7671
+ sourceFile.addStatements(
7672
+ /* ts */
7673
+ `
7674
+ import { createContext } from '${relativeContextPath}';
7675
+ import { initTRPC, TRPCError } from '@trpc/server';
7676
+ import { createTRPCServerActionHandler } from '@stryke/trpc-next/action-handler';
7677
+ `
7678
+ );
7679
+ }
7668
7680
  sourceFile.addStatements(
7669
7681
  /* ts */
7670
7682
  `
7671
- export const t = trpc.initTRPC.context<Context>().create(${config.trpcOptionsPath ? "trpcOptions" : ""});
7683
+ export const t = trpc.initTRPC.context<Context>().create(${config.trpcOptions ? "trpcOptions" : ""});
7672
7684
  `
7673
7685
  );
7674
7686
  const middlewares = [];
@@ -7724,11 +7736,44 @@ async function generateBaseRouter(sourceFile, config, options) {
7724
7736
  )
7725
7737
  });
7726
7738
  }
7739
+ sourceFile.addStatements(
7740
+ /* ts */
7741
+ `
7742
+ /**
7743
+ * Create a server-side caller
7744
+ * @see https://trpc.io/docs/server/server-side-calls
7745
+ */
7746
+ export const createCallerFactory = t.createCallerFactory;`
7747
+ );
7727
7748
  sourceFile.addStatements(
7728
7749
  /* ts */
7729
7750
  `
7730
7751
  export const publicProcedure = t.procedure; `
7731
7752
  );
7753
+ if (config.useTRPCNext) {
7754
+ sourceFile.addStatements(
7755
+ /* ts */
7756
+ `
7757
+ export const protectedProcedure = publicProcedure.use((opts) => {
7758
+ const { session } = opts.ctx;
7759
+
7760
+ if (!session?.user) {
7761
+ throw new TRPCError({
7762
+ code: 'UNAUTHORIZED',
7763
+ });
7764
+ }
7765
+
7766
+ return opts.next({ ctx: { session } });
7767
+ });
7768
+ `
7769
+ );
7770
+ sourceFile.addStatements(
7771
+ /* ts */
7772
+ `
7773
+ export const createAction = createTRPCServerActionHandler(t, createContext);
7774
+ `
7775
+ );
7776
+ }
7732
7777
  if (middlewares.length > 0) {
7733
7778
  const procName = getProcedureName(config);
7734
7779
  middlewares.forEach((middleware, i) => {
@@ -7950,7 +7995,9 @@ var constructShield = /* @__PURE__ */ __name(async ({ queries, mutations, subscr
7950
7995
  })},`;
7951
7996
  rootItems += subscriptionLinesWrapped;
7952
7997
  }
7953
- if (rootItems.length === 0) return "";
7998
+ if (rootItems.length === 0) {
7999
+ return "";
8000
+ }
7954
8001
  let shieldText = getImports("trpc-shield");
7955
8002
  const internals = await getPrismaInternals();
7956
8003
  const outputDir = internals.parseEnvValue(options.generator.output);
@@ -11617,6 +11664,27 @@ async function generate(options) {
11617
11664
  consoleLog("Skipping tRPC Shield generation");
11618
11665
  }
11619
11666
  consoleLog(`Generating tRPC source code for ${models.length} models`);
11667
+ if (config.trpcOptions && typeof config.trpcOptions === "boolean") {
11668
+ const trpcOptionsOutputPath = joinPaths(outputDir, "options.ts");
11669
+ consoleLog("Generating tRPC options source file");
11670
+ await writeFileSafely(trpcOptionsOutputPath, `import { ZodError } from 'zod';${config.useTRPCNext ? '\nimport { transformer } from "@stryke/trpc-next/shared";' : ""}
11671
+
11672
+ export default {${config.useTRPCNext ? "\n transformer," : ""}
11673
+ errorFormatter({ shape, error }) {
11674
+ return {
11675
+ ...shape,
11676
+ data: {
11677
+ ...shape.data,
11678
+ zodError:
11679
+ error.code === 'BAD_REQUEST' && error.cause instanceof ZodError
11680
+ ? error.cause.flatten()
11681
+ : null,
11682
+ },
11683
+ };
11684
+ },
11685
+ };
11686
+ `);
11687
+ }
11620
11688
  resolveModelsComments(models, hiddenModels);
11621
11689
  const createRouter = project.createSourceFile(path5.resolve(outputDir, "routers", "helpers", "createRouter.ts"), void 0, {
11622
11690
  overwrite: true
@@ -11645,6 +11713,10 @@ async function generate(options) {
11645
11713
  consoleLog(`Skipping model ${model} as it is hidden`);
11646
11714
  continue;
11647
11715
  }
11716
+ if (!model) {
11717
+ consoleLog(`Skipping model ${model} as it is not defined`);
11718
+ continue;
11719
+ }
11648
11720
  const modelActions = Object.keys(operations).filter((opType) => (
11649
11721
  // eslint-disable-next-line unicorn/prefer-includes
11650
11722
  config.generateModelActions.some((generateModelAction) => generateModelAction === opType.replace("One", ""))
@@ -11653,7 +11725,7 @@ async function generate(options) {
11653
11725
  consoleLog(`Skipping model ${model} as it has no actions to generate`);
11654
11726
  continue;
11655
11727
  }
11656
- const plural = (0, import_pluralize.default)(model.toLowerCase());
11728
+ const plural = (0, import_pluralize.default)(lowerCaseFirst(model));
11657
11729
  consoleLog(`Generating tRPC router for model ${model}`);
11658
11730
  generateRouterImport(appRouter, plural, model);
11659
11731
  const modelRouter = project.createSourceFile(path5.resolve(outputDir, "routers", `${model}.router.ts`), void 0, {
package/dist/index.cjs CHANGED
@@ -2627,6 +2627,12 @@ function normalizeString(path6, allowAboveRoot) {
2627
2627
  }
2628
2628
  __name(normalizeString, "normalizeString");
2629
2629
 
2630
+ // ../string-format/src/lower-case-first.ts
2631
+ init_cjs_shims();
2632
+ var lowerCaseFirst = /* @__PURE__ */ __name((input) => {
2633
+ return input ? input.charAt(0).toLowerCase() + input.slice(1) : input;
2634
+ }, "lowerCaseFirst");
2635
+
2630
2636
  // src/prisma-generator.ts
2631
2637
  var import_node_path6 = __toESM(require("node:path"), 1);
2632
2638
  var import_pluralize = __toESM(require_pluralize(), 1);
@@ -6882,8 +6888,9 @@ var configSchema = z.object({
6882
6888
  withShield: configShield.default("true"),
6883
6889
  withZod: configBoolean.default("true"),
6884
6890
  contextPath: z.string().default("../src/trpc/context"),
6885
- trpcOptionsPath: z.string().optional(),
6891
+ trpcOptions: z.boolean().or(z.string()).optional(),
6886
6892
  showModelNameInProcedure: configBoolean.default("true"),
6893
+ useTRPCNext: configBoolean.default("false"),
6887
6894
  generateModelActions: z.string().default(Object.values(ModelAction).join(",")).transform((arg) => {
6888
6895
  return arg.split(",").map((action) => modelActionEnum.parse(action.trim()));
6889
6896
  })
@@ -6892,12 +6899,6 @@ var configSchema = z.object({
6892
6899
  // src/helpers.ts
6893
6900
  init_cjs_shims();
6894
6901
 
6895
- // ../string-format/src/lower-case-first.ts
6896
- init_cjs_shims();
6897
- var lowerCaseFirst = /* @__PURE__ */ __name((input) => {
6898
- return input ? input.charAt(0).toLowerCase() + input.slice(1) : input;
6899
- }, "lowerCaseFirst");
6900
-
6901
6902
  // src/utils/get-prisma-internals.ts
6902
6903
  init_cjs_shims();
6903
6904
 
@@ -7642,24 +7643,35 @@ var generateRouterImport = /* @__PURE__ */ __name((sourceFile, modelNamePlural,
7642
7643
  async function generateBaseRouter(sourceFile, config, options) {
7643
7644
  const internals = await getPrismaInternals();
7644
7645
  const outputDir = internals.parseEnvValue(options.generator.output);
7646
+ const relativeContextPath = getRelativePath(outputDir, config.contextPath, true, options.schemaPath);
7645
7647
  sourceFile.addStatements(
7646
7648
  /* ts */
7647
7649
  `
7648
- import type { Context } from '${getRelativePath(outputDir, config.contextPath, true, options.schemaPath)}';
7650
+ import type { Context } from '${relativeContextPath}';
7649
7651
  `
7650
7652
  );
7651
- if (config.trpcOptionsPath) {
7653
+ if (config.trpcOptions) {
7652
7654
  sourceFile.addStatements(
7653
7655
  /* ts */
7654
7656
  `
7655
- import trpcOptions from '${getRelativePath(outputDir, config.trpcOptionsPath, true, options.schemaPath)}';
7657
+ import trpcOptions from '${getRelativePath(outputDir, typeof config.trpcOptions === "boolean" ? joinPaths(outputDir, "options") : config.trpcOptions, true, options.schemaPath)}';
7656
7658
  `
7657
7659
  );
7658
7660
  }
7661
+ if (config.useTRPCNext) {
7662
+ sourceFile.addStatements(
7663
+ /* ts */
7664
+ `
7665
+ import { createContext } from '${relativeContextPath}';
7666
+ import { initTRPC, TRPCError } from '@trpc/server';
7667
+ import { createTRPCServerActionHandler } from '@stryke/trpc-next/action-handler';
7668
+ `
7669
+ );
7670
+ }
7659
7671
  sourceFile.addStatements(
7660
7672
  /* ts */
7661
7673
  `
7662
- export const t = trpc.initTRPC.context<Context>().create(${config.trpcOptionsPath ? "trpcOptions" : ""});
7674
+ export const t = trpc.initTRPC.context<Context>().create(${config.trpcOptions ? "trpcOptions" : ""});
7663
7675
  `
7664
7676
  );
7665
7677
  const middlewares = [];
@@ -7715,11 +7727,44 @@ async function generateBaseRouter(sourceFile, config, options) {
7715
7727
  )
7716
7728
  });
7717
7729
  }
7730
+ sourceFile.addStatements(
7731
+ /* ts */
7732
+ `
7733
+ /**
7734
+ * Create a server-side caller
7735
+ * @see https://trpc.io/docs/server/server-side-calls
7736
+ */
7737
+ export const createCallerFactory = t.createCallerFactory;`
7738
+ );
7718
7739
  sourceFile.addStatements(
7719
7740
  /* ts */
7720
7741
  `
7721
7742
  export const publicProcedure = t.procedure; `
7722
7743
  );
7744
+ if (config.useTRPCNext) {
7745
+ sourceFile.addStatements(
7746
+ /* ts */
7747
+ `
7748
+ export const protectedProcedure = publicProcedure.use((opts) => {
7749
+ const { session } = opts.ctx;
7750
+
7751
+ if (!session?.user) {
7752
+ throw new TRPCError({
7753
+ code: 'UNAUTHORIZED',
7754
+ });
7755
+ }
7756
+
7757
+ return opts.next({ ctx: { session } });
7758
+ });
7759
+ `
7760
+ );
7761
+ sourceFile.addStatements(
7762
+ /* ts */
7763
+ `
7764
+ export const createAction = createTRPCServerActionHandler(t, createContext);
7765
+ `
7766
+ );
7767
+ }
7723
7768
  if (middlewares.length > 0) {
7724
7769
  const procName = getProcedureName(config);
7725
7770
  middlewares.forEach((middleware, i) => {
@@ -7941,7 +7986,9 @@ var constructShield = /* @__PURE__ */ __name(async ({ queries, mutations, subscr
7941
7986
  })},`;
7942
7987
  rootItems += subscriptionLinesWrapped;
7943
7988
  }
7944
- if (rootItems.length === 0) return "";
7989
+ if (rootItems.length === 0) {
7990
+ return "";
7991
+ }
7945
7992
  let shieldText = getImports("trpc-shield");
7946
7993
  const internals = await getPrismaInternals();
7947
7994
  const outputDir = internals.parseEnvValue(options.generator.output);
@@ -11608,6 +11655,27 @@ async function generate(options) {
11608
11655
  consoleLog("Skipping tRPC Shield generation");
11609
11656
  }
11610
11657
  consoleLog(`Generating tRPC source code for ${models.length} models`);
11658
+ if (config.trpcOptions && typeof config.trpcOptions === "boolean") {
11659
+ const trpcOptionsOutputPath = joinPaths(outputDir, "options.ts");
11660
+ consoleLog("Generating tRPC options source file");
11661
+ await writeFileSafely(trpcOptionsOutputPath, `import { ZodError } from 'zod';${config.useTRPCNext ? '\nimport { transformer } from "@stryke/trpc-next/shared";' : ""}
11662
+
11663
+ export default {${config.useTRPCNext ? "\n transformer," : ""}
11664
+ errorFormatter({ shape, error }) {
11665
+ return {
11666
+ ...shape,
11667
+ data: {
11668
+ ...shape.data,
11669
+ zodError:
11670
+ error.code === 'BAD_REQUEST' && error.cause instanceof ZodError
11671
+ ? error.cause.flatten()
11672
+ : null,
11673
+ },
11674
+ };
11675
+ },
11676
+ };
11677
+ `);
11678
+ }
11611
11679
  resolveModelsComments(models, hiddenModels);
11612
11680
  const createRouter = project.createSourceFile(import_node_path6.default.resolve(outputDir, "routers", "helpers", "createRouter.ts"), void 0, {
11613
11681
  overwrite: true
@@ -11636,6 +11704,10 @@ async function generate(options) {
11636
11704
  consoleLog(`Skipping model ${model} as it is hidden`);
11637
11705
  continue;
11638
11706
  }
11707
+ if (!model) {
11708
+ consoleLog(`Skipping model ${model} as it is not defined`);
11709
+ continue;
11710
+ }
11639
11711
  const modelActions = Object.keys(operations).filter((opType) => (
11640
11712
  // eslint-disable-next-line unicorn/prefer-includes
11641
11713
  config.generateModelActions.some((generateModelAction) => generateModelAction === opType.replace("One", ""))
@@ -11644,7 +11716,7 @@ async function generate(options) {
11644
11716
  consoleLog(`Skipping model ${model} as it has no actions to generate`);
11645
11717
  continue;
11646
11718
  }
11647
- const plural = (0, import_pluralize.default)(model.toLowerCase());
11719
+ const plural = (0, import_pluralize.default)(lowerCaseFirst(model));
11648
11720
  consoleLog(`Generating tRPC router for model ${model}`);
11649
11721
  generateRouterImport(appRouter, plural, model);
11650
11722
  const modelRouter = project.createSourceFile(import_node_path6.default.resolve(outputDir, "routers", `${model}.router.ts`), void 0, {
package/dist/index.js CHANGED
@@ -2632,6 +2632,12 @@ function normalizeString(path6, allowAboveRoot) {
2632
2632
  }
2633
2633
  __name(normalizeString, "normalizeString");
2634
2634
 
2635
+ // ../string-format/src/lower-case-first.ts
2636
+ init_esm_shims();
2637
+ var lowerCaseFirst = /* @__PURE__ */ __name((input) => {
2638
+ return input ? input.charAt(0).toLowerCase() + input.slice(1) : input;
2639
+ }, "lowerCaseFirst");
2640
+
2635
2641
  // src/prisma-generator.ts
2636
2642
  var import_pluralize = __toESM(require_pluralize(), 1);
2637
2643
  import path5 from "node:path";
@@ -6887,8 +6893,9 @@ var configSchema = z.object({
6887
6893
  withShield: configShield.default("true"),
6888
6894
  withZod: configBoolean.default("true"),
6889
6895
  contextPath: z.string().default("../src/trpc/context"),
6890
- trpcOptionsPath: z.string().optional(),
6896
+ trpcOptions: z.boolean().or(z.string()).optional(),
6891
6897
  showModelNameInProcedure: configBoolean.default("true"),
6898
+ useTRPCNext: configBoolean.default("false"),
6892
6899
  generateModelActions: z.string().default(Object.values(ModelAction).join(",")).transform((arg) => {
6893
6900
  return arg.split(",").map((action) => modelActionEnum.parse(action.trim()));
6894
6901
  })
@@ -6897,12 +6904,6 @@ var configSchema = z.object({
6897
6904
  // src/helpers.ts
6898
6905
  init_esm_shims();
6899
6906
 
6900
- // ../string-format/src/lower-case-first.ts
6901
- init_esm_shims();
6902
- var lowerCaseFirst = /* @__PURE__ */ __name((input) => {
6903
- return input ? input.charAt(0).toLowerCase() + input.slice(1) : input;
6904
- }, "lowerCaseFirst");
6905
-
6906
6907
  // src/utils/get-prisma-internals.ts
6907
6908
  init_esm_shims();
6908
6909
 
@@ -7647,24 +7648,35 @@ var generateRouterImport = /* @__PURE__ */ __name((sourceFile, modelNamePlural,
7647
7648
  async function generateBaseRouter(sourceFile, config, options) {
7648
7649
  const internals = await getPrismaInternals();
7649
7650
  const outputDir = internals.parseEnvValue(options.generator.output);
7651
+ const relativeContextPath = getRelativePath(outputDir, config.contextPath, true, options.schemaPath);
7650
7652
  sourceFile.addStatements(
7651
7653
  /* ts */
7652
7654
  `
7653
- import type { Context } from '${getRelativePath(outputDir, config.contextPath, true, options.schemaPath)}';
7655
+ import type { Context } from '${relativeContextPath}';
7654
7656
  `
7655
7657
  );
7656
- if (config.trpcOptionsPath) {
7658
+ if (config.trpcOptions) {
7657
7659
  sourceFile.addStatements(
7658
7660
  /* ts */
7659
7661
  `
7660
- import trpcOptions from '${getRelativePath(outputDir, config.trpcOptionsPath, true, options.schemaPath)}';
7662
+ import trpcOptions from '${getRelativePath(outputDir, typeof config.trpcOptions === "boolean" ? joinPaths(outputDir, "options") : config.trpcOptions, true, options.schemaPath)}';
7661
7663
  `
7662
7664
  );
7663
7665
  }
7666
+ if (config.useTRPCNext) {
7667
+ sourceFile.addStatements(
7668
+ /* ts */
7669
+ `
7670
+ import { createContext } from '${relativeContextPath}';
7671
+ import { initTRPC, TRPCError } from '@trpc/server';
7672
+ import { createTRPCServerActionHandler } from '@stryke/trpc-next/action-handler';
7673
+ `
7674
+ );
7675
+ }
7664
7676
  sourceFile.addStatements(
7665
7677
  /* ts */
7666
7678
  `
7667
- export const t = trpc.initTRPC.context<Context>().create(${config.trpcOptionsPath ? "trpcOptions" : ""});
7679
+ export const t = trpc.initTRPC.context<Context>().create(${config.trpcOptions ? "trpcOptions" : ""});
7668
7680
  `
7669
7681
  );
7670
7682
  const middlewares = [];
@@ -7720,11 +7732,44 @@ async function generateBaseRouter(sourceFile, config, options) {
7720
7732
  )
7721
7733
  });
7722
7734
  }
7735
+ sourceFile.addStatements(
7736
+ /* ts */
7737
+ `
7738
+ /**
7739
+ * Create a server-side caller
7740
+ * @see https://trpc.io/docs/server/server-side-calls
7741
+ */
7742
+ export const createCallerFactory = t.createCallerFactory;`
7743
+ );
7723
7744
  sourceFile.addStatements(
7724
7745
  /* ts */
7725
7746
  `
7726
7747
  export const publicProcedure = t.procedure; `
7727
7748
  );
7749
+ if (config.useTRPCNext) {
7750
+ sourceFile.addStatements(
7751
+ /* ts */
7752
+ `
7753
+ export const protectedProcedure = publicProcedure.use((opts) => {
7754
+ const { session } = opts.ctx;
7755
+
7756
+ if (!session?.user) {
7757
+ throw new TRPCError({
7758
+ code: 'UNAUTHORIZED',
7759
+ });
7760
+ }
7761
+
7762
+ return opts.next({ ctx: { session } });
7763
+ });
7764
+ `
7765
+ );
7766
+ sourceFile.addStatements(
7767
+ /* ts */
7768
+ `
7769
+ export const createAction = createTRPCServerActionHandler(t, createContext);
7770
+ `
7771
+ );
7772
+ }
7728
7773
  if (middlewares.length > 0) {
7729
7774
  const procName = getProcedureName(config);
7730
7775
  middlewares.forEach((middleware, i) => {
@@ -7946,7 +7991,9 @@ var constructShield = /* @__PURE__ */ __name(async ({ queries, mutations, subscr
7946
7991
  })},`;
7947
7992
  rootItems += subscriptionLinesWrapped;
7948
7993
  }
7949
- if (rootItems.length === 0) return "";
7994
+ if (rootItems.length === 0) {
7995
+ return "";
7996
+ }
7950
7997
  let shieldText = getImports("trpc-shield");
7951
7998
  const internals = await getPrismaInternals();
7952
7999
  const outputDir = internals.parseEnvValue(options.generator.output);
@@ -11613,6 +11660,27 @@ async function generate(options) {
11613
11660
  consoleLog("Skipping tRPC Shield generation");
11614
11661
  }
11615
11662
  consoleLog(`Generating tRPC source code for ${models.length} models`);
11663
+ if (config.trpcOptions && typeof config.trpcOptions === "boolean") {
11664
+ const trpcOptionsOutputPath = joinPaths(outputDir, "options.ts");
11665
+ consoleLog("Generating tRPC options source file");
11666
+ await writeFileSafely(trpcOptionsOutputPath, `import { ZodError } from 'zod';${config.useTRPCNext ? '\nimport { transformer } from "@stryke/trpc-next/shared";' : ""}
11667
+
11668
+ export default {${config.useTRPCNext ? "\n transformer," : ""}
11669
+ errorFormatter({ shape, error }) {
11670
+ return {
11671
+ ...shape,
11672
+ data: {
11673
+ ...shape.data,
11674
+ zodError:
11675
+ error.code === 'BAD_REQUEST' && error.cause instanceof ZodError
11676
+ ? error.cause.flatten()
11677
+ : null,
11678
+ },
11679
+ };
11680
+ },
11681
+ };
11682
+ `);
11683
+ }
11616
11684
  resolveModelsComments(models, hiddenModels);
11617
11685
  const createRouter = project.createSourceFile(path5.resolve(outputDir, "routers", "helpers", "createRouter.ts"), void 0, {
11618
11686
  overwrite: true
@@ -11641,6 +11709,10 @@ async function generate(options) {
11641
11709
  consoleLog(`Skipping model ${model} as it is hidden`);
11642
11710
  continue;
11643
11711
  }
11712
+ if (!model) {
11713
+ consoleLog(`Skipping model ${model} as it is not defined`);
11714
+ continue;
11715
+ }
11644
11716
  const modelActions = Object.keys(operations).filter((opType) => (
11645
11717
  // eslint-disable-next-line unicorn/prefer-includes
11646
11718
  config.generateModelActions.some((generateModelAction) => generateModelAction === opType.replace("One", ""))
@@ -11649,7 +11721,7 @@ async function generate(options) {
11649
11721
  consoleLog(`Skipping model ${model} as it has no actions to generate`);
11650
11722
  continue;
11651
11723
  }
11652
- const plural = (0, import_pluralize.default)(model.toLowerCase());
11724
+ const plural = (0, import_pluralize.default)(lowerCaseFirst(model));
11653
11725
  consoleLog(`Generating tRPC router for model ${model}`);
11654
11726
  generateRouterImport(appRouter, plural, model);
11655
11727
  const modelRouter = project.createSourceFile(path5.resolve(outputDir, "routers", `${model}.router.ts`), void 0, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stryke/prisma-trpc-generator",
3
- "version": "0.4.8",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "description": "A fork of the prisma-trpc-generator code to work in ESM with Prisma v6.",
6
6
  "repository": {