@schmock/faker 2.2.3 → 2.3.1

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.
Files changed (65) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +45 -0
  3. package/dist/constants.d.ts +82 -1
  4. package/dist/constants.d.ts.map +1 -1
  5. package/dist/field-mappings.d.ts.map +1 -1
  6. package/dist/field-name-matcher.d.ts +19 -0
  7. package/dist/field-name-matcher.d.ts.map +1 -1
  8. package/dist/index.d.ts +3 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +4 -1
  11. package/dist/jsf-config.d.ts +27 -2
  12. package/dist/jsf-config.d.ts.map +1 -1
  13. package/dist/output-limits.d.ts +3 -0
  14. package/dist/output-limits.d.ts.map +1 -0
  15. package/dist/overrides.d.ts +2 -1
  16. package/dist/overrides.d.ts.map +1 -1
  17. package/dist/schema-children.d.ts +14 -0
  18. package/dist/schema-children.d.ts.map +1 -0
  19. package/dist/schema-enhancement.d.ts +1 -0
  20. package/dist/schema-enhancement.d.ts.map +1 -1
  21. package/dist/validation.d.ts +24 -5
  22. package/dist/validation.d.ts.map +1 -1
  23. package/package.json +19 -9
  24. package/dist/constants.js +0 -8
  25. package/dist/field-mappings.js +0 -1107
  26. package/dist/field-name-matcher.js +0 -149
  27. package/dist/jsf-config.js +0 -35
  28. package/dist/overrides.js +0 -131
  29. package/dist/schema-enhancement.js +0 -89
  30. package/dist/test-utils.d.ts +0 -57
  31. package/dist/test-utils.d.ts.map +0 -1
  32. package/dist/test-utils.js +0 -271
  33. package/dist/validation.js +0 -300
  34. package/src/advanced-features.test.ts +0 -912
  35. package/src/audit-faker-args.test.ts +0 -97
  36. package/src/constants.d.ts.map +0 -1
  37. package/src/constants.ts +0 -9
  38. package/src/data-quality.test.ts +0 -415
  39. package/src/error-handling.test.ts +0 -504
  40. package/src/field-mappings.test.ts +0 -351
  41. package/src/field-mappings.ts +0 -1141
  42. package/src/field-name-matcher.test.ts +0 -292
  43. package/src/field-name-matcher.ts +0 -188
  44. package/src/index.d.ts.map +0 -1
  45. package/src/index.test.ts +0 -1218
  46. package/src/index.ts +0 -168
  47. package/src/integration.test.ts +0 -634
  48. package/src/jsf-config.d.ts.map +0 -1
  49. package/src/jsf-config.ts +0 -48
  50. package/src/overrides.d.ts.map +0 -1
  51. package/src/overrides.property.test.ts +0 -172
  52. package/src/overrides.test.ts +0 -38
  53. package/src/overrides.ts +0 -176
  54. package/src/performance.test.ts +0 -494
  55. package/src/plugin-integration.test.ts +0 -575
  56. package/src/post-process.test.ts +0 -151
  57. package/src/real-world.test.ts +0 -636
  58. package/src/schema-enhancement.d.ts.map +0 -1
  59. package/src/schema-enhancement.test.ts +0 -216
  60. package/src/schema-enhancement.ts +0 -128
  61. package/src/steps/deterministic-seeds.steps.ts +0 -35
  62. package/src/steps/faker-plugin.steps.ts +0 -109
  63. package/src/test-utils.ts +0 -365
  64. package/src/validation.d.ts.map +0 -1
  65. package/src/validation.ts +0 -417
package/src/test-utils.ts DELETED
@@ -1,365 +0,0 @@
1
- import type { JSONSchema7 } from "json-schema";
2
- import { expect } from "vitest";
3
- import { generateFromSchema } from "./index";
4
-
5
- interface FakerSchema extends JSONSchema7 {
6
- faker?: string;
7
- }
8
-
9
- // Schema Factory Functions
10
- export const schemas = {
11
- simple: {
12
- string: (): JSONSchema7 => ({
13
- type: "string",
14
- }),
15
-
16
- number: (): JSONSchema7 => ({
17
- type: "number",
18
- }),
19
-
20
- object: (properties: Record<string, JSONSchema7> = {}): JSONSchema7 => ({
21
- type: "object",
22
- properties,
23
- }),
24
-
25
- array: (
26
- items: JSONSchema7,
27
- constraints?: { minItems?: number; maxItems?: number },
28
- ): JSONSchema7 => ({
29
- type: "array",
30
- items,
31
- ...constraints,
32
- }),
33
- },
34
-
35
- withFaker: (type: JSONSchema7["type"], fakerMethod: string): FakerSchema => ({
36
- type,
37
- faker: fakerMethod,
38
- }),
39
-
40
- nested: {
41
- deep: (
42
- depth: number,
43
- leafSchema: JSONSchema7 = schemas.simple.string(),
44
- ): JSONSchema7 => {
45
- if (depth <= 0) return leafSchema;
46
- return {
47
- type: "object",
48
- properties: {
49
- nested: schemas.nested.deep(depth - 1, leafSchema),
50
- },
51
- };
52
- },
53
-
54
- wide: (
55
- width: number,
56
- propertySchema: JSONSchema7 = schemas.simple.string(),
57
- ): JSONSchema7 => ({
58
- type: "object",
59
- properties: Object.fromEntries(
60
- Array.from({ length: width }, (_, i) => [`prop${i}`, propertySchema]),
61
- ),
62
- }),
63
- },
64
-
65
- complex: {
66
- user: (): JSONSchema7 => ({
67
- type: "object",
68
- properties: {
69
- id: { type: "string", format: "uuid" },
70
- email: { type: "string" },
71
- firstName: { type: "string" },
72
- lastName: { type: "string" },
73
- createdAt: { type: "string" },
74
- },
75
- required: ["id", "email"],
76
- }),
77
-
78
- apiResponse: (): JSONSchema7 => ({
79
- type: "object",
80
- properties: {
81
- success: { type: "boolean" },
82
- data: {
83
- type: "array",
84
- items: schemas.complex.user(),
85
- },
86
- meta: {
87
- type: "object",
88
- properties: {
89
- page: { type: "number" },
90
- total: { type: "number" },
91
- },
92
- },
93
- },
94
- }),
95
- },
96
- };
97
-
98
- // Validation Helpers
99
- export const validators = {
100
- // Check if a field was mapped to a faker method by comparing with unmapped behavior
101
- isFieldMapped: async (
102
- fieldName: string,
103
- fieldType: JSONSchema7["type"] = "string",
104
- ): Promise<boolean> => {
105
- const mappedSchema: JSONSchema7 = {
106
- type: "object",
107
- properties: {
108
- [fieldName]: { type: fieldType },
109
- },
110
- };
111
-
112
- const unmappedSchema: JSONSchema7 = {
113
- type: "object",
114
- properties: {
115
- unmappedRandomField12345: { type: fieldType },
116
- },
117
- };
118
-
119
- // Generate multiple samples to check for patterns
120
- const mappedSamples: any[] = [];
121
- for (let i = 0; i < 10; i++) {
122
- const result = (await generateFromSchema({
123
- schema: mappedSchema,
124
- })) as Record<string, unknown>;
125
- mappedSamples.push(result[fieldName]);
126
- }
127
-
128
- const unmappedSamples: any[] = [];
129
- for (let i = 0; i < 10; i++) {
130
- const result = (await generateFromSchema({
131
- schema: unmappedSchema,
132
- })) as Record<string, unknown>;
133
- unmappedSamples.push(result.unmappedRandomField12345);
134
- }
135
-
136
- // If field is mapped to a specific faker method, it should have different characteristics
137
- // than the generic unmapped field
138
- return (
139
- analyzeDataCharacteristics(mappedSamples) !==
140
- analyzeDataCharacteristics(unmappedSamples)
141
- );
142
- },
143
-
144
- // Analyze uniqueness of generated data
145
- uniquenessRatio: (samples: any[]): number => {
146
- const unique = new Set(samples);
147
- return unique.size / samples.length;
148
- },
149
-
150
- // Check if all samples match a basic pattern without being too specific
151
- allMatch: (samples: any[], validator: (sample: any) => boolean): boolean => {
152
- return samples.every(validator);
153
- },
154
-
155
- // Check if data appears to be from a specific faker category
156
- appearsToBeFromCategory: (
157
- samples: string[],
158
- category: "email" | "name" | "phone" | "address" | "uuid" | "date",
159
- ): boolean => {
160
- switch (category) {
161
- case "email":
162
- return validators.allMatch(
163
- samples,
164
- (s) => typeof s === "string" && s.includes("@") && s.includes("."),
165
- );
166
- case "name":
167
- return validators.allMatch(
168
- samples,
169
- (s) =>
170
- typeof s === "string" &&
171
- s.length > 1 &&
172
- s.length < 50 &&
173
- /^[A-Z]/.test(s),
174
- );
175
- case "phone":
176
- return validators.allMatch(
177
- samples,
178
- (s) => typeof s === "string" && /\d/.test(s) && s.length > 10,
179
- );
180
- case "address":
181
- return validators.allMatch(
182
- samples,
183
- (s) =>
184
- typeof s === "string" &&
185
- s.length > 10 &&
186
- /\d/.test(s) &&
187
- /[A-Z]/.test(s),
188
- );
189
- case "uuid":
190
- return validators.allMatch(
191
- samples,
192
- (s) =>
193
- typeof s === "string" &&
194
- /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
195
- s,
196
- ),
197
- );
198
- case "date":
199
- return validators.allMatch(
200
- samples,
201
- (s) => typeof s === "string" && !Number.isNaN(Date.parse(s)),
202
- );
203
- default:
204
- return false;
205
- }
206
- },
207
- };
208
-
209
- // Performance Testing Utilities
210
- export const performance = {
211
- measure: async <T>(
212
- fn: () => T | Promise<T>,
213
- ): Promise<{ result: T; duration: number }> => {
214
- const start = Date.now();
215
- const result = await fn();
216
- const duration = Date.now() - start;
217
- return { result, duration };
218
- },
219
-
220
- measureMemory: (fn: () => void): number => {
221
- if (globalThis.gc) {
222
- globalThis.gc();
223
- }
224
- const before = process.memoryUsage().heapUsed;
225
- fn();
226
- const after = process.memoryUsage().heapUsed;
227
- return after - before;
228
- },
229
-
230
- benchmark: async (
231
- _name: string,
232
- fn: () => any,
233
- iterations = 100,
234
- ): Promise<{ mean: number; min: number; max: number }> => {
235
- const times: number[] = [];
236
-
237
- for (let i = 0; i < iterations; i++) {
238
- const start = Date.now();
239
- await fn();
240
- const duration = Date.now() - start;
241
- times.push(duration);
242
- }
243
-
244
- return {
245
- mean: times.reduce((a, b) => a + b, 0) / times.length,
246
- min: Math.min(...times),
247
- max: Math.max(...times),
248
- };
249
- },
250
- };
251
-
252
- // Test Data Generators
253
- export const generate = {
254
- samples: async <T>(
255
- schema: JSONSchema7,
256
- count = 10,
257
- options?: any,
258
- ): Promise<T[]> => {
259
- const results: T[] = [];
260
- for (let i = 0; i < count; i++) {
261
- results.push((await generateFromSchema({ schema, ...options })) as T);
262
- }
263
- return results;
264
- },
265
-
266
- withSeed: async (schema: JSONSchema7, _seed?: number): Promise<any> => {
267
- // Note: faker.js doesn't support seeding in the same way,
268
- // but we can at least ensure consistent test behavior
269
- return await generateFromSchema({ schema });
270
- },
271
- };
272
-
273
- // Statistical Analysis
274
- export const stats = {
275
- distribution: (samples: any[]): Map<any, number> => {
276
- const dist = new Map<any, number>();
277
- for (const sample of samples) {
278
- const key = JSON.stringify(sample);
279
- dist.set(key, (dist.get(key) || 0) + 1);
280
- }
281
- return dist;
282
- },
283
-
284
- entropy: (samples: any[]): number => {
285
- const dist = stats.distribution(samples);
286
- const total = samples.length;
287
- let entropy = 0;
288
-
289
- for (const count of dist.values()) {
290
- const p = count / total;
291
- if (p > 0) {
292
- entropy -= p * Math.log2(p);
293
- }
294
- }
295
-
296
- return entropy;
297
- },
298
- };
299
-
300
- // Schema Validation Test Helpers
301
- export const schemaTests = {
302
- expectValid: async (schema: JSONSchema7): Promise<void> => {
303
- await expect(generateFromSchema({ schema })).resolves.not.toThrow();
304
- },
305
-
306
- expectInvalid: async (
307
- schema: any,
308
- errorMessage?: string | RegExp,
309
- ): Promise<void> => {
310
- if (errorMessage) {
311
- await expect(generateFromSchema({ schema })).rejects.toThrow(
312
- errorMessage,
313
- );
314
- } else {
315
- await expect(generateFromSchema({ schema })).rejects.toThrow();
316
- }
317
- },
318
-
319
- expectSchemaError: async (
320
- schema: any,
321
- path: string,
322
- issue?: string,
323
- ): Promise<void> => {
324
- try {
325
- await generateFromSchema({ schema });
326
- throw new Error("Expected schema validation to fail");
327
- } catch (error: any) {
328
- expect(error.name).toBe("SchemaValidationError");
329
- // The schemaPath is in the context
330
- if (error.context?.schemaPath) {
331
- expect(error.context.schemaPath).toBe(path);
332
- }
333
- if (issue) {
334
- expect(error.message).toContain(issue);
335
- }
336
- }
337
- },
338
- };
339
-
340
- // Helper to analyze data characteristics without hardcoding patterns
341
- function analyzeDataCharacteristics(samples: any[]): string {
342
- if (samples.length === 0) return "empty";
343
-
344
- const first = samples[0];
345
- const type = typeof first;
346
-
347
- if (type !== "string") return type;
348
-
349
- // Analyze string characteristics
350
- const characteristics: string[] = [type];
351
-
352
- // Check common patterns without being too specific
353
- if (samples.every((s) => s.includes("@"))) characteristics.push("has-at");
354
- if (samples.every((s) => /^\d+$/.test(s))) characteristics.push("numeric");
355
- if (samples.every((s) => /^[0-9a-f-]+$/i.test(s)))
356
- characteristics.push("hex-like");
357
- if (samples.every((s) => s.length > 50)) characteristics.push("long");
358
- if (samples.every((s) => s.length < 10)) characteristics.push("short");
359
- if (validators.uniquenessRatio(samples) > 0.8)
360
- characteristics.push("high-entropy");
361
- if (validators.uniquenessRatio(samples) < 0.2)
362
- characteristics.push("low-entropy");
363
-
364
- return characteristics.join("-");
365
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["validation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAY/C,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAElE;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,SAAM,GAAG,IAAI,CAiJpE;AAwMD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAmC7D"}