realitydb 1.9.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +80 -21
- package/dist/index.js +544 -65
- package/package.json +1 -1
package/LICENSE
CHANGED
|
@@ -1,21 +1,80 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
Business Source License 1.1
|
|
2
|
+
|
|
3
|
+
Parameters
|
|
4
|
+
|
|
5
|
+
Licensor: Mpingo Systems Ltd (Eddy Mkwambe)
|
|
6
|
+
Licensed Work: RealityDB Sandbox
|
|
7
|
+
The Licensed Work is (c) 2026 Mpingo Systems Ltd
|
|
8
|
+
Additional Use Grant: You may make use of the Licensed Work, provided that
|
|
9
|
+
you do not use the Licensed Work for a Synthetic Data
|
|
10
|
+
Service, SQL Learning Service, or Database Simulation
|
|
11
|
+
Service.
|
|
12
|
+
|
|
13
|
+
A "Synthetic Data Service" is a commercial offering
|
|
14
|
+
that allows third parties to access the functionality
|
|
15
|
+
of the Licensed Work by generating synthetic database
|
|
16
|
+
records, test data, or simulation environments.
|
|
17
|
+
|
|
18
|
+
A "SQL Learning Service" is a commercial offering that
|
|
19
|
+
allows third parties to practice SQL queries against
|
|
20
|
+
auto-graded challenges using functionality substantially
|
|
21
|
+
derived from the Licensed Work.
|
|
22
|
+
|
|
23
|
+
A "Database Simulation Service" is a commercial offering
|
|
24
|
+
that allows third parties to create or access simulated
|
|
25
|
+
database environments with lifecycle-coherent data using
|
|
26
|
+
functionality substantially derived from the Licensed Work.
|
|
27
|
+
|
|
28
|
+
You may use the Licensed Work for internal testing,
|
|
29
|
+
development, education, research, and any non-competing
|
|
30
|
+
commercial purpose without restriction.
|
|
31
|
+
|
|
32
|
+
Change Date: March 31, 2030
|
|
33
|
+
Change License: Apache License, Version 2.0
|
|
34
|
+
|
|
35
|
+
For information about alternative licensing arrangements for the Licensed Work,
|
|
36
|
+
please contact: licensing@realitydb.dev
|
|
37
|
+
|
|
38
|
+
Notice
|
|
39
|
+
|
|
40
|
+
Business Source License 1.1 (the "License")
|
|
41
|
+
|
|
42
|
+
The Licensor hereby grants you the right to copy, modify, create derivative
|
|
43
|
+
works, redistribute, and make non-production use of the Licensed Work. The
|
|
44
|
+
Licensor may make an Additional Use Grant, above, permitting limited production
|
|
45
|
+
use.
|
|
46
|
+
|
|
47
|
+
Effective on the Change Date, or the fourth anniversary of the first publicly
|
|
48
|
+
available distribution of a specific version of the Licensed Work under this
|
|
49
|
+
License, whichever comes first, the Licensor hereby grants you rights under
|
|
50
|
+
the terms of the Change License, and the rights granted in the paragraph
|
|
51
|
+
above terminate.
|
|
52
|
+
|
|
53
|
+
If your use of the Licensed Work does not comply with the requirements
|
|
54
|
+
currently in effect as described in this License, you must purchase a
|
|
55
|
+
commercial license from the Licensor, its affiliated entities, or authorized
|
|
56
|
+
resellers, or you must refrain from using the Licensed Work.
|
|
57
|
+
|
|
58
|
+
All copies of the original and modified Licensed Work, and derivative works
|
|
59
|
+
of the Licensed Work, are subject to this License. This License applies
|
|
60
|
+
separately for each version of the Licensed Work and the Change Date may vary
|
|
61
|
+
for each version of the Licensed Work released by Licensor.
|
|
62
|
+
|
|
63
|
+
You must conspicuously display this License on each original or modified copy
|
|
64
|
+
of the Licensed Work. If you receive the Licensed Work in original or
|
|
65
|
+
modified form from a third party, the terms and conditions set forth in this
|
|
66
|
+
License apply to your use of that work.
|
|
67
|
+
|
|
68
|
+
Any use of the Licensed Work in violation of this License will automatically
|
|
69
|
+
terminate your rights under this License for the current and all other
|
|
70
|
+
versions of the Licensed Work.
|
|
71
|
+
|
|
72
|
+
This License does not grant you any right in any trademark or logo of
|
|
73
|
+
Licensor or its affiliates (provided that you may use a trademark or logo of
|
|
74
|
+
Licensor as expressly required by this License).
|
|
75
|
+
|
|
76
|
+
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
|
|
77
|
+
AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
|
|
78
|
+
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
|
|
79
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
|
|
80
|
+
TITLE.
|
package/dist/index.js
CHANGED
|
@@ -23297,23 +23297,42 @@ function escapeCsvField(value) {
|
|
|
23297
23297
|
// ../../packages/generators/dist/exporters/sql.js
|
|
23298
23298
|
var import_promises3 = require("fs/promises");
|
|
23299
23299
|
var import_node_path3 = require("path");
|
|
23300
|
-
async function exportToSql(dataset, outputDir, tableOrder) {
|
|
23300
|
+
async function exportToSql(dataset, outputDir, tableOrder, options) {
|
|
23301
23301
|
await (0, import_promises3.mkdir)(outputDir, { recursive: true });
|
|
23302
|
+
const batchSize = options?.batchSize ?? 50;
|
|
23302
23303
|
const lines = [];
|
|
23303
|
-
lines.push("--
|
|
23304
|
+
lines.push("-- =================================================================");
|
|
23305
|
+
lines.push("-- Generated by RealityDB");
|
|
23306
|
+
if (options?.templateName) {
|
|
23307
|
+
lines.push(`-- Template: ${options.templateName}`);
|
|
23308
|
+
}
|
|
23304
23309
|
lines.push(`-- Seed: ${dataset.seed}`);
|
|
23305
23310
|
lines.push(`-- Generated at: ${dataset.generatedAt}`);
|
|
23311
|
+
lines.push("-- =================================================================");
|
|
23312
|
+
lines.push("");
|
|
23313
|
+
if (options?.ddl) {
|
|
23314
|
+
lines.push("-- --- SCHEMA ---------------------------------------------------------");
|
|
23315
|
+
lines.push("");
|
|
23316
|
+
lines.push(options.ddl);
|
|
23317
|
+
lines.push("");
|
|
23318
|
+
}
|
|
23319
|
+
lines.push("-- --- DATA -----------------------------------------------------------");
|
|
23306
23320
|
lines.push("");
|
|
23307
23321
|
for (const tableName of tableOrder) {
|
|
23308
23322
|
const table = dataset.tables.get(tableName);
|
|
23309
23323
|
if (!table || table.rows.length === 0)
|
|
23310
23324
|
continue;
|
|
23311
23325
|
const quotedColumns = table.columns.map((c) => `"${c}"`).join(", ");
|
|
23312
|
-
for (
|
|
23313
|
-
const
|
|
23314
|
-
|
|
23326
|
+
for (let i = 0; i < table.rows.length; i += batchSize) {
|
|
23327
|
+
const batch = table.rows.slice(i, i + batchSize);
|
|
23328
|
+
const valueRows = batch.map((row) => {
|
|
23329
|
+
const values = table.columns.map((col) => escapeSqlValue(row[col])).join(", ");
|
|
23330
|
+
return ` (${values})`;
|
|
23331
|
+
});
|
|
23332
|
+
lines.push(`INSERT INTO "${tableName}" (${quotedColumns}) VALUES`);
|
|
23333
|
+
lines.push(valueRows.join(",\n") + ";");
|
|
23334
|
+
lines.push("");
|
|
23315
23335
|
}
|
|
23316
|
-
lines.push("");
|
|
23317
23336
|
}
|
|
23318
23337
|
const filePath = (0, import_node_path3.join)(outputDir, "seed.sql");
|
|
23319
23338
|
await (0, import_promises3.writeFile)(filePath, lines.join("\n"), "utf-8");
|
|
@@ -24692,10 +24711,10 @@ function exportRealityPack(dataset, plan, schema, options) {
|
|
|
24692
24711
|
}))
|
|
24693
24712
|
};
|
|
24694
24713
|
const packDataset = { tables: {} };
|
|
24695
|
-
for (const [tableName, table] of dataset.tables) {
|
|
24714
|
+
for (const [tableName, table] of Array.from(dataset.tables.entries())) {
|
|
24696
24715
|
packDataset.tables[tableName] = {
|
|
24697
|
-
columns: table.columns,
|
|
24698
|
-
rows: table.rows,
|
|
24716
|
+
columns: [...table.columns],
|
|
24717
|
+
rows: table.rows.map((row) => ({ ...row })),
|
|
24699
24718
|
rowCount: table.rowCount
|
|
24700
24719
|
};
|
|
24701
24720
|
}
|
|
@@ -27940,8 +27959,8 @@ function getSimulationProfile(name) {
|
|
|
27940
27959
|
var saasTemplate = {
|
|
27941
27960
|
name: "saas",
|
|
27942
27961
|
version: "2.0",
|
|
27943
|
-
description: "SaaS
|
|
27944
|
-
targetTables: ["organizations", "users", "plans", "subscriptions", "invoices", "payments"],
|
|
27962
|
+
description: "SaaS platform with 10 tables: organizations, users, plans, features, plan_features, subscriptions, invoices, payments, sessions, events",
|
|
27963
|
+
targetTables: ["organizations", "users", "plans", "features", "plan_features", "subscriptions", "invoices", "payments", "sessions", "events"],
|
|
27945
27964
|
tableConfigs: /* @__PURE__ */ new Map([
|
|
27946
27965
|
["organizations", {
|
|
27947
27966
|
tableName: "organizations",
|
|
@@ -28098,7 +28117,7 @@ var saasTemplate = {
|
|
|
28098
28117
|
{
|
|
28099
28118
|
columnName: "trial_ends_at",
|
|
28100
28119
|
strategy: { kind: "timestamp", options: { mode: "past" } },
|
|
28101
|
-
description: "Nullable \
|
|
28120
|
+
description: "Nullable \xC3\u0192\xC2\xA2\xC3\xA2\xE2\u20AC\u0161\xC2\xAC\xC3\xA2\xE2\u201A\xAC\xC2\x9D null for non-trial subscriptions"
|
|
28102
28121
|
},
|
|
28103
28122
|
{
|
|
28104
28123
|
columnName: "current_period_start",
|
|
@@ -28116,7 +28135,7 @@ var saasTemplate = {
|
|
|
28116
28135
|
{
|
|
28117
28136
|
columnName: "canceled_at",
|
|
28118
28137
|
strategy: { kind: "timestamp", options: { mode: "past" } },
|
|
28119
|
-
description: "Nullable \
|
|
28138
|
+
description: "Nullable \xC3\u0192\xC2\xA2\xC3\xA2\xE2\u20AC\u0161\xC2\xAC\xC3\xA2\xE2\u201A\xAC\xC2\x9D should be null for active/trialing subscriptions"
|
|
28120
28139
|
}
|
|
28121
28140
|
]
|
|
28122
28141
|
}],
|
|
@@ -28157,7 +28176,7 @@ var saasTemplate = {
|
|
|
28157
28176
|
{
|
|
28158
28177
|
columnName: "paid_at",
|
|
28159
28178
|
strategy: { kind: "timestamp", options: { mode: "past" } },
|
|
28160
|
-
description: "Nullable \
|
|
28179
|
+
description: "Nullable \xC3\u0192\xC2\xA2\xC3\xA2\xE2\u20AC\u0161\xC2\xAC\xC3\xA2\xE2\u201A\xAC\xC2\x9D null for unpaid invoices"
|
|
28161
28180
|
},
|
|
28162
28181
|
{
|
|
28163
28182
|
columnName: "created_at",
|
|
@@ -28214,7 +28233,7 @@ var saasTemplate = {
|
|
|
28214
28233
|
weights: [0.35, 0.3, 0.2, 0.15]
|
|
28215
28234
|
}
|
|
28216
28235
|
},
|
|
28217
|
-
description: "Nullable \
|
|
28236
|
+
description: "Nullable \xC3\u0192\xC2\xA2\xC3\xA2\xE2\u20AC\u0161\xC2\xAC\xC3\xA2\xE2\u201A\xAC\xC2\x9D null for successful payments"
|
|
28218
28237
|
},
|
|
28219
28238
|
{
|
|
28220
28239
|
columnName: "paid_at",
|
|
@@ -28222,6 +28241,50 @@ var saasTemplate = {
|
|
|
28222
28241
|
strategy: { kind: "timestamp", options: { mode: "past" } }
|
|
28223
28242
|
}
|
|
28224
28243
|
]
|
|
28244
|
+
}],
|
|
28245
|
+
["features", {
|
|
28246
|
+
tableName: "features",
|
|
28247
|
+
matchPattern: ["features", "*feature*"],
|
|
28248
|
+
rowCountMultiplier: 0.02,
|
|
28249
|
+
columnOverrides: [
|
|
28250
|
+
{ columnName: "name", strategy: { kind: "text", options: { mode: "short" } } },
|
|
28251
|
+
{ columnName: "category", strategy: { kind: "enum", options: { values: ["core", "analytics", "security", "integration"], weights: [0.35, 0.25, 0.2, 0.2] } } },
|
|
28252
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
28253
|
+
]
|
|
28254
|
+
}],
|
|
28255
|
+
["plan_features", {
|
|
28256
|
+
tableName: "plan_features",
|
|
28257
|
+
matchPattern: ["plan_features", "*plan_feature*"],
|
|
28258
|
+
rowCountMultiplier: 0.06,
|
|
28259
|
+
columnOverrides: [
|
|
28260
|
+
{ columnName: "enabled", strategy: { kind: "boolean" } },
|
|
28261
|
+
{ columnName: "limit_value", strategy: { kind: "integer", options: { min: 0, max: 1e4 } } },
|
|
28262
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
28263
|
+
]
|
|
28264
|
+
}],
|
|
28265
|
+
["sessions", {
|
|
28266
|
+
tableName: "sessions",
|
|
28267
|
+
matchPattern: ["sessions", "*session*"],
|
|
28268
|
+
rowCountMultiplier: 8,
|
|
28269
|
+
columnOverrides: [
|
|
28270
|
+
{ columnName: "started_at", strategy: { kind: "timestamp", options: { mode: "past" } } },
|
|
28271
|
+
{ columnName: "ended_at", strategy: { kind: "timestamp", options: { mode: "recent" } } },
|
|
28272
|
+
{ columnName: "duration_seconds", strategy: { kind: "integer", options: { min: 10, max: 14400 } } },
|
|
28273
|
+
{ columnName: "ip_address", strategy: { kind: "text", options: { mode: "short" } } },
|
|
28274
|
+
{ columnName: "user_agent", strategy: { kind: "text" } },
|
|
28275
|
+
{ columnName: "country", strategy: { kind: "enum", options: { values: ["US", "UK", "CA", "DE", "FR", "AU", "IN", "BR"], weights: [0.5, 0.1, 0.08, 0.06, 0.05, 0.04, 0.04, 0.03] } } },
|
|
28276
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
28277
|
+
]
|
|
28278
|
+
}],
|
|
28279
|
+
["events", {
|
|
28280
|
+
tableName: "events",
|
|
28281
|
+
matchPattern: ["events", "*event*"],
|
|
28282
|
+
rowCountMultiplier: 10,
|
|
28283
|
+
columnOverrides: [
|
|
28284
|
+
{ columnName: "event_type", strategy: { kind: "enum", options: { values: ["page_view", "button_click", "api_call", "feature_use", "error", "search"], weights: [0.4, 0.2, 0.15, 0.12, 0.05, 0.08] } } },
|
|
28285
|
+
{ columnName: "event_name", strategy: { kind: "text", options: { mode: "short" } } },
|
|
28286
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "recent" } } }
|
|
28287
|
+
]
|
|
28225
28288
|
}]
|
|
28226
28289
|
])
|
|
28227
28290
|
};
|
|
@@ -28230,8 +28293,8 @@ var saasTemplate = {
|
|
|
28230
28293
|
var ecommerceTemplate = {
|
|
28231
28294
|
name: "ecommerce",
|
|
28232
28295
|
version: "2.0",
|
|
28233
|
-
description: "E-commerce
|
|
28234
|
-
targetTables: ["customers", "categories", "products", "orders", "order_items", "reviews"],
|
|
28296
|
+
description: "E-commerce platform with 12 tables: customers, categories, products, orders, order_items, reviews, sessions, cart_items, payments, refunds, shipments, disputes",
|
|
28297
|
+
targetTables: ["customers", "categories", "products", "orders", "order_items", "reviews", "sessions", "cart_items", "payments", "refunds", "shipments", "disputes"],
|
|
28235
28298
|
tableConfigs: /* @__PURE__ */ new Map([
|
|
28236
28299
|
["customers", {
|
|
28237
28300
|
tableName: "customers",
|
|
@@ -28340,7 +28403,7 @@ var ecommerceTemplate = {
|
|
|
28340
28403
|
{
|
|
28341
28404
|
columnName: "compare_at_price_cents",
|
|
28342
28405
|
strategy: { kind: "money", options: { min: 0, max: 2e5 } },
|
|
28343
|
-
description: "Nullable \
|
|
28406
|
+
description: "Nullable \xC3\xA2\xE2\u201A\xAC\xE2\u20AC\x9D original price before discount"
|
|
28344
28407
|
},
|
|
28345
28408
|
{
|
|
28346
28409
|
columnName: "brand",
|
|
@@ -28426,13 +28489,13 @@ var ecommerceTemplate = {
|
|
|
28426
28489
|
columnName: "shipped_at",
|
|
28427
28490
|
matchPattern: ["shipped_at", "ship_date"],
|
|
28428
28491
|
strategy: { kind: "timestamp", options: { mode: "past" } },
|
|
28429
|
-
description: "Nullable \
|
|
28492
|
+
description: "Nullable \xC3\xA2\xE2\u201A\xAC\xE2\u20AC\x9D null for pending/processing orders"
|
|
28430
28493
|
},
|
|
28431
28494
|
{
|
|
28432
28495
|
columnName: "delivered_at",
|
|
28433
28496
|
matchPattern: ["delivered_at", "delivery_date"],
|
|
28434
28497
|
strategy: { kind: "timestamp", options: { mode: "past" } },
|
|
28435
|
-
description: "Nullable \
|
|
28498
|
+
description: "Nullable \xC3\xA2\xE2\u201A\xAC\xE2\u20AC\x9D null for non-delivered orders"
|
|
28436
28499
|
}
|
|
28437
28500
|
]
|
|
28438
28501
|
}],
|
|
@@ -28484,6 +28547,76 @@ var ecommerceTemplate = {
|
|
|
28484
28547
|
strategy: { kind: "timestamp", options: { mode: "past" } }
|
|
28485
28548
|
}
|
|
28486
28549
|
]
|
|
28550
|
+
}],
|
|
28551
|
+
["sessions", {
|
|
28552
|
+
tableName: "sessions",
|
|
28553
|
+
matchPattern: ["sessions", "*session*"],
|
|
28554
|
+
rowCountMultiplier: 8,
|
|
28555
|
+
columnOverrides: [
|
|
28556
|
+
{ columnName: "started_at", strategy: { kind: "timestamp", options: { mode: "past" } } },
|
|
28557
|
+
{ columnName: "ended_at", strategy: { kind: "timestamp", options: { mode: "recent" } } },
|
|
28558
|
+
{ columnName: "page_count", strategy: { kind: "integer", options: { min: 1, max: 50 } } },
|
|
28559
|
+
{ columnName: "device_type", strategy: { kind: "enum", options: { values: ["desktop", "mobile", "tablet"], weights: [0.45, 0.4, 0.15] } } },
|
|
28560
|
+
{ columnName: "utm_source", strategy: { kind: "enum", options: { values: ["direct", "google", "email", "facebook", "organic"], weights: [0.35, 0.25, 0.15, 0.1, 0.15] } } },
|
|
28561
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
28562
|
+
]
|
|
28563
|
+
}],
|
|
28564
|
+
["cart_items", {
|
|
28565
|
+
tableName: "cart_items",
|
|
28566
|
+
matchPattern: ["cart_items", "*cart*"],
|
|
28567
|
+
rowCountMultiplier: 8,
|
|
28568
|
+
columnOverrides: [
|
|
28569
|
+
{ columnName: "quantity", strategy: { kind: "integer", options: { min: 1, max: 5 } } },
|
|
28570
|
+
{ columnName: "price_cents", strategy: { kind: "integer", options: { min: 499, max: 99999 } } },
|
|
28571
|
+
{ columnName: "added_at", strategy: { kind: "timestamp", options: { mode: "past" } } },
|
|
28572
|
+
{ columnName: "converted", strategy: { kind: "boolean" } },
|
|
28573
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
28574
|
+
]
|
|
28575
|
+
}],
|
|
28576
|
+
["payments", {
|
|
28577
|
+
tableName: "payments",
|
|
28578
|
+
matchPattern: ["payments", "*payment*"],
|
|
28579
|
+
rowCountMultiplier: 3,
|
|
28580
|
+
columnOverrides: [
|
|
28581
|
+
{ columnName: "amount_cents", strategy: { kind: "integer", options: { min: 499, max: 2e5 } } },
|
|
28582
|
+
{ columnName: "method", strategy: { kind: "enum", options: { values: ["credit_card", "debit_card", "paypal", "apple_pay", "klarna"], weights: [0.55, 0.15, 0.15, 0.1, 0.05] } } },
|
|
28583
|
+
{ columnName: "status", strategy: { kind: "enum", options: { values: ["succeeded", "failed", "pending", "refunded"], weights: [0.8, 0.12, 0.03, 0.05] } } },
|
|
28584
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
28585
|
+
]
|
|
28586
|
+
}],
|
|
28587
|
+
["refunds", {
|
|
28588
|
+
tableName: "refunds",
|
|
28589
|
+
matchPattern: ["refunds", "*refund*"],
|
|
28590
|
+
rowCountMultiplier: 0.4,
|
|
28591
|
+
columnOverrides: [
|
|
28592
|
+
{ columnName: "amount_cents", strategy: { kind: "integer", options: { min: 499, max: 1e5 } } },
|
|
28593
|
+
{ columnName: "reason", strategy: { kind: "enum", options: { values: ["defective", "wrong_item", "changed_mind", "late_delivery", "duplicate"], weights: [0.25, 0.2, 0.3, 0.15, 0.1] } } },
|
|
28594
|
+
{ columnName: "status", strategy: { kind: "enum", options: { values: ["processed", "pending", "denied"], weights: [0.7, 0.2, 0.1] } } },
|
|
28595
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
28596
|
+
]
|
|
28597
|
+
}],
|
|
28598
|
+
["shipments", {
|
|
28599
|
+
tableName: "shipments",
|
|
28600
|
+
matchPattern: ["shipments", "*shipment*"],
|
|
28601
|
+
rowCountMultiplier: 3,
|
|
28602
|
+
columnOverrides: [
|
|
28603
|
+
{ columnName: "carrier", strategy: { kind: "enum", options: { values: ["fedex", "ups", "usps", "dhl"], weights: [0.3, 0.3, 0.25, 0.15] } } },
|
|
28604
|
+
{ columnName: "status", strategy: { kind: "enum", options: { values: ["delivered", "in_transit", "out_for_delivery", "exception", "label_created"], weights: [0.5, 0.25, 0.1, 0.1, 0.05] } } },
|
|
28605
|
+
{ columnName: "shipped_at", strategy: { kind: "timestamp", options: { mode: "past" } } },
|
|
28606
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
28607
|
+
]
|
|
28608
|
+
}],
|
|
28609
|
+
["disputes", {
|
|
28610
|
+
tableName: "disputes",
|
|
28611
|
+
matchPattern: ["disputes", "*dispute*"],
|
|
28612
|
+
rowCountMultiplier: 0.05,
|
|
28613
|
+
columnOverrides: [
|
|
28614
|
+
{ columnName: "reason", strategy: { kind: "enum", options: { values: ["fraud", "not_received", "not_as_described", "duplicate", "other"], weights: [0.2, 0.3, 0.25, 0.1, 0.15] } } },
|
|
28615
|
+
{ columnName: "status", strategy: { kind: "enum", options: { values: ["open", "under_review", "won", "lost"], weights: [0.15, 0.25, 0.35, 0.25] } } },
|
|
28616
|
+
{ columnName: "amount_cents", strategy: { kind: "integer", options: { min: 499, max: 5e4 } } },
|
|
28617
|
+
{ columnName: "evidence_submitted", strategy: { kind: "boolean" } },
|
|
28618
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
28619
|
+
]
|
|
28487
28620
|
}]
|
|
28488
28621
|
])
|
|
28489
28622
|
};
|
|
@@ -28492,7 +28625,7 @@ var ecommerceTemplate = {
|
|
|
28492
28625
|
var educationTemplate = {
|
|
28493
28626
|
name: "education",
|
|
28494
28627
|
version: "2.0",
|
|
28495
|
-
description: "K-12 school system with teachers, classes, students, grades,
|
|
28628
|
+
description: "K-12 school system with 6 tables: teachers, classes, students, enrollments, grades, attendance",
|
|
28496
28629
|
targetTables: ["teachers", "classes", "students", "enrollments", "grades", "attendance"],
|
|
28497
28630
|
tableConfigs: /* @__PURE__ */ new Map([
|
|
28498
28631
|
["teachers", {
|
|
@@ -28762,8 +28895,8 @@ var educationTemplate = {
|
|
|
28762
28895
|
var fintechTemplate = {
|
|
28763
28896
|
name: "fintech",
|
|
28764
28897
|
version: "2.0",
|
|
28765
|
-
description: "Financial
|
|
28766
|
-
targetTables: ["accounts", "transactions", "fraud_alerts", "settlements", "chargebacks"],
|
|
28898
|
+
description: "Financial platform with 10 tables: accounts, transactions, transfers, cards, authorizations, settlements, fraud_alerts, fraud_investigations, chargebacks, compliance_checks",
|
|
28899
|
+
targetTables: ["accounts", "transactions", "fraud_alerts", "settlements", "chargebacks", "transfers", "cards", "authorizations", "fraud_investigations", "compliance_checks"],
|
|
28767
28900
|
tableConfigs: /* @__PURE__ */ new Map([
|
|
28768
28901
|
["accounts", {
|
|
28769
28902
|
tableName: "accounts",
|
|
@@ -28831,7 +28964,7 @@ var fintechTemplate = {
|
|
|
28831
28964
|
{
|
|
28832
28965
|
columnName: "closed_at",
|
|
28833
28966
|
strategy: { kind: "timestamp", options: { mode: "past" } },
|
|
28834
|
-
description: "Nullable \
|
|
28967
|
+
description: "Nullable \xC3\u0192\xC2\xA2\xC3\xA2\xE2\u20AC\u0161\xC2\xAC\xC3\xA2\xE2\u201A\xAC\xC2\x9D null for active accounts"
|
|
28835
28968
|
}
|
|
28836
28969
|
]
|
|
28837
28970
|
}],
|
|
@@ -28952,7 +29085,7 @@ var fintechTemplate = {
|
|
|
28952
29085
|
{
|
|
28953
29086
|
columnName: "resolved_at",
|
|
28954
29087
|
strategy: { kind: "timestamp", options: { mode: "past" } },
|
|
28955
|
-
description: "Nullable \
|
|
29088
|
+
description: "Nullable \xC3\u0192\xC2\xA2\xC3\xA2\xE2\u20AC\u0161\xC2\xAC\xC3\xA2\xE2\u201A\xAC\xC2\x9D null for open/investigating alerts"
|
|
28956
29089
|
}
|
|
28957
29090
|
]
|
|
28958
29091
|
}],
|
|
@@ -28988,7 +29121,7 @@ var fintechTemplate = {
|
|
|
28988
29121
|
{
|
|
28989
29122
|
columnName: "settled_at",
|
|
28990
29123
|
strategy: { kind: "timestamp", options: { mode: "past" } },
|
|
28991
|
-
description: "Nullable \
|
|
29124
|
+
description: "Nullable \xC3\u0192\xC2\xA2\xC3\xA2\xE2\u20AC\u0161\xC2\xAC\xC3\xA2\xE2\u201A\xAC\xC2\x9D null for pending settlements"
|
|
28992
29125
|
},
|
|
28993
29126
|
{
|
|
28994
29127
|
columnName: "created_at",
|
|
@@ -29032,9 +29165,70 @@ var fintechTemplate = {
|
|
|
29032
29165
|
{
|
|
29033
29166
|
columnName: "resolved_at",
|
|
29034
29167
|
strategy: { kind: "timestamp", options: { mode: "past" } },
|
|
29035
|
-
description: "Nullable \
|
|
29168
|
+
description: "Nullable \xC3\u0192\xC2\xA2\xC3\xA2\xE2\u20AC\u0161\xC2\xAC\xC3\xA2\xE2\u201A\xAC\xC2\x9D null for open/under_review chargebacks"
|
|
29036
29169
|
}
|
|
29037
29170
|
]
|
|
29171
|
+
}],
|
|
29172
|
+
["transfers", {
|
|
29173
|
+
tableName: "transfers",
|
|
29174
|
+
matchPattern: ["transfers", "*transfer*"],
|
|
29175
|
+
rowCountMultiplier: 5,
|
|
29176
|
+
columnOverrides: [
|
|
29177
|
+
{ columnName: "amount_cents", strategy: { kind: "integer", options: { min: 100, max: 5e6 } } },
|
|
29178
|
+
{ columnName: "status", strategy: { kind: "enum", options: { values: ["completed", "pending", "failed", "cancelled"], weights: [0.75, 0.12, 0.08, 0.05] } } },
|
|
29179
|
+
{ columnName: "reference", strategy: { kind: "text", options: { mode: "short" } } },
|
|
29180
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
29181
|
+
]
|
|
29182
|
+
}],
|
|
29183
|
+
["cards", {
|
|
29184
|
+
tableName: "cards",
|
|
29185
|
+
matchPattern: ["cards", "*card*"],
|
|
29186
|
+
rowCountMultiplier: 2.5,
|
|
29187
|
+
columnOverrides: [
|
|
29188
|
+
{ columnName: "card_number_last_four", strategy: { kind: "text", options: { mode: "short" } } },
|
|
29189
|
+
{ columnName: "card_type", strategy: { kind: "enum", options: { values: ["debit", "credit"], weights: [0.6, 0.4] } } },
|
|
29190
|
+
{ columnName: "status", strategy: { kind: "enum", options: { values: ["active", "blocked", "expired", "cancelled"], weights: [0.75, 0.08, 0.12, 0.05] } } },
|
|
29191
|
+
{ columnName: "daily_limit_cents", strategy: { kind: "integer", options: { min: 5e4, max: 1e6 } } },
|
|
29192
|
+
{ columnName: "expires_at", strategy: { kind: "timestamp", options: { mode: "recent" } } },
|
|
29193
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
29194
|
+
]
|
|
29195
|
+
}],
|
|
29196
|
+
["authorizations", {
|
|
29197
|
+
tableName: "authorizations",
|
|
29198
|
+
matchPattern: ["authorizations", "*authorization*", "*auth*"],
|
|
29199
|
+
rowCountMultiplier: 8,
|
|
29200
|
+
columnOverrides: [
|
|
29201
|
+
{ columnName: "merchant_name", strategy: { kind: "company_name" } },
|
|
29202
|
+
{ columnName: "amount_cents", strategy: { kind: "integer", options: { min: 100, max: 5e5 } } },
|
|
29203
|
+
{ columnName: "status", strategy: { kind: "enum", options: { values: ["approved", "declined", "reversed"], weights: [0.85, 0.1, 0.05] } } },
|
|
29204
|
+
{ columnName: "decline_reason", strategy: { kind: "enum", options: { values: ["insufficient_funds", "card_blocked", "suspicious_activity", "expired_card", "limit_exceeded"], weights: [0.3, 0.2, 0.25, 0.1, 0.15] } } },
|
|
29205
|
+
{ columnName: "authorized_at", strategy: { kind: "timestamp", options: { mode: "past" } } },
|
|
29206
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
29207
|
+
]
|
|
29208
|
+
}],
|
|
29209
|
+
["fraud_investigations", {
|
|
29210
|
+
tableName: "fraud_investigations",
|
|
29211
|
+
matchPattern: ["fraud_investigations", "*investigation*"],
|
|
29212
|
+
rowCountMultiplier: 0.2,
|
|
29213
|
+
columnOverrides: [
|
|
29214
|
+
{ columnName: "investigator_notes", strategy: { kind: "text" } },
|
|
29215
|
+
{ columnName: "outcome", strategy: { kind: "enum", options: { values: ["confirmed_fraud", "false_positive", "inconclusive"], weights: [0.3, 0.5, 0.2] } } },
|
|
29216
|
+
{ columnName: "amount_recovered_cents", strategy: { kind: "integer", options: { min: 0, max: 5e5 } } },
|
|
29217
|
+
{ columnName: "closed_at", strategy: { kind: "timestamp", options: { mode: "recent" } } },
|
|
29218
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
29219
|
+
]
|
|
29220
|
+
}],
|
|
29221
|
+
["compliance_checks", {
|
|
29222
|
+
tableName: "compliance_checks",
|
|
29223
|
+
matchPattern: ["compliance_checks", "*compliance*"],
|
|
29224
|
+
rowCountMultiplier: 2,
|
|
29225
|
+
columnOverrides: [
|
|
29226
|
+
{ columnName: "check_type", strategy: { kind: "enum", options: { values: ["kyc_verification", "aml_screening", "pep_check", "sanctions_check"], weights: [0.35, 0.3, 0.2, 0.15] } } },
|
|
29227
|
+
{ columnName: "result", strategy: { kind: "enum", options: { values: ["pass", "fail", "review_needed"], weights: [0.7, 0.1, 0.2] } } },
|
|
29228
|
+
{ columnName: "notes", strategy: { kind: "text" } },
|
|
29229
|
+
{ columnName: "performed_at", strategy: { kind: "timestamp", options: { mode: "past" } } },
|
|
29230
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
29231
|
+
]
|
|
29038
29232
|
}]
|
|
29039
29233
|
])
|
|
29040
29234
|
};
|
|
@@ -29043,8 +29237,8 @@ var fintechTemplate = {
|
|
|
29043
29237
|
var healthcareTemplate = {
|
|
29044
29238
|
name: "healthcare",
|
|
29045
29239
|
version: "2.0",
|
|
29046
|
-
description: "Healthcare
|
|
29047
|
-
targetTables: ["patients", "providers", "encounters", "diagnoses", "billing", "medications", "vitals"],
|
|
29240
|
+
description: "Healthcare network with 13 tables: patients, providers, encounters, diagnoses, procedures, prescriptions, lab_orders, lab_results, vitals, billing, medications, insurance_claims, claim_payments",
|
|
29241
|
+
targetTables: ["patients", "providers", "encounters", "diagnoses", "billing", "medications", "vitals", "procedures", "prescriptions", "lab_orders", "lab_results", "insurance_claims", "claim_payments"],
|
|
29048
29242
|
tableConfigs: /* @__PURE__ */ new Map([
|
|
29049
29243
|
["patients", {
|
|
29050
29244
|
tableName: "patients",
|
|
@@ -29204,12 +29398,12 @@ var healthcareTemplate = {
|
|
|
29204
29398
|
{
|
|
29205
29399
|
columnName: "checked_in_at",
|
|
29206
29400
|
strategy: { kind: "timestamp", options: { mode: "past" } },
|
|
29207
|
-
description: "Nullable \
|
|
29401
|
+
description: "Nullable \xC3\xA2\xE2\u201A\xAC\xE2\u20AC\x9D null for scheduled/canceled encounters"
|
|
29208
29402
|
},
|
|
29209
29403
|
{
|
|
29210
29404
|
columnName: "discharged_at",
|
|
29211
29405
|
strategy: { kind: "timestamp", options: { mode: "past" } },
|
|
29212
|
-
description: "Nullable \
|
|
29406
|
+
description: "Nullable \xC3\xA2\xE2\u201A\xAC\xE2\u20AC\x9D null for non-completed encounters"
|
|
29213
29407
|
}
|
|
29214
29408
|
]
|
|
29215
29409
|
}],
|
|
@@ -29308,7 +29502,7 @@ var healthcareTemplate = {
|
|
|
29308
29502
|
{
|
|
29309
29503
|
columnName: "paid_at",
|
|
29310
29504
|
strategy: { kind: "timestamp", options: { mode: "past" } },
|
|
29311
|
-
description: "Nullable \
|
|
29505
|
+
description: "Nullable \xC3\xA2\xE2\u201A\xAC\xE2\u20AC\x9D null for unpaid bills"
|
|
29312
29506
|
}
|
|
29313
29507
|
]
|
|
29314
29508
|
}],
|
|
@@ -29363,7 +29557,7 @@ var healthcareTemplate = {
|
|
|
29363
29557
|
{
|
|
29364
29558
|
columnName: "end_date",
|
|
29365
29559
|
strategy: { kind: "timestamp", options: { mode: "past" } },
|
|
29366
|
-
description: "Nullable \
|
|
29560
|
+
description: "Nullable \xC3\xA2\xE2\u201A\xAC\xE2\u20AC\x9D null for ongoing medications"
|
|
29367
29561
|
},
|
|
29368
29562
|
{
|
|
29369
29563
|
columnName: "status",
|
|
@@ -29411,6 +29605,85 @@ var healthcareTemplate = {
|
|
|
29411
29605
|
strategy: { kind: "timestamp", options: { mode: "past" } }
|
|
29412
29606
|
}
|
|
29413
29607
|
]
|
|
29608
|
+
}],
|
|
29609
|
+
["procedures", {
|
|
29610
|
+
tableName: "procedures",
|
|
29611
|
+
matchPattern: ["procedures", "*procedure*"],
|
|
29612
|
+
rowCountMultiplier: 5,
|
|
29613
|
+
columnOverrides: [
|
|
29614
|
+
{ columnName: "cpt_code", strategy: { kind: "text", options: { mode: "short" } } },
|
|
29615
|
+
{ columnName: "procedure_name", strategy: { kind: "text" } },
|
|
29616
|
+
{ columnName: "status", strategy: { kind: "enum", options: { values: ["completed", "scheduled", "cancelled"], weights: [0.7, 0.2, 0.1] } } },
|
|
29617
|
+
{ columnName: "performed_at", strategy: { kind: "timestamp", options: { mode: "past" } } },
|
|
29618
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
29619
|
+
]
|
|
29620
|
+
}],
|
|
29621
|
+
["prescriptions", {
|
|
29622
|
+
tableName: "prescriptions",
|
|
29623
|
+
matchPattern: ["prescriptions", "*prescription*"],
|
|
29624
|
+
rowCountMultiplier: 8,
|
|
29625
|
+
columnOverrides: [
|
|
29626
|
+
{ columnName: "dosage", strategy: { kind: "text", options: { mode: "short" } } },
|
|
29627
|
+
{ columnName: "frequency", strategy: { kind: "enum", options: { values: ["once_daily", "twice_daily", "three_times_daily", "as_needed", "weekly"], weights: [0.35, 0.25, 0.15, 0.15, 0.1] } } },
|
|
29628
|
+
{ columnName: "duration_days", strategy: { kind: "integer", options: { min: 5, max: 365 } } },
|
|
29629
|
+
{ columnName: "refills_remaining", strategy: { kind: "integer", options: { min: 0, max: 12 } } },
|
|
29630
|
+
{ columnName: "status", strategy: { kind: "enum", options: { values: ["active", "completed", "cancelled", "expired"], weights: [0.45, 0.3, 0.1, 0.15] } } },
|
|
29631
|
+
{ columnName: "prescribed_at", strategy: { kind: "timestamp", options: { mode: "past" } } },
|
|
29632
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
29633
|
+
]
|
|
29634
|
+
}],
|
|
29635
|
+
["lab_orders", {
|
|
29636
|
+
tableName: "lab_orders",
|
|
29637
|
+
matchPattern: ["lab_orders", "*lab_order*"],
|
|
29638
|
+
rowCountMultiplier: 4,
|
|
29639
|
+
columnOverrides: [
|
|
29640
|
+
{ columnName: "test_name", strategy: { kind: "text" } },
|
|
29641
|
+
{ columnName: "priority", strategy: { kind: "enum", options: { values: ["routine", "urgent", "stat"], weights: [0.7, 0.2, 0.1] } } },
|
|
29642
|
+
{ columnName: "status", strategy: { kind: "enum", options: { values: ["ordered", "collected", "resulted", "cancelled"], weights: [0.15, 0.1, 0.65, 0.1] } } },
|
|
29643
|
+
{ columnName: "ordered_at", strategy: { kind: "timestamp", options: { mode: "past" } } },
|
|
29644
|
+
{ columnName: "resulted_at", strategy: { kind: "timestamp", options: { mode: "recent" } } },
|
|
29645
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
29646
|
+
]
|
|
29647
|
+
}],
|
|
29648
|
+
["lab_results", {
|
|
29649
|
+
tableName: "lab_results",
|
|
29650
|
+
matchPattern: ["lab_results", "*lab_result*"],
|
|
29651
|
+
rowCountMultiplier: 10,
|
|
29652
|
+
columnOverrides: [
|
|
29653
|
+
{ columnName: "component", strategy: { kind: "text", options: { mode: "short" } } },
|
|
29654
|
+
{ columnName: "value", strategy: { kind: "float", options: { min: 0.1, max: 500 } } },
|
|
29655
|
+
{ columnName: "unit", strategy: { kind: "enum", options: { values: ["mg/dL", "mmol/L", "g/dL", "mEq/L", "U/L", "ng/mL", "cells/uL"], weights: [0.2, 0.15, 0.15, 0.15, 0.15, 0.1, 0.1] } } },
|
|
29656
|
+
{ columnName: "reference_range", strategy: { kind: "text", options: { mode: "short" } } },
|
|
29657
|
+
{ columnName: "abnormal_flag", strategy: { kind: "enum", options: { values: ["normal", "low", "high", "critical"], weights: [0.65, 0.15, 0.15, 0.05] } } },
|
|
29658
|
+
{ columnName: "resulted_at", strategy: { kind: "timestamp", options: { mode: "recent" } } },
|
|
29659
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
29660
|
+
]
|
|
29661
|
+
}],
|
|
29662
|
+
["insurance_claims", {
|
|
29663
|
+
tableName: "insurance_claims",
|
|
29664
|
+
matchPattern: ["insurance_claims", "*claim*"],
|
|
29665
|
+
rowCountMultiplier: 6,
|
|
29666
|
+
columnOverrides: [
|
|
29667
|
+
{ columnName: "total_charges_cents", strategy: { kind: "integer", options: { min: 5e3, max: 5e5 } } },
|
|
29668
|
+
{ columnName: "allowed_amount_cents", strategy: { kind: "integer", options: { min: 3e3, max: 4e5 } } },
|
|
29669
|
+
{ columnName: "patient_responsibility_cents", strategy: { kind: "integer", options: { min: 0, max: 1e5 } } },
|
|
29670
|
+
{ columnName: "status", strategy: { kind: "enum", options: { values: ["submitted", "adjudicated", "paid", "denied", "appealed"], weights: [0.15, 0.1, 0.55, 0.12, 0.08] } } },
|
|
29671
|
+
{ columnName: "submitted_at", strategy: { kind: "timestamp", options: { mode: "past" } } },
|
|
29672
|
+
{ columnName: "paid_at", strategy: { kind: "timestamp", options: { mode: "recent" } } },
|
|
29673
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
29674
|
+
]
|
|
29675
|
+
}],
|
|
29676
|
+
["claim_payments", {
|
|
29677
|
+
tableName: "claim_payments",
|
|
29678
|
+
matchPattern: ["claim_payments", "*claim_payment*"],
|
|
29679
|
+
rowCountMultiplier: 4,
|
|
29680
|
+
columnOverrides: [
|
|
29681
|
+
{ columnName: "amount_cents", strategy: { kind: "integer", options: { min: 1e3, max: 4e5 } } },
|
|
29682
|
+
{ columnName: "payment_method", strategy: { kind: "enum", options: { values: ["eft", "check", "wire"], weights: [0.7, 0.2, 0.1] } } },
|
|
29683
|
+
{ columnName: "status", strategy: { kind: "enum", options: { values: ["processed", "pending", "failed"], weights: [0.8, 0.12, 0.08] } } },
|
|
29684
|
+
{ columnName: "paid_at", strategy: { kind: "timestamp", options: { mode: "recent" } } },
|
|
29685
|
+
{ columnName: "created_at", strategy: { kind: "timestamp", options: { mode: "past" } } }
|
|
29686
|
+
]
|
|
29414
29687
|
}]
|
|
29415
29688
|
])
|
|
29416
29689
|
};
|
|
@@ -30095,8 +30368,9 @@ function buildGenerationPlan(schema, config, timelineConfig) {
|
|
|
30095
30368
|
for (const fk of schema.foreignKeys) {
|
|
30096
30369
|
fkBySource.set(`${fk.sourceTable}.${fk.sourceColumn}`, fk);
|
|
30097
30370
|
}
|
|
30371
|
+
const templateTargetSet = template ? new Set(template.targetTables) : null;
|
|
30098
30372
|
const tables = schema.tables.map((table) => {
|
|
30099
|
-
const tableForeignKeys = schema.foreignKeys.filter((fk) => fk.sourceTable === table.name);
|
|
30373
|
+
const tableForeignKeys = schema.foreignKeys.filter((fk) => fk.sourceTable === table.name && (!templateTargetSet || templateTargetSet.has(fk.targetTable)));
|
|
30100
30374
|
const dependencies = tableForeignKeys.map((fk) => fk.targetTable);
|
|
30101
30375
|
const uniqueDeps = [...new Set(dependencies)];
|
|
30102
30376
|
const tableConfig = template && registry && templateLookupName ? registry.matchTable(templateLookupName, table.name) : null;
|
|
@@ -30162,7 +30436,7 @@ function buildGenerationPlan(schema, config, timelineConfig) {
|
|
|
30162
30436
|
isUnique: column.isUnique
|
|
30163
30437
|
};
|
|
30164
30438
|
const fk = fkBySource.get(`${table.name}.${column.name}`);
|
|
30165
|
-
if (fk) {
|
|
30439
|
+
if (fk && (!templateTargetSet || templateTargetSet.has(fk.targetTable))) {
|
|
30166
30440
|
columnPlan.strategy = { kind: "foreign_key" };
|
|
30167
30441
|
const ref = {
|
|
30168
30442
|
referencedTable: fk.targetTable,
|
|
@@ -30192,7 +30466,7 @@ function buildGenerationPlan(schema, config, timelineConfig) {
|
|
|
30192
30466
|
});
|
|
30193
30467
|
}
|
|
30194
30468
|
}
|
|
30195
|
-
const rowCount = tableConfig?.rowCountMultiplier ? Math.round(defaultRowCount * tableConfig.rowCountMultiplier) : defaultRowCount;
|
|
30469
|
+
const rowCount = tableConfig?.rowCountMultiplier ? Math.max(1, Math.round(defaultRowCount * tableConfig.rowCountMultiplier)) : defaultRowCount;
|
|
30196
30470
|
const enabled = template ? tableConfig !== null : true;
|
|
30197
30471
|
const tablePlan = {
|
|
30198
30472
|
tableName: table.name,
|
|
@@ -30207,26 +30481,17 @@ function buildGenerationPlan(schema, config, timelineConfig) {
|
|
|
30207
30481
|
return tablePlan;
|
|
30208
30482
|
});
|
|
30209
30483
|
if (template) {
|
|
30210
|
-
const
|
|
30211
|
-
|
|
30212
|
-
|
|
30213
|
-
|
|
30214
|
-
for (const tablePlan of tables) {
|
|
30215
|
-
if (tablePlan.enabled) {
|
|
30216
|
-
for (const dep of tablePlan.dependencies) {
|
|
30217
|
-
if (!enabledSet.has(dep)) {
|
|
30218
|
-
enabledSet.add(dep);
|
|
30219
|
-
const depPlan = tables.find((t) => t.tableName === dep);
|
|
30220
|
-
if (depPlan && !depPlan.enabled) {
|
|
30221
|
-
depPlan.enabled = true;
|
|
30222
|
-
changed = true;
|
|
30223
|
-
}
|
|
30224
|
-
}
|
|
30225
|
-
}
|
|
30226
|
-
}
|
|
30484
|
+
const targetSet = new Set(template.targetTables);
|
|
30485
|
+
for (const tablePlan of tables) {
|
|
30486
|
+
if (tablePlan.enabled && !targetSet.has(tablePlan.tableName)) {
|
|
30487
|
+
tablePlan.enabled = false;
|
|
30227
30488
|
}
|
|
30228
30489
|
}
|
|
30229
30490
|
}
|
|
30491
|
+
const enabledNames = new Set(tables.filter((t) => t.enabled).map((t) => t.tableName));
|
|
30492
|
+
const filteredTableOrder = tableOrder.filter((name) => enabledNames.has(name));
|
|
30493
|
+
tableOrder.length = 0;
|
|
30494
|
+
tableOrder.push(...filteredTableOrder);
|
|
30230
30495
|
if (timelineConfig?.enabled) {
|
|
30231
30496
|
const temporalConstraints = resolveTemporalConstraints(schema, schema.foreignKeys, config.template);
|
|
30232
30497
|
for (const tablePlan of tables) {
|
|
@@ -31485,9 +31750,22 @@ async function exportDataset(config, options) {
|
|
|
31485
31750
|
case "csv":
|
|
31486
31751
|
files = await exportToCsv(dataset, outputDir);
|
|
31487
31752
|
break;
|
|
31488
|
-
case "sql":
|
|
31489
|
-
|
|
31753
|
+
case "sql": {
|
|
31754
|
+
const templateTableSet = new Set(plan.tableOrder);
|
|
31755
|
+
const scopedSchema = {
|
|
31756
|
+
...schema,
|
|
31757
|
+
tables: schema.tables.filter((t) => templateTableSet.has(t.name)),
|
|
31758
|
+
foreignKeys: schema.foreignKeys.filter((fk) => templateTableSet.has(fk.sourceTable) && templateTableSet.has(fk.targetTable))
|
|
31759
|
+
};
|
|
31760
|
+
scopedSchema.tableCount = scopedSchema.tables.length;
|
|
31761
|
+
scopedSchema.foreignKeyCount = scopedSchema.foreignKeys.length;
|
|
31762
|
+
files = await exportToSql(dataset, outputDir, plan.tableOrder, {
|
|
31763
|
+
ddl: generateCreateTableDDL(scopedSchema),
|
|
31764
|
+
batchSize: options?.batchSize ?? 50,
|
|
31765
|
+
templateName: plan.config.templateName
|
|
31766
|
+
});
|
|
31490
31767
|
break;
|
|
31768
|
+
}
|
|
31491
31769
|
default:
|
|
31492
31770
|
throw new Error(`Unknown export format: "${format}". Supported: json, csv, sql`);
|
|
31493
31771
|
}
|
|
@@ -31672,15 +31950,92 @@ async function captureDatabase(config, options) {
|
|
|
31672
31950
|
foreignKeyCount: filteredFKs.length
|
|
31673
31951
|
};
|
|
31674
31952
|
const ddl = generateCreateTableDDL(filteredSchema);
|
|
31953
|
+
let aroundFilter;
|
|
31954
|
+
if (options.around) {
|
|
31955
|
+
aroundFilter = /* @__PURE__ */ new Map();
|
|
31956
|
+
const { column: aroundCol, value: aroundVal } = options.around;
|
|
31957
|
+
for (const table of filteredTables) {
|
|
31958
|
+
const hasCol = table.columns.some((c) => c.name === aroundCol);
|
|
31959
|
+
if (hasCol) {
|
|
31960
|
+
aroundFilter.set(table.name, { column: aroundCol, values: /* @__PURE__ */ new Set([aroundVal]) });
|
|
31961
|
+
}
|
|
31962
|
+
}
|
|
31963
|
+
for (const fk of filteredFKs) {
|
|
31964
|
+
const sourceFilter = aroundFilter.get(fk.targetTable);
|
|
31965
|
+
if (sourceFilter && sourceFilter.column === fk.targetColumn) {
|
|
31966
|
+
aroundFilter.set(fk.sourceTable, { column: fk.sourceColumn, values: sourceFilter.values });
|
|
31967
|
+
}
|
|
31968
|
+
}
|
|
31969
|
+
}
|
|
31970
|
+
const detectionsByTable = /* @__PURE__ */ new Map();
|
|
31971
|
+
let piiSummary;
|
|
31972
|
+
if (options.safe) {
|
|
31973
|
+
const mode = "gdpr";
|
|
31974
|
+
for (const table of filteredTables) {
|
|
31975
|
+
const tableForeignKeys = filteredFKs.filter((fk) => fk.sourceTable === table.name);
|
|
31976
|
+
const detections = detectTablePII(table.columns, tableForeignKeys, table.name, mode);
|
|
31977
|
+
detectionsByTable.set(table.name, detections);
|
|
31978
|
+
}
|
|
31979
|
+
let columnsDetected = 0;
|
|
31980
|
+
let tablesAffected = 0;
|
|
31981
|
+
const categoriesFound = /* @__PURE__ */ new Set();
|
|
31982
|
+
for (const [, detections] of detectionsByTable) {
|
|
31983
|
+
const piiCols = detections.filter((d) => d.shouldMask);
|
|
31984
|
+
if (piiCols.length > 0) {
|
|
31985
|
+
tablesAffected++;
|
|
31986
|
+
columnsDetected += piiCols.length;
|
|
31987
|
+
for (const d of piiCols) {
|
|
31988
|
+
categoriesFound.add(d.category);
|
|
31989
|
+
}
|
|
31990
|
+
}
|
|
31991
|
+
}
|
|
31992
|
+
piiSummary = {
|
|
31993
|
+
columnsDetected,
|
|
31994
|
+
tablesAffected,
|
|
31995
|
+
categoriesFound: Array.from(categoriesFound)
|
|
31996
|
+
};
|
|
31997
|
+
}
|
|
31675
31998
|
const packDataset = { tables: {} };
|
|
31676
31999
|
const tableDetails = [];
|
|
31677
32000
|
let totalRows = 0;
|
|
32001
|
+
const safeMode = options.safeMode ?? "mask";
|
|
32002
|
+
const random = options.safe ? createSeededRandom(42) : void 0;
|
|
32003
|
+
const tokenPrefix = options.safe && safeMode === "tokenize" ? generateTokenPrefix() : void 0;
|
|
31678
32004
|
for (const tableName of tablesToCapture) {
|
|
31679
32005
|
const tableSchema = filteredTables.find((t) => t.name === tableName);
|
|
31680
32006
|
if (!tableSchema)
|
|
31681
32007
|
continue;
|
|
31682
32008
|
const columns = tableSchema.columns.map((c) => c.name);
|
|
31683
|
-
|
|
32009
|
+
let rows = await readTableRows(pool, tableName, columns);
|
|
32010
|
+
const filter = aroundFilter?.get(tableName);
|
|
32011
|
+
if (filter) {
|
|
32012
|
+
rows = rows.filter((row) => {
|
|
32013
|
+
const val = row[filter.column];
|
|
32014
|
+
return val !== null && val !== void 0 && filter.values.has(String(val));
|
|
32015
|
+
});
|
|
32016
|
+
}
|
|
32017
|
+
if (options.maxRows !== void 0 && rows.length > options.maxRows) {
|
|
32018
|
+
rows = rows.slice(0, options.maxRows);
|
|
32019
|
+
}
|
|
32020
|
+
if (options.safe) {
|
|
32021
|
+
const detections = detectionsByTable.get(tableName);
|
|
32022
|
+
if (detections) {
|
|
32023
|
+
const hasPII = detections.some((d) => d.shouldMask);
|
|
32024
|
+
if (hasPII) {
|
|
32025
|
+
if (safeMode === "tokenize" && tokenPrefix) {
|
|
32026
|
+
const { tokenizedRows } = tokenizeTableRows(rows, detections, tableName, tokenPrefix);
|
|
32027
|
+
rows = tokenizedRows;
|
|
32028
|
+
} else if (safeMode === "redact") {
|
|
32029
|
+
const redactDetections = detections.map((d) => d.shouldMask ? { ...d, maskStrategy: "redact" } : d);
|
|
32030
|
+
const { maskedRows } = maskTableRows(rows, redactDetections, random, tableName);
|
|
32031
|
+
rows = maskedRows;
|
|
32032
|
+
} else {
|
|
32033
|
+
const { maskedRows } = maskTableRows(rows, detections, random, tableName);
|
|
32034
|
+
rows = maskedRows;
|
|
32035
|
+
}
|
|
32036
|
+
}
|
|
32037
|
+
}
|
|
32038
|
+
}
|
|
31684
32039
|
const rowCount = rows.length;
|
|
31685
32040
|
packDataset.tables[tableName] = {
|
|
31686
32041
|
columns,
|
|
@@ -31725,6 +32080,7 @@ async function captureDatabase(config, options) {
|
|
|
31725
32080
|
}
|
|
31726
32081
|
};
|
|
31727
32082
|
const masked = maskConnection(config.database.connectionString);
|
|
32083
|
+
const safeModeValue = options.safe ? safeMode === "tokenize" ? "tokenized" : safeMode === "redact" ? "redacted" : "masked" : "raw";
|
|
31728
32084
|
const pack = {
|
|
31729
32085
|
format: "realitydb-pack",
|
|
31730
32086
|
version: "1.0",
|
|
@@ -31736,7 +32092,9 @@ async function captureDatabase(config, options) {
|
|
|
31736
32092
|
totalRows,
|
|
31737
32093
|
tableCount: tablesToCapture.length,
|
|
31738
32094
|
ddl,
|
|
31739
|
-
capturedFrom: masked
|
|
32095
|
+
capturedFrom: masked,
|
|
32096
|
+
safeMode: safeModeValue,
|
|
32097
|
+
piiSummary
|
|
31740
32098
|
},
|
|
31741
32099
|
schema: packSchema,
|
|
31742
32100
|
plan,
|
|
@@ -31751,7 +32109,8 @@ async function captureDatabase(config, options) {
|
|
|
31751
32109
|
totalRows,
|
|
31752
32110
|
tableCount: tablesToCapture.length,
|
|
31753
32111
|
durationMs,
|
|
31754
|
-
tableDetails
|
|
32112
|
+
tableDetails,
|
|
32113
|
+
piiSummary
|
|
31755
32114
|
};
|
|
31756
32115
|
} finally {
|
|
31757
32116
|
await closeConnection(pool);
|
|
@@ -33285,6 +33644,7 @@ async function exportCommand(options) {
|
|
|
33285
33644
|
console.log("");
|
|
33286
33645
|
console.log("Generating dataset...");
|
|
33287
33646
|
}
|
|
33647
|
+
const batchSize = options.batchSize ? parseInt(options.batchSize, 10) : void 0;
|
|
33288
33648
|
const result = await exportDataset(config, {
|
|
33289
33649
|
format,
|
|
33290
33650
|
outputDir,
|
|
@@ -33294,7 +33654,8 @@ async function exportCommand(options) {
|
|
|
33294
33654
|
timeline,
|
|
33295
33655
|
scenarios: scenario,
|
|
33296
33656
|
scenarioIntensity,
|
|
33297
|
-
scenarioSchedule: options.scenarioSchedule
|
|
33657
|
+
scenarioSchedule: options.scenarioSchedule,
|
|
33658
|
+
batchSize
|
|
33298
33659
|
});
|
|
33299
33660
|
const durationMs = Math.round(performance.now() - start);
|
|
33300
33661
|
if (options.ci) {
|
|
@@ -33737,6 +34098,18 @@ async function captureCommand(options) {
|
|
|
33737
34098
|
const config = await loadConfig(options.configPath);
|
|
33738
34099
|
const masked = maskConnectionString(config.database.connectionString);
|
|
33739
34100
|
const tables = options.tables ? options.tables.split(",").map((t) => t.trim()).filter((t) => t.length > 0) : void 0;
|
|
34101
|
+
const safeMode = options.safe ? ["mask", "tokenize", "redact"].includes(options.safeMode ?? "") ? options.safeMode : "mask" : void 0;
|
|
34102
|
+
const maxRows = options.maxRows ? parseInt(options.maxRows, 10) : void 0;
|
|
34103
|
+
let around;
|
|
34104
|
+
if (options.around) {
|
|
34105
|
+
const eqIdx = options.around.indexOf("=");
|
|
34106
|
+
if (eqIdx > 0) {
|
|
34107
|
+
around = {
|
|
34108
|
+
column: options.around.substring(0, eqIdx),
|
|
34109
|
+
value: options.around.substring(eqIdx + 1)
|
|
34110
|
+
};
|
|
34111
|
+
}
|
|
34112
|
+
}
|
|
33740
34113
|
if (!options.ci) {
|
|
33741
34114
|
console.log("");
|
|
33742
34115
|
console.log("RealityDB Capture");
|
|
@@ -33746,6 +34119,15 @@ async function captureCommand(options) {
|
|
|
33746
34119
|
if (tables) {
|
|
33747
34120
|
console.log(`Tables: ${tables.join(", ")}`);
|
|
33748
34121
|
}
|
|
34122
|
+
if (options.safe) {
|
|
34123
|
+
console.log(`Safe mode: ${safeMode} (PII will be sanitized)`);
|
|
34124
|
+
}
|
|
34125
|
+
if (maxRows !== void 0) {
|
|
34126
|
+
console.log(`Max rows per table: ${maxRows}`);
|
|
34127
|
+
}
|
|
34128
|
+
if (around) {
|
|
34129
|
+
console.log("");
|
|
34130
|
+
}
|
|
33749
34131
|
console.log("");
|
|
33750
34132
|
console.log("Capturing...");
|
|
33751
34133
|
}
|
|
@@ -33753,7 +34135,11 @@ async function captureCommand(options) {
|
|
|
33753
34135
|
name: options.name,
|
|
33754
34136
|
description: options.description,
|
|
33755
34137
|
tables,
|
|
33756
|
-
outputDir: options.output
|
|
34138
|
+
outputDir: options.output,
|
|
34139
|
+
safe: options.safe,
|
|
34140
|
+
safeMode,
|
|
34141
|
+
maxRows,
|
|
34142
|
+
around
|
|
33757
34143
|
});
|
|
33758
34144
|
const durationMs = Math.round(performance.now() - start);
|
|
33759
34145
|
if (options.ci) {
|
|
@@ -33769,6 +34155,8 @@ async function captureCommand(options) {
|
|
|
33769
34155
|
filePath: result.filePath,
|
|
33770
34156
|
tableCount: result.tableCount,
|
|
33771
34157
|
totalRows: result.totalRows,
|
|
34158
|
+
safeMode: result.pack.metadata.safeMode,
|
|
34159
|
+
piiSummary: result.piiSummary,
|
|
33772
34160
|
tables: result.tableDetails.map((t) => ({
|
|
33773
34161
|
name: t.name,
|
|
33774
34162
|
rowCount: t.rowCount
|
|
@@ -33778,6 +34166,21 @@ async function captureCommand(options) {
|
|
|
33778
34166
|
}));
|
|
33779
34167
|
return;
|
|
33780
34168
|
}
|
|
34169
|
+
if (options.safe && result.piiSummary) {
|
|
34170
|
+
const { columnsDetected, tablesAffected, categoriesFound } = result.piiSummary;
|
|
34171
|
+
if (columnsDetected > 0) {
|
|
34172
|
+
console.log(`PII detected: ${columnsDetected} columns across ${tablesAffected} tables. Sanitizing...`);
|
|
34173
|
+
console.log(` Categories: ${categoriesFound.join(", ")}`);
|
|
34174
|
+
console.log("");
|
|
34175
|
+
} else {
|
|
34176
|
+
console.log("No PII detected \u2014 data captured as-is.");
|
|
34177
|
+
console.log("");
|
|
34178
|
+
}
|
|
34179
|
+
}
|
|
34180
|
+
if (around) {
|
|
34181
|
+
console.log(`Capturing rows related to ${around.column}=${around.value} across ${result.tableCount} tables`);
|
|
34182
|
+
console.log("");
|
|
34183
|
+
}
|
|
33781
34184
|
for (const table of result.tableDetails) {
|
|
33782
34185
|
console.log(` ${table.name}: ${table.rowCount} rows`);
|
|
33783
34186
|
}
|
|
@@ -33785,6 +34188,9 @@ async function captureCommand(options) {
|
|
|
33785
34188
|
const sizeKb = Math.round(fileStat.size / 1024);
|
|
33786
34189
|
console.log("");
|
|
33787
34190
|
console.log(`Captured: ${result.filePath} (${sizeKb} KB)`);
|
|
34191
|
+
if (options.safe) {
|
|
34192
|
+
console.log(`Privacy: PII sanitized (${safeMode} mode). Safe to share.`);
|
|
34193
|
+
}
|
|
33788
34194
|
console.log("Schema DDL included. Share this file to reproduce the environment.");
|
|
33789
34195
|
console.log("");
|
|
33790
34196
|
} catch (err) {
|
|
@@ -33915,6 +34321,19 @@ var VERSION9 = "0.10.0";
|
|
|
33915
34321
|
function isUrl(input) {
|
|
33916
34322
|
return input.startsWith("http://") || input.startsWith("https://");
|
|
33917
34323
|
}
|
|
34324
|
+
function displaySafeModeStatus(safeMode) {
|
|
34325
|
+
if (!safeMode) {
|
|
34326
|
+
console.warn("Note: This pack was captured before privacy-safe mode was available");
|
|
34327
|
+
} else if (safeMode === "raw") {
|
|
34328
|
+
console.log("WARNING: This pack contains raw (unsanitized) data");
|
|
34329
|
+
} else if (safeMode === "masked") {
|
|
34330
|
+
console.log("This pack was captured with PII masking");
|
|
34331
|
+
} else if (safeMode === "tokenized") {
|
|
34332
|
+
console.log("This pack was captured with PII tokenization");
|
|
34333
|
+
} else if (safeMode === "redacted") {
|
|
34334
|
+
console.log("This pack was captured with PII redaction");
|
|
34335
|
+
}
|
|
34336
|
+
}
|
|
33918
34337
|
async function loadCommand(filePath, options) {
|
|
33919
34338
|
const start = performance.now();
|
|
33920
34339
|
try {
|
|
@@ -33950,6 +34369,57 @@ async function loadCommand(filePath, options) {
|
|
|
33950
34369
|
}
|
|
33951
34370
|
}
|
|
33952
34371
|
const pack = await loadRealityPack(localPath);
|
|
34372
|
+
if (options.preview) {
|
|
34373
|
+
const meta2 = pack.metadata;
|
|
34374
|
+
const safeMode2 = meta2.safeMode;
|
|
34375
|
+
const piiSummary = meta2.piiSummary;
|
|
34376
|
+
if (options.ci) {
|
|
34377
|
+
const tableNames = Object.keys(pack.dataset.tables);
|
|
34378
|
+
const tableInfo = tableNames.map((name) => ({
|
|
34379
|
+
name,
|
|
34380
|
+
rowCount: pack.dataset.tables[name].rowCount
|
|
34381
|
+
}));
|
|
34382
|
+
console.log(formatCIOutput({
|
|
34383
|
+
success: true,
|
|
34384
|
+
command: "load",
|
|
34385
|
+
version: VERSION9,
|
|
34386
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34387
|
+
durationMs: Math.round(performance.now() - start),
|
|
34388
|
+
data: {
|
|
34389
|
+
packName: pack.metadata.name,
|
|
34390
|
+
safeMode: safeMode2 ?? null,
|
|
34391
|
+
piiSummary: piiSummary ?? null,
|
|
34392
|
+
tableCount: pack.metadata.tableCount,
|
|
34393
|
+
totalRows: pack.metadata.totalRows,
|
|
34394
|
+
tables: tableInfo
|
|
34395
|
+
}
|
|
34396
|
+
}));
|
|
34397
|
+
return;
|
|
34398
|
+
}
|
|
34399
|
+
console.log("");
|
|
34400
|
+
console.log("Reality Pack Preview");
|
|
34401
|
+
console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
|
|
34402
|
+
console.log(`Name: ${pack.metadata.name}`);
|
|
34403
|
+
if (pack.metadata.description) {
|
|
34404
|
+
console.log(`Description: ${pack.metadata.description}`);
|
|
34405
|
+
}
|
|
34406
|
+
console.log(`Tables: ${pack.metadata.tableCount}`);
|
|
34407
|
+
console.log(`Total rows: ${pack.metadata.totalRows}`);
|
|
34408
|
+
console.log("");
|
|
34409
|
+
displaySafeModeStatus(safeMode2);
|
|
34410
|
+
if (piiSummary) {
|
|
34411
|
+
console.log(` PII columns detected: ${piiSummary.columnsDetected}`);
|
|
34412
|
+
console.log(` Tables affected: ${piiSummary.tablesAffected}`);
|
|
34413
|
+
console.log(` Categories: ${piiSummary.categoriesFound.join(", ")}`);
|
|
34414
|
+
}
|
|
34415
|
+
console.log("");
|
|
34416
|
+
console.log("Tables:");
|
|
34417
|
+
for (const [name, tableData] of Object.entries(pack.dataset.tables)) {
|
|
34418
|
+
console.log(` ${name}: ${tableData.rowCount} rows`);
|
|
34419
|
+
}
|
|
34420
|
+
console.log("");
|
|
34421
|
+
return;
|
|
34422
|
+
}
|
|
33953
34423
|
if (options.showDdl) {
|
|
33954
34424
|
const ddl = pack.metadata.ddl;
|
|
33955
34425
|
if (options.ci) {
|
|
@@ -33982,6 +34452,8 @@ async function loadCommand(filePath, options) {
|
|
|
33982
34452
|
}
|
|
33983
34453
|
const config = await loadConfig(options.configPath);
|
|
33984
34454
|
const masked = maskConnectionString(config.database.connectionString);
|
|
34455
|
+
const meta = pack.metadata;
|
|
34456
|
+
const safeMode = meta.safeMode;
|
|
33985
34457
|
if (!options.ci) {
|
|
33986
34458
|
console.log("");
|
|
33987
34459
|
console.log("RealityDB Load");
|
|
@@ -34001,6 +34473,8 @@ async function loadCommand(filePath, options) {
|
|
|
34001
34473
|
console.log("Schema DDL: included");
|
|
34002
34474
|
}
|
|
34003
34475
|
console.log("");
|
|
34476
|
+
displaySafeModeStatus(safeMode);
|
|
34477
|
+
console.log("");
|
|
34004
34478
|
}
|
|
34005
34479
|
if (!options.ci && !options.confirm) {
|
|
34006
34480
|
console.error("[realitydb] Load requires --confirm flag.");
|
|
@@ -34008,6 +34482,9 @@ async function loadCommand(filePath, options) {
|
|
|
34008
34482
|
console.error("");
|
|
34009
34483
|
console.error("To view the schema DDL first:");
|
|
34010
34484
|
console.error(` realitydb load ${filePath} --show-ddl`);
|
|
34485
|
+
console.error("");
|
|
34486
|
+
console.error("To preview pack contents:");
|
|
34487
|
+
console.error(` realitydb load ${filePath} --preview`);
|
|
34011
34488
|
process.exit(1);
|
|
34012
34489
|
}
|
|
34013
34490
|
if (!options.ci) {
|
|
@@ -34026,6 +34503,7 @@ async function loadCommand(filePath, options) {
|
|
|
34026
34503
|
database: masked,
|
|
34027
34504
|
packName: pack.metadata.name,
|
|
34028
34505
|
totalRows: result.totalRows,
|
|
34506
|
+
safeMode: safeMode ?? null,
|
|
34029
34507
|
source: isUrl(filePath) ? filePath : void 0,
|
|
34030
34508
|
tables: result.insertResult.tables.map((t) => ({
|
|
34031
34509
|
name: t.tableName,
|
|
@@ -34043,7 +34521,8 @@ async function loadCommand(filePath, options) {
|
|
|
34043
34521
|
}
|
|
34044
34522
|
const totalTime = (result.durationMs / 1e3).toFixed(1);
|
|
34045
34523
|
console.log("");
|
|
34046
|
-
console.log(`
|
|
34524
|
+
console.log(`Bug reproduction environment ready. ${result.insertResult.tables.length} tables, ${result.totalRows} rows loaded.`);
|
|
34525
|
+
console.log(`Load complete in ${totalTime}s`);
|
|
34047
34526
|
console.log("");
|
|
34048
34527
|
} catch (err) {
|
|
34049
34528
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -35664,7 +36143,7 @@ async function simulateWebhooksCommand(options) {
|
|
|
35664
36143
|
}
|
|
35665
36144
|
|
|
35666
36145
|
// src/cli.ts
|
|
35667
|
-
var VERSION17 = "
|
|
36146
|
+
var VERSION17 = "2.0.1";
|
|
35668
36147
|
function run(argv) {
|
|
35669
36148
|
const program2 = new Command();
|
|
35670
36149
|
program2.name("realitydb").description("RealityDB -- Developer Reality Platform").version(VERSION17).option("--config <path>", "Path to config file").option("--ci", "CI mode: JSON output, no prompts, proper exit codes", false).option("--verbose", "Enable verbose output", false);
|
|
@@ -35687,7 +36166,7 @@ function run(argv) {
|
|
|
35687
36166
|
const opts = program2.opts();
|
|
35688
36167
|
await resetCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
|
|
35689
36168
|
});
|
|
35690
|
-
program2.command("export").description("Export generated data").option("--format <format>", "Output format (json|csv|sql)", "json").option("--output <dir>", "Output directory", "./.realitydb").option("--records <count>", "Number of records per table").option("--seed <number>", "Random seed for reproducibility").option("--template <name>", "Template to use").option("--timeline <duration>", 'Timeline duration (e.g., "12-months", "1-year")').option("--scenario <names>", "Scenarios to apply (comma-separated)").option("--scenario-intensity <level>", "Scenario intensity (low|medium|high)", "medium").option("--scenario-schedule <schedule>", 'Timeline-scheduled scenarios (e.g., "fraud-spike:month-6,churn-spike:month-9")').action(async (cmdOpts) => {
|
|
36169
|
+
program2.command("export").description("Export generated data").option("--format <format>", "Output format (json|csv|sql)", "json").option("--output <dir>", "Output directory", "./.realitydb").option("--records <count>", "Number of records per table").option("--seed <number>", "Random seed for reproducibility").option("--template <name>", "Template to use").option("--timeline <duration>", 'Timeline duration (e.g., "12-months", "1-year")').option("--scenario <names>", "Scenarios to apply (comma-separated)").option("--scenario-intensity <level>", "Scenario intensity (low|medium|high)", "medium").option("--scenario-schedule <schedule>", 'Timeline-scheduled scenarios (e.g., "fraud-spike:month-6,churn-spike:month-9")').option("--batch-size <number>", "Rows per INSERT statement for SQL format (default: 50)").action(async (cmdOpts) => {
|
|
35691
36170
|
const opts = program2.opts();
|
|
35692
36171
|
await exportCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
|
|
35693
36172
|
});
|
|
@@ -35766,7 +36245,7 @@ function run(argv) {
|
|
|
35766
36245
|
const opts = program2.opts();
|
|
35767
36246
|
await simulateWebhooksCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
|
|
35768
36247
|
});
|
|
35769
|
-
program2.command("capture").description("Capture live database state into a Reality Pack").requiredOption("--name <name>", "Name for the captured pack").option("--description <desc>", "Pack description").option("--tables <tables>", "Comma-separated list of tables to capture").option("--output <dir>", "Output directory", ".").action(async (cmdOpts) => {
|
|
36248
|
+
program2.command("capture").description("Capture live database state into a Reality Pack").requiredOption("--name <name>", "Name for the captured pack").option("--description <desc>", "Pack description").option("--tables <tables>", "Comma-separated list of tables to capture").option("--output <dir>", "Output directory", ".").option("--safe", "Enable privacy-safe capture (sanitize PII before writing)").option("--safe-mode <mode>", "PII sanitization mode: mask (default), tokenize, redact", "mask").option("--max-rows <count>", "Maximum rows to capture per table").option("--around <column=value>", "Capture rows related to a specific entity (follows FK chains)").action(async (cmdOpts) => {
|
|
35770
36249
|
const opts = program2.opts();
|
|
35771
36250
|
await captureCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
|
|
35772
36251
|
});
|
|
@@ -35774,7 +36253,7 @@ function run(argv) {
|
|
|
35774
36253
|
const opts = program2.opts();
|
|
35775
36254
|
await shareCommand(filePath, { ...cmdOpts, ci: opts.ci, configPath: opts.config });
|
|
35776
36255
|
});
|
|
35777
|
-
program2.command("load <file>").description("Load a Reality Pack into the database (file path or URL)").option("--confirm", "Confirm import operation").option("--show-ddl", "Show schema DDL without importing").action(async (filePath, cmdOpts) => {
|
|
36256
|
+
program2.command("load <file>").description("Load a Reality Pack into the database (file path or URL)").option("--confirm", "Confirm import operation").option("--show-ddl", "Show schema DDL without importing").option("--preview", "Preview pack contents without importing").action(async (filePath, cmdOpts) => {
|
|
35778
36257
|
const opts = program2.opts();
|
|
35779
36258
|
await loadCommand(filePath, { ...cmdOpts, ci: opts.ci, configPath: opts.config });
|
|
35780
36259
|
});
|