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/LICENSE +51 -0
- package/README.md +193 -0
- package/dist/cli.js +895 -0
- package/dist/lib.cjs +753 -0
- package/dist/lib.d.cts +160 -0
- package/dist/lib.d.ts +160 -0
- package/dist/lib.js +702 -0
- package/package.json +48 -0
package/dist/lib.d.cts
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seeded pseudo-random number generator (mulberry32).
|
|
3
|
+
*
|
|
4
|
+
* Deterministic: the same seed always yields the same sequence, which is what
|
|
5
|
+
* makes fake-data fixtures reproducible across runs and machines. Every
|
|
6
|
+
* generator in this package draws exclusively from an `RNG` instance so that a
|
|
7
|
+
* fixed `--seed` produces byte-identical output.
|
|
8
|
+
*/
|
|
9
|
+
/** Hash an arbitrary string to a 32-bit unsigned integer (for string seeds). */
|
|
10
|
+
declare function hashSeed(input: string): number;
|
|
11
|
+
/** Coerce a user-supplied seed (number, numeric string, or arbitrary string). */
|
|
12
|
+
declare function normalizeSeed(seed: number | string): number;
|
|
13
|
+
/** A seeded random source with typed convenience helpers. */
|
|
14
|
+
declare class RNG {
|
|
15
|
+
private readonly _next;
|
|
16
|
+
readonly seed: number;
|
|
17
|
+
constructor(seed: number | string);
|
|
18
|
+
/** Uniform float in [0, 1). */
|
|
19
|
+
next(): number;
|
|
20
|
+
/** Inclusive integer in [min, max]. */
|
|
21
|
+
int(min: number, max: number): number;
|
|
22
|
+
/** Float in [min, max) rounded to `decimals` places (default 2). */
|
|
23
|
+
float(min: number, max: number, decimals?: number): number;
|
|
24
|
+
/** `true` with probability `prob` (default 0.5). */
|
|
25
|
+
bool(prob?: number): boolean;
|
|
26
|
+
/** Pick one element uniformly. Throws on an empty array. */
|
|
27
|
+
pick<T>(items: readonly T[]): T;
|
|
28
|
+
/** Pick `n` distinct elements (Fisher–Yates partial shuffle). */
|
|
29
|
+
sample<T>(items: readonly T[], n: number): T[];
|
|
30
|
+
/** Return a shuffled copy. */
|
|
31
|
+
shuffle<T>(items: readonly T[]): T[];
|
|
32
|
+
/** Weighted pick. Entries are `[value, weight]`; weights need not sum to 1. */
|
|
33
|
+
weighted<T>(entries: readonly (readonly [T, number])[]): T;
|
|
34
|
+
/** A string of `len` random hex characters. */
|
|
35
|
+
hex(len: number): string;
|
|
36
|
+
/** A string of `len` random decimal digits. */
|
|
37
|
+
digits(len: number): string;
|
|
38
|
+
/** Pick `len` characters from an alphabet. */
|
|
39
|
+
chars(alphabet: string, len: number): string;
|
|
40
|
+
/** An RFC-4122 version-4 UUID, drawn deterministically from this RNG. */
|
|
41
|
+
uuid(): string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Locale data tables. `en` (default) is generic English/US-ish; `ne` is
|
|
46
|
+
* Nepal-aware (romanized Nepali names, districts, provinces, NPR, +977 phones).
|
|
47
|
+
* Everything here is a plain constant so generators stay pure functions of the
|
|
48
|
+
* RNG plus a locale table.
|
|
49
|
+
*/
|
|
50
|
+
type Locale = "en" | "ne";
|
|
51
|
+
interface LocaleData {
|
|
52
|
+
firstNamesMale: string[];
|
|
53
|
+
firstNamesFemale: string[];
|
|
54
|
+
lastNames: string[];
|
|
55
|
+
cities: string[];
|
|
56
|
+
states: string[];
|
|
57
|
+
country: string;
|
|
58
|
+
countryCode: string;
|
|
59
|
+
streetNames: string[];
|
|
60
|
+
streetSuffixes: string[];
|
|
61
|
+
/** How to build a postal/ZIP code for this locale. */
|
|
62
|
+
zip: (r: {
|
|
63
|
+
digits: (n: number) => string;
|
|
64
|
+
}) => string;
|
|
65
|
+
currency: {
|
|
66
|
+
code: string;
|
|
67
|
+
symbol: string;
|
|
68
|
+
};
|
|
69
|
+
/** E.164 phone (with +country) and a local-format phone. */
|
|
70
|
+
phone: (r: {
|
|
71
|
+
digits: (n: number) => string;
|
|
72
|
+
pick: <T>(a: readonly T[]) => T;
|
|
73
|
+
}) => {
|
|
74
|
+
e164: string;
|
|
75
|
+
local: string;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
declare const LOCALES: Record<Locale, LocaleData>;
|
|
79
|
+
declare function isLocale(v: string): v is Locale;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The generator library. Each generator is a pure function of a `GenContext`
|
|
83
|
+
* (an RNG + locale + row index + the partially-built row) and an optional list
|
|
84
|
+
* of positional args. Generators are looked up by name from the `generators`
|
|
85
|
+
* registry, which powers the CLI, the schema engine and the `list` command.
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
interface GenContext {
|
|
89
|
+
rng: RNG;
|
|
90
|
+
locale: Locale;
|
|
91
|
+
/** Zero-based row index — used by `autoincrement`. */
|
|
92
|
+
index: number;
|
|
93
|
+
/** The row built so far; lets `email` derive from an earlier `firstName`. */
|
|
94
|
+
row: Record<string, unknown>;
|
|
95
|
+
}
|
|
96
|
+
type GenArg = string | number;
|
|
97
|
+
type Generator = (ctx: GenContext, args: GenArg[]) => unknown;
|
|
98
|
+
/** Strip accents/spaces/punctuation to a lowercase URL slug. */
|
|
99
|
+
declare function slugify(input: string): string;
|
|
100
|
+
declare const generators: Record<string, Generator>;
|
|
101
|
+
/** Short human sample values for the `list` command / discovery. */
|
|
102
|
+
declare const GEN_ORDER: string[];
|
|
103
|
+
/** Look up + invoke a generator by name, throwing a clear error if unknown. */
|
|
104
|
+
declare function callGen(name: string, ctx: GenContext, args: GenArg[]): unknown;
|
|
105
|
+
declare function hasGen(name: string): boolean;
|
|
106
|
+
|
|
107
|
+
type Spec = (ctx: GenContext) => unknown;
|
|
108
|
+
interface Field {
|
|
109
|
+
key: string;
|
|
110
|
+
spec: Spec;
|
|
111
|
+
}
|
|
112
|
+
/** Parse the inner arg string of `gen(...)` into positional args. */
|
|
113
|
+
declare function parseArgString(inner: string): GenArg[];
|
|
114
|
+
/** Compile a string spec like `fullName` or `int(18..65)` into a resolver. */
|
|
115
|
+
declare function specFromString(raw: string): Spec;
|
|
116
|
+
/** Compile any JSON schema value (string | object | primitive) into a resolver. */
|
|
117
|
+
declare function specFromJson(value: unknown): Spec;
|
|
118
|
+
/** Parse an inline `--fields` string into an ordered list of fields. */
|
|
119
|
+
declare function parseFields(input: string): Field[];
|
|
120
|
+
/** Parse a JSON schema object into an ordered list of fields. */
|
|
121
|
+
declare function parseJsonSchema(schema: unknown): Field[];
|
|
122
|
+
interface GenerateOptions {
|
|
123
|
+
count?: number;
|
|
124
|
+
seed?: number | string;
|
|
125
|
+
locale?: Locale;
|
|
126
|
+
}
|
|
127
|
+
/** Generate `count` rows from a compiled field list. Deterministic under `seed`. */
|
|
128
|
+
declare function generateRows(fields: Field[], opts?: GenerateOptions): Record<string, unknown>[];
|
|
129
|
+
/** Generate `count` scalar values from a single generator spec string. */
|
|
130
|
+
declare function generateValues(specStr: string, opts?: GenerateOptions): unknown[];
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Output formatters: JSON (array), NDJSON (one object per line), CSV (with a
|
|
134
|
+
* header row) and SQL `INSERT` statements. String values in SQL and CSV are
|
|
135
|
+
* escaped so a value containing a quote can't break — or inject into — the
|
|
136
|
+
* output.
|
|
137
|
+
*/
|
|
138
|
+
type Format = "json" | "ndjson" | "csv" | "sql";
|
|
139
|
+
declare function isFormat(v: string): v is Format;
|
|
140
|
+
interface FormatOptions {
|
|
141
|
+
format: Format;
|
|
142
|
+
pretty?: boolean;
|
|
143
|
+
/** Required for `sql`: the target table name. */
|
|
144
|
+
table?: string;
|
|
145
|
+
}
|
|
146
|
+
type Row = Record<string, unknown>;
|
|
147
|
+
/** The union of keys across rows, preserving first-seen order. */
|
|
148
|
+
declare function columnsOf(rows: Row[]): string[];
|
|
149
|
+
declare function toCsv(rows: Row[]): string;
|
|
150
|
+
/** Escape a single SQL value. Strings are single-quoted with `'` doubled. */
|
|
151
|
+
declare function sqlValue(v: unknown): string;
|
|
152
|
+
/** Quote a SQL identifier (table/column) defensively with double quotes. */
|
|
153
|
+
declare function sqlIdent(name: string): string;
|
|
154
|
+
declare function toSql(rows: Row[], table: string): string;
|
|
155
|
+
/** Format an array of rows in the requested output format. */
|
|
156
|
+
declare function formatRows(rows: Row[], opts: FormatOptions): string;
|
|
157
|
+
/** Format an array of scalar values (single-generator mode). */
|
|
158
|
+
declare function formatValues(values: unknown[], column: string, opts: FormatOptions): string;
|
|
159
|
+
|
|
160
|
+
export { type Field, type Format, type FormatOptions, GEN_ORDER, type GenArg, type GenContext, type GenerateOptions, type Generator, LOCALES, type Locale, type LocaleData, RNG, type Spec, callGen, columnsOf, formatRows, formatValues, generateRows, generateValues, generators, hasGen, hashSeed, isFormat, isLocale, normalizeSeed, parseArgString, parseFields, parseJsonSchema, slugify, specFromJson, specFromString, sqlIdent, sqlValue, toCsv, toSql };
|
package/dist/lib.d.ts
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seeded pseudo-random number generator (mulberry32).
|
|
3
|
+
*
|
|
4
|
+
* Deterministic: the same seed always yields the same sequence, which is what
|
|
5
|
+
* makes fake-data fixtures reproducible across runs and machines. Every
|
|
6
|
+
* generator in this package draws exclusively from an `RNG` instance so that a
|
|
7
|
+
* fixed `--seed` produces byte-identical output.
|
|
8
|
+
*/
|
|
9
|
+
/** Hash an arbitrary string to a 32-bit unsigned integer (for string seeds). */
|
|
10
|
+
declare function hashSeed(input: string): number;
|
|
11
|
+
/** Coerce a user-supplied seed (number, numeric string, or arbitrary string). */
|
|
12
|
+
declare function normalizeSeed(seed: number | string): number;
|
|
13
|
+
/** A seeded random source with typed convenience helpers. */
|
|
14
|
+
declare class RNG {
|
|
15
|
+
private readonly _next;
|
|
16
|
+
readonly seed: number;
|
|
17
|
+
constructor(seed: number | string);
|
|
18
|
+
/** Uniform float in [0, 1). */
|
|
19
|
+
next(): number;
|
|
20
|
+
/** Inclusive integer in [min, max]. */
|
|
21
|
+
int(min: number, max: number): number;
|
|
22
|
+
/** Float in [min, max) rounded to `decimals` places (default 2). */
|
|
23
|
+
float(min: number, max: number, decimals?: number): number;
|
|
24
|
+
/** `true` with probability `prob` (default 0.5). */
|
|
25
|
+
bool(prob?: number): boolean;
|
|
26
|
+
/** Pick one element uniformly. Throws on an empty array. */
|
|
27
|
+
pick<T>(items: readonly T[]): T;
|
|
28
|
+
/** Pick `n` distinct elements (Fisher–Yates partial shuffle). */
|
|
29
|
+
sample<T>(items: readonly T[], n: number): T[];
|
|
30
|
+
/** Return a shuffled copy. */
|
|
31
|
+
shuffle<T>(items: readonly T[]): T[];
|
|
32
|
+
/** Weighted pick. Entries are `[value, weight]`; weights need not sum to 1. */
|
|
33
|
+
weighted<T>(entries: readonly (readonly [T, number])[]): T;
|
|
34
|
+
/** A string of `len` random hex characters. */
|
|
35
|
+
hex(len: number): string;
|
|
36
|
+
/** A string of `len` random decimal digits. */
|
|
37
|
+
digits(len: number): string;
|
|
38
|
+
/** Pick `len` characters from an alphabet. */
|
|
39
|
+
chars(alphabet: string, len: number): string;
|
|
40
|
+
/** An RFC-4122 version-4 UUID, drawn deterministically from this RNG. */
|
|
41
|
+
uuid(): string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Locale data tables. `en` (default) is generic English/US-ish; `ne` is
|
|
46
|
+
* Nepal-aware (romanized Nepali names, districts, provinces, NPR, +977 phones).
|
|
47
|
+
* Everything here is a plain constant so generators stay pure functions of the
|
|
48
|
+
* RNG plus a locale table.
|
|
49
|
+
*/
|
|
50
|
+
type Locale = "en" | "ne";
|
|
51
|
+
interface LocaleData {
|
|
52
|
+
firstNamesMale: string[];
|
|
53
|
+
firstNamesFemale: string[];
|
|
54
|
+
lastNames: string[];
|
|
55
|
+
cities: string[];
|
|
56
|
+
states: string[];
|
|
57
|
+
country: string;
|
|
58
|
+
countryCode: string;
|
|
59
|
+
streetNames: string[];
|
|
60
|
+
streetSuffixes: string[];
|
|
61
|
+
/** How to build a postal/ZIP code for this locale. */
|
|
62
|
+
zip: (r: {
|
|
63
|
+
digits: (n: number) => string;
|
|
64
|
+
}) => string;
|
|
65
|
+
currency: {
|
|
66
|
+
code: string;
|
|
67
|
+
symbol: string;
|
|
68
|
+
};
|
|
69
|
+
/** E.164 phone (with +country) and a local-format phone. */
|
|
70
|
+
phone: (r: {
|
|
71
|
+
digits: (n: number) => string;
|
|
72
|
+
pick: <T>(a: readonly T[]) => T;
|
|
73
|
+
}) => {
|
|
74
|
+
e164: string;
|
|
75
|
+
local: string;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
declare const LOCALES: Record<Locale, LocaleData>;
|
|
79
|
+
declare function isLocale(v: string): v is Locale;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The generator library. Each generator is a pure function of a `GenContext`
|
|
83
|
+
* (an RNG + locale + row index + the partially-built row) and an optional list
|
|
84
|
+
* of positional args. Generators are looked up by name from the `generators`
|
|
85
|
+
* registry, which powers the CLI, the schema engine and the `list` command.
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
interface GenContext {
|
|
89
|
+
rng: RNG;
|
|
90
|
+
locale: Locale;
|
|
91
|
+
/** Zero-based row index — used by `autoincrement`. */
|
|
92
|
+
index: number;
|
|
93
|
+
/** The row built so far; lets `email` derive from an earlier `firstName`. */
|
|
94
|
+
row: Record<string, unknown>;
|
|
95
|
+
}
|
|
96
|
+
type GenArg = string | number;
|
|
97
|
+
type Generator = (ctx: GenContext, args: GenArg[]) => unknown;
|
|
98
|
+
/** Strip accents/spaces/punctuation to a lowercase URL slug. */
|
|
99
|
+
declare function slugify(input: string): string;
|
|
100
|
+
declare const generators: Record<string, Generator>;
|
|
101
|
+
/** Short human sample values for the `list` command / discovery. */
|
|
102
|
+
declare const GEN_ORDER: string[];
|
|
103
|
+
/** Look up + invoke a generator by name, throwing a clear error if unknown. */
|
|
104
|
+
declare function callGen(name: string, ctx: GenContext, args: GenArg[]): unknown;
|
|
105
|
+
declare function hasGen(name: string): boolean;
|
|
106
|
+
|
|
107
|
+
type Spec = (ctx: GenContext) => unknown;
|
|
108
|
+
interface Field {
|
|
109
|
+
key: string;
|
|
110
|
+
spec: Spec;
|
|
111
|
+
}
|
|
112
|
+
/** Parse the inner arg string of `gen(...)` into positional args. */
|
|
113
|
+
declare function parseArgString(inner: string): GenArg[];
|
|
114
|
+
/** Compile a string spec like `fullName` or `int(18..65)` into a resolver. */
|
|
115
|
+
declare function specFromString(raw: string): Spec;
|
|
116
|
+
/** Compile any JSON schema value (string | object | primitive) into a resolver. */
|
|
117
|
+
declare function specFromJson(value: unknown): Spec;
|
|
118
|
+
/** Parse an inline `--fields` string into an ordered list of fields. */
|
|
119
|
+
declare function parseFields(input: string): Field[];
|
|
120
|
+
/** Parse a JSON schema object into an ordered list of fields. */
|
|
121
|
+
declare function parseJsonSchema(schema: unknown): Field[];
|
|
122
|
+
interface GenerateOptions {
|
|
123
|
+
count?: number;
|
|
124
|
+
seed?: number | string;
|
|
125
|
+
locale?: Locale;
|
|
126
|
+
}
|
|
127
|
+
/** Generate `count` rows from a compiled field list. Deterministic under `seed`. */
|
|
128
|
+
declare function generateRows(fields: Field[], opts?: GenerateOptions): Record<string, unknown>[];
|
|
129
|
+
/** Generate `count` scalar values from a single generator spec string. */
|
|
130
|
+
declare function generateValues(specStr: string, opts?: GenerateOptions): unknown[];
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Output formatters: JSON (array), NDJSON (one object per line), CSV (with a
|
|
134
|
+
* header row) and SQL `INSERT` statements. String values in SQL and CSV are
|
|
135
|
+
* escaped so a value containing a quote can't break — or inject into — the
|
|
136
|
+
* output.
|
|
137
|
+
*/
|
|
138
|
+
type Format = "json" | "ndjson" | "csv" | "sql";
|
|
139
|
+
declare function isFormat(v: string): v is Format;
|
|
140
|
+
interface FormatOptions {
|
|
141
|
+
format: Format;
|
|
142
|
+
pretty?: boolean;
|
|
143
|
+
/** Required for `sql`: the target table name. */
|
|
144
|
+
table?: string;
|
|
145
|
+
}
|
|
146
|
+
type Row = Record<string, unknown>;
|
|
147
|
+
/** The union of keys across rows, preserving first-seen order. */
|
|
148
|
+
declare function columnsOf(rows: Row[]): string[];
|
|
149
|
+
declare function toCsv(rows: Row[]): string;
|
|
150
|
+
/** Escape a single SQL value. Strings are single-quoted with `'` doubled. */
|
|
151
|
+
declare function sqlValue(v: unknown): string;
|
|
152
|
+
/** Quote a SQL identifier (table/column) defensively with double quotes. */
|
|
153
|
+
declare function sqlIdent(name: string): string;
|
|
154
|
+
declare function toSql(rows: Row[], table: string): string;
|
|
155
|
+
/** Format an array of rows in the requested output format. */
|
|
156
|
+
declare function formatRows(rows: Row[], opts: FormatOptions): string;
|
|
157
|
+
/** Format an array of scalar values (single-generator mode). */
|
|
158
|
+
declare function formatValues(values: unknown[], column: string, opts: FormatOptions): string;
|
|
159
|
+
|
|
160
|
+
export { type Field, type Format, type FormatOptions, GEN_ORDER, type GenArg, type GenContext, type GenerateOptions, type Generator, LOCALES, type Locale, type LocaleData, RNG, type Spec, callGen, columnsOf, formatRows, formatValues, generateRows, generateValues, generators, hasGen, hashSeed, isFormat, isLocale, normalizeSeed, parseArgString, parseFields, parseJsonSchema, slugify, specFromJson, specFromString, sqlIdent, sqlValue, toCsv, toSql };
|