@anil-labs/factory 0.1.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.
Files changed (98) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/LICENSE +21 -0
  3. package/README.md +371 -0
  4. package/dist/builders/index.d.cts +40 -0
  5. package/dist/builders/index.d.ts +40 -0
  6. package/dist/chunks/faker-BOtDMmjd.cjs +1430 -0
  7. package/dist/chunks/faker-BOtDMmjd.cjs.map +1 -0
  8. package/dist/chunks/faker-BlEhpR26.mjs +1287 -0
  9. package/dist/chunks/faker-BlEhpR26.mjs.map +1 -0
  10. package/dist/chunks/persist-DcARfeC-.cjs +134 -0
  11. package/dist/chunks/persist-DcARfeC-.cjs.map +1 -0
  12. package/dist/chunks/persist-ZGX3NWMF.mjs +117 -0
  13. package/dist/chunks/persist-ZGX3NWMF.mjs.map +1 -0
  14. package/dist/core/collection.d.cts +41 -0
  15. package/dist/core/collection.d.ts +41 -0
  16. package/dist/core/factory.d.cts +115 -0
  17. package/dist/core/factory.d.ts +115 -0
  18. package/dist/core/index.d.cts +6 -0
  19. package/dist/core/index.d.ts +6 -0
  20. package/dist/core/registry.d.cts +20 -0
  21. package/dist/core/registry.d.ts +20 -0
  22. package/dist/core/sequence.d.cts +36 -0
  23. package/dist/core/sequence.d.ts +36 -0
  24. package/dist/core/types.d.cts +47 -0
  25. package/dist/core/types.d.ts +47 -0
  26. package/dist/faker/color.d.cts +22 -0
  27. package/dist/faker/color.d.ts +22 -0
  28. package/dist/faker/commerce.d.cts +21 -0
  29. package/dist/faker/commerce.d.ts +21 -0
  30. package/dist/faker/company.d.cts +20 -0
  31. package/dist/faker/company.d.ts +20 -0
  32. package/dist/faker/datatype.d.cts +16 -0
  33. package/dist/faker/datatype.d.ts +16 -0
  34. package/dist/faker/date.d.cts +29 -0
  35. package/dist/faker/date.d.ts +29 -0
  36. package/dist/faker/faker.d.cts +82 -0
  37. package/dist/faker/faker.d.ts +82 -0
  38. package/dist/faker/finance.d.cts +25 -0
  39. package/dist/faker/finance.d.ts +25 -0
  40. package/dist/faker/helpers.d.cts +52 -0
  41. package/dist/faker/helpers.d.ts +52 -0
  42. package/dist/faker/image.d.cts +22 -0
  43. package/dist/faker/image.d.ts +22 -0
  44. package/dist/faker/index.d.cts +21 -0
  45. package/dist/faker/index.d.ts +21 -0
  46. package/dist/faker/internet.d.cts +33 -0
  47. package/dist/faker/internet.d.ts +33 -0
  48. package/dist/faker/locale.d.cts +26 -0
  49. package/dist/faker/locale.d.ts +26 -0
  50. package/dist/faker/location.d.cts +30 -0
  51. package/dist/faker/location.d.ts +30 -0
  52. package/dist/faker/lorem.d.cts +26 -0
  53. package/dist/faker/lorem.d.ts +26 -0
  54. package/dist/faker/number.d.cts +31 -0
  55. package/dist/faker/number.d.ts +31 -0
  56. package/dist/faker/person.d.cts +29 -0
  57. package/dist/faker/person.d.ts +29 -0
  58. package/dist/faker/regex.d.cts +19 -0
  59. package/dist/faker/regex.d.ts +19 -0
  60. package/dist/faker/string.d.cts +33 -0
  61. package/dist/faker/string.d.ts +33 -0
  62. package/dist/faker/system.d.cts +29 -0
  63. package/dist/faker/system.d.ts +29 -0
  64. package/dist/faker.cjs +26 -0
  65. package/dist/faker.mjs +3 -0
  66. package/dist/index.cjs +635 -0
  67. package/dist/index.cjs.map +1 -0
  68. package/dist/index.d.cts +37 -0
  69. package/dist/index.d.ts +37 -0
  70. package/dist/index.mjs +596 -0
  71. package/dist/index.mjs.map +1 -0
  72. package/dist/locales/en.cjs +351 -0
  73. package/dist/locales/en.cjs.map +1 -0
  74. package/dist/locales/en.d.cts +11 -0
  75. package/dist/locales/en.d.ts +11 -0
  76. package/dist/locales/en.mjs +350 -0
  77. package/dist/locales/en.mjs.map +1 -0
  78. package/dist/locales/types.d.cts +30 -0
  79. package/dist/locales/types.d.ts +30 -0
  80. package/dist/persist/console.d.cts +15 -0
  81. package/dist/persist/console.d.ts +15 -0
  82. package/dist/persist/http.d.cts +42 -0
  83. package/dist/persist/http.d.ts +42 -0
  84. package/dist/persist/index.d.cts +5 -0
  85. package/dist/persist/index.d.ts +5 -0
  86. package/dist/persist/memory.d.cts +26 -0
  87. package/dist/persist/memory.d.ts +26 -0
  88. package/dist/persist.cjs +5 -0
  89. package/dist/persist.mjs +2 -0
  90. package/dist/prng/index.d.cts +5 -0
  91. package/dist/prng/index.d.ts +5 -0
  92. package/dist/prng/mulberry32.d.cts +19 -0
  93. package/dist/prng/mulberry32.d.ts +19 -0
  94. package/dist/prng/types.d.cts +23 -0
  95. package/dist/prng/types.d.ts +23 -0
  96. package/dist/snapshot/index.d.cts +16 -0
  97. package/dist/snapshot/index.d.ts +16 -0
  98. package/package.json +136 -0
@@ -0,0 +1,1287 @@
1
+ import { en } from "../locales/en.mjs";
2
+ //#region src/prng/mulberry32.ts
3
+ /**
4
+ * Mulberry32 — 32-bit, ~4 billion period, very fast, deterministic.
5
+ *
6
+ * Good enough for test data and snapshots. NOT cryptographically secure.
7
+ *
8
+ * @see https://gist.github.com/tommyettinger/46a3b8f97c8e3a59e1e0c7f8e85bcde6
9
+ */
10
+ var Mulberry32 = class {
11
+ state;
12
+ constructor(seed) {
13
+ this.state = normalizeSeed(seed);
14
+ }
15
+ get currentSeed() {
16
+ return this.state >>> 0;
17
+ }
18
+ seed(seed) {
19
+ this.state = normalizeSeed(seed);
20
+ }
21
+ next() {
22
+ this.state = this.state + 1831565813 >>> 0;
23
+ let t = this.state;
24
+ t = Math.imul(t ^ t >>> 15, t | 1);
25
+ t ^= t + Math.imul(t ^ t >>> 7, t | 61);
26
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
27
+ }
28
+ int(min, max) {
29
+ if (max < min) [min, max] = [max, min];
30
+ return Math.floor(this.next() * (max - min + 1)) + min;
31
+ }
32
+ float(min, max, decimals = 2) {
33
+ const v = this.next() * (max - min) + min;
34
+ const factor = 10 ** decimals;
35
+ return Math.round(v * factor) / factor;
36
+ }
37
+ bool(chance = .5) {
38
+ return this.next() < chance;
39
+ }
40
+ pick(items) {
41
+ if (items.length === 0) throw new Error("[Prng] pick(): array is empty.");
42
+ const picked = items[this.int(0, items.length - 1)];
43
+ if (picked === void 0) throw new Error("[Prng] pick(): unreachable index");
44
+ return picked;
45
+ }
46
+ };
47
+ /**
48
+ * Coerce any input into a non-zero 32-bit unsigned integer. We map `0` to the
49
+ * golden-ratio constant so callers passing `0` get a deterministic-but-non-zero
50
+ * starting state (zero would emit a long initial run of small numbers).
51
+ */
52
+ function normalizeSeed(seed) {
53
+ if (typeof seed !== "number" || Number.isNaN(seed)) return (Date.now() ^ Math.floor(Math.random() * 4294967295)) >>> 0;
54
+ const truncated = Math.trunc(seed) >>> 0;
55
+ return truncated === 0 ? 2654435769 : truncated;
56
+ }
57
+ //#endregion
58
+ //#region src/prng/index.ts
59
+ /** Construct a default PRNG (currently Mulberry32). */
60
+ function createPrng(seed) {
61
+ return new Mulberry32(seed);
62
+ }
63
+ //#endregion
64
+ //#region src/faker/locale.ts
65
+ /**
66
+ * Live reference to the active locale data. A single instance is shared by
67
+ * every faker namespace, so swapping the locale at the `Faker` level
68
+ * propagates instantly without rebuilding modules.
69
+ */
70
+ var LocaleRef = class {
71
+ currentName;
72
+ currentData;
73
+ constructor(initial = "en") {
74
+ this.currentName = initial;
75
+ const data = registry.get(initial);
76
+ if (!data) throw new Error(`[Locale] Unknown locale "${initial}". Registered: ${[...registry.keys()].join(", ")}`);
77
+ this.currentData = data;
78
+ }
79
+ /** Read the currently-active locale data. */
80
+ get data() {
81
+ return this.currentData;
82
+ }
83
+ /** Read the active locale's identifier (e.g. `"en"`). */
84
+ get name() {
85
+ return this.currentName;
86
+ }
87
+ /** Swap to a different registered locale. Throws if unknown. */
88
+ set(name) {
89
+ const data = registry.get(name);
90
+ if (!data) throw new Error(`[Locale] Unknown locale "${name}". Registered: ${[...registry.keys()].join(", ")}`);
91
+ this.currentName = name;
92
+ this.currentData = data;
93
+ }
94
+ };
95
+ var registry = /* @__PURE__ */ new Map();
96
+ registry.set("en", en);
97
+ /** Register a new locale. Overwrites if `name` already exists. */
98
+ function registerLocale(name, data) {
99
+ registry.set(name, data);
100
+ }
101
+ /** Read a locale's raw data without making it active. */
102
+ function getLocale(name) {
103
+ return registry.get(name);
104
+ }
105
+ /** List every registered locale identifier. */
106
+ function listLocales() {
107
+ return [...registry.keys()];
108
+ }
109
+ //#endregion
110
+ //#region src/faker/person.ts
111
+ /**
112
+ * Personal-name namespace.
113
+ *
114
+ * @example
115
+ * ```ts
116
+ * faker.person.firstName() // "Sarah"
117
+ * faker.person.firstName('male') // "James"
118
+ * faker.person.fullName() // "Olivia Patel"
119
+ * faker.person.jobTitle() // → from `company.jobTitle()`
120
+ * ```
121
+ */
122
+ var Person = class {
123
+ rng;
124
+ locale;
125
+ constructor(rng, locale) {
126
+ this.rng = rng;
127
+ this.locale = locale;
128
+ }
129
+ firstName(sex) {
130
+ const d = this.locale.data;
131
+ if (sex === "male" && d.firstNamesMale?.length) return this.rng.pick(d.firstNamesMale);
132
+ if (sex === "female" && d.firstNamesFemale?.length) return this.rng.pick(d.firstNamesFemale);
133
+ return this.rng.pick(d.firstNames);
134
+ }
135
+ lastName() {
136
+ return this.rng.pick(this.locale.data.lastNames);
137
+ }
138
+ fullName(opts = {}) {
139
+ const parts = [];
140
+ if (opts.withPrefix) parts.push(this.prefix());
141
+ parts.push(this.firstName(opts.sex), this.lastName());
142
+ if (opts.withSuffix) parts.push(this.suffix());
143
+ return parts.join(" ");
144
+ }
145
+ prefix() {
146
+ return this.rng.pick(this.locale.data.prefixes);
147
+ }
148
+ suffix() {
149
+ return this.rng.pick(this.locale.data.suffixes);
150
+ }
151
+ /** Returns `"male"` or `"female"`. */
152
+ sex() {
153
+ return this.rng.bool() ? "male" : "female";
154
+ }
155
+ };
156
+ //#endregion
157
+ //#region src/faker/internet.ts
158
+ /**
159
+ * Internet / network namespace.
160
+ *
161
+ * @example
162
+ * ```ts
163
+ * faker.internet.email() // "olivia.patel91@example.com"
164
+ * faker.internet.email({ firstName: 'Alice', lastName: 'Wu' }) // "alice.wu41@…"
165
+ * faker.internet.userName() // "alex_anderson"
166
+ * faker.internet.url() // "https://app.gupta.io"
167
+ * faker.internet.ipv4() // "172.16.42.7"
168
+ * faker.internet.password(12) // "K8m$pQrt2Wz!"
169
+ * ```
170
+ */
171
+ var Internet = class {
172
+ rng;
173
+ locale;
174
+ constructor(rng, locale) {
175
+ this.rng = rng;
176
+ this.locale = locale;
177
+ }
178
+ email(opts = {}) {
179
+ const first = (opts.firstName ?? this.rng.pick(this.locale.data.firstNames)).toLowerCase();
180
+ const last = (opts.lastName ?? this.rng.pick(this.locale.data.lastNames)).toLowerCase();
181
+ const suffix = this.rng.int(1, 99).toString();
182
+ return `${this.rng.pick([
183
+ `${first}.${last}`,
184
+ `${first}${last}`,
185
+ `${first}_${last}`
186
+ ])}${suffix}@${this.rng.pick(this.locale.data.emailDomains)}`;
187
+ }
188
+ userName() {
189
+ const first = this.rng.pick(this.locale.data.firstNames).toLowerCase();
190
+ const last = this.rng.pick(this.locale.data.lastNames).toLowerCase();
191
+ const numeric = this.rng.int(1, 999).toString();
192
+ return this.rng.pick([
193
+ `${first}.${last}`,
194
+ `${first}_${last}`,
195
+ `${first}${numeric}`
196
+ ]);
197
+ }
198
+ /** Bare domain (e.g. `acme.io`). */
199
+ domainName() {
200
+ return `${this.rng.pick(this.locale.data.firstNames).toLowerCase()}.${this.rng.pick(this.locale.data.tlds)}`;
201
+ }
202
+ url() {
203
+ return `https://${this.rng.pick([
204
+ "www",
205
+ "app",
206
+ "api",
207
+ "blog",
208
+ "docs"
209
+ ])}.${this.domainName()}`;
210
+ }
211
+ ipv4() {
212
+ return [
213
+ this.rng.int(1, 255),
214
+ this.rng.int(0, 255),
215
+ this.rng.int(0, 255),
216
+ this.rng.int(1, 254)
217
+ ].join(".");
218
+ }
219
+ ipv6() {
220
+ return Array.from({ length: 8 }, () => this.rng.int(0, 65535).toString(16).padStart(4, "0")).join(":");
221
+ }
222
+ /** Random MAC address (colon-separated). */
223
+ mac() {
224
+ return Array.from({ length: 6 }, () => this.rng.int(0, 255).toString(16).padStart(2, "0")).join(":");
225
+ }
226
+ password(length = 12) {
227
+ const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_+=";
228
+ let out = "";
229
+ for (let i = 0; i < length; i++) {
230
+ const ch = chars[this.rng.int(0, 75)];
231
+ if (ch !== void 0) out += ch;
232
+ }
233
+ return out;
234
+ }
235
+ };
236
+ //#endregion
237
+ //#region src/faker/location.ts
238
+ /**
239
+ * Postal-address namespace.
240
+ *
241
+ * @example
242
+ * ```ts
243
+ * faker.location.streetAddress() // "742 Oak Ave"
244
+ * faker.location.city() // "Seattle"
245
+ * faker.location.country() // "United States"
246
+ * faker.location.latitude() // 47.6062
247
+ * ```
248
+ */
249
+ var Location = class {
250
+ rng;
251
+ locale;
252
+ constructor(rng, locale) {
253
+ this.rng = rng;
254
+ this.locale = locale;
255
+ }
256
+ streetAddress() {
257
+ return `${this.rng.int(100, 9999).toString()} ${this.rng.pick(this.locale.data.streetNames)} ${this.rng.pick(this.locale.data.streetSuffixes)}`;
258
+ }
259
+ city() {
260
+ return this.rng.pick(this.locale.data.cities);
261
+ }
262
+ state() {
263
+ return this.rng.pick(this.locale.data.states);
264
+ }
265
+ zipCode() {
266
+ return String(this.rng.int(1e4, 99999));
267
+ }
268
+ /** Locale's primary country (e.g. `"United States"` for `en`). */
269
+ country() {
270
+ return this.locale.data.country;
271
+ }
272
+ /** Random country from the locale's broader country list. */
273
+ countryName() {
274
+ return this.rng.pick(this.locale.data.countries);
275
+ }
276
+ /** Full single-line address. */
277
+ fullAddress() {
278
+ return `${this.streetAddress()}, ${this.city()}, ${this.state()} ${this.zipCode()}`;
279
+ }
280
+ latitude(min = -90, max = 90) {
281
+ return this.rng.float(min, max, 4);
282
+ }
283
+ longitude(min = -180, max = 180) {
284
+ return this.rng.float(min, max, 4);
285
+ }
286
+ };
287
+ //#endregion
288
+ //#region src/faker/lorem.ts
289
+ /** Capitalise the first character of a string. */
290
+ function capitalize(s) {
291
+ const first = s[0];
292
+ return first === void 0 ? s : first.toUpperCase() + s.slice(1);
293
+ }
294
+ /**
295
+ * Lorem-ipsum text generator.
296
+ *
297
+ * @example
298
+ * ```ts
299
+ * faker.lorem.word() // "consectetur"
300
+ * faker.lorem.words(3) // "dolor sit amet"
301
+ * faker.lorem.sentence() // "Ut labore et dolore magna aliqua."
302
+ * faker.lorem.paragraph()
303
+ * faker.lorem.paragraphs(3)
304
+ * ```
305
+ */
306
+ var Lorem = class {
307
+ rng;
308
+ locale;
309
+ constructor(rng, locale) {
310
+ this.rng = rng;
311
+ this.locale = locale;
312
+ }
313
+ word() {
314
+ return this.rng.pick(this.locale.data.loremWords);
315
+ }
316
+ words(count = 3) {
317
+ return Array.from({ length: count }, () => this.word()).join(" ");
318
+ }
319
+ sentence(wordCount) {
320
+ const count = wordCount ?? this.rng.int(4, 12);
321
+ return capitalize(this.words(count)) + ".";
322
+ }
323
+ paragraph(sentenceCount) {
324
+ const count = sentenceCount ?? this.rng.int(3, 6);
325
+ return Array.from({ length: count }, () => this.sentence()).join(" ");
326
+ }
327
+ paragraphs(count = 3) {
328
+ return Array.from({ length: count }, () => this.paragraph()).join("\n\n");
329
+ }
330
+ /** Alias of `paragraph()` — matches faker.js. */
331
+ text() {
332
+ return this.paragraph();
333
+ }
334
+ };
335
+ //#endregion
336
+ //#region src/faker/date.ts
337
+ var DAY_MS = 864e5;
338
+ /**
339
+ * Date / time generators.
340
+ *
341
+ * @example
342
+ * ```ts
343
+ * faker.date.past() // a Date in the last 365 days
344
+ * faker.date.recent(30) // last 30 days
345
+ * faker.date.future(60) // next 60 days
346
+ * faker.date.between(a, b)
347
+ * faker.date.birthdate({ min: 18, max: 65 })
348
+ * ```
349
+ */
350
+ var DateGen = class {
351
+ rng;
352
+ constructor(rng) {
353
+ this.rng = rng;
354
+ }
355
+ past(days = 365) {
356
+ const now = Date.now();
357
+ return new Date(this.rng.int(now - days * DAY_MS, now - 1));
358
+ }
359
+ recent(days = 30) {
360
+ return this.past(days);
361
+ }
362
+ future(days = 30) {
363
+ const now = Date.now();
364
+ return new Date(this.rng.int(now + 1, now + days * DAY_MS));
365
+ }
366
+ soon(days = 7) {
367
+ return this.future(days);
368
+ }
369
+ between(from, to) {
370
+ const a = from.getTime();
371
+ const b = to.getTime();
372
+ return new Date(this.rng.int(Math.min(a, b), Math.max(a, b)));
373
+ }
374
+ /** ISO-8601 string of a random recent date. */
375
+ iso(days = 365) {
376
+ return this.past(days).toISOString();
377
+ }
378
+ /** A plausible birthdate for someone in `[min, max]` years old. */
379
+ birthdate(opts = {}) {
380
+ const min = opts.min ?? 18;
381
+ const max = opts.max ?? 80;
382
+ const now = Date.now();
383
+ const minTime = now - max * 365 * DAY_MS;
384
+ const maxTime = now - min * 365 * DAY_MS;
385
+ return new Date(this.rng.int(minTime, maxTime));
386
+ }
387
+ };
388
+ //#endregion
389
+ //#region src/faker/number.ts
390
+ /**
391
+ * Number generators.
392
+ *
393
+ * @example
394
+ * ```ts
395
+ * faker.number.int({ min: 1, max: 100 })
396
+ * faker.number.float({ min: 0, max: 1, decimals: 3 })
397
+ * faker.number.bigInt({ min: 0n, max: 1000n })
398
+ * faker.number.between(1, 5)
399
+ * ```
400
+ */
401
+ var NumberGen = class {
402
+ rng;
403
+ constructor(rng) {
404
+ this.rng = rng;
405
+ }
406
+ int(opts = {}) {
407
+ return this.rng.int(opts.min ?? 0, opts.max ?? Number.MAX_SAFE_INTEGER);
408
+ }
409
+ float(opts = {}) {
410
+ return this.rng.float(opts.min ?? 0, opts.max ?? 1, opts.decimals ?? 2);
411
+ }
412
+ bigInt(opts = {}) {
413
+ const min = opts.min ?? 0n;
414
+ const max = opts.max ?? 1000000000n;
415
+ if (max < min) throw new Error("[Number] bigInt: max < min");
416
+ const range = max - min + 1n;
417
+ const lo = BigInt(this.rng.int(0, 4294967295));
418
+ return min + (BigInt(this.rng.int(0, 4294967295)) << 32n | lo) % range;
419
+ }
420
+ /** Convenience: integer in `[min, max]`. */
421
+ between(min, max) {
422
+ return this.rng.int(min, max);
423
+ }
424
+ };
425
+ //#endregion
426
+ //#region src/faker/string.ts
427
+ var ALPHA = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
428
+ var NUMERIC = "0123456789";
429
+ var ALPHANUMERIC = ALPHA + NUMERIC;
430
+ var HEX = "0123456789abcdef";
431
+ var NANOID = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
432
+ /**
433
+ * String / identifier generators.
434
+ *
435
+ * @example
436
+ * ```ts
437
+ * faker.string.uuid() // "f47ac10b-58cc-4372-a567-0e02b2c3d479"
438
+ * faker.string.nanoid()
439
+ * faker.string.alphanumeric(8)
440
+ * faker.string.hexadecimal(16)
441
+ * faker.string.sample(20) // any printable char
442
+ * faker.string.slug() // "dolor-sit-amet"
443
+ * ```
444
+ */
445
+ var StringGen = class {
446
+ rng;
447
+ constructor(rng) {
448
+ this.rng = rng;
449
+ }
450
+ /** RFC-4122 v4 UUID. */
451
+ uuid() {
452
+ const bytes = Array.from({ length: 16 }, () => this.rng.int(0, 255));
453
+ bytes[6] = (bytes[6] ?? 0) & 15 | 64;
454
+ bytes[8] = (bytes[8] ?? 0) & 63 | 128;
455
+ const hex = bytes.map((b) => b.toString(16).padStart(2, "0")).join("");
456
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
457
+ }
458
+ /** URL-safe random ID — same alphabet as nanoid. */
459
+ nanoid(length = 21) {
460
+ return this.pickFrom(NANOID, length);
461
+ }
462
+ alpha(length = 10) {
463
+ return this.pickFrom(ALPHA, length);
464
+ }
465
+ numeric(length = 10) {
466
+ return this.pickFrom(NUMERIC, length);
467
+ }
468
+ alphanumeric(length = 10) {
469
+ return this.pickFrom(ALPHANUMERIC, length);
470
+ }
471
+ hexadecimal(length = 8, opts = {}) {
472
+ return (opts.prefix ?? "") + this.pickFrom(HEX, length);
473
+ }
474
+ /** Random printable ASCII (32–126), any character. */
475
+ sample(length = 10) {
476
+ let out = "";
477
+ for (let i = 0; i < length; i++) out += String.fromCharCode(this.rng.int(33, 126));
478
+ return out;
479
+ }
480
+ /** Lowercase, hyphen-joined word sequence. */
481
+ slug(words = 3, dictionary) {
482
+ const pool = dictionary ?? DEFAULT_SLUG_WORDS;
483
+ return Array.from({ length: words }, () => this.rng.pick(pool)).join("-");
484
+ }
485
+ pickFrom(pool, length) {
486
+ let out = "";
487
+ for (let i = 0; i < length; i++) {
488
+ const ch = pool[this.rng.int(0, pool.length - 1)];
489
+ if (ch !== void 0) out += ch;
490
+ }
491
+ return out;
492
+ }
493
+ };
494
+ var DEFAULT_SLUG_WORDS = [
495
+ "amber",
496
+ "azure",
497
+ "cedar",
498
+ "cobalt",
499
+ "coral",
500
+ "dawn",
501
+ "ember",
502
+ "fern",
503
+ "frost",
504
+ "glass",
505
+ "haven",
506
+ "iris",
507
+ "jade",
508
+ "lake",
509
+ "maple",
510
+ "meadow",
511
+ "nova",
512
+ "opal",
513
+ "pine",
514
+ "quartz",
515
+ "river",
516
+ "sage",
517
+ "silk",
518
+ "stone",
519
+ "tide",
520
+ "umber",
521
+ "velvet",
522
+ "wave",
523
+ "xeno",
524
+ "yarn",
525
+ "zenith"
526
+ ];
527
+ //#endregion
528
+ //#region src/faker/color.ts
529
+ /**
530
+ * Color generators.
531
+ *
532
+ * @example
533
+ * ```ts
534
+ * faker.color.name() // "amber"
535
+ * faker.color.hex() // "#3f8ad5"
536
+ * faker.color.rgb() // "rgb(63, 138, 213)"
537
+ * faker.color.hsl() // "hsl(217, 64%, 54%)"
538
+ * ```
539
+ */
540
+ var Color = class {
541
+ rng;
542
+ locale;
543
+ constructor(rng, locale) {
544
+ this.rng = rng;
545
+ this.locale = locale;
546
+ }
547
+ name() {
548
+ return this.rng.pick(this.locale.data.colors);
549
+ }
550
+ hex() {
551
+ return "#" + this.rng.int(0, 16777215).toString(16).padStart(6, "0");
552
+ }
553
+ rgb() {
554
+ return `rgb(${this.rng.int(0, 255).toString()}, ${this.rng.int(0, 255).toString()}, ${this.rng.int(0, 255).toString()})`;
555
+ }
556
+ hsl() {
557
+ return `hsl(${this.rng.int(0, 360).toString()}, ${this.rng.int(40, 90).toString()}%, ${this.rng.int(30, 70).toString()}%)`;
558
+ }
559
+ };
560
+ //#endregion
561
+ //#region src/faker/company.ts
562
+ /**
563
+ * Company / employment generators.
564
+ *
565
+ * @example
566
+ * ```ts
567
+ * faker.company.name() // "Stark Industries"
568
+ * faker.company.jobTitle() // "Frontend Developer"
569
+ * faker.company.buzzPhrase() // "leverage cross-platform synergies"
570
+ * ```
571
+ */
572
+ var Company = class {
573
+ rng;
574
+ locale;
575
+ constructor(rng, locale) {
576
+ this.rng = rng;
577
+ this.locale = locale;
578
+ }
579
+ name() {
580
+ return this.rng.pick(this.locale.data.companies);
581
+ }
582
+ jobTitle() {
583
+ return this.rng.pick(this.locale.data.jobTitles);
584
+ }
585
+ buzzPhrase() {
586
+ return this.rng.pick(this.locale.data.buzzPhrases);
587
+ }
588
+ };
589
+ //#endregion
590
+ //#region src/faker/commerce.ts
591
+ /**
592
+ * Commerce generators.
593
+ *
594
+ * @example
595
+ * ```ts
596
+ * faker.commerce.productName() // "Bamboo Notebook"
597
+ * faker.commerce.price() // 24.99
598
+ * faker.commerce.department() // "Electronics"
599
+ * ```
600
+ */
601
+ var Commerce = class {
602
+ rng;
603
+ locale;
604
+ constructor(rng, locale) {
605
+ this.rng = rng;
606
+ this.locale = locale;
607
+ }
608
+ productName() {
609
+ return this.rng.pick(this.locale.data.productNames);
610
+ }
611
+ department() {
612
+ return this.rng.pick(this.locale.data.departments);
613
+ }
614
+ price(min = 1, max = 1e3, decimals = 2) {
615
+ return this.rng.float(min, max, decimals);
616
+ }
617
+ productDescription() {
618
+ return `${this.rng.pick([
619
+ "Premium",
620
+ "Eco-friendly",
621
+ "Hand-crafted",
622
+ "Vintage",
623
+ "Modern"
624
+ ])} ${this.productName().toLowerCase()} designed for everyday use.`;
625
+ }
626
+ };
627
+ //#endregion
628
+ //#region src/faker/finance.ts
629
+ /**
630
+ * Finance generators.
631
+ *
632
+ * @example
633
+ * ```ts
634
+ * faker.finance.amount() // "327.41"
635
+ * faker.finance.amount(0, 10, 2, '$') // "$4.27"
636
+ * faker.finance.accountNumber()
637
+ * faker.finance.creditCardNumber() // 16-digit Luhn-valid number
638
+ * faker.finance.currencyCode()
639
+ * faker.finance.iban()
640
+ * ```
641
+ */
642
+ var Finance = class {
643
+ rng;
644
+ constructor(rng) {
645
+ this.rng = rng;
646
+ }
647
+ amount(min = 0, max = 1e3, decimals = 2, symbol = "") {
648
+ return symbol + this.rng.float(min, max, decimals).toFixed(decimals);
649
+ }
650
+ accountNumber(digits = 10) {
651
+ let out = "";
652
+ for (let i = 0; i < digits; i++) out += this.rng.int(0, 9).toString();
653
+ return out;
654
+ }
655
+ /** Generates a Luhn-valid 16-digit credit-card number. */
656
+ creditCardNumber() {
657
+ const digits = [];
658
+ for (let i = 0; i < 15; i++) digits.push(this.rng.int(0, 9));
659
+ let sum = 0;
660
+ for (let i = digits.length - 1; i >= 0; i--) {
661
+ const raw = digits[i];
662
+ if (raw === void 0) continue;
663
+ let d = raw;
664
+ if ((digits.length - i) % 2 === 1) {
665
+ d *= 2;
666
+ if (d > 9) d -= 9;
667
+ }
668
+ sum += d;
669
+ }
670
+ digits.push((10 - sum % 10) % 10);
671
+ return digits.join("");
672
+ }
673
+ currencyCode() {
674
+ return this.rng.pick(CURRENCY_CODES);
675
+ }
676
+ iban(countryCode = "GB", length = 22) {
677
+ let body = "";
678
+ for (let i = 0; i < length - 4; i++) body += this.rng.int(0, 9).toString();
679
+ return `${countryCode}${this.rng.int(10, 99).toString()}${body}`;
680
+ }
681
+ bitcoinAddress() {
682
+ const chars = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz123456789";
683
+ let out = this.rng.pick(["1", "3"]);
684
+ const length = this.rng.int(25, 33);
685
+ for (let i = 1; i < length; i++) {
686
+ const ch = chars[this.rng.int(0, 57)];
687
+ if (ch !== void 0) out += ch;
688
+ }
689
+ return out;
690
+ }
691
+ };
692
+ var CURRENCY_CODES = [
693
+ "USD",
694
+ "EUR",
695
+ "GBP",
696
+ "JPY",
697
+ "CHF",
698
+ "CAD",
699
+ "AUD",
700
+ "CNY",
701
+ "INR",
702
+ "NPR",
703
+ "BRL",
704
+ "MXN",
705
+ "SGD",
706
+ "HKD",
707
+ "KRW"
708
+ ];
709
+ //#endregion
710
+ //#region src/faker/image.ts
711
+ /**
712
+ * Image-URL generators. No bytes are produced — just predictable URLs that
713
+ * resolve to real images from public providers.
714
+ *
715
+ * @example
716
+ * ```ts
717
+ * faker.image.url() // picsum.photos URL
718
+ * faker.image.avatar() // ui-avatars URL
719
+ * faker.image.dataUri(64, 64) // tiny embeddable PNG
720
+ * ```
721
+ */
722
+ var Image = class {
723
+ rng;
724
+ constructor(rng) {
725
+ this.rng = rng;
726
+ }
727
+ /** Picsum-photos placeholder URL. */
728
+ url(width = 640, height = 480) {
729
+ const random = this.rng.int(1, 1e4).toString();
730
+ return `https://picsum.photos/${width.toString()}/${height.toString()}?random=${random}`;
731
+ }
732
+ /** ui-avatars.com avatar URL — needs a name to render initials. */
733
+ avatar(name = "User") {
734
+ return `https://ui-avatars.com/api/?${new URLSearchParams({
735
+ name,
736
+ size: String(this.rng.pick([
737
+ 64,
738
+ 96,
739
+ 128,
740
+ 256
741
+ ])),
742
+ background: this.rng.int(0, 16777215).toString(16).padStart(6, "0"),
743
+ color: "fff"
744
+ }).toString()}`;
745
+ }
746
+ /** Tiny single-color PNG data-uri — useful for testing inline-image flows. */
747
+ dataUri(width = 1, height = 1) {
748
+ return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=";
749
+ }
750
+ };
751
+ //#endregion
752
+ //#region src/faker/system.ts
753
+ /**
754
+ * Filesystem / operating-system generators.
755
+ *
756
+ * @example
757
+ * ```ts
758
+ * faker.system.fileName() // "amber-cedar-pine.json"
759
+ * faker.system.commonFileExt() // "pdf"
760
+ * faker.system.mimeType() // "image/png"
761
+ * faker.system.filePath() // "/var/log/glass-stone.txt"
762
+ * ```
763
+ */
764
+ var System = class {
765
+ rng;
766
+ locale;
767
+ strings;
768
+ constructor(rng, locale, strings) {
769
+ this.rng = rng;
770
+ this.locale = locale;
771
+ this.strings = strings;
772
+ }
773
+ commonFileExt() {
774
+ return this.rng.pick(this.locale.data.fileExtensions);
775
+ }
776
+ fileExt() {
777
+ return this.rng.pick(this.locale.data.fileExtensions);
778
+ }
779
+ fileName(opts = {}) {
780
+ const base = this.strings.slug(this.rng.int(2, 4));
781
+ return opts.withExt === false ? base : `${base}.${this.commonFileExt()}`;
782
+ }
783
+ directoryPath() {
784
+ const depth = this.rng.int(1, 4);
785
+ return "/" + Array.from({ length: depth }, () => this.strings.slug(1)).join("/");
786
+ }
787
+ filePath() {
788
+ return `${this.directoryPath()}/${this.fileName()}`;
789
+ }
790
+ mimeType() {
791
+ return this.rng.pick(this.locale.data.mimeTypes);
792
+ }
793
+ semver() {
794
+ return [
795
+ this.rng.int(0, 10),
796
+ this.rng.int(0, 20),
797
+ this.rng.int(0, 100)
798
+ ].join(".");
799
+ }
800
+ };
801
+ //#endregion
802
+ //#region src/faker/datatype.ts
803
+ /**
804
+ * Primitive datatype generators.
805
+ *
806
+ * @example
807
+ * ```ts
808
+ * faker.datatype.boolean() // true or false
809
+ * faker.datatype.boolean(0.8) // true with 80% probability
810
+ * ```
811
+ */
812
+ var Datatype = class {
813
+ rng;
814
+ constructor(rng) {
815
+ this.rng = rng;
816
+ }
817
+ /** Boolean with probability `chance` of `true` (default 0.5). */
818
+ boolean(chance = .5) {
819
+ return this.rng.bool(chance);
820
+ }
821
+ };
822
+ //#endregion
823
+ //#region src/faker/regex.ts
824
+ /**
825
+ * Generate a sample string that matches the given regular-expression pattern.
826
+ *
827
+ * Supports the regex subset commonly used in test data:
828
+ * - Literals, dot, escaped characters
829
+ * - Character classes `[a-z]`, `[^…]`, `\d`, `\D`, `\w`, `\W`, `\s`, `\S`
830
+ * - Groups `(...)`, non-capturing `(?:...)`, alternation `a|b|c`
831
+ * - Quantifiers `*`, `+`, `?`, `{n}`, `{n,m}` (lazy `?` is ignored)
832
+ *
833
+ * Unsupported regex features (lookbehind/lookahead, backreferences,
834
+ * named groups) are silently treated as literals.
835
+ *
836
+ * @example
837
+ * ```ts
838
+ * generateFromRegex(/[A-Z]{3}-\d{4}/, prng) // "ZQX-4172"
839
+ * ```
840
+ */
841
+ function generateFromRegex(pattern, rng) {
842
+ return render(new RegexParser(pattern instanceof RegExp ? pattern.source : pattern).parse(), rng);
843
+ }
844
+ function charRange(startCode, endCode) {
845
+ const out = [];
846
+ for (let c = startCode; c <= endCode; c++) out.push(String.fromCharCode(c));
847
+ return out;
848
+ }
849
+ var D = charRange(48, 57);
850
+ var L = charRange(97, 122);
851
+ var U = charRange(65, 90);
852
+ var W = [
853
+ ...D,
854
+ ...L,
855
+ ...U,
856
+ "_"
857
+ ];
858
+ var S = [" ", " "];
859
+ var NW = [
860
+ " ",
861
+ "!",
862
+ "@",
863
+ "#",
864
+ "$",
865
+ "%",
866
+ "&",
867
+ "*",
868
+ "-",
869
+ "+",
870
+ "=",
871
+ ";",
872
+ ":",
873
+ ",",
874
+ ".",
875
+ "/",
876
+ "?"
877
+ ];
878
+ var ALL = [
879
+ ...W,
880
+ ...S,
881
+ "!",
882
+ "@",
883
+ "#",
884
+ "$",
885
+ "%",
886
+ "^",
887
+ "&",
888
+ "*",
889
+ "(",
890
+ ")",
891
+ "-",
892
+ "+"
893
+ ];
894
+ function expandEscape(ch) {
895
+ switch (ch) {
896
+ case "d": return [...D];
897
+ case "D": return [
898
+ ...L,
899
+ ...U,
900
+ "_",
901
+ " "
902
+ ];
903
+ case "w": return [...W];
904
+ case "W": return [...NW];
905
+ case "s": return [...S];
906
+ case "S": return [...W, ...NW];
907
+ case "n": return ["\n"];
908
+ case "t": return [" "];
909
+ case "r": return ["\r"];
910
+ default: return [ch];
911
+ }
912
+ }
913
+ var RegexParser = class {
914
+ src;
915
+ pos = 0;
916
+ constructor(src) {
917
+ this.src = src;
918
+ }
919
+ parse() {
920
+ return this.parseAlt();
921
+ }
922
+ peek() {
923
+ return this.src[this.pos];
924
+ }
925
+ parseAlt() {
926
+ const branches = [this.parseSeq()];
927
+ while (this.peek() === "|") {
928
+ this.pos++;
929
+ branches.push(this.parseSeq());
930
+ }
931
+ if (branches.length === 1) {
932
+ const only = branches[0];
933
+ if (only === void 0) throw new Error("[regex] unreachable: empty branches");
934
+ return only;
935
+ }
936
+ return {
937
+ kind: "alt",
938
+ branches
939
+ };
940
+ }
941
+ parseSeq() {
942
+ const items = [];
943
+ while (this.pos < this.src.length && this.peek() !== ")" && this.peek() !== "|") {
944
+ const node = this.parseAtom();
945
+ const q = this.parseQuant();
946
+ items.push({
947
+ node,
948
+ min: q.min,
949
+ max: q.max
950
+ });
951
+ if (this.peek() === "?") this.pos++;
952
+ }
953
+ return {
954
+ kind: "seq",
955
+ items
956
+ };
957
+ }
958
+ parseAtom() {
959
+ const ch = this.peek();
960
+ if (ch === "(") {
961
+ this.pos++;
962
+ if (this.peek() === "?") {
963
+ const colon = this.src.indexOf(":", this.pos);
964
+ if (colon !== -1) this.pos = colon + 1;
965
+ }
966
+ const inner = this.parseAlt();
967
+ if (this.peek() === ")") this.pos++;
968
+ return inner;
969
+ }
970
+ if (ch === "[") {
971
+ this.pos++;
972
+ return {
973
+ kind: "class",
974
+ pool: this.parseCharClass()
975
+ };
976
+ }
977
+ if (ch === ".") {
978
+ this.pos++;
979
+ return { kind: "dot" };
980
+ }
981
+ if (ch === "^" || ch === "$") {
982
+ this.pos++;
983
+ return {
984
+ kind: "lit",
985
+ value: ""
986
+ };
987
+ }
988
+ if (ch === "\\") {
989
+ this.pos++;
990
+ return {
991
+ kind: "class",
992
+ pool: expandEscape(this.src[this.pos++] ?? "")
993
+ };
994
+ }
995
+ this.pos++;
996
+ return {
997
+ kind: "lit",
998
+ value: ch ?? ""
999
+ };
1000
+ }
1001
+ parseCharClass() {
1002
+ let negate = false;
1003
+ if (this.peek() === "^") {
1004
+ negate = true;
1005
+ this.pos++;
1006
+ }
1007
+ const pool = [];
1008
+ while (this.pos < this.src.length && this.peek() !== "]") if (this.peek() === "\\") {
1009
+ this.pos++;
1010
+ pool.push(...expandEscape(this.src[this.pos++] ?? ""));
1011
+ } else if (this.src[this.pos + 1] === "-" && this.src[this.pos + 2] && this.src[this.pos + 2] !== "]") {
1012
+ const fromCh = this.src[this.pos];
1013
+ const toCh = this.src[this.pos + 2];
1014
+ if (fromCh !== void 0 && toCh !== void 0) {
1015
+ const from = fromCh.charCodeAt(0);
1016
+ const to = toCh.charCodeAt(0);
1017
+ for (let c = from; c <= to; c++) pool.push(String.fromCharCode(c));
1018
+ }
1019
+ this.pos += 3;
1020
+ } else {
1021
+ const ch = this.src[this.pos++];
1022
+ if (ch !== void 0) pool.push(ch);
1023
+ }
1024
+ if (this.peek() === "]") this.pos++;
1025
+ if (negate) {
1026
+ const set = new Set(pool);
1027
+ return ALL.filter((c) => !set.has(c));
1028
+ }
1029
+ return pool.length > 0 ? pool : ["a"];
1030
+ }
1031
+ parseQuant() {
1032
+ const ch = this.peek();
1033
+ if (ch === "*") {
1034
+ this.pos++;
1035
+ return {
1036
+ min: 0,
1037
+ max: 8
1038
+ };
1039
+ }
1040
+ if (ch === "+") {
1041
+ this.pos++;
1042
+ return {
1043
+ min: 1,
1044
+ max: 8
1045
+ };
1046
+ }
1047
+ if (ch === "?") {
1048
+ this.pos++;
1049
+ return {
1050
+ min: 0,
1051
+ max: 1
1052
+ };
1053
+ }
1054
+ if (ch === "{") {
1055
+ const end = this.src.indexOf("}", this.pos);
1056
+ if (end !== -1) {
1057
+ const inner = this.src.slice(this.pos + 1, end);
1058
+ this.pos = end + 1;
1059
+ if (this.peek() === "?") this.pos++;
1060
+ const parts = inner.split(",");
1061
+ const lo = parseInt(parts[0] ?? "1", 10);
1062
+ const hi = parts.length > 1 ? parts[1] ? parseInt(parts[1], 10) : lo + 4 : lo;
1063
+ return {
1064
+ min: lo,
1065
+ max: Math.min(hi, lo + 10)
1066
+ };
1067
+ }
1068
+ }
1069
+ return {
1070
+ min: 1,
1071
+ max: 1
1072
+ };
1073
+ }
1074
+ };
1075
+ function render(node, rng) {
1076
+ switch (node.kind) {
1077
+ case "lit": return node.value;
1078
+ case "class": return node.pool.length > 0 ? rng.pick(node.pool) : "";
1079
+ case "dot": return rng.pick([...W, " "]);
1080
+ case "seq": {
1081
+ let out = "";
1082
+ for (const item of node.items) {
1083
+ const count = rng.int(item.min, item.max);
1084
+ for (let i = 0; i < count; i++) out += render(item.node, rng);
1085
+ }
1086
+ return out;
1087
+ }
1088
+ case "alt": return render(rng.pick(node.branches), rng);
1089
+ }
1090
+ }
1091
+ //#endregion
1092
+ //#region src/faker/helpers.ts
1093
+ /**
1094
+ * General helpers — operate on arbitrary inputs, not tied to any locale or
1095
+ * faker namespace.
1096
+ *
1097
+ * @example
1098
+ * ```ts
1099
+ * faker.helpers.arrayElement([1, 2, 3]) // 2
1100
+ * faker.helpers.arrayElements([1, 2, 3, 4], 2) // [3, 1]
1101
+ * faker.helpers.shuffle([1, 2, 3]) // [2, 3, 1]
1102
+ * faker.helpers.weightedArrayElement([
1103
+ * { value: 'rare', weight: 1 },
1104
+ * { value: 'common', weight: 9 },
1105
+ * ])
1106
+ * faker.helpers.fromRegExp(/[A-Z]{3}\d{4}/) // "PWB7401"
1107
+ * faker.helpers.unique(() => faker.internet.email(), 5)
1108
+ * ```
1109
+ */
1110
+ var Helpers = class {
1111
+ rng;
1112
+ constructor(rng) {
1113
+ this.rng = rng;
1114
+ }
1115
+ arrayElement(items) {
1116
+ return this.rng.pick(items);
1117
+ }
1118
+ /** Pick `count` distinct elements from `items` (no replacement). */
1119
+ arrayElements(items, count) {
1120
+ const n = count ?? this.rng.int(1, items.length);
1121
+ if (n > items.length) throw new Error(`[Helpers] arrayElements: requested ${n.toString()} from ${items.length.toString()} items.`);
1122
+ return this.shuffle(items).slice(0, n);
1123
+ }
1124
+ shuffle(items) {
1125
+ const copy = [...items];
1126
+ for (let i = copy.length - 1; i > 0; i--) {
1127
+ const j = this.rng.int(0, i);
1128
+ const a = copy[i];
1129
+ const b = copy[j];
1130
+ if (a === void 0 || b === void 0) continue;
1131
+ copy[i] = b;
1132
+ copy[j] = a;
1133
+ }
1134
+ return copy;
1135
+ }
1136
+ weightedArrayElement(items) {
1137
+ if (items.length === 0) throw new Error("[Helpers] weightedArrayElement: empty list.");
1138
+ const total = items.reduce((acc, it) => acc + it.weight, 0);
1139
+ if (total <= 0) throw new Error("[Helpers] weightedArrayElement: weights sum to <= 0.");
1140
+ let target = this.rng.next() * total;
1141
+ for (const it of items) {
1142
+ target -= it.weight;
1143
+ if (target <= 0) return it.value;
1144
+ }
1145
+ const last = items[items.length - 1];
1146
+ if (last === void 0) throw new Error("[Helpers] weightedArrayElement: unreachable");
1147
+ return last.value;
1148
+ }
1149
+ /** Build an array of length `length` by calling `fn(index)`. */
1150
+ multiple(length, fn) {
1151
+ return Array.from({ length }, (_, i) => fn(i));
1152
+ }
1153
+ /** Repeat a string `count` times. */
1154
+ repeat(value, count) {
1155
+ return value.repeat(count);
1156
+ }
1157
+ /** Sample-string matching a regex. */
1158
+ fromRegExp(pattern) {
1159
+ return generateFromRegex(pattern, this.rng);
1160
+ }
1161
+ /**
1162
+ * Collect `count` unique results from `fn`. Throws if the retry budget is
1163
+ * exhausted before reaching `count`.
1164
+ */
1165
+ unique(fn, count, options = {}) {
1166
+ const out = /* @__PURE__ */ new Set();
1167
+ const budget = options.maxRetries ?? count * 10;
1168
+ let attempts = 0;
1169
+ while (out.size < count && attempts < budget) {
1170
+ out.add(fn());
1171
+ attempts++;
1172
+ }
1173
+ if (out.size < count) throw new Error(`[Helpers] unique: could not produce ${count.toString()} unique values after ${budget.toString()} attempts (got ${out.size.toString()}).`);
1174
+ return [...out];
1175
+ }
1176
+ /** Pick a random `enum` value, handling numeric reverse-mappings. */
1177
+ enumValue(enumObj) {
1178
+ const numericKeys = Object.keys(enumObj).filter((k) => /^\d+$/.test(k));
1179
+ const values = numericKeys.length > 0 ? numericKeys.map((k) => enumObj[k]) : Object.values(enumObj);
1180
+ if (values.length === 0) throw new Error("[Helpers] enumValue: enum has no values.");
1181
+ return this.rng.pick(values);
1182
+ }
1183
+ /** With probability `chance`, return `value`; otherwise `undefined`. */
1184
+ maybe(value, chance = .5) {
1185
+ return this.rng.bool(chance) ? value : void 0;
1186
+ }
1187
+ };
1188
+ //#endregion
1189
+ //#region src/faker/faker.ts
1190
+ /**
1191
+ * Faceted, seedable, locale-aware random-data generator.
1192
+ *
1193
+ * Every namespace shares the same PRNG and locale reference — `seed()` and
1194
+ * `locale()` mutate that shared state in place, so changes propagate without
1195
+ * re-constructing modules.
1196
+ *
1197
+ * @example
1198
+ * ```ts
1199
+ * import { Faker } from '@anil-labs/factory'
1200
+ *
1201
+ * const f = new Faker({ seed: 42, locale: 'en' })
1202
+ * f.person.fullName() // "Olivia Patel"
1203
+ * f.seed(42)
1204
+ * f.person.fullName() // "Olivia Patel" — deterministic
1205
+ *
1206
+ * // Or use the package's default instance:
1207
+ * import { faker } from '@anil-labs/factory'
1208
+ * faker.seed(1)
1209
+ * faker.internet.email()
1210
+ * ```
1211
+ */
1212
+ var Faker = class Faker {
1213
+ rng;
1214
+ localeRef;
1215
+ person;
1216
+ internet;
1217
+ location;
1218
+ lorem;
1219
+ date;
1220
+ number;
1221
+ string;
1222
+ color;
1223
+ company;
1224
+ commerce;
1225
+ finance;
1226
+ image;
1227
+ system;
1228
+ datatype;
1229
+ helpers;
1230
+ constructor(opts = {}) {
1231
+ this.rng = createPrng(opts.seed);
1232
+ this.localeRef = new LocaleRef(opts.locale ?? "en");
1233
+ this.person = new Person(this.rng, this.localeRef);
1234
+ this.internet = new Internet(this.rng, this.localeRef);
1235
+ this.location = new Location(this.rng, this.localeRef);
1236
+ this.lorem = new Lorem(this.rng, this.localeRef);
1237
+ this.date = new DateGen(this.rng);
1238
+ this.number = new NumberGen(this.rng);
1239
+ this.string = new StringGen(this.rng);
1240
+ this.color = new Color(this.rng, this.localeRef);
1241
+ this.company = new Company(this.rng, this.localeRef);
1242
+ this.commerce = new Commerce(this.rng, this.localeRef);
1243
+ this.finance = new Finance(this.rng);
1244
+ this.image = new Image(this.rng);
1245
+ this.system = new System(this.rng, this.localeRef, this.string);
1246
+ this.datatype = new Datatype(this.rng);
1247
+ this.helpers = new Helpers(this.rng);
1248
+ }
1249
+ /** Reseed the underlying PRNG. Subsequent calls are deterministic from here. */
1250
+ seed(seed) {
1251
+ this.rng.seed(seed);
1252
+ return this;
1253
+ }
1254
+ /** Switch the active locale. Throws if unknown. */
1255
+ locale(name) {
1256
+ this.localeRef.set(name);
1257
+ return this;
1258
+ }
1259
+ /** Read the current locale identifier (e.g. `"en"`). */
1260
+ currentLocale() {
1261
+ return this.localeRef.name;
1262
+ }
1263
+ /** Read the current seed (useful for snapshot reproduction). */
1264
+ currentSeed() {
1265
+ return this.rng.currentSeed;
1266
+ }
1267
+ /**
1268
+ * Build a fresh, independent `Faker` with its own PRNG seeded from this
1269
+ * one's current state. Useful when you need to fork a deterministic stream.
1270
+ */
1271
+ fork() {
1272
+ return new Faker({
1273
+ seed: this.rng.int(0, 4294967295),
1274
+ locale: this.localeRef.name
1275
+ });
1276
+ }
1277
+ /** Access the underlying PRNG. Advanced use only. */
1278
+ rawPrng() {
1279
+ return this.rng;
1280
+ }
1281
+ };
1282
+ /** Default singleton — mutable via `faker.seed()` / `faker.locale()`. */
1283
+ var faker = new Faker();
1284
+ //#endregion
1285
+ export { createPrng as C, registerLocale as S, Internet as _, Datatype as a, getLocale as b, Finance as c, Color as d, StringGen as f, Location as g, Lorem as h, generateFromRegex as i, Commerce as l, DateGen as m, faker as n, System as o, NumberGen as p, Helpers as r, Image as s, Faker as t, Company as u, Person as v, Mulberry32 as w, listLocales as x, LocaleRef as y };
1286
+
1287
+ //# sourceMappingURL=faker-BlEhpR26.mjs.map