lacspace-fake 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.
package/dist/lib.cjs ADDED
@@ -0,0 +1,753 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/lib.ts
21
+ var lib_exports = {};
22
+ __export(lib_exports, {
23
+ GEN_ORDER: () => GEN_ORDER,
24
+ LOCALES: () => LOCALES,
25
+ RNG: () => RNG,
26
+ callGen: () => callGen,
27
+ columnsOf: () => columnsOf,
28
+ formatRows: () => formatRows,
29
+ formatValues: () => formatValues,
30
+ generateRows: () => generateRows,
31
+ generateValues: () => generateValues,
32
+ generators: () => generators,
33
+ hasGen: () => hasGen,
34
+ hashSeed: () => hashSeed,
35
+ isFormat: () => isFormat,
36
+ isLocale: () => isLocale,
37
+ normalizeSeed: () => normalizeSeed,
38
+ parseArgString: () => parseArgString,
39
+ parseFields: () => parseFields,
40
+ parseJsonSchema: () => parseJsonSchema,
41
+ slugify: () => slugify,
42
+ specFromJson: () => specFromJson,
43
+ specFromString: () => specFromString,
44
+ sqlIdent: () => sqlIdent,
45
+ sqlValue: () => sqlValue,
46
+ toCsv: () => toCsv,
47
+ toSql: () => toSql
48
+ });
49
+ module.exports = __toCommonJS(lib_exports);
50
+
51
+ // src/prng.ts
52
+ function hashSeed(input) {
53
+ let h = 2166136261 >>> 0;
54
+ for (let i = 0; i < input.length; i++) {
55
+ h ^= input.charCodeAt(i);
56
+ h = Math.imul(h, 16777619);
57
+ }
58
+ return h >>> 0;
59
+ }
60
+ function normalizeSeed(seed) {
61
+ if (typeof seed === "number") return Math.floor(seed) >>> 0;
62
+ const trimmed = seed.trim();
63
+ if (/^-?\d+$/.test(trimmed)) return Math.abs(Number(trimmed)) >>> 0;
64
+ return hashSeed(trimmed);
65
+ }
66
+ function mulberry32(a) {
67
+ let state = a >>> 0;
68
+ return function next() {
69
+ state = state + 1831565813 | 0;
70
+ let t = state;
71
+ t = Math.imul(t ^ t >>> 15, t | 1);
72
+ t ^= t + Math.imul(t ^ t >>> 7, t | 61);
73
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
74
+ };
75
+ }
76
+ var RNG = class {
77
+ _next;
78
+ seed;
79
+ constructor(seed) {
80
+ this.seed = normalizeSeed(seed);
81
+ this._next = mulberry32(this.seed);
82
+ }
83
+ /** Uniform float in [0, 1). */
84
+ next() {
85
+ return this._next();
86
+ }
87
+ /** Inclusive integer in [min, max]. */
88
+ int(min, max) {
89
+ if (max < min) [min, max] = [max, min];
90
+ return min + Math.floor(this.next() * (max - min + 1));
91
+ }
92
+ /** Float in [min, max) rounded to `decimals` places (default 2). */
93
+ float(min, max, decimals = 2) {
94
+ if (max < min) [min, max] = [max, min];
95
+ const v = min + this.next() * (max - min);
96
+ const f = 10 ** decimals;
97
+ return Math.round(v * f) / f;
98
+ }
99
+ /** `true` with probability `prob` (default 0.5). */
100
+ bool(prob = 0.5) {
101
+ return this.next() < prob;
102
+ }
103
+ /** Pick one element uniformly. Throws on an empty array. */
104
+ pick(items) {
105
+ if (items.length === 0) throw new Error("pick() called on an empty array");
106
+ return items[Math.floor(this.next() * items.length)];
107
+ }
108
+ /** Pick `n` distinct elements (Fisher–Yates partial shuffle). */
109
+ sample(items, n) {
110
+ const arr = items.slice();
111
+ const k = Math.min(n, arr.length);
112
+ for (let i = 0; i < k; i++) {
113
+ const j = i + Math.floor(this.next() * (arr.length - i));
114
+ [arr[i], arr[j]] = [arr[j], arr[i]];
115
+ }
116
+ return arr.slice(0, k);
117
+ }
118
+ /** Return a shuffled copy. */
119
+ shuffle(items) {
120
+ return this.sample(items, items.length);
121
+ }
122
+ /** Weighted pick. Entries are `[value, weight]`; weights need not sum to 1. */
123
+ weighted(entries) {
124
+ const total = entries.reduce((s, [, w]) => s + (w > 0 ? w : 0), 0);
125
+ if (total <= 0) throw new Error("weighted() needs at least one positive weight");
126
+ let r = this.next() * total;
127
+ for (const [value, w] of entries) {
128
+ if (w <= 0) continue;
129
+ r -= w;
130
+ if (r < 0) return value;
131
+ }
132
+ return entries[entries.length - 1][0];
133
+ }
134
+ /** A string of `len` random hex characters. */
135
+ hex(len) {
136
+ let out = "";
137
+ for (let i = 0; i < len; i++) out += "0123456789abcdef"[this.int(0, 15)];
138
+ return out;
139
+ }
140
+ /** A string of `len` random decimal digits. */
141
+ digits(len) {
142
+ let out = "";
143
+ for (let i = 0; i < len; i++) out += String(this.int(0, 9));
144
+ return out;
145
+ }
146
+ /** Pick `len` characters from an alphabet. */
147
+ chars(alphabet, len) {
148
+ let out = "";
149
+ for (let i = 0; i < len; i++) out += alphabet[this.int(0, alphabet.length - 1)];
150
+ return out;
151
+ }
152
+ /** An RFC-4122 version-4 UUID, drawn deterministically from this RNG. */
153
+ uuid() {
154
+ const h = this.hex(32).split("");
155
+ h[12] = "4";
156
+ h[16] = "89ab"[this.int(0, 3)];
157
+ const s = h.join("");
158
+ return `${s.slice(0, 8)}-${s.slice(8, 12)}-${s.slice(12, 16)}-${s.slice(16, 20)}-${s.slice(20, 32)}`;
159
+ }
160
+ };
161
+
162
+ // src/data.ts
163
+ var LOREM = "lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua enim ad minim veniam quis nostrud exercitation ullamco laboris nisi aliquip ex ea commodo consequat duis aute irure in reprehenderit voluptate velit esse cillum eu fugiat nulla pariatur excepteur sint occaecat cupidatat non proident sunt culpa qui officia deserunt mollit anim id est laborum".split(" ");
164
+ var LOREM_WORDS = LOREM;
165
+ var EMAIL_DOMAINS = ["gmail.com", "yahoo.com", "outlook.com", "hotmail.com", "proton.me", "icloud.com"];
166
+ var URL_TLDS = ["com", "net", "org", "io", "dev", "co", "app", "xyz"];
167
+ var COMPANY_SUFFIXES = ["Inc", "LLC", "Ltd", "Group", "Labs", "Technologies", "Systems", "Solutions", "Holdings", "Partners"];
168
+ var COMPANY_PREFIXES = ["Blue", "Green", "Bright", "Silver", "North", "Peak", "Core", "Nova", "Prime", "Vertex", "Quantum", "Apex", "Cloud", "Iron", "Golden"];
169
+ var COMPANY_ROOTS = ["wave", "byte", "forge", "sphere", "logic", "sync", "grid", "flux", "scale", "stack", "pulse", "bloom", "shift", "orbit", "loop"];
170
+ var BUZZ_ADJ = ["synergistic", "scalable", "frictionless", "customer-centric", "cutting-edge", "cloud-native", "next-generation", "end-to-end", "data-driven", "seamless", "robust", "agile"];
171
+ var BUZZ_NOUN = ["solutions", "paradigms", "platforms", "architectures", "ecosystems", "workflows", "insights", "experiences", "pipelines", "frameworks", "channels", "networks"];
172
+ var BUZZ_VERB = ["engineer", "empower", "streamline", "orchestrate", "harness", "leverage", "optimize", "accelerate", "transform", "unlock", "scale", "deliver"];
173
+ var JOB_LEVELS = ["Junior", "Senior", "Lead", "Principal", "Staff", "Chief", "Head of", "Associate"];
174
+ var JOB_ROLES = ["Engineer", "Developer", "Designer", "Manager", "Analyst", "Consultant", "Architect", "Specialist", "Officer", "Strategist", "Scientist", "Administrator"];
175
+ var DEPARTMENTS = ["Engineering", "Sales", "Marketing", "Finance", "Human Resources", "Operations", "Support", "Product", "Design", "Legal", "Research", "IT"];
176
+ var PRODUCT_ADJ = ["Ergonomic", "Rustic", "Handcrafted", "Sleek", "Refined", "Intelligent", "Modern", "Premium", "Compact", "Elegant", "Durable", "Lightweight"];
177
+ var PRODUCT_MATERIAL = ["Steel", "Wooden", "Cotton", "Leather", "Bamboo", "Ceramic", "Plastic", "Concrete", "Glass", "Copper"];
178
+ var PRODUCT_NOUN = ["Chair", "Table", "Keyboard", "Bottle", "Backpack", "Lamp", "Shoes", "Watch", "Headphones", "Jacket", "Mug", "Gloves", "Wallet", "Speaker"];
179
+ var PRODUCT_CATEGORIES = ["Electronics", "Books", "Clothing", "Home", "Toys", "Sports", "Beauty", "Grocery", "Automotive", "Garden", "Health", "Office"];
180
+ var COLORS = ["red", "green", "blue", "yellow", "orange", "purple", "teal", "black", "white", "gray", "pink", "brown"];
181
+ var EN = {
182
+ firstNamesMale: ["James", "John", "Michael", "David", "Robert", "William", "Daniel", "Thomas", "Joseph", "Ethan", "Liam", "Noah", "Lucas", "Henry", "Alexander"],
183
+ firstNamesFemale: ["Mary", "Emma", "Olivia", "Sophia", "Isabella", "Ava", "Charlotte", "Amelia", "Emily", "Grace", "Chloe", "Zoe", "Hannah", "Lily", "Nora"],
184
+ lastNames: ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez", "Wilson", "Anderson", "Taylor", "Thomas", "Moore"],
185
+ cities: ["New York", "London", "San Francisco", "Berlin", "Toronto", "Sydney", "Singapore", "Tokyo", "Paris", "Amsterdam", "Austin", "Seattle", "Boston", "Chicago", "Denver"],
186
+ states: ["California", "Texas", "New York", "Florida", "Washington", "Illinois", "Ohio", "Georgia", "Colorado", "Oregon", "Arizona", "Nevada"],
187
+ country: "United States",
188
+ countryCode: "US",
189
+ streetNames: ["Maple", "Oak", "Pine", "Cedar", "Elm", "Washington", "Lake", "Hill", "Sunset", "River", "Park", "Main", "Highland", "Franklin", "Union"],
190
+ streetSuffixes: ["Street", "Avenue", "Boulevard", "Lane", "Road", "Drive", "Court", "Way", "Terrace", "Place"],
191
+ zip: (r) => r.digits(5),
192
+ currency: { code: "USD", symbol: "$" },
193
+ phone: (r) => {
194
+ const area = r.digits(3);
195
+ const rest = `${r.digits(3)}${r.digits(4)}`;
196
+ return { e164: `+1${area}${rest}`, local: `(${area}) ${rest.slice(0, 3)}-${rest.slice(3)}` };
197
+ }
198
+ };
199
+ var NE = {
200
+ firstNamesMale: ["Aarav", "Aayush", "Anish", "Bibek", "Prakash", "Rajesh", "Sujan", "Kiran", "Nabin", "Suman", "Dipesh", "Hari", "Krishna", "Bishal", "Rohit", "Manish", "Saroj", "Sandesh"],
201
+ firstNamesFemale: ["Anjali", "Sita", "Gita", "Puja", "Sunita", "Rita", "Sarita", "Nisha", "Priya", "Laxmi", "Sabina", "Muna", "Rekha", "Asha", "Deepa", "Sushmita", "Manisha", "Pratima"],
202
+ lastNames: ["Sharma", "Shrestha", "Adhikari", "Karki", "Thapa", "Gurung", "Magar", "Rai", "Limbu", "Tamang", "Bhattarai", "Poudel", "Koirala", "Acharya", "Dahal", "Bhandari", "Pandey", "Khadka", "Basnet", "Maharjan"],
203
+ cities: ["Kathmandu", "Lalitpur", "Bhaktapur", "Pokhara", "Biratnagar", "Birgunj", "Dharan", "Butwal", "Hetauda", "Nepalgunj", "Dhangadhi", "Janakpur", "Itahari", "Bharatpur", "Damak"],
204
+ states: ["Koshi", "Madhesh", "Bagmati", "Gandaki", "Lumbini", "Karnali", "Sudurpashchim"],
205
+ country: "Nepal",
206
+ countryCode: "NP",
207
+ streetNames: ["New Road", "Durbar Marg", "Lakeside", "Putalisadak", "Baneshwor", "Thamel", "Kupondole", "Jawalakhel", "Maitighar", "Baluwatar", "Sanepa", "Boudha"],
208
+ streetSuffixes: ["Marg", "Chowk", "Tole", "Path", "Road", "Sadak"],
209
+ zip: (r) => r.digits(5),
210
+ currency: { code: "NPR", symbol: "Rs." },
211
+ phone: (r) => {
212
+ const prefix = r.pick(["98", "97"]);
213
+ const carrier = r.pick(["4", "5", "6", "0", "1", "8"]);
214
+ const rest = r.digits(7);
215
+ const local = `${prefix}${carrier}${rest}`;
216
+ return { e164: `+977${local}`, local: `${local.slice(0, 3)}-${local.slice(3)}` };
217
+ }
218
+ };
219
+ var LOCALES = { en: EN, ne: NE };
220
+ function isLocale(v) {
221
+ return v === "en" || v === "ne";
222
+ }
223
+
224
+ // src/generators.ts
225
+ function data(ctx) {
226
+ return LOCALES[ctx.locale];
227
+ }
228
+ function num(a, fallback) {
229
+ if (a === void 0) return fallback;
230
+ const n = typeof a === "number" ? a : Number(a);
231
+ return Number.isFinite(n) ? n : fallback;
232
+ }
233
+ function str(a, fallback = "") {
234
+ return a === void 0 ? fallback : String(a);
235
+ }
236
+ function slugify(input) {
237
+ return input.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
238
+ }
239
+ function capitalize(s) {
240
+ return s.length ? s[0].toUpperCase() + s.slice(1) : s;
241
+ }
242
+ function pickFirstName(ctx, gender) {
243
+ const d = data(ctx);
244
+ const g = gender ?? (ctx.rng.bool() ? "male" : "female");
245
+ return ctx.rng.pick(g === "male" ? d.firstNamesMale : d.firstNamesFemale);
246
+ }
247
+ function nameParts(ctx) {
248
+ const d = data(ctx);
249
+ const rowFirst = ctx.row["firstName"];
250
+ const rowLast = ctx.row["lastName"];
251
+ const first = typeof rowFirst === "string" && rowFirst ? rowFirst : pickFirstName(ctx);
252
+ const last = typeof rowLast === "string" && rowLast ? rowLast : ctx.rng.pick(d.lastNames);
253
+ return { first, last };
254
+ }
255
+ function makeWords(ctx, count) {
256
+ const out = [];
257
+ for (let i = 0; i < count; i++) out.push(ctx.rng.pick(LOREM_WORDS));
258
+ return out.join(" ");
259
+ }
260
+ function makeSentence(ctx, words) {
261
+ const n = words ?? ctx.rng.int(6, 14);
262
+ return capitalize(makeWords(ctx, n)) + ".";
263
+ }
264
+ function makeParagraph(ctx, sentences) {
265
+ const n = sentences ?? ctx.rng.int(3, 6);
266
+ const out = [];
267
+ for (let i = 0; i < n; i++) out.push(makeSentence(ctx));
268
+ return out.join(" ");
269
+ }
270
+ var DAY_MS = 864e5;
271
+ function isoOf(ms) {
272
+ return new Date(ms).toISOString();
273
+ }
274
+ var generators = {
275
+ // person
276
+ firstName: (ctx, a) => pickFirstName(ctx, a[0] === "male" || a[0] === "female" ? a[0] : void 0),
277
+ lastName: (ctx) => ctx.rng.pick(data(ctx).lastNames),
278
+ fullName: (ctx) => {
279
+ const { first, last } = nameParts(ctx);
280
+ return `${first} ${last}`;
281
+ },
282
+ name: (ctx) => generators["fullName"](ctx, []),
283
+ gender: (ctx) => ctx.rng.pick(["male", "female"]),
284
+ age: (ctx, a) => ctx.rng.int(num(a[0], 18), num(a[1], 80)),
285
+ dateOfBirth: (ctx, a) => {
286
+ const minAge = num(a[0], 18);
287
+ const maxAge = num(a[1], 80);
288
+ const years = ctx.rng.int(minAge, maxAge);
289
+ const ms = Date.now() - years * 365.25 * DAY_MS - ctx.rng.int(0, 364) * DAY_MS;
290
+ return isoOf(ms).slice(0, 10);
291
+ },
292
+ dob: (ctx, a) => generators["dateOfBirth"](ctx, a),
293
+ // internet
294
+ username: (ctx) => {
295
+ const { first, last } = nameParts(ctx);
296
+ const sep = ctx.rng.pick(["", ".", "_"]);
297
+ const tail = ctx.rng.bool(0.6) ? String(ctx.rng.int(1, 999)) : "";
298
+ return `${first.toLowerCase()}${sep}${last.toLowerCase()}${tail}`;
299
+ },
300
+ email: (ctx, a) => {
301
+ const { first, last } = nameParts(ctx);
302
+ const rowUser = ctx.row["username"];
303
+ const localBase = typeof rowUser === "string" && rowUser ? rowUser : `${first.toLowerCase()}${ctx.rng.pick([".", "_", ""])}${last.toLowerCase()}`;
304
+ const suffix = ctx.rng.bool(0.5) ? String(ctx.rng.int(1, 99)) : "";
305
+ const domain = a[0] !== void 0 ? str(a[0]) : ctx.rng.pick(EMAIL_DOMAINS);
306
+ return `${slugify(localBase).replace(/-/g, ".")}${suffix}@${domain}`;
307
+ },
308
+ domain: (ctx) => `${ctx.rng.pick(COMPANY_ROOTS)}${ctx.rng.pick(COMPANY_ROOTS)}.${ctx.rng.pick(URL_TLDS)}`,
309
+ url: (ctx) => `https://${ctx.rng.pick(COMPANY_ROOTS)}${ctx.rng.pick(COMPANY_ROOTS)}.${ctx.rng.pick(URL_TLDS)}`,
310
+ slug: (ctx, a) => {
311
+ const words = num(a[0], ctx.rng.int(2, 4));
312
+ return slugify(makeWords(ctx, words));
313
+ },
314
+ ipv4: (ctx) => `${ctx.rng.int(1, 255)}.${ctx.rng.int(0, 255)}.${ctx.rng.int(0, 255)}.${ctx.rng.int(1, 254)}`,
315
+ ipv6: (ctx) => Array.from({ length: 8 }, () => ctx.rng.hex(4)).join(":"),
316
+ mac: (ctx) => Array.from({ length: 6 }, () => ctx.rng.hex(2)).join(":"),
317
+ password: (ctx, a) => {
318
+ const len = num(a[0], 12);
319
+ return ctx.rng.chars("abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789!@#$%&*", len);
320
+ },
321
+ uuid: (ctx) => ctx.rng.uuid(),
322
+ // phone
323
+ phone: (ctx) => data(ctx).phone(ctx.rng).e164,
324
+ phoneLocal: (ctx) => data(ctx).phone(ctx.rng).local,
325
+ // address
326
+ street: (ctx) => {
327
+ const d = data(ctx);
328
+ return `${ctx.rng.int(1, 9999)} ${ctx.rng.pick(d.streetNames)} ${ctx.rng.pick(d.streetSuffixes)}`;
329
+ },
330
+ city: (ctx) => ctx.rng.pick(data(ctx).cities),
331
+ state: (ctx) => ctx.rng.pick(data(ctx).states),
332
+ province: (ctx) => ctx.rng.pick(data(ctx).states),
333
+ country: (ctx) => data(ctx).country,
334
+ countryCode: (ctx) => data(ctx).countryCode,
335
+ zip: (ctx) => data(ctx).zip(ctx.rng),
336
+ postalCode: (ctx) => data(ctx).zip(ctx.rng),
337
+ address: (ctx) => {
338
+ const d = data(ctx);
339
+ const street = `${ctx.rng.int(1, 9999)} ${ctx.rng.pick(d.streetNames)} ${ctx.rng.pick(d.streetSuffixes)}`;
340
+ return `${street}, ${ctx.rng.pick(d.cities)}, ${ctx.rng.pick(d.states)} ${d.zip(ctx.rng)}`;
341
+ },
342
+ latitude: (ctx) => ctx.rng.float(-90, 90, 6),
343
+ longitude: (ctx) => ctx.rng.float(-180, 180, 6),
344
+ latlng: (ctx) => `${ctx.rng.float(-90, 90, 6)},${ctx.rng.float(-180, 180, 6)}`,
345
+ // company
346
+ company: (ctx) => `${ctx.rng.pick(COMPANY_PREFIXES)}${ctx.rng.pick(COMPANY_ROOTS)} ${ctx.rng.pick(COMPANY_SUFFIXES)}`,
347
+ catchphrase: (ctx) => capitalize(`${ctx.rng.pick(BUZZ_VERB)} ${ctx.rng.pick(BUZZ_ADJ)} ${ctx.rng.pick(BUZZ_NOUN)}`),
348
+ jobTitle: (ctx) => `${ctx.rng.pick(JOB_LEVELS)} ${ctx.rng.pick(JOB_ROLES)}`,
349
+ department: (ctx) => ctx.rng.pick(DEPARTMENTS),
350
+ // commerce
351
+ productName: (ctx) => `${ctx.rng.pick(PRODUCT_ADJ)} ${ctx.rng.pick(PRODUCT_MATERIAL)} ${ctx.rng.pick(PRODUCT_NOUN)}`,
352
+ price: (ctx, a) => ctx.rng.float(num(a[0], 1), num(a[1], 999), 2),
353
+ sku: (ctx) => `${ctx.rng.chars("ABCDEFGHJKLMNPQRSTUVWXYZ", 3)}-${ctx.rng.digits(6)}`,
354
+ currency: (ctx) => data(ctx).currency.code,
355
+ category: (ctx) => ctx.rng.pick(PRODUCT_CATEGORIES),
356
+ color: (ctx) => ctx.rng.pick(COLORS),
357
+ // text
358
+ word: (ctx) => ctx.rng.pick(LOREM_WORDS),
359
+ words: (ctx, a) => makeWords(ctx, num(a[0], 3)),
360
+ sentence: (ctx, a) => makeSentence(ctx, a[0] !== void 0 ? num(a[0], 8) : void 0),
361
+ paragraph: (ctx, a) => makeParagraph(ctx, a[0] !== void 0 ? num(a[0], 4) : void 0),
362
+ lorem: (ctx, a) => makeParagraph(ctx, num(a[0], 3)),
363
+ // datetime
364
+ past: (ctx, a) => {
365
+ const days = num(a[0], 365);
366
+ return isoOf(Date.now() - ctx.rng.int(1, Math.max(1, days)) * DAY_MS - ctx.rng.int(0, DAY_MS));
367
+ },
368
+ future: (ctx, a) => {
369
+ const days = num(a[0], 365);
370
+ return isoOf(Date.now() + ctx.rng.int(1, Math.max(1, days)) * DAY_MS + ctx.rng.int(0, DAY_MS));
371
+ },
372
+ recent: (ctx, a) => {
373
+ const days = num(a[0], 7);
374
+ return isoOf(Date.now() - ctx.rng.int(0, Math.max(1, days) * DAY_MS));
375
+ },
376
+ soon: (ctx, a) => {
377
+ const days = num(a[0], 7);
378
+ return isoOf(Date.now() + ctx.rng.int(0, Math.max(1, days) * DAY_MS));
379
+ },
380
+ between: (ctx, a) => {
381
+ const from = Date.parse(str(a[0]));
382
+ const to = Date.parse(str(a[1]));
383
+ if (Number.isNaN(from) || Number.isNaN(to)) throw new Error("between(from..to) needs two ISO dates");
384
+ const lo = Math.min(from, to);
385
+ const hi = Math.max(from, to);
386
+ return isoOf(lo + Math.floor(ctx.rng.next() * (hi - lo)));
387
+ },
388
+ timestamp: (ctx, a) => {
389
+ const days = num(a[0], 365);
390
+ return isoOf(Date.now() - ctx.rng.int(0, Math.max(1, days)) * DAY_MS);
391
+ },
392
+ date: (ctx, a) => String(generators["timestamp"](ctx, a)).slice(0, 10),
393
+ time: (ctx) => `${String(ctx.rng.int(0, 23)).padStart(2, "0")}:${String(ctx.rng.int(0, 59)).padStart(2, "0")}`,
394
+ // numbers / booleans / enums
395
+ int: (ctx, a) => ctx.rng.int(num(a[0], 0), num(a[1], 100)),
396
+ number: (ctx, a) => ctx.rng.int(num(a[0], 0), num(a[1], 100)),
397
+ float: (ctx, a) => ctx.rng.float(num(a[0], 0), num(a[1], 1), num(a[2], 2)),
398
+ digit: (ctx) => ctx.rng.int(0, 9),
399
+ bool: (ctx, a) => ctx.rng.bool(a[0] !== void 0 ? num(a[0], 0.5) : 0.5),
400
+ boolean: (ctx, a) => ctx.rng.bool(a[0] !== void 0 ? num(a[0], 0.5) : 0.5),
401
+ oneOf: (ctx, a) => {
402
+ if (a.length === 0) throw new Error("oneOf(...) needs at least one option");
403
+ return ctx.rng.pick(a);
404
+ },
405
+ enum: (ctx, a) => generators["oneOf"](ctx, a),
406
+ weighted: (ctx, a) => {
407
+ const entries = a.map((raw) => {
408
+ const s = String(raw);
409
+ const idx = s.lastIndexOf(":");
410
+ if (idx < 0) return [s, 1];
411
+ return [s.slice(0, idx), Number(s.slice(idx + 1)) || 0];
412
+ });
413
+ if (entries.length === 0) throw new Error("weighted(...) needs at least one value:weight");
414
+ return ctx.rng.weighted(entries);
415
+ },
416
+ // ids
417
+ autoincrement: (ctx, a) => num(a[0], 1) + ctx.index,
418
+ autoInc: (ctx, a) => generators["autoincrement"](ctx, a),
419
+ id: (ctx, a) => generators["autoincrement"](ctx, a),
420
+ nanoid: (ctx, a) => ctx.rng.chars("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-", num(a[0], 21)),
421
+ objectId: (ctx) => ctx.rng.hex(24),
422
+ // Nepal-flavoured ids (locale-aware amount/tax numbers)
423
+ pan: (ctx) => ctx.rng.digits(9),
424
+ vat: (ctx) => ctx.rng.digits(9)
425
+ };
426
+ var GEN_ORDER = [
427
+ "firstName",
428
+ "lastName",
429
+ "fullName",
430
+ "gender",
431
+ "age",
432
+ "dateOfBirth",
433
+ "email",
434
+ "username",
435
+ "url",
436
+ "domain",
437
+ "ipv4",
438
+ "ipv6",
439
+ "mac",
440
+ "password",
441
+ "uuid",
442
+ "slug",
443
+ "phone",
444
+ "phoneLocal",
445
+ "street",
446
+ "city",
447
+ "state",
448
+ "country",
449
+ "countryCode",
450
+ "zip",
451
+ "address",
452
+ "latitude",
453
+ "longitude",
454
+ "latlng",
455
+ "company",
456
+ "catchphrase",
457
+ "jobTitle",
458
+ "department",
459
+ "productName",
460
+ "price",
461
+ "sku",
462
+ "currency",
463
+ "category",
464
+ "color",
465
+ "word",
466
+ "words",
467
+ "sentence",
468
+ "paragraph",
469
+ "lorem",
470
+ "past",
471
+ "future",
472
+ "recent",
473
+ "soon",
474
+ "between",
475
+ "timestamp",
476
+ "date",
477
+ "time",
478
+ "int",
479
+ "float",
480
+ "bool",
481
+ "oneOf",
482
+ "weighted",
483
+ "digit",
484
+ "autoincrement",
485
+ "nanoid",
486
+ "objectId",
487
+ "pan",
488
+ "vat"
489
+ ];
490
+ function callGen(name, ctx, args) {
491
+ const gen = generators[name];
492
+ if (!gen) throw new Error(`Unknown generator: "${name}". Run \`lacspace-fake list\` to see all generators.`);
493
+ return gen(ctx, args);
494
+ }
495
+ function hasGen(name) {
496
+ return Object.prototype.hasOwnProperty.call(generators, name);
497
+ }
498
+
499
+ // src/schema.ts
500
+ function splitTopLevel(input, sep) {
501
+ const out = [];
502
+ let depth = 0;
503
+ let cur = "";
504
+ for (const ch of input) {
505
+ if (ch === "(") depth++;
506
+ else if (ch === ")") depth = Math.max(0, depth - 1);
507
+ if (ch === sep && depth === 0) {
508
+ out.push(cur);
509
+ cur = "";
510
+ } else {
511
+ cur += ch;
512
+ }
513
+ }
514
+ if (cur.trim() !== "" || out.length) out.push(cur);
515
+ return out.map((s) => s.trim()).filter((s) => s.length > 0);
516
+ }
517
+ function coerceArg(token) {
518
+ const t = token.trim();
519
+ if (/^-?\d+(\.\d+)?$/.test(t)) return Number(t);
520
+ return t;
521
+ }
522
+ function parseArgString(inner) {
523
+ const trimmed = inner.trim();
524
+ if (trimmed === "") return [];
525
+ let parts;
526
+ if (trimmed.includes("|")) parts = trimmed.split("|");
527
+ else if (trimmed.includes("..")) parts = trimmed.split("..");
528
+ else parts = splitTopLevel(trimmed, ",");
529
+ return parts.map((p) => coerceArg(p));
530
+ }
531
+ function specFromString(raw) {
532
+ const s = raw.trim();
533
+ const m = /^([A-Za-z_][A-Za-z0-9_]*)\s*(?:\((.*)\))?$/.exec(s);
534
+ if (!m) throw new Error(`Invalid generator spec: "${raw}"`);
535
+ const name = m[1];
536
+ const args = m[2] !== void 0 ? parseArgString(m[2]) : [];
537
+ callGen(name, probeCtx(), args);
538
+ return (ctx) => callGen(name, ctx, args);
539
+ }
540
+ function probeCtx() {
541
+ return { rng: new RNG(1), locale: "en", index: 0, row: {} };
542
+ }
543
+ function isRecord(v) {
544
+ return typeof v === "object" && v !== null && !Array.isArray(v);
545
+ }
546
+ function specFromJson(value) {
547
+ if (typeof value === "string") return specFromString(value);
548
+ if (typeof value === "number" || typeof value === "boolean" || value === null) {
549
+ return () => value;
550
+ }
551
+ if (Array.isArray(value)) {
552
+ const specs = value.map((v) => specFromJson(v));
553
+ return (ctx) => specs[ctx.rng.int(0, specs.length - 1)](ctx);
554
+ }
555
+ if (isRecord(value)) {
556
+ const type = value["type"];
557
+ if (type === "array") {
558
+ const a = value;
559
+ if (a.of === void 0) throw new Error('array spec needs an "of" field');
560
+ const itemSpec = specFromJson(a.of);
561
+ return (ctx) => {
562
+ const n = typeof a.count === "number" ? a.count : ctx.rng.int(typeof a.min === "number" ? a.min : 1, typeof a.max === "number" ? a.max : 3);
563
+ const out = [];
564
+ for (let i = 0; i < n; i++) out.push(itemSpec(ctx));
565
+ return out;
566
+ };
567
+ }
568
+ if (type === "object") {
569
+ const o = value;
570
+ if (!isRecord(o.properties)) throw new Error('object spec needs a "properties" map');
571
+ const fields2 = fieldsFromRecord(o.properties);
572
+ return (ctx) => buildObject(fields2, ctx);
573
+ }
574
+ if (typeof type === "string") {
575
+ const args = argsFromJsonObject(value);
576
+ return (ctx) => callGen(type, ctx, args);
577
+ }
578
+ const fields = fieldsFromRecord(value);
579
+ return (ctx) => buildObject(fields, ctx);
580
+ }
581
+ throw new Error(`Unsupported schema value: ${JSON.stringify(value)}`);
582
+ }
583
+ function argsFromJsonObject(obj) {
584
+ if (Array.isArray(obj["args"])) return obj["args"].map((v) => typeof v === "number" ? v : String(v));
585
+ if (Array.isArray(obj["values"])) return obj["values"].map((v) => typeof v === "number" ? v : String(v));
586
+ const out = [];
587
+ if (typeof obj["min"] === "number") out.push(obj["min"]);
588
+ if (typeof obj["max"] === "number") out.push(obj["max"]);
589
+ if (typeof obj["decimals"] === "number") out.push(obj["decimals"]);
590
+ if (out.length === 0 && typeof obj["prob"] === "number") out.push(obj["prob"]);
591
+ if (out.length === 0 && typeof obj["count"] === "number") out.push(obj["count"]);
592
+ return out;
593
+ }
594
+ function fieldsFromRecord(rec) {
595
+ return Object.keys(rec).map((key) => ({ key, spec: specFromJson(rec[key]) }));
596
+ }
597
+ function buildObject(fields, parent) {
598
+ const row = {};
599
+ const ctx = { rng: parent.rng, locale: parent.locale, index: parent.index, row };
600
+ for (const f of fields) row[f.key] = f.spec(ctx);
601
+ return row;
602
+ }
603
+ function parseFields(input) {
604
+ const specs = splitTopLevel(input, ",");
605
+ if (specs.length === 0) throw new Error("--fields is empty");
606
+ return specs.map((chunk) => {
607
+ const idx = chunk.indexOf(":");
608
+ if (idx < 0) throw new Error(`Field "${chunk}" must be in the form key:generator`);
609
+ const key = chunk.slice(0, idx).trim();
610
+ const specStr = chunk.slice(idx + 1).trim();
611
+ if (!key) throw new Error(`Field "${chunk}" has an empty key`);
612
+ return { key, spec: specFromString(specStr) };
613
+ });
614
+ }
615
+ function parseJsonSchema(schema) {
616
+ if (!isRecord(schema)) throw new Error("A JSON schema must be an object mapping field \u2192 spec");
617
+ const body = isRecord(schema["fields"]) ? schema["fields"] : isRecord(schema["properties"]) && schema["type"] === "object" ? schema["properties"] : schema;
618
+ const fields = fieldsFromRecord(body);
619
+ if (fields.length === 0) throw new Error("The JSON schema has no fields");
620
+ return fields;
621
+ }
622
+ function generateRows(fields, opts = {}) {
623
+ const count = Math.max(0, opts.count ?? 10);
624
+ const seed = opts.seed ?? Math.floor(Math.random() * 4294967295);
625
+ const locale = opts.locale ?? "en";
626
+ const rng = new RNG(seed);
627
+ const rows = [];
628
+ for (let i = 0; i < count; i++) {
629
+ const row = {};
630
+ const ctx = { rng, locale, index: i, row };
631
+ for (const f of fields) row[f.key] = f.spec(ctx);
632
+ rows.push(row);
633
+ }
634
+ return rows;
635
+ }
636
+ function generateValues(specStr, opts = {}) {
637
+ const spec = specFromString(specStr);
638
+ const count = Math.max(0, opts.count ?? 10);
639
+ const seed = opts.seed ?? Math.floor(Math.random() * 4294967295);
640
+ const locale = opts.locale ?? "en";
641
+ const rng = new RNG(seed);
642
+ const out = [];
643
+ for (let i = 0; i < count; i++) {
644
+ out.push(spec({ rng, locale, index: i, row: {} }));
645
+ }
646
+ return out;
647
+ }
648
+
649
+ // src/format.ts
650
+ function isFormat(v) {
651
+ return v === "json" || v === "ndjson" || v === "csv" || v === "sql";
652
+ }
653
+ function columnsOf(rows) {
654
+ const seen = /* @__PURE__ */ new Set();
655
+ const cols = [];
656
+ for (const r of rows) {
657
+ for (const k of Object.keys(r)) {
658
+ if (!seen.has(k)) {
659
+ seen.add(k);
660
+ cols.push(k);
661
+ }
662
+ }
663
+ }
664
+ return cols;
665
+ }
666
+ function cellString(v) {
667
+ if (v === null || v === void 0) return "";
668
+ if (typeof v === "object") return JSON.stringify(v);
669
+ return String(v);
670
+ }
671
+ function csvEscape(v) {
672
+ if (v === null || v === void 0) return "";
673
+ const s = cellString(v);
674
+ if (/[",\n\r]/.test(s)) return `"${s.replace(/"/g, '""')}"`;
675
+ return s;
676
+ }
677
+ function toCsv(rows) {
678
+ const cols = columnsOf(rows);
679
+ const lines = [cols.map(csvEscape).join(",")];
680
+ for (const r of rows) lines.push(cols.map((c) => csvEscape(r[c])).join(","));
681
+ return lines.join("\n");
682
+ }
683
+ function sqlValue(v) {
684
+ if (v === null || v === void 0) return "NULL";
685
+ if (typeof v === "number") return Number.isFinite(v) ? String(v) : "NULL";
686
+ if (typeof v === "boolean") return v ? "TRUE" : "FALSE";
687
+ const s = typeof v === "object" ? JSON.stringify(v) : String(v);
688
+ return `'${s.replace(/'/g, "''")}'`;
689
+ }
690
+ function sqlIdent(name) {
691
+ return `"${String(name).replace(/"/g, '""')}"`;
692
+ }
693
+ function toSql(rows, table) {
694
+ if (!table) throw new Error("SQL output needs a --table name");
695
+ const cols = columnsOf(rows);
696
+ if (rows.length === 0) return `-- no rows for ${sqlIdent(table)}`;
697
+ const colList = cols.map(sqlIdent).join(", ");
698
+ const valueRows = rows.map((r) => ` (${cols.map((c) => sqlValue(r[c])).join(", ")})`);
699
+ return `INSERT INTO ${sqlIdent(table)} (${colList}) VALUES
700
+ ${valueRows.join(",\n")};`;
701
+ }
702
+ function formatRows(rows, opts) {
703
+ switch (opts.format) {
704
+ case "json":
705
+ return JSON.stringify(rows, null, opts.pretty ? 2 : 0);
706
+ case "ndjson":
707
+ return rows.map((r) => JSON.stringify(r)).join("\n");
708
+ case "csv":
709
+ return toCsv(rows);
710
+ case "sql":
711
+ return toSql(rows, opts.table ?? "");
712
+ }
713
+ }
714
+ function formatValues(values, column, opts) {
715
+ switch (opts.format) {
716
+ case "json":
717
+ return JSON.stringify(values, null, opts.pretty ? 2 : 0);
718
+ case "ndjson":
719
+ return values.map((v) => JSON.stringify(v)).join("\n");
720
+ case "csv":
721
+ return toCsv(values.map((v) => ({ [column]: v })));
722
+ case "sql":
723
+ return toSql(values.map((v) => ({ [column]: v })), opts.table ?? column);
724
+ }
725
+ }
726
+ // Annotate the CommonJS export names for ESM import in node:
727
+ 0 && (module.exports = {
728
+ GEN_ORDER,
729
+ LOCALES,
730
+ RNG,
731
+ callGen,
732
+ columnsOf,
733
+ formatRows,
734
+ formatValues,
735
+ generateRows,
736
+ generateValues,
737
+ generators,
738
+ hasGen,
739
+ hashSeed,
740
+ isFormat,
741
+ isLocale,
742
+ normalizeSeed,
743
+ parseArgString,
744
+ parseFields,
745
+ parseJsonSchema,
746
+ slugify,
747
+ specFromJson,
748
+ specFromString,
749
+ sqlIdent,
750
+ sqlValue,
751
+ toCsv,
752
+ toSql
753
+ });