lacspace-fake 0.1.0 → 0.2.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/README.md +73 -17
- package/dist/cli.js +464 -63
- package/dist/lib.cjs +437 -38
- package/dist/lib.d.cts +98 -4
- package/dist/lib.d.ts +98 -4
- package/dist/lib.js +423 -38
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -11,6 +11,17 @@ every machine), **Nepal-aware** with `--locale ne`, and it emits ready-to-run
|
|
|
11
11
|
npx lacspace-fake --fields "id:autoincrement,name:fullName,email:email,age:int(18..65)" -n 5
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
+
## New in 0.2.0
|
|
15
|
+
|
|
16
|
+
- **Relations / linked tables** — `--relations schema.json` generates several entities where one references another's ids (`ref(users.id)`), with guaranteed referential integrity (every foreign key exists).
|
|
17
|
+
- **Template fields** — `full:template({{firstName}} {{lastName}})` interpolates earlier fields and inline generators.
|
|
18
|
+
- **`unique(...)` constraint** — `email:unique(email)` guarantees no duplicate values across rows.
|
|
19
|
+
- **More locales** — added `es` (Spanish) and `fr` (French) alongside `en` and `ne`.
|
|
20
|
+
- **`--ddl`** — for `-f sql`, also emit a `CREATE TABLE` with column types inferred from the data.
|
|
21
|
+
- **~15 new generators** — `ulid`, `hexColor`/`rgb`/`hsl`, `semver`, `mimeType`, `fileExt`/`fileName`/`filePath`, `timezone`, `currencyCode`, `creditCardMasked`/`cardBrand`, `iban`, `bic`.
|
|
22
|
+
|
|
23
|
+
All additive and backward compatible — existing schemas, flags and output are unchanged.
|
|
24
|
+
|
|
14
25
|
## Why it exists
|
|
15
26
|
|
|
16
27
|
- **Free & keyless.** No API key, no account, no network calls, no telemetry — runs fully offline.
|
|
@@ -32,11 +43,21 @@ npx lacspace-fake --fields "id:autoincrement,name:fullName,role:oneOf(admin|user
|
|
|
32
43
|
# From a JSON schema, out to a CSV file
|
|
33
44
|
npx lacspace-fake --schema users.json -n 50 -f csv -o users.csv
|
|
34
45
|
|
|
35
|
-
# Nepal locale
|
|
46
|
+
# Nepal / Spanish / French locale
|
|
36
47
|
npx lacspace-fake --fields "name:fullName,phone:phone,district:city" --locale ne -n 10
|
|
48
|
+
npx lacspace-fake --fields "name:fullName,phone:phone" --locale es -n 5
|
|
49
|
+
|
|
50
|
+
# Template + unique fields
|
|
51
|
+
npx lacspace-fake --fields "id:unique(uuid),first:firstName,handle:template({{first}}-{{int(1..99)}})" -n 5
|
|
37
52
|
|
|
38
|
-
#
|
|
39
|
-
npx lacspace-fake
|
|
53
|
+
# SQL with CREATE TABLE DDL
|
|
54
|
+
npx lacspace-fake --fields "id:autoincrement,name:fullName,score:float(0..100)" -f sql --table users --ddl
|
|
55
|
+
|
|
56
|
+
# Linked tables with foreign keys
|
|
57
|
+
npx lacspace-fake --relations shop.json -f sql --ddl
|
|
58
|
+
|
|
59
|
+
# Just five ULIDs
|
|
60
|
+
npx lacspace-fake ulid -n 5 --seed 42
|
|
40
61
|
|
|
41
62
|
# Discover every generator
|
|
42
63
|
npx lacspace-fake list
|
|
@@ -109,11 +130,14 @@ key:generator(args) age:int(18..65) role:oneOf(admin|user)
|
|
|
109
130
|
|
|
110
131
|
- Numeric ranges use `..` — `int(18..65)`, `price(10..999)`, `float(0..1)`
|
|
111
132
|
- Option lists use `|` — `oneOf(admin|user|guest)`
|
|
112
|
-
- Weighted picks use `value:weight` — `weighted(admin:1|user:9)`
|
|
133
|
+
- Weighted picks use `value:weight` — `weighted(admin:1|user:9)` (a weighted enum)
|
|
113
134
|
- Date windows use `..` — `between(2020-01-01..2024-12-31)`
|
|
135
|
+
- **Unique** wraps any generator — `email:unique(email)`, `id:unique(int(1..1000000))` — no two rows repeat a value
|
|
136
|
+
- **Templates** interpolate `{{...}}` — `full:template({{firstName}} {{lastName}})`, `email:template({{username}}@{{domain}})`
|
|
114
137
|
|
|
115
138
|
Fields evaluate in order, so a later field can derive from an earlier one:
|
|
116
139
|
`firstName:firstName,lastName:lastName,email:email` yields emails built from each row's name.
|
|
140
|
+
Inside a `template(...)`, a `{{token}}` that matches an earlier field reuses its value; otherwise it is evaluated as a generator.
|
|
117
141
|
|
|
118
142
|
## Generators
|
|
119
143
|
|
|
@@ -123,13 +147,37 @@ street · city · state · country · countryCode · zip · address · latitude
|
|
|
123
147
|
latlng · company · catchphrase · jobTitle · department · productName · price · sku ·
|
|
124
148
|
currency · category · color · word · words · sentence · paragraph · lorem · past ·
|
|
125
149
|
future · recent · soon · between · timestamp · date · time · int · float · bool ·
|
|
126
|
-
oneOf · weighted · digit · autoincrement · nanoid · objectId · pan · vat
|
|
150
|
+
oneOf · weighted · digit · autoincrement · nanoid · objectId · pan · vat ·
|
|
151
|
+
ulid · hexColor · rgb · hsl · semver · mimeType · fileExt · fileName · filePath ·
|
|
152
|
+
timezone · currencyCode · creditCardMasked · cardBrand · iban · bic`
|
|
127
153
|
|
|
128
154
|
Run `lacspace-fake list` for a live sample of each.
|
|
129
155
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
156
|
+
## Relations (linked tables with foreign keys)
|
|
157
|
+
|
|
158
|
+
A relations schema maps each entity to `{ count, fields }`. A field whose spec is
|
|
159
|
+
`ref(<entity>.<field>)` is a **foreign key**, drawn from the already-generated column of
|
|
160
|
+
an earlier entity — so every FK is guaranteed to exist. The whole dataset is drawn from
|
|
161
|
+
one seed, so it's byte-reproducible.
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"users": { "count": 10, "fields": { "id": "unique(int(1..99999))", "name": "fullName" } },
|
|
166
|
+
"orders": { "count": 30, "fields": { "id": "autoincrement", "userId": "ref(users.id)", "total": "price(5..500)" } }
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
$ npx lacspace-fake --relations shop.json -f sql --ddl --seed 42
|
|
172
|
+
CREATE TABLE "users" ( "id" INTEGER NOT NULL, "name" TEXT NOT NULL );
|
|
173
|
+
INSERT INTO "users" ("id", "name") VALUES ... ;
|
|
174
|
+
CREATE TABLE "orders" ( "id" INTEGER NOT NULL, "userId" INTEGER NOT NULL, "total" REAL NOT NULL );
|
|
175
|
+
INSERT INTO "orders" ("id", "userId", "total") VALUES ... ; -- every userId exists in users
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Entities must be declared parent-first (a `ref(...)` can only point at an entity above it).
|
|
179
|
+
`json` output emits one object of arrays; `sql` emits a block per table; `csv`/`ndjson`
|
|
180
|
+
emit one `# <table>` section per entity.
|
|
133
181
|
|
|
134
182
|
## CLI reference
|
|
135
183
|
|
|
@@ -140,10 +188,12 @@ Run `lacspace-fake list` for a live sample of each.
|
|
|
140
188
|
| `-n, --count <n>` | Number of rows/values (default 10) |
|
|
141
189
|
| `-f, --format <fmt>` | `json` (default), `ndjson`, `csv`, `sql` |
|
|
142
190
|
| `-t, --table <name>` | Table name for `-f sql` |
|
|
191
|
+
| `--ddl` | For `-f sql`: also emit `CREATE TABLE` with inferred column types |
|
|
143
192
|
| `--fields <spec>` | Inline schema string |
|
|
144
193
|
| `--schema <file>` | JSON schema file (`-` for stdin) |
|
|
194
|
+
| `--relations <file>` | JSON relations schema → linked entities with foreign keys (`-` for stdin) |
|
|
145
195
|
| `-s, --seed <str>` | Seed for reproducible output (number or any string) |
|
|
146
|
-
| `-l, --locale <loc>` | `en` (default)
|
|
196
|
+
| `-l, --locale <loc>` | `en` (default), `ne` (Nepal), `es` (Spanish) or `fr` (French) |
|
|
147
197
|
| `--pretty` | Pretty-print JSON |
|
|
148
198
|
| `-o, --out <file>` | Write to a file instead of stdout |
|
|
149
199
|
| `-h, --help` / `-v, --version` | Help / version |
|
|
@@ -164,15 +214,21 @@ formatRows(rows, { format: "sql", table: "users" });
|
|
|
164
214
|
|
|
165
215
|
| Export | Signature |
|
|
166
216
|
|--------|-----------|
|
|
167
|
-
| `parseFields(spec)` | `(input: string) => Field[]` — compile an inline field string |
|
|
217
|
+
| `parseFields(spec)` | `(input: string) => Field[]` — compile an inline field string (`unique(...)`/`template(...)` aware) |
|
|
168
218
|
| `parseJsonSchema(obj)` | `(schema: unknown) => Field[]` — compile a JSON schema object |
|
|
169
|
-
| `generateRows(fields, opts)` | `(Field[], { count?, seed?, locale? }) => Record<string, unknown>[]` |
|
|
219
|
+
| `generateRows(fields, opts)` | `(Field[], { count?, seed?, locale? }) => Record<string, unknown>[]` — enforces `unique` fields |
|
|
170
220
|
| `generateValues(spec, opts)` | `(specStr: string, { count?, seed?, locale? }) => unknown[]` |
|
|
171
|
-
| `
|
|
221
|
+
| `parseRelations(obj)` | `(schema: unknown) => CompiledEntity[]` — compile a relations schema |
|
|
222
|
+
| `generateDataset(entities, opts)` | `(CompiledEntity[], opts) => Record<string, Row[]>` — linked data with FKs |
|
|
223
|
+
| `generateRelations(obj, opts)` | parse + generate a linked dataset in one call |
|
|
224
|
+
| `formatRows(rows, opts)` | `(rows, { format, pretty?, table?, ddl? }) => string` |
|
|
225
|
+
| `formatDataset(dataset, opts)` | format a `{ entity: rows }` dataset (JSON object / per-table SQL / sections) |
|
|
172
226
|
| `formatValues(values, col, opts)` | scalar-value formatter |
|
|
173
|
-
| `toCsv(rows)` / `toSql(rows, table)` | direct formatters |
|
|
227
|
+
| `toCsv(rows)` / `toSql(rows, table, { ddl? })` | direct formatters |
|
|
228
|
+
| `toCreateTable(rows, table)` / `inferSqlType(values)` | DDL builder + column-type inference |
|
|
229
|
+
| `compileTemplate(body, compile)` | build a template-field resolver |
|
|
174
230
|
| `sqlValue(v)` / `sqlIdent(name)` | SQL escaping primitives |
|
|
175
|
-
| `generators` / `callGen(name, ctx, args)` | the generator registry |
|
|
231
|
+
| `generators` / `callGen(name, ctx, args)` | the generator registry (built-ins + 0.2.0 extras) |
|
|
176
232
|
| `RNG` | the seeded mulberry32 PRNG (`int`, `float`, `bool`, `pick`, `weighted`, `uuid`, …) |
|
|
177
233
|
| `slugify(str)` | accent/punctuation-safe URL slug |
|
|
178
234
|
|
|
@@ -180,9 +236,9 @@ Types (`Field`, `Spec`, `Format`, `FormatOptions`, `GenContext`, `Locale`, …)
|
|
|
180
236
|
|
|
181
237
|
## Limitations
|
|
182
238
|
|
|
183
|
-
- Data is **plausible, not real** — it's for tests and demos, never production identities.
|
|
184
|
-
- Locales are `en
|
|
185
|
-
- Relations
|
|
239
|
+
- Data is **plausible, not real** — it's for tests and demos, never production identities. `creditCardMasked`/`iban`/`bic` are structurally-shaped placeholders, never valid instruments.
|
|
240
|
+
- Locales are `en`, `ne`, `es` and `fr`; `en` is generic English/US-ish, not per-country.
|
|
241
|
+
- Relations resolve foreign keys from the parent's generated column (guaranteed to exist); a `ref(...)` must point at an entity declared earlier in the schema.
|
|
186
242
|
- Determinism holds for a given package version; generator internals may evolve across minor versions.
|
|
187
243
|
- Time-based generators (`past`, `future`, `recent`) are anchored to the current clock, so their absolute instants shift day to day (still deterministic within a run given a seed).
|
|
188
244
|
|