Repository: Quramy/prisma-fabbrica
Pull request #2 (2022-11-17 16:22:15)

Rename generated functions


Patch:
diff --git a/examples/example-prj/.gitignore b/examples/example-prj/.gitignore
index 70da772..6d81dbe 100644
--- a/examples/example-prj/.gitignore
+++ b/examples/example-prj/.gitignore
@@ -3,4 +3,3 @@ node_modules
 .env
 prisma/*.db
 prisma/*.db-journal
-__generated__/
diff --git a/examples/example-prj/src/__generated__/fabbrica.ts b/examples/example-prj/src/__generated__/fabbrica.ts
new file mode 100644
index 0000000..aede79e
--- /dev/null
+++ b/examples/example-prj/src/__generated__/fabbrica.ts
@@ -0,0 +1,58 @@
+import { Prisma } from "@prisma/client";
+import { getClient } from "@quramy/prisma-fabbrica";
+import scalarFieldValueGenerator from "@quramy/prisma-fabbrica/lib/scalar/gen";
+import { Resolver, resolveValue } from "@quramy/prisma-fabbrica/lib/helpers";
+type UserScalarFields = {
+    id: string;
+    name: string;
+};
+type UserFactoryDefineInput = {
+    id?: string;
+    name?: string;
+    posts?: Prisma.PostCreateNestedManyWithoutAuthorInput;
+};
+type UserFactoryDefineOptions = {
+    defaultData: Resolver<UserFactoryDefineInput>;
+};
+function autoGenrateUserScalars(): UserScalarFields {
+    return {
+        id: scalarFieldValueGenerator.String({ modelName: "User", fieldName: "id", isId: true, isUnique: false }),
+        name: scalarFieldValueGenerator.String({ modelName: "User", fieldName: "name", isId: false, isUnique: false })
+    };
+}
+export function defineUserFactory({ defaultData: defaultDataResolver }: UserFactoryDefineOptions) {
+    const create = async (inputData: Partial<Prisma.UserCreateInput> = {}) => {
+        const requiredScalarData = autoGenrateUserScalars();
+        const defaultData = await resolveValue(defaultDataResolver);
+        const data = { ...requiredScalarData, ...defaultData, ...inputData };
+        return await getClient().user.create({ data });
+    };
+    return { create };
+}
+type PostScalarFields = {
+    id: string;
+    title: string;
+};
+type PostFactoryDefineInput = {
+    id?: string;
+    title?: string;
+    author: Prisma.UserCreateNestedOneWithoutPostsInput;
+};
+type PostFactoryDefineOptions = {
+    defaultData: Resolver<PostFactoryDefineInput>;
+};
+function autoGenratePostScalars(): PostScalarFields {
+    return {
+        id: scalarFieldValueGenerator.String({ modelName: "Post", fieldName: "id", isId: true, isUnique: false }),
+        title: scalarFieldValueGenerator.String({ modelName: "Post", fieldName: "title", isId: false, isUnique: false })
+    };
+}
+export function definePostFactory({ defaultData: defaultDataResolver }: PostFactoryDefineOptions) {
+    const create = async (inputData: Partial<Prisma.PostCreateInput> = {}) => {
+        const requiredScalarData = autoGenratePostScalars();
+        const defaultData = await resolveValue(defaultDataResolver);
+        const data = { ...requiredScalarData, ...defaultData, ...inputData };
+        return await getClient().post.create({ data });
+    };
+    return { create };
+}
diff --git a/packages/prisma-fabbrica/src/generator.ts b/packages/prisma-fabbrica/src/generator.ts
index dbd7aa5..5297d63 100644
--- a/packages/prisma-fabbrica/src/generator.ts
+++ b/packages/prisma-fabbrica/src/generator.ts
@@ -11,7 +11,7 @@ import { getSourceFile } from "./templates";
 generatorHandler({
   onManifest: () => ({
     prettyName: "fabbrica",
-    defaultOutput: "../src/__generated__/factories.ts",
+    defaultOutput: "../src/__generated__/fabbrica.ts",
     requiresGenerators: ["prisma-client-js"],
   }),
   onGenerate: async options => {
diff --git a/packages/prisma-fabbrica/src/helpers/index.ts b/packages/prisma-fabbrica/src/helpers/index.ts
new file mode 100644
index 0000000..6649f6f
--- /dev/null
+++ b/packages/prisma-fabbrica/src/helpers/index.ts
@@ -0,0 +1,1 @@
+export * from "./valueResolver";
diff --git a/packages/prisma-fabbrica/src/helpers/valueResolver.ts b/packages/prisma-fabbrica/src/helpers/valueResolver.ts
new file mode 100644
index 0000000..edfdea7
--- /dev/null
+++ b/packages/prisma-fabbrica/src/helpers/valueResolver.ts
@@ -0,0 +1,6 @@
+export type Resolver<T extends Record<string, unknown>> = T | (() => T) | (() => PromiseLike<T>);
+
+export async function resolveValue<T extends Record<string, unknown>>(resolver: Resolver<T>) {
+  const fn = typeof resolver === "function" ? resolver : () => Promise.resolve(resolver);
+  return (await fn()) as T;
+}
diff --git a/packages/prisma-fabbrica/src/templates/index.ts b/packages/prisma-fabbrica/src/templates/index.ts
index 90f3cff..d6d5d84 100644
--- a/packages/prisma-fabbrica/src/templates/index.ts
+++ b/packages/prisma-fabbrica/src/templates/index.ts
@@ -35,21 +35,8 @@ export const header = template.sourceFile`
   import { Prisma } from "@prisma/client";
   import { getClient } from "@quramy/prisma-fabbrica";
   import scalarFieldValueGenerator from "@quramy/prisma-fabbrica/lib/scalar/gen";
+  import { Resolver, resolveValue } from "@quramy/prisma-fabbrica/lib/helpers";
   
-  type Resolver<T extends Record<string, unknown>> =
-    | T
-    | (() => T)
-    | (() => PromiseLike<T>);
-  
-  async function resolveValue<T extends Record<string, unknown>>(
-    resolver: Resolver<T>
-  ) {
-    const fn =
-      typeof resolver === "function" ? resolver : () => Promise.resolve(resolver);
-    return (await fn()) as T;
-  }
-
-  const defineFnMap = new Map<unknown, (options: any) => unknown>();
 `;
 
 export const scalarFieldType = (
@@ -131,13 +118,13 @@ export const modelFactoryDefineInput = (modelName: string, inputTpue: DMMF.Input
     ]),
   });
 
-export const defineModelFactoryOptions = (modelName: string) =>
+export const modelFactoryDefineOptions = (modelName: string) =>
   template.statement<ts.TypeAliasDeclaration>`
-    type DEFINE_MODEL_FACTORY_OPTIONS = {
-      defaultAttrs: Resolver<MODEL_FACTORY_DEFINE_INPUT>;
+    type MODEL_FACTORY_DEFINE_OPTIONS = {
+      defaultData: Resolver<MODEL_FACTORY_DEFINE_INPUT>;
     };
   `({
-    DEFINE_MODEL_FACTORY_OPTIONS: ts.factory.createIdentifier(`Define${modelName}FactoryOptions`),
+    MODEL_FACTORY_DEFINE_OPTIONS: ts.factory.createIdentifier(`${modelName}FactoryDefineOptions`),
     MODEL_FACTORY_DEFINE_INPUT: ts.factory.createIdentifier(`${modelName}FactoryDefineInput`),
   });
 
@@ -174,15 +161,15 @@ export const autoGenrateModelScalars = (modelName: string, inputType: DMMF.Input
 
 export const defineModelFactory = (modelName: string) =>
   template.statement<ts.FunctionDeclaration>`
-    function DEFINE_MODEL_FACTORY({
-      defaultAttrs: defaultAttributesResolver
-    }: DEFINE_MODEL_FACTORY_OPTIONS) {
+    export function DEFINE_MODEL_FACTORY({
+      defaultData: defaultDataResolver
+    }: MODEL_FACTORY_DEFINE_OPTIONS) {
       const create = async (
-        inputAttributes: Partial<Prisma.MODEL_CREATE_INPUT> = {}
+        inputData: Partial<Prisma.MODEL_CREATE_INPUT> = {}
       ) => {
-        const scalarsAttributes = AUTO_GENRATE_MODEL_SCALARS()
-        const defaultAttributes = await resolveValue(defaultAttributesResolver);
-        const data = { ...scalarsAttributes, ...defaultAttributes, ...inputAttributes };
+        const requiredScalarData = AUTO_GENRATE_MODEL_SCALARS()
+        const defaultData= await resolveValue(defaultDataResolver);
+        const data = { ...requiredScalarData, ...defaultData, ...inputData};
         return await getClient().MODEL_KEY.create({ data });
       };
       return { create };
@@ -190,7 +177,7 @@ export const defineModelFactory = (modelName: string) =>
   `({
     MODEL_KEY: ts.factory.createIdentifier(camelize(modelName)),
     DEFINE_MODEL_FACTORY: ts.factory.createIdentifier(`define${modelName}Factory`),
-    DEFINE_MODEL_FACTORY_OPTIONS: ts.factory.createIdentifier(`Define${modelName}FactoryOptions`),
+    MODEL_FACTORY_DEFINE_OPTIONS: ts.factory.createIdentifier(`${modelName}FactoryDefineOptions`),
     MODEL_CREATE_INPUT: ts.factory.createIdentifier(`${modelName}CreateInput`),
     AUTO_GENRATE_MODEL_SCALARS: ts.factory.createIdentifier(`autoGenrate${modelName}Scalars`),
   });
@@ -203,39 +190,16 @@ export const defineFnMapSet = (modelName: string) =>
     DEFINE_MODEL_FACTORY: ts.factory.createIdentifier(`define${modelName}Factory`),
   });
 
-export const defineFactoryOverload = (modelName: string) =>
-  template.statement<ts.FunctionDeclaration>`
-    export function defineFactory(
-      name: MODEL_NAME,
-      options: DEFINE_MODEL_FACTORY_OPTIONS,
-    ): ReturnType<typeof DEFINE_MODEL_FACTORY>;
-  `({
-    MODEL_NAME: ts.factory.createStringLiteral(modelName),
-    DEFINE_MODEL_FACTORY: ts.factory.createIdentifier(`define${modelName}Factory`),
-    DEFINE_MODEL_FACTORY_OPTIONS: ts.factory.createIdentifier(`Define${modelName}FactoryOptions`),
-  });
-
-export const defineFactoryImpl = template.statement`
-  export function defineFactory(name: unknown, options: unknown): unknown {
-    const defineFn = defineFnMap.get(name);
-    if (!defineFn) throw new Error("Invalid model name");
-    return defineFn(options);
-  }
-`;
-
 export function getSourceFile(document: DMMF.Document) {
   const statements = [
     ...header().statements,
     ...document.datamodel.models.flatMap(model => [
       modelScalarFields(model.name, findPrsimaCreateInputTypeFromModelName(document, model.name)),
       modelFactoryDefineInput(model.name, findPrsimaCreateInputTypeFromModelName(document, model.name)),
-      defineModelFactoryOptions(model.name),
+      modelFactoryDefineOptions(model.name),
       autoGenrateModelScalars(model.name, findPrsimaCreateInputTypeFromModelName(document, model.name), model),
       defineModelFactory(model.name),
     ]),
-    ...document.datamodel.models.map(model => defineFnMapSet(model.name)),
-    ...document.datamodel.models.map(model => defineFactoryOverload(model.name)),
-    defineFactoryImpl(),
   ];
 
   return ts.factory.updateSourceFile(header(), statements);


Test patch:
diff --git a/examples/example-prj/src/sample.test.ts b/examples/example-prj/src/sample.test.ts
index a31fba1..efd19ee 100644
--- a/examples/example-prj/src/sample.test.ts
+++ b/examples/example-prj/src/sample.test.ts
@@ -1,11 +1,11 @@
-import { defineFactory } from "./__generated__/factories";
+import { defineUserFactory, definePostFactory } from "./__generated__/fabbrica";
 
-const UserFactory = defineFactory("User", {
-  defaultAttrs: {},
+const UserFactory = defineUserFactory({
+  defaultData: {},
 });
 
-const PostFactory = defineFactory("Post", {
-  defaultAttrs: async () => ({
+const PostFactory = definePostFactory({
+  defaultData: async () => ({
     author: {
       connect: {
         id: (await UserFactory.create()).id,
diff --git a/packages/prisma-fabbrica/src/__snapshots__/templates.test.ts.snap b/packages/prisma-fabbrica/src/__snapshots__/templates.test.ts.snap
deleted file mode 100644
index 77c32de..0000000
--- a/packages/prisma-fabbrica/src/__snapshots__/templates.test.ts.snap
+++ /dev/null
@@ -1,48 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`getSourceFile generates TypeScript AST 1`] = `
-"import { Prisma } from "@prisma/client";
-import { getClient } from "@quramy/prisma-fabbrica";
-import scalarFieldValueGenerator from "@quramy/prisma-fabbrica/lib/scalar/gen";
-type Resolver<T extends Record<string, unknown>> = T | (() => T) | (() => PromiseLike<T>);
-async function resolveValue<T extends Record<string, unknown>>(resolver: Resolver<T>) {
-    const fn = typeof resolver === "function" ? resolver : () => Promise.resolve(resolver);
-    return (await fn()) as T;
-}
-const defineFnMap = new Map<unknown, (options: any) => unknown>();
-type UserScalarFields = {
-    id: number;
-    name: string;
-};
-type UserFactoryDefineInput = {
-    id?: number;
-    name?: string;
-};
-type DefineUserFactoryOptions = {
-    defaultAttrs: Resolver<UserFactoryDefineInput>;
-};
-function autoGenrateUserScalars(): UserScalarFields {
-    return {
-        id: scalarFieldValueGenerator.Int({ modelName: "User", fieldName: "id", isId: true, isUnique: false }),
-        name: scalarFieldValueGenerator.String({ modelName: "User", fieldName: "name", isId: false, isUnique: false })
-    };
-}
-function defineUserFactory({ defaultAttrs: defaultAttributesResolver }: DefineUserFactoryOptions) {
-    const create = async (inputAttributes: Partial<Prisma.UserCreateInput> = {}) => {
-        const scalarsAttributes = autoGenrateUserScalars();
-        const defaultAttributes = await resolveValue(defaultAttributesResolver);
-        const data = { ...scalarsAttributes, ...defaultAttributes, ...inputAttributes };
-        return await getClient().user.create({ data });
-    };
-    return { create };
-}
-defineFnMap.set("User", defineUserFactory);
-export function defineFactory(name: "User", options: DefineUserFactoryOptions): ReturnType<typeof defineUserFactory>;
-export function defineFactory(name: unknown, options: unknown): unknown {
-    const defineFn = defineFnMap.get(name);
-    if (!defineFn)
-        throw new Error("Invalid model name");
-    return defineFn(options);
-}
-"
-`;
diff --git a/packages/prisma-fabbrica/src/templates/__snapshots__/index.test.ts.snap b/packages/prisma-fabbrica/src/templates/__snapshots__/index.test.ts.snap
new file mode 100644
index 0000000..a3150ca
--- /dev/null
+++ b/packages/prisma-fabbrica/src/templates/__snapshots__/index.test.ts.snap
@@ -0,0 +1,35 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`getSourceFile generates TypeScript AST 1`] = `
+"import { Prisma } from "@prisma/client";
+import { getClient } from "@quramy/prisma-fabbrica";
+import scalarFieldValueGenerator from "@quramy/prisma-fabbrica/lib/scalar/gen";
+import { Resolver, resolveValue } from "@quramy/prisma-fabbrica/lib/helpers";
+type UserScalarFields = {
+    id: number;
+    name: string;
+};
+type UserFactoryDefineInput = {
+    id?: number;
+    name?: string;
+};
+type UserFactoryDefineOptions = {
+    defaultData: Resolver<UserFactoryDefineInput>;
+};
+function autoGenrateUserScalars(): UserScalarFields {
+    return {
+        id: scalarFieldValueGenerator.Int({ modelName: "User", fieldName: "id", isId: true, isUnique: false }),
+        name: scalarFieldValueGenerator.String({ modelName: "User", fieldName: "name", isId: false, isUnique: false })
+    };
+}
+export function defineUserFactory({ defaultData: defaultDataResolver }: UserFactoryDefineOptions) {
+    const create = async (inputData: Partial<Prisma.UserCreateInput> = {}) => {
+        const requiredScalarData = autoGenrateUserScalars();
+        const defaultData = await resolveValue(defaultDataResolver);
+        const data = { ...requiredScalarData, ...defaultData, ...inputData };
+        return await getClient().user.create({ data });
+    };
+    return { create };
+}
+"
+`;
diff --git a/packages/prisma-fabbrica/src/templates.test.ts b/packages/prisma-fabbrica/src/templates/index.test.ts
similarity index 97%
rename from packages/prisma-fabbrica/src/templates.test.ts
rename to packages/prisma-fabbrica/src/templates/index.test.ts
index 607700c..969f9e1 100644
--- a/packages/prisma-fabbrica/src/templates.test.ts
+++ b/packages/prisma-fabbrica/src/templates/index.test.ts
@@ -1,7 +1,7 @@
 import { getDMMF } from "@prisma/internals";
 import { template, printNode } from "talt";
 
-import { modelScalarFields, getSourceFile, findPrsimaCreateInputTypeFromModelName } from "./templates";
+import { modelScalarFields, getSourceFile, findPrsimaCreateInputTypeFromModelName } from ".";
 
 describe(modelScalarFields, () => {
   it("generates literal type field type pattern", async () => {