@casekit/orm2-testing 1.0.0 → 1.0.2

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.
@@ -0,0 +1,6 @@
1
+ import { NormalizedConfig } from "@casekit/orm2-config";
2
+ import { ModelDefinitions, ModelName, ModelType } from "@casekit/orm2-schema";
3
+ export type Factory<Models extends ModelDefinitions> = {
4
+ [M in ModelName<Models>]: (overrides?: Partial<ModelType<Models[M]>>) => ModelType<Models[M]>;
5
+ };
6
+ export declare const makeFactory: <Models extends ModelDefinitions>(config: NormalizedConfig) => Factory<Models>;
@@ -0,0 +1,30 @@
1
+ import { mapValues, uniq } from "es-toolkit";
2
+ import { z } from "zod";
3
+ import { generate } from "./generate.js";
4
+ export const makeFactory = (config) => {
5
+ return mapValues(config.models, (model) => {
6
+ // We never want to generate foreign key values
7
+ // as there's no way for us to know how to generate
8
+ // valid ones. This is up to the user to provide.
9
+ const fkOverrides = Object.fromEntries(uniq(model.foreignKeys.flatMap((fk) => fk.fields)).map((fk) => [
10
+ fk,
11
+ null,
12
+ ]));
13
+ const fields = Object.entries(model.fields)
14
+ .filter(([_, f]) => !f.provided)
15
+ .map(([name, f]) => [
16
+ name,
17
+ f.default
18
+ ? f.zodSchema.optional()
19
+ : f.nullable
20
+ ? f.zodSchema.nullable()
21
+ : f.zodSchema,
22
+ ]);
23
+ const schema = z.object(Object.fromEntries(fields));
24
+ return (overrides) => ({
25
+ ...generate(schema),
26
+ ...fkOverrides,
27
+ ...overrides,
28
+ });
29
+ });
30
+ };
@@ -0,0 +1,2 @@
1
+ import { ZodType } from "zod";
2
+ export declare const generate: <T>(schema: ZodType<T>, overrides?: Partial<T>) => T;
@@ -1,49 +1,58 @@
1
1
  import { faker } from "@faker-js/faker";
2
- import z, { ZodObject, ZodType } from "zod";
3
- import { $ZodType } from "zod/v4/core";
4
-
5
- const generateInner = <T>(schema: $ZodType<T>): unknown => {
2
+ import z, { ZodObject } from "zod";
3
+ const generateInner = (schema) => {
6
4
  if (schema instanceof ZodObject) {
7
5
  const shape = schema.shape;
8
- const result: Record<string, unknown> = {};
6
+ const result = {};
9
7
  for (const key in shape) {
10
8
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
11
9
  result[key] = generateInner(shape[key]);
12
10
  }
13
- return result as T;
14
- } else if (schema instanceof z.ZodOptional) {
11
+ return result;
12
+ }
13
+ else if (schema instanceof z.ZodOptional) {
15
14
  return generateInner(schema.def.innerType);
16
- } else if (schema instanceof z.ZodRecord) {
15
+ }
16
+ else if (schema instanceof z.ZodRecord) {
17
17
  return {
18
18
  a: generateInner(schema.valueType),
19
19
  b: generateInner(schema.valueType),
20
20
  c: generateInner(schema.valueType),
21
21
  };
22
- } else if (schema instanceof z.ZodEnum) {
22
+ }
23
+ else if (schema instanceof z.ZodEnum) {
23
24
  return faker.helpers.arrayElement(Object.values(schema.def.entries));
24
- } else if (schema instanceof z.ZodArray) {
25
+ }
26
+ else if (schema instanceof z.ZodArray) {
25
27
  return faker.helpers.multiple(() => generateInner(schema.element), {
26
28
  count: { min: 1, max: 3 },
27
29
  });
28
- } else if (schema instanceof z.ZodDate) {
30
+ }
31
+ else if (schema instanceof z.ZodDate) {
29
32
  return faker.date.past();
30
- } else if (schema instanceof z.ZodBoolean) {
33
+ }
34
+ else if (schema instanceof z.ZodBoolean) {
31
35
  return faker.datatype.boolean();
32
- } else if (schema instanceof z.ZodUUID) {
36
+ }
37
+ else if (schema instanceof z.ZodUUID) {
33
38
  return faker.string.uuid();
34
- } else if (schema instanceof z.ZodString) {
39
+ }
40
+ else if (schema instanceof z.ZodString) {
35
41
  return faker.lorem.word();
36
- } else if (schema instanceof z.ZodEmail) {
42
+ }
43
+ else if (schema instanceof z.ZodEmail) {
37
44
  return faker.internet.exampleEmail();
38
- } else if (schema instanceof z.ZodBigInt) {
45
+ }
46
+ else if (schema instanceof z.ZodBigInt) {
39
47
  return faker.number.int({ min: 1, max: 100 });
40
- } else if (schema instanceof z.ZodNumber) {
48
+ }
49
+ else if (schema instanceof z.ZodNumber) {
41
50
  return faker.number.int({ min: 1, max: 100 });
42
- } else {
51
+ }
52
+ else {
43
53
  return undefined;
44
54
  }
45
55
  };
46
-
47
- export const generate = <T>(schema: ZodType<T>, overrides?: Partial<T>): T => {
48
- return { ...(generateInner(schema) as T), ...overrides };
56
+ export const generate = (schema, overrides) => {
57
+ return { ...generateInner(schema), ...overrides };
49
58
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,23 +1,18 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
  import { z } from "zod";
3
-
4
3
  import { generate } from "./generate.js";
5
-
6
4
  describe("generate", () => {
7
5
  it("generates a simple object with string fields", () => {
8
6
  const schema = z.object({
9
7
  name: z.string(),
10
8
  description: z.string(),
11
9
  });
12
-
13
10
  const result = generate(schema);
14
-
15
11
  expect(result).toEqual({
16
12
  name: expect.any(String),
17
13
  description: expect.any(String),
18
14
  });
19
15
  });
20
-
21
16
  it("generates an object with various field types", () => {
22
17
  const schema = z.object({
23
18
  id: z.uuid(),
@@ -27,9 +22,7 @@ describe("generate", () => {
27
22
  createdAt: z.date(),
28
23
  balance: z.bigint(),
29
24
  });
30
-
31
25
  const result = generate(schema);
32
-
33
26
  expect(result).toEqual({
34
27
  id: expect.stringMatching(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/),
35
28
  name: expect.any(String),
@@ -39,7 +32,6 @@ describe("generate", () => {
39
32
  balance: expect.any(Number),
40
33
  });
41
34
  });
42
-
43
35
  it("generates nested objects", () => {
44
36
  const schema = z.object({
45
37
  user: z.object({
@@ -51,9 +43,7 @@ describe("generate", () => {
51
43
  theme: z.string(),
52
44
  }),
53
45
  });
54
-
55
46
  const result = generate(schema);
56
-
57
47
  expect(result).toEqual({
58
48
  user: {
59
49
  name: expect.any(String),
@@ -65,27 +55,21 @@ describe("generate", () => {
65
55
  },
66
56
  });
67
57
  });
68
-
69
58
  it("generates arrays", () => {
70
59
  const schema = z.object({
71
60
  tags: z.array(z.string()),
72
61
  scores: z.array(z.number()),
73
62
  });
74
-
75
63
  const result = generate(schema);
76
-
77
64
  expect(result.tags).toEqual(expect.arrayContaining([expect.any(String)]));
78
65
  expect(result.scores).toEqual(expect.arrayContaining([expect.any(Number)]));
79
66
  });
80
-
81
67
  it("generates records", () => {
82
68
  const schema = z.object({
83
69
  metadata: z.record(z.string(), z.string()),
84
70
  counts: z.record(z.number(), z.string()),
85
71
  });
86
-
87
72
  const result = generate(schema);
88
-
89
73
  expect(result).toEqual({
90
74
  metadata: {
91
75
  a: expect.any(String),
@@ -99,19 +83,14 @@ describe("generate", () => {
99
83
  },
100
84
  });
101
85
  });
102
-
103
86
  it("generates arrays of objects", () => {
104
87
  const schema = z.object({
105
- users: z.array(
106
- z.object({
107
- id: z.string().uuid(),
108
- name: z.string(),
109
- }),
110
- ),
88
+ users: z.array(z.object({
89
+ id: z.string().uuid(),
90
+ name: z.string(),
91
+ })),
111
92
  });
112
-
113
93
  const result = generate(schema);
114
-
115
94
  expect(result).toEqual({
116
95
  users: expect.arrayContaining([
117
96
  expect.objectContaining({
@@ -121,44 +100,37 @@ describe("generate", () => {
121
100
  ]),
122
101
  });
123
102
  });
124
-
125
103
  it("applies overrides to generated data", () => {
126
104
  const schema = z.object({
127
105
  name: z.string(),
128
106
  age: z.number(),
129
107
  isActive: z.boolean(),
130
108
  });
131
-
132
109
  const result = generate(schema, {
133
110
  name: "John Doe",
134
111
  age: 30,
135
112
  });
136
-
137
113
  expect(result).toEqual({
138
114
  name: "John Doe",
139
115
  age: 30,
140
116
  isActive: expect.any(Boolean),
141
117
  });
142
118
  });
143
-
144
119
  it("handles partial overrides", () => {
145
120
  const schema = z.object({
146
121
  id: z.string().uuid(),
147
122
  name: z.string(),
148
123
  email: z.string(),
149
124
  });
150
-
151
125
  const result = generate(schema, {
152
126
  name: "Jane Smith",
153
127
  });
154
-
155
128
  expect(result).toEqual({
156
129
  id: expect.stringMatching(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/),
157
130
  name: "Jane Smith",
158
131
  email: expect.any(String),
159
132
  });
160
133
  });
161
-
162
134
  it("generates deeply nested structures", () => {
163
135
  const schema = z.object({
164
136
  level1: z.object({
@@ -169,9 +141,7 @@ describe("generate", () => {
169
141
  }),
170
142
  }),
171
143
  });
172
-
173
144
  const result = generate(schema);
174
-
175
145
  expect(result).toEqual({
176
146
  level1: {
177
147
  level2: {
@@ -182,39 +152,31 @@ describe("generate", () => {
182
152
  },
183
153
  });
184
154
  });
185
-
186
155
  it("handles unknown schema types by returning undefined", () => {
187
- const customSchema = z.custom<string>((val) => typeof val === "string");
156
+ const customSchema = z.custom((val) => typeof val === "string");
188
157
  const schema = z.object({
189
158
  custom: customSchema,
190
159
  });
191
-
192
160
  const result = generate(schema);
193
-
194
161
  expect(result).toEqual({
195
162
  custom: undefined,
196
163
  });
197
164
  });
198
-
199
165
  it("generates complex mixed structures", () => {
200
166
  const schema = z.object({
201
167
  company: z.object({
202
168
  name: z.string(),
203
169
  founded: z.date(),
204
- employees: z.array(
205
- z.object({
206
- id: z.uuid(),
207
- name: z.string(),
208
- email: z.string(),
209
- active: z.boolean(),
210
- }),
211
- ),
170
+ employees: z.array(z.object({
171
+ id: z.uuid(),
172
+ name: z.string(),
173
+ email: z.string(),
174
+ active: z.boolean(),
175
+ })),
212
176
  metadata: z.record(z.string(), z.string()),
213
177
  }),
214
178
  });
215
-
216
179
  const result = generate(schema);
217
-
218
180
  expect(result).toEqual({
219
181
  company: {
220
182
  name: expect.any(String),
package/build/index.js ADDED
@@ -0,0 +1 @@
1
+ export { makeFactory } from "./factory.js";
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@casekit/orm2-testing",
3
3
  "description": "",
4
- "version": "1.0.0",
4
+ "version": "1.0.2",
5
5
  "author": "",
6
6
  "dependencies": {
7
7
  "@faker-js/faker": "^9.8.0",
8
8
  "es-toolkit": "^1.39.3",
9
- "@casekit/orm2-config": "1.0.0",
10
- "@casekit/sql": "1.0.0",
11
- "@casekit/toolbox": "1.0.0",
12
- "@casekit/orm2-schema": "1.0.0"
9
+ "@casekit/orm2-config": "1.0.2",
10
+ "@casekit/orm2-schema": "1.0.2",
11
+ "@casekit/sql": "1.0.2",
12
+ "@casekit/toolbox": "1.0.2"
13
13
  },
14
14
  "devDependencies": {
15
15
  "@trivago/prettier-plugin-sort-imports": "^5.2.2",
@@ -19,17 +19,17 @@
19
19
  "prettier-plugin-svelte": "^3.4.0",
20
20
  "vite-tsconfig-paths": "^5.1.4",
21
21
  "vitest": "^3.2.4",
22
- "@casekit/prettier-config": "1.0.0",
23
- "@casekit/tsconfig": "1.0.0"
22
+ "@casekit/tsconfig": "1.0.2",
23
+ "@casekit/prettier-config": "1.0.2"
24
24
  },
25
25
  "exports": {
26
- ".": "./src/index.ts"
26
+ ".": "./build/index.js"
27
27
  },
28
28
  "files": [
29
- "/src"
29
+ "/build"
30
30
  ],
31
31
  "imports": {
32
- "#*": "./src/*"
32
+ "#*": "./build/*"
33
33
  },
34
34
  "keywords": [],
35
35
  "license": "ISC",
package/src/factory.ts DELETED
@@ -1,47 +0,0 @@
1
- import { mapValues, uniq } from "es-toolkit";
2
- import { z } from "zod";
3
-
4
- import { NormalizedConfig } from "@casekit/orm2-config";
5
- import { ModelDefinitions, ModelName, ModelType } from "@casekit/orm2-schema";
6
-
7
- import { generate } from "./generate.js";
8
-
9
- export type Factory<Models extends ModelDefinitions> = {
10
- [M in ModelName<Models>]: (
11
- overrides?: Partial<ModelType<Models[M]>>,
12
- ) => ModelType<Models[M]>;
13
- };
14
-
15
- export const makeFactory = <Models extends ModelDefinitions>(
16
- config: NormalizedConfig,
17
- ): Factory<Models> => {
18
- return mapValues(config.models, (model) => {
19
- // We never want to generate foreign key values
20
- // as there's no way for us to know how to generate
21
- // valid ones. This is up to the user to provide.
22
- const fkOverrides = Object.fromEntries(
23
- uniq(model.foreignKeys.flatMap((fk) => fk.fields)).map((fk) => [
24
- fk,
25
- null,
26
- ]),
27
- );
28
-
29
- const fields = Object.entries(model.fields)
30
- .filter(([_, f]) => !f.provided)
31
- .map(([name, f]) => [
32
- name,
33
- f.default
34
- ? f.zodSchema.optional()
35
- : f.nullable
36
- ? f.zodSchema.nullable()
37
- : f.zodSchema,
38
- ]);
39
-
40
- const schema = z.object(Object.fromEntries(fields));
41
- return (overrides: Record<string, unknown>) => ({
42
- ...generate(schema),
43
- ...fkOverrides,
44
- ...overrides,
45
- });
46
- }) as Factory<Models>;
47
- };
File without changes