realitydb 1.8.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +701 -114
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -20958,7 +20958,7 @@ var require_pool_connection = __commonJS({
|
|
|
20958
20958
|
var require_make_done_cb = __commonJS({
|
|
20959
20959
|
"../../node_modules/.pnpm/mysql2@3.19.1_@types+node@25.3.5/node_modules/mysql2/lib/promise/make_done_cb.js"(exports2, module2) {
|
|
20960
20960
|
"use strict";
|
|
20961
|
-
function makeDoneCb(
|
|
20961
|
+
function makeDoneCb(resolve14, reject, localErr) {
|
|
20962
20962
|
return function(err, rows, fields) {
|
|
20963
20963
|
if (err) {
|
|
20964
20964
|
localErr.message = err.message;
|
|
@@ -20969,7 +20969,7 @@ var require_make_done_cb = __commonJS({
|
|
|
20969
20969
|
localErr.sqlMessage = err.sqlMessage;
|
|
20970
20970
|
reject(localErr);
|
|
20971
20971
|
} else {
|
|
20972
|
-
|
|
20972
|
+
resolve14([rows, fields]);
|
|
20973
20973
|
}
|
|
20974
20974
|
};
|
|
20975
20975
|
}
|
|
@@ -20990,8 +20990,8 @@ var require_prepared_statement_info = __commonJS({
|
|
|
20990
20990
|
execute(parameters) {
|
|
20991
20991
|
const s = this.statement;
|
|
20992
20992
|
const localErr = new Error();
|
|
20993
|
-
return new this.Promise((
|
|
20994
|
-
const done = makeDoneCb(
|
|
20993
|
+
return new this.Promise((resolve14, reject) => {
|
|
20994
|
+
const done = makeDoneCb(resolve14, reject, localErr);
|
|
20995
20995
|
if (parameters) {
|
|
20996
20996
|
s.execute(parameters, done);
|
|
20997
20997
|
} else {
|
|
@@ -21000,9 +21000,9 @@ var require_prepared_statement_info = __commonJS({
|
|
|
21000
21000
|
});
|
|
21001
21001
|
}
|
|
21002
21002
|
close() {
|
|
21003
|
-
return new this.Promise((
|
|
21003
|
+
return new this.Promise((resolve14) => {
|
|
21004
21004
|
this.statement.close();
|
|
21005
|
-
|
|
21005
|
+
resolve14();
|
|
21006
21006
|
});
|
|
21007
21007
|
}
|
|
21008
21008
|
};
|
|
@@ -21071,8 +21071,8 @@ var require_connection2 = __commonJS({
|
|
|
21071
21071
|
"Callback function is not available with promise clients."
|
|
21072
21072
|
);
|
|
21073
21073
|
}
|
|
21074
|
-
return new this.Promise((
|
|
21075
|
-
const done = makeDoneCb(
|
|
21074
|
+
return new this.Promise((resolve14, reject) => {
|
|
21075
|
+
const done = makeDoneCb(resolve14, reject, localErr);
|
|
21076
21076
|
if (params !== void 0) {
|
|
21077
21077
|
c.query(query, params, done);
|
|
21078
21078
|
} else {
|
|
@@ -21088,8 +21088,8 @@ var require_connection2 = __commonJS({
|
|
|
21088
21088
|
"Callback function is not available with promise clients."
|
|
21089
21089
|
);
|
|
21090
21090
|
}
|
|
21091
|
-
return new this.Promise((
|
|
21092
|
-
const done = makeDoneCb(
|
|
21091
|
+
return new this.Promise((resolve14, reject) => {
|
|
21092
|
+
const done = makeDoneCb(resolve14, reject, localErr);
|
|
21093
21093
|
if (params !== void 0) {
|
|
21094
21094
|
c.execute(query, params, done);
|
|
21095
21095
|
} else {
|
|
@@ -21098,8 +21098,8 @@ var require_connection2 = __commonJS({
|
|
|
21098
21098
|
});
|
|
21099
21099
|
}
|
|
21100
21100
|
end() {
|
|
21101
|
-
return new this.Promise((
|
|
21102
|
-
this.connection.end(
|
|
21101
|
+
return new this.Promise((resolve14) => {
|
|
21102
|
+
this.connection.end(resolve14);
|
|
21103
21103
|
});
|
|
21104
21104
|
}
|
|
21105
21105
|
async [Symbol.asyncDispose]() {
|
|
@@ -21110,31 +21110,31 @@ var require_connection2 = __commonJS({
|
|
|
21110
21110
|
beginTransaction() {
|
|
21111
21111
|
const c = this.connection;
|
|
21112
21112
|
const localErr = new Error();
|
|
21113
|
-
return new this.Promise((
|
|
21114
|
-
const done = makeDoneCb(
|
|
21113
|
+
return new this.Promise((resolve14, reject) => {
|
|
21114
|
+
const done = makeDoneCb(resolve14, reject, localErr);
|
|
21115
21115
|
c.beginTransaction(done);
|
|
21116
21116
|
});
|
|
21117
21117
|
}
|
|
21118
21118
|
commit() {
|
|
21119
21119
|
const c = this.connection;
|
|
21120
21120
|
const localErr = new Error();
|
|
21121
|
-
return new this.Promise((
|
|
21122
|
-
const done = makeDoneCb(
|
|
21121
|
+
return new this.Promise((resolve14, reject) => {
|
|
21122
|
+
const done = makeDoneCb(resolve14, reject, localErr);
|
|
21123
21123
|
c.commit(done);
|
|
21124
21124
|
});
|
|
21125
21125
|
}
|
|
21126
21126
|
rollback() {
|
|
21127
21127
|
const c = this.connection;
|
|
21128
21128
|
const localErr = new Error();
|
|
21129
|
-
return new this.Promise((
|
|
21130
|
-
const done = makeDoneCb(
|
|
21129
|
+
return new this.Promise((resolve14, reject) => {
|
|
21130
|
+
const done = makeDoneCb(resolve14, reject, localErr);
|
|
21131
21131
|
c.rollback(done);
|
|
21132
21132
|
});
|
|
21133
21133
|
}
|
|
21134
21134
|
ping() {
|
|
21135
21135
|
const c = this.connection;
|
|
21136
21136
|
const localErr = new Error();
|
|
21137
|
-
return new this.Promise((
|
|
21137
|
+
return new this.Promise((resolve14, reject) => {
|
|
21138
21138
|
c.ping((err) => {
|
|
21139
21139
|
if (err) {
|
|
21140
21140
|
localErr.message = err.message;
|
|
@@ -21144,7 +21144,7 @@ var require_connection2 = __commonJS({
|
|
|
21144
21144
|
localErr.sqlMessage = err.sqlMessage;
|
|
21145
21145
|
reject(localErr);
|
|
21146
21146
|
} else {
|
|
21147
|
-
|
|
21147
|
+
resolve14(true);
|
|
21148
21148
|
}
|
|
21149
21149
|
});
|
|
21150
21150
|
});
|
|
@@ -21152,7 +21152,7 @@ var require_connection2 = __commonJS({
|
|
|
21152
21152
|
connect() {
|
|
21153
21153
|
const c = this.connection;
|
|
21154
21154
|
const localErr = new Error();
|
|
21155
|
-
return new this.Promise((
|
|
21155
|
+
return new this.Promise((resolve14, reject) => {
|
|
21156
21156
|
c.connect((err, param) => {
|
|
21157
21157
|
if (err) {
|
|
21158
21158
|
localErr.message = err.message;
|
|
@@ -21162,7 +21162,7 @@ var require_connection2 = __commonJS({
|
|
|
21162
21162
|
localErr.sqlMessage = err.sqlMessage;
|
|
21163
21163
|
reject(localErr);
|
|
21164
21164
|
} else {
|
|
21165
|
-
|
|
21165
|
+
resolve14(param);
|
|
21166
21166
|
}
|
|
21167
21167
|
});
|
|
21168
21168
|
});
|
|
@@ -21171,7 +21171,7 @@ var require_connection2 = __commonJS({
|
|
|
21171
21171
|
const c = this.connection;
|
|
21172
21172
|
const promiseImpl = this.Promise;
|
|
21173
21173
|
const localErr = new Error();
|
|
21174
|
-
return new this.Promise((
|
|
21174
|
+
return new this.Promise((resolve14, reject) => {
|
|
21175
21175
|
c.prepare(options, (err, statement) => {
|
|
21176
21176
|
if (err) {
|
|
21177
21177
|
localErr.message = err.message;
|
|
@@ -21185,7 +21185,7 @@ var require_connection2 = __commonJS({
|
|
|
21185
21185
|
statement,
|
|
21186
21186
|
promiseImpl
|
|
21187
21187
|
);
|
|
21188
|
-
|
|
21188
|
+
resolve14(wrappedStatement);
|
|
21189
21189
|
}
|
|
21190
21190
|
});
|
|
21191
21191
|
});
|
|
@@ -21193,7 +21193,7 @@ var require_connection2 = __commonJS({
|
|
|
21193
21193
|
changeUser(options) {
|
|
21194
21194
|
const c = this.connection;
|
|
21195
21195
|
const localErr = new Error();
|
|
21196
|
-
return new this.Promise((
|
|
21196
|
+
return new this.Promise((resolve14, reject) => {
|
|
21197
21197
|
c.changeUser(options, (err) => {
|
|
21198
21198
|
if (err) {
|
|
21199
21199
|
localErr.message = err.message;
|
|
@@ -21203,7 +21203,7 @@ var require_connection2 = __commonJS({
|
|
|
21203
21203
|
localErr.sqlMessage = err.sqlMessage;
|
|
21204
21204
|
reject(localErr);
|
|
21205
21205
|
} else {
|
|
21206
|
-
|
|
21206
|
+
resolve14();
|
|
21207
21207
|
}
|
|
21208
21208
|
});
|
|
21209
21209
|
});
|
|
@@ -21546,12 +21546,12 @@ var require_pool2 = __commonJS({
|
|
|
21546
21546
|
}
|
|
21547
21547
|
getConnection() {
|
|
21548
21548
|
const corePool = this.pool;
|
|
21549
|
-
return new this.Promise((
|
|
21549
|
+
return new this.Promise((resolve14, reject) => {
|
|
21550
21550
|
corePool.getConnection((err, coreConnection) => {
|
|
21551
21551
|
if (err) {
|
|
21552
21552
|
reject(err);
|
|
21553
21553
|
} else {
|
|
21554
|
-
|
|
21554
|
+
resolve14(new PromisePoolConnection(coreConnection, this.Promise));
|
|
21555
21555
|
}
|
|
21556
21556
|
});
|
|
21557
21557
|
});
|
|
@@ -21567,8 +21567,8 @@ var require_pool2 = __commonJS({
|
|
|
21567
21567
|
"Callback function is not available with promise clients."
|
|
21568
21568
|
);
|
|
21569
21569
|
}
|
|
21570
|
-
return new this.Promise((
|
|
21571
|
-
const done = makeDoneCb(
|
|
21570
|
+
return new this.Promise((resolve14, reject) => {
|
|
21571
|
+
const done = makeDoneCb(resolve14, reject, localErr);
|
|
21572
21572
|
if (args !== void 0) {
|
|
21573
21573
|
corePool.query(sql, args, done);
|
|
21574
21574
|
} else {
|
|
@@ -21584,8 +21584,8 @@ var require_pool2 = __commonJS({
|
|
|
21584
21584
|
"Callback function is not available with promise clients."
|
|
21585
21585
|
);
|
|
21586
21586
|
}
|
|
21587
|
-
return new this.Promise((
|
|
21588
|
-
const done = makeDoneCb(
|
|
21587
|
+
return new this.Promise((resolve14, reject) => {
|
|
21588
|
+
const done = makeDoneCb(resolve14, reject, localErr);
|
|
21589
21589
|
if (args) {
|
|
21590
21590
|
corePool.execute(sql, args, done);
|
|
21591
21591
|
} else {
|
|
@@ -21596,7 +21596,7 @@ var require_pool2 = __commonJS({
|
|
|
21596
21596
|
end() {
|
|
21597
21597
|
const corePool = this.pool;
|
|
21598
21598
|
const localErr = new Error();
|
|
21599
|
-
return new this.Promise((
|
|
21599
|
+
return new this.Promise((resolve14, reject) => {
|
|
21600
21600
|
corePool.end((err) => {
|
|
21601
21601
|
if (err) {
|
|
21602
21602
|
localErr.message = err.message;
|
|
@@ -21606,7 +21606,7 @@ var require_pool2 = __commonJS({
|
|
|
21606
21606
|
localErr.sqlMessage = err.sqlMessage;
|
|
21607
21607
|
reject(localErr);
|
|
21608
21608
|
} else {
|
|
21609
|
-
|
|
21609
|
+
resolve14();
|
|
21610
21610
|
}
|
|
21611
21611
|
});
|
|
21612
21612
|
});
|
|
@@ -22051,12 +22051,12 @@ var require_pool_cluster2 = __commonJS({
|
|
|
22051
22051
|
}
|
|
22052
22052
|
getConnection() {
|
|
22053
22053
|
const corePoolNamespace = this.poolNamespace;
|
|
22054
|
-
return new this.Promise((
|
|
22054
|
+
return new this.Promise((resolve14, reject) => {
|
|
22055
22055
|
corePoolNamespace.getConnection((err, coreConnection) => {
|
|
22056
22056
|
if (err) {
|
|
22057
22057
|
reject(err);
|
|
22058
22058
|
} else {
|
|
22059
|
-
|
|
22059
|
+
resolve14(new PromisePoolConnection(coreConnection, this.Promise));
|
|
22060
22060
|
}
|
|
22061
22061
|
});
|
|
22062
22062
|
});
|
|
@@ -22069,8 +22069,8 @@ var require_pool_cluster2 = __commonJS({
|
|
|
22069
22069
|
"Callback function is not available with promise clients."
|
|
22070
22070
|
);
|
|
22071
22071
|
}
|
|
22072
|
-
return new this.Promise((
|
|
22073
|
-
const done = makeDoneCb(
|
|
22072
|
+
return new this.Promise((resolve14, reject) => {
|
|
22073
|
+
const done = makeDoneCb(resolve14, reject, localErr);
|
|
22074
22074
|
corePoolNamespace.query(sql, values, done);
|
|
22075
22075
|
});
|
|
22076
22076
|
}
|
|
@@ -22082,8 +22082,8 @@ var require_pool_cluster2 = __commonJS({
|
|
|
22082
22082
|
"Callback function is not available with promise clients."
|
|
22083
22083
|
);
|
|
22084
22084
|
}
|
|
22085
|
-
return new this.Promise((
|
|
22086
|
-
const done = makeDoneCb(
|
|
22085
|
+
return new this.Promise((resolve14, reject) => {
|
|
22086
|
+
const done = makeDoneCb(resolve14, reject, localErr);
|
|
22087
22087
|
corePoolNamespace.execute(sql, values, done);
|
|
22088
22088
|
});
|
|
22089
22089
|
}
|
|
@@ -22118,9 +22118,9 @@ var require_promise = __commonJS({
|
|
|
22118
22118
|
"no Promise implementation available.Use promise-enabled node version or pass userland Promise implementation as parameter, for example: { Promise: require('bluebird') }"
|
|
22119
22119
|
);
|
|
22120
22120
|
}
|
|
22121
|
-
return new thePromise((
|
|
22121
|
+
return new thePromise((resolve14, reject) => {
|
|
22122
22122
|
coreConnection.once("connect", () => {
|
|
22123
|
-
|
|
22123
|
+
resolve14(new PromiseConnection(coreConnection, thePromise));
|
|
22124
22124
|
});
|
|
22125
22125
|
coreConnection.once("error", (err) => {
|
|
22126
22126
|
createConnectionErr.message = err.message;
|
|
@@ -22150,7 +22150,7 @@ var require_promise = __commonJS({
|
|
|
22150
22150
|
}
|
|
22151
22151
|
getConnection(pattern, selector) {
|
|
22152
22152
|
const corePoolCluster = this.poolCluster;
|
|
22153
|
-
return new this.Promise((
|
|
22153
|
+
return new this.Promise((resolve14, reject) => {
|
|
22154
22154
|
corePoolCluster.getConnection(
|
|
22155
22155
|
pattern,
|
|
22156
22156
|
selector,
|
|
@@ -22158,7 +22158,7 @@ var require_promise = __commonJS({
|
|
|
22158
22158
|
if (err) {
|
|
22159
22159
|
reject(err);
|
|
22160
22160
|
} else {
|
|
22161
|
-
|
|
22161
|
+
resolve14(new PromisePoolConnection(coreConnection, this.Promise));
|
|
22162
22162
|
}
|
|
22163
22163
|
}
|
|
22164
22164
|
);
|
|
@@ -22172,8 +22172,8 @@ var require_promise = __commonJS({
|
|
|
22172
22172
|
"Callback function is not available with promise clients."
|
|
22173
22173
|
);
|
|
22174
22174
|
}
|
|
22175
|
-
return new this.Promise((
|
|
22176
|
-
const done = makeDoneCb(
|
|
22175
|
+
return new this.Promise((resolve14, reject) => {
|
|
22176
|
+
const done = makeDoneCb(resolve14, reject, localErr);
|
|
22177
22177
|
corePoolCluster.query(sql, args, done);
|
|
22178
22178
|
});
|
|
22179
22179
|
}
|
|
@@ -22185,8 +22185,8 @@ var require_promise = __commonJS({
|
|
|
22185
22185
|
"Callback function is not available with promise clients."
|
|
22186
22186
|
);
|
|
22187
22187
|
}
|
|
22188
|
-
return new this.Promise((
|
|
22189
|
-
const done = makeDoneCb(
|
|
22188
|
+
return new this.Promise((resolve14, reject) => {
|
|
22189
|
+
const done = makeDoneCb(resolve14, reject, localErr);
|
|
22190
22190
|
corePoolCluster.execute(sql, args, done);
|
|
22191
22191
|
});
|
|
22192
22192
|
}
|
|
@@ -22199,7 +22199,7 @@ var require_promise = __commonJS({
|
|
|
22199
22199
|
end() {
|
|
22200
22200
|
const corePoolCluster = this.poolCluster;
|
|
22201
22201
|
const localErr = new Error();
|
|
22202
|
-
return new this.Promise((
|
|
22202
|
+
return new this.Promise((resolve14, reject) => {
|
|
22203
22203
|
corePoolCluster.end((err) => {
|
|
22204
22204
|
if (err) {
|
|
22205
22205
|
localErr.message = err.message;
|
|
@@ -22209,7 +22209,7 @@ var require_promise = __commonJS({
|
|
|
22209
22209
|
localErr.sqlMessage = err.sqlMessage;
|
|
22210
22210
|
reject(localErr);
|
|
22211
22211
|
} else {
|
|
22212
|
-
|
|
22212
|
+
resolve14();
|
|
22213
22213
|
}
|
|
22214
22214
|
});
|
|
22215
22215
|
});
|
|
@@ -31672,15 +31672,92 @@ async function captureDatabase(config, options) {
|
|
|
31672
31672
|
foreignKeyCount: filteredFKs.length
|
|
31673
31673
|
};
|
|
31674
31674
|
const ddl = generateCreateTableDDL(filteredSchema);
|
|
31675
|
+
let aroundFilter;
|
|
31676
|
+
if (options.around) {
|
|
31677
|
+
aroundFilter = /* @__PURE__ */ new Map();
|
|
31678
|
+
const { column: aroundCol, value: aroundVal } = options.around;
|
|
31679
|
+
for (const table of filteredTables) {
|
|
31680
|
+
const hasCol = table.columns.some((c) => c.name === aroundCol);
|
|
31681
|
+
if (hasCol) {
|
|
31682
|
+
aroundFilter.set(table.name, { column: aroundCol, values: /* @__PURE__ */ new Set([aroundVal]) });
|
|
31683
|
+
}
|
|
31684
|
+
}
|
|
31685
|
+
for (const fk of filteredFKs) {
|
|
31686
|
+
const sourceFilter = aroundFilter.get(fk.targetTable);
|
|
31687
|
+
if (sourceFilter && sourceFilter.column === fk.targetColumn) {
|
|
31688
|
+
aroundFilter.set(fk.sourceTable, { column: fk.sourceColumn, values: sourceFilter.values });
|
|
31689
|
+
}
|
|
31690
|
+
}
|
|
31691
|
+
}
|
|
31692
|
+
const detectionsByTable = /* @__PURE__ */ new Map();
|
|
31693
|
+
let piiSummary;
|
|
31694
|
+
if (options.safe) {
|
|
31695
|
+
const mode = "gdpr";
|
|
31696
|
+
for (const table of filteredTables) {
|
|
31697
|
+
const tableForeignKeys = filteredFKs.filter((fk) => fk.sourceTable === table.name);
|
|
31698
|
+
const detections = detectTablePII(table.columns, tableForeignKeys, table.name, mode);
|
|
31699
|
+
detectionsByTable.set(table.name, detections);
|
|
31700
|
+
}
|
|
31701
|
+
let columnsDetected = 0;
|
|
31702
|
+
let tablesAffected = 0;
|
|
31703
|
+
const categoriesFound = /* @__PURE__ */ new Set();
|
|
31704
|
+
for (const [, detections] of detectionsByTable) {
|
|
31705
|
+
const piiCols = detections.filter((d) => d.shouldMask);
|
|
31706
|
+
if (piiCols.length > 0) {
|
|
31707
|
+
tablesAffected++;
|
|
31708
|
+
columnsDetected += piiCols.length;
|
|
31709
|
+
for (const d of piiCols) {
|
|
31710
|
+
categoriesFound.add(d.category);
|
|
31711
|
+
}
|
|
31712
|
+
}
|
|
31713
|
+
}
|
|
31714
|
+
piiSummary = {
|
|
31715
|
+
columnsDetected,
|
|
31716
|
+
tablesAffected,
|
|
31717
|
+
categoriesFound: Array.from(categoriesFound)
|
|
31718
|
+
};
|
|
31719
|
+
}
|
|
31675
31720
|
const packDataset = { tables: {} };
|
|
31676
31721
|
const tableDetails = [];
|
|
31677
31722
|
let totalRows = 0;
|
|
31723
|
+
const safeMode = options.safeMode ?? "mask";
|
|
31724
|
+
const random = options.safe ? createSeededRandom(42) : void 0;
|
|
31725
|
+
const tokenPrefix = options.safe && safeMode === "tokenize" ? generateTokenPrefix() : void 0;
|
|
31678
31726
|
for (const tableName of tablesToCapture) {
|
|
31679
31727
|
const tableSchema = filteredTables.find((t) => t.name === tableName);
|
|
31680
31728
|
if (!tableSchema)
|
|
31681
31729
|
continue;
|
|
31682
31730
|
const columns = tableSchema.columns.map((c) => c.name);
|
|
31683
|
-
|
|
31731
|
+
let rows = await readTableRows(pool, tableName, columns);
|
|
31732
|
+
const filter = aroundFilter?.get(tableName);
|
|
31733
|
+
if (filter) {
|
|
31734
|
+
rows = rows.filter((row) => {
|
|
31735
|
+
const val = row[filter.column];
|
|
31736
|
+
return val !== null && val !== void 0 && filter.values.has(String(val));
|
|
31737
|
+
});
|
|
31738
|
+
}
|
|
31739
|
+
if (options.maxRows !== void 0 && rows.length > options.maxRows) {
|
|
31740
|
+
rows = rows.slice(0, options.maxRows);
|
|
31741
|
+
}
|
|
31742
|
+
if (options.safe) {
|
|
31743
|
+
const detections = detectionsByTable.get(tableName);
|
|
31744
|
+
if (detections) {
|
|
31745
|
+
const hasPII = detections.some((d) => d.shouldMask);
|
|
31746
|
+
if (hasPII) {
|
|
31747
|
+
if (safeMode === "tokenize" && tokenPrefix) {
|
|
31748
|
+
const { tokenizedRows } = tokenizeTableRows(rows, detections, tableName, tokenPrefix);
|
|
31749
|
+
rows = tokenizedRows;
|
|
31750
|
+
} else if (safeMode === "redact") {
|
|
31751
|
+
const redactDetections = detections.map((d) => d.shouldMask ? { ...d, maskStrategy: "redact" } : d);
|
|
31752
|
+
const { maskedRows } = maskTableRows(rows, redactDetections, random, tableName);
|
|
31753
|
+
rows = maskedRows;
|
|
31754
|
+
} else {
|
|
31755
|
+
const { maskedRows } = maskTableRows(rows, detections, random, tableName);
|
|
31756
|
+
rows = maskedRows;
|
|
31757
|
+
}
|
|
31758
|
+
}
|
|
31759
|
+
}
|
|
31760
|
+
}
|
|
31684
31761
|
const rowCount = rows.length;
|
|
31685
31762
|
packDataset.tables[tableName] = {
|
|
31686
31763
|
columns,
|
|
@@ -31725,6 +31802,7 @@ async function captureDatabase(config, options) {
|
|
|
31725
31802
|
}
|
|
31726
31803
|
};
|
|
31727
31804
|
const masked = maskConnection(config.database.connectionString);
|
|
31805
|
+
const safeModeValue = options.safe ? safeMode === "tokenize" ? "tokenized" : safeMode === "redact" ? "redacted" : "masked" : "raw";
|
|
31728
31806
|
const pack = {
|
|
31729
31807
|
format: "realitydb-pack",
|
|
31730
31808
|
version: "1.0",
|
|
@@ -31736,7 +31814,9 @@ async function captureDatabase(config, options) {
|
|
|
31736
31814
|
totalRows,
|
|
31737
31815
|
tableCount: tablesToCapture.length,
|
|
31738
31816
|
ddl,
|
|
31739
|
-
capturedFrom: masked
|
|
31817
|
+
capturedFrom: masked,
|
|
31818
|
+
safeMode: safeModeValue,
|
|
31819
|
+
piiSummary
|
|
31740
31820
|
},
|
|
31741
31821
|
schema: packSchema,
|
|
31742
31822
|
plan,
|
|
@@ -31751,7 +31831,8 @@ async function captureDatabase(config, options) {
|
|
|
31751
31831
|
totalRows,
|
|
31752
31832
|
tableCount: tablesToCapture.length,
|
|
31753
31833
|
durationMs,
|
|
31754
|
-
tableDetails
|
|
31834
|
+
tableDetails,
|
|
31835
|
+
piiSummary
|
|
31755
31836
|
};
|
|
31756
31837
|
} finally {
|
|
31757
31838
|
await closeConnection(pool);
|
|
@@ -31779,7 +31860,7 @@ async function uploadToGist(content, options) {
|
|
|
31779
31860
|
[options.filename]: { content }
|
|
31780
31861
|
}
|
|
31781
31862
|
});
|
|
31782
|
-
return new Promise((
|
|
31863
|
+
return new Promise((resolve14, reject) => {
|
|
31783
31864
|
const req = import_node_https.default.request({
|
|
31784
31865
|
hostname: "api.github.com",
|
|
31785
31866
|
path: "/gists",
|
|
@@ -31801,7 +31882,7 @@ async function uploadToGist(content, options) {
|
|
|
31801
31882
|
try {
|
|
31802
31883
|
const parsed = JSON.parse(data);
|
|
31803
31884
|
const fileEntry = parsed.files[options.filename];
|
|
31804
|
-
|
|
31885
|
+
resolve14({
|
|
31805
31886
|
url: parsed.html_url,
|
|
31806
31887
|
rawUrl: fileEntry?.raw_url ?? parsed.html_url,
|
|
31807
31888
|
gistId: parsed.id
|
|
@@ -31928,7 +32009,7 @@ function fetchUrl(url, redirectCount = 0) {
|
|
|
31928
32009
|
throw new Error("Too many redirects");
|
|
31929
32010
|
}
|
|
31930
32011
|
const lib = url.startsWith("https") ? import_node_https2.default : import_node_http.default;
|
|
31931
|
-
return new Promise((
|
|
32012
|
+
return new Promise((resolve14, reject) => {
|
|
31932
32013
|
const req = lib.get(url, {
|
|
31933
32014
|
headers: {
|
|
31934
32015
|
"User-Agent": "realitydb-cli",
|
|
@@ -31936,7 +32017,7 @@ function fetchUrl(url, redirectCount = 0) {
|
|
|
31936
32017
|
}
|
|
31937
32018
|
}, (res) => {
|
|
31938
32019
|
if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
31939
|
-
|
|
32020
|
+
resolve14(fetchUrl(res.headers.location, redirectCount + 1));
|
|
31940
32021
|
return;
|
|
31941
32022
|
}
|
|
31942
32023
|
if (res.statusCode && (res.statusCode < 200 || res.statusCode >= 300)) {
|
|
@@ -31949,7 +32030,7 @@ function fetchUrl(url, redirectCount = 0) {
|
|
|
31949
32030
|
});
|
|
31950
32031
|
res.on("end", () => {
|
|
31951
32032
|
const buffer = Buffer.concat(chunks);
|
|
31952
|
-
|
|
32033
|
+
resolve14(buffer.toString("utf-8"));
|
|
31953
32034
|
});
|
|
31954
32035
|
});
|
|
31955
32036
|
req.on("error", (err) => {
|
|
@@ -32457,9 +32538,9 @@ var DEFAULT_CONNECTIONS = {
|
|
|
32457
32538
|
};
|
|
32458
32539
|
var SUPPORTED_CLIENTS = ["postgres", "mysql"];
|
|
32459
32540
|
function ask(rl, prompt) {
|
|
32460
|
-
return new Promise((
|
|
32541
|
+
return new Promise((resolve14) => {
|
|
32461
32542
|
rl.question(prompt, (answer) => {
|
|
32462
|
-
|
|
32543
|
+
resolve14(answer);
|
|
32463
32544
|
});
|
|
32464
32545
|
});
|
|
32465
32546
|
}
|
|
@@ -33737,6 +33818,18 @@ async function captureCommand(options) {
|
|
|
33737
33818
|
const config = await loadConfig(options.configPath);
|
|
33738
33819
|
const masked = maskConnectionString(config.database.connectionString);
|
|
33739
33820
|
const tables = options.tables ? options.tables.split(",").map((t) => t.trim()).filter((t) => t.length > 0) : void 0;
|
|
33821
|
+
const safeMode = options.safe ? ["mask", "tokenize", "redact"].includes(options.safeMode ?? "") ? options.safeMode : "mask" : void 0;
|
|
33822
|
+
const maxRows = options.maxRows ? parseInt(options.maxRows, 10) : void 0;
|
|
33823
|
+
let around;
|
|
33824
|
+
if (options.around) {
|
|
33825
|
+
const eqIdx = options.around.indexOf("=");
|
|
33826
|
+
if (eqIdx > 0) {
|
|
33827
|
+
around = {
|
|
33828
|
+
column: options.around.substring(0, eqIdx),
|
|
33829
|
+
value: options.around.substring(eqIdx + 1)
|
|
33830
|
+
};
|
|
33831
|
+
}
|
|
33832
|
+
}
|
|
33740
33833
|
if (!options.ci) {
|
|
33741
33834
|
console.log("");
|
|
33742
33835
|
console.log("RealityDB Capture");
|
|
@@ -33746,6 +33839,15 @@ async function captureCommand(options) {
|
|
|
33746
33839
|
if (tables) {
|
|
33747
33840
|
console.log(`Tables: ${tables.join(", ")}`);
|
|
33748
33841
|
}
|
|
33842
|
+
if (options.safe) {
|
|
33843
|
+
console.log(`Safe mode: ${safeMode} (PII will be sanitized)`);
|
|
33844
|
+
}
|
|
33845
|
+
if (maxRows !== void 0) {
|
|
33846
|
+
console.log(`Max rows per table: ${maxRows}`);
|
|
33847
|
+
}
|
|
33848
|
+
if (around) {
|
|
33849
|
+
console.log("");
|
|
33850
|
+
}
|
|
33749
33851
|
console.log("");
|
|
33750
33852
|
console.log("Capturing...");
|
|
33751
33853
|
}
|
|
@@ -33753,7 +33855,11 @@ async function captureCommand(options) {
|
|
|
33753
33855
|
name: options.name,
|
|
33754
33856
|
description: options.description,
|
|
33755
33857
|
tables,
|
|
33756
|
-
outputDir: options.output
|
|
33858
|
+
outputDir: options.output,
|
|
33859
|
+
safe: options.safe,
|
|
33860
|
+
safeMode,
|
|
33861
|
+
maxRows,
|
|
33862
|
+
around
|
|
33757
33863
|
});
|
|
33758
33864
|
const durationMs = Math.round(performance.now() - start);
|
|
33759
33865
|
if (options.ci) {
|
|
@@ -33769,6 +33875,8 @@ async function captureCommand(options) {
|
|
|
33769
33875
|
filePath: result.filePath,
|
|
33770
33876
|
tableCount: result.tableCount,
|
|
33771
33877
|
totalRows: result.totalRows,
|
|
33878
|
+
safeMode: result.pack.metadata.safeMode,
|
|
33879
|
+
piiSummary: result.piiSummary,
|
|
33772
33880
|
tables: result.tableDetails.map((t) => ({
|
|
33773
33881
|
name: t.name,
|
|
33774
33882
|
rowCount: t.rowCount
|
|
@@ -33778,6 +33886,21 @@ async function captureCommand(options) {
|
|
|
33778
33886
|
}));
|
|
33779
33887
|
return;
|
|
33780
33888
|
}
|
|
33889
|
+
if (options.safe && result.piiSummary) {
|
|
33890
|
+
const { columnsDetected, tablesAffected, categoriesFound } = result.piiSummary;
|
|
33891
|
+
if (columnsDetected > 0) {
|
|
33892
|
+
console.log(`PII detected: ${columnsDetected} columns across ${tablesAffected} tables. Sanitizing...`);
|
|
33893
|
+
console.log(` Categories: ${categoriesFound.join(", ")}`);
|
|
33894
|
+
console.log("");
|
|
33895
|
+
} else {
|
|
33896
|
+
console.log("No PII detected \u2014 data captured as-is.");
|
|
33897
|
+
console.log("");
|
|
33898
|
+
}
|
|
33899
|
+
}
|
|
33900
|
+
if (around) {
|
|
33901
|
+
console.log(`Capturing rows related to ${around.column}=${around.value} across ${result.tableCount} tables`);
|
|
33902
|
+
console.log("");
|
|
33903
|
+
}
|
|
33781
33904
|
for (const table of result.tableDetails) {
|
|
33782
33905
|
console.log(` ${table.name}: ${table.rowCount} rows`);
|
|
33783
33906
|
}
|
|
@@ -33785,6 +33908,9 @@ async function captureCommand(options) {
|
|
|
33785
33908
|
const sizeKb = Math.round(fileStat.size / 1024);
|
|
33786
33909
|
console.log("");
|
|
33787
33910
|
console.log(`Captured: ${result.filePath} (${sizeKb} KB)`);
|
|
33911
|
+
if (options.safe) {
|
|
33912
|
+
console.log(`Privacy: PII sanitized (${safeMode} mode). Safe to share.`);
|
|
33913
|
+
}
|
|
33788
33914
|
console.log("Schema DDL included. Share this file to reproduce the environment.");
|
|
33789
33915
|
console.log("");
|
|
33790
33916
|
} catch (err) {
|
|
@@ -33915,6 +34041,19 @@ var VERSION9 = "0.10.0";
|
|
|
33915
34041
|
function isUrl(input) {
|
|
33916
34042
|
return input.startsWith("http://") || input.startsWith("https://");
|
|
33917
34043
|
}
|
|
34044
|
+
function displaySafeModeStatus(safeMode) {
|
|
34045
|
+
if (!safeMode) {
|
|
34046
|
+
console.warn("Note: This pack was captured before privacy-safe mode was available");
|
|
34047
|
+
} else if (safeMode === "raw") {
|
|
34048
|
+
console.log("WARNING: This pack contains raw (unsanitized) data");
|
|
34049
|
+
} else if (safeMode === "masked") {
|
|
34050
|
+
console.log("This pack was captured with PII masking");
|
|
34051
|
+
} else if (safeMode === "tokenized") {
|
|
34052
|
+
console.log("This pack was captured with PII tokenization");
|
|
34053
|
+
} else if (safeMode === "redacted") {
|
|
34054
|
+
console.log("This pack was captured with PII redaction");
|
|
34055
|
+
}
|
|
34056
|
+
}
|
|
33918
34057
|
async function loadCommand(filePath, options) {
|
|
33919
34058
|
const start = performance.now();
|
|
33920
34059
|
try {
|
|
@@ -33950,6 +34089,57 @@ async function loadCommand(filePath, options) {
|
|
|
33950
34089
|
}
|
|
33951
34090
|
}
|
|
33952
34091
|
const pack = await loadRealityPack(localPath);
|
|
34092
|
+
if (options.preview) {
|
|
34093
|
+
const meta2 = pack.metadata;
|
|
34094
|
+
const safeMode2 = meta2.safeMode;
|
|
34095
|
+
const piiSummary = meta2.piiSummary;
|
|
34096
|
+
if (options.ci) {
|
|
34097
|
+
const tableNames = Object.keys(pack.dataset.tables);
|
|
34098
|
+
const tableInfo = tableNames.map((name) => ({
|
|
34099
|
+
name,
|
|
34100
|
+
rowCount: pack.dataset.tables[name].rowCount
|
|
34101
|
+
}));
|
|
34102
|
+
console.log(formatCIOutput({
|
|
34103
|
+
success: true,
|
|
34104
|
+
command: "load",
|
|
34105
|
+
version: VERSION9,
|
|
34106
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34107
|
+
durationMs: Math.round(performance.now() - start),
|
|
34108
|
+
data: {
|
|
34109
|
+
packName: pack.metadata.name,
|
|
34110
|
+
safeMode: safeMode2 ?? null,
|
|
34111
|
+
piiSummary: piiSummary ?? null,
|
|
34112
|
+
tableCount: pack.metadata.tableCount,
|
|
34113
|
+
totalRows: pack.metadata.totalRows,
|
|
34114
|
+
tables: tableInfo
|
|
34115
|
+
}
|
|
34116
|
+
}));
|
|
34117
|
+
return;
|
|
34118
|
+
}
|
|
34119
|
+
console.log("");
|
|
34120
|
+
console.log("Reality Pack Preview");
|
|
34121
|
+
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");
|
|
34122
|
+
console.log(`Name: ${pack.metadata.name}`);
|
|
34123
|
+
if (pack.metadata.description) {
|
|
34124
|
+
console.log(`Description: ${pack.metadata.description}`);
|
|
34125
|
+
}
|
|
34126
|
+
console.log(`Tables: ${pack.metadata.tableCount}`);
|
|
34127
|
+
console.log(`Total rows: ${pack.metadata.totalRows}`);
|
|
34128
|
+
console.log("");
|
|
34129
|
+
displaySafeModeStatus(safeMode2);
|
|
34130
|
+
if (piiSummary) {
|
|
34131
|
+
console.log(` PII columns detected: ${piiSummary.columnsDetected}`);
|
|
34132
|
+
console.log(` Tables affected: ${piiSummary.tablesAffected}`);
|
|
34133
|
+
console.log(` Categories: ${piiSummary.categoriesFound.join(", ")}`);
|
|
34134
|
+
}
|
|
34135
|
+
console.log("");
|
|
34136
|
+
console.log("Tables:");
|
|
34137
|
+
for (const [name, tableData] of Object.entries(pack.dataset.tables)) {
|
|
34138
|
+
console.log(` ${name}: ${tableData.rowCount} rows`);
|
|
34139
|
+
}
|
|
34140
|
+
console.log("");
|
|
34141
|
+
return;
|
|
34142
|
+
}
|
|
33953
34143
|
if (options.showDdl) {
|
|
33954
34144
|
const ddl = pack.metadata.ddl;
|
|
33955
34145
|
if (options.ci) {
|
|
@@ -33982,6 +34172,8 @@ async function loadCommand(filePath, options) {
|
|
|
33982
34172
|
}
|
|
33983
34173
|
const config = await loadConfig(options.configPath);
|
|
33984
34174
|
const masked = maskConnectionString(config.database.connectionString);
|
|
34175
|
+
const meta = pack.metadata;
|
|
34176
|
+
const safeMode = meta.safeMode;
|
|
33985
34177
|
if (!options.ci) {
|
|
33986
34178
|
console.log("");
|
|
33987
34179
|
console.log("RealityDB Load");
|
|
@@ -34001,6 +34193,8 @@ async function loadCommand(filePath, options) {
|
|
|
34001
34193
|
console.log("Schema DDL: included");
|
|
34002
34194
|
}
|
|
34003
34195
|
console.log("");
|
|
34196
|
+
displaySafeModeStatus(safeMode);
|
|
34197
|
+
console.log("");
|
|
34004
34198
|
}
|
|
34005
34199
|
if (!options.ci && !options.confirm) {
|
|
34006
34200
|
console.error("[realitydb] Load requires --confirm flag.");
|
|
@@ -34008,6 +34202,9 @@ async function loadCommand(filePath, options) {
|
|
|
34008
34202
|
console.error("");
|
|
34009
34203
|
console.error("To view the schema DDL first:");
|
|
34010
34204
|
console.error(` realitydb load ${filePath} --show-ddl`);
|
|
34205
|
+
console.error("");
|
|
34206
|
+
console.error("To preview pack contents:");
|
|
34207
|
+
console.error(` realitydb load ${filePath} --preview`);
|
|
34011
34208
|
process.exit(1);
|
|
34012
34209
|
}
|
|
34013
34210
|
if (!options.ci) {
|
|
@@ -34026,6 +34223,7 @@ async function loadCommand(filePath, options) {
|
|
|
34026
34223
|
database: masked,
|
|
34027
34224
|
packName: pack.metadata.name,
|
|
34028
34225
|
totalRows: result.totalRows,
|
|
34226
|
+
safeMode: safeMode ?? null,
|
|
34029
34227
|
source: isUrl(filePath) ? filePath : void 0,
|
|
34030
34228
|
tables: result.insertResult.tables.map((t) => ({
|
|
34031
34229
|
name: t.tableName,
|
|
@@ -34043,7 +34241,8 @@ async function loadCommand(filePath, options) {
|
|
|
34043
34241
|
}
|
|
34044
34242
|
const totalTime = (result.durationMs / 1e3).toFixed(1);
|
|
34045
34243
|
console.log("");
|
|
34046
|
-
console.log(`
|
|
34244
|
+
console.log(`Bug reproduction environment ready. ${result.insertResult.tables.length} tables, ${result.totalRows} rows loaded.`);
|
|
34245
|
+
console.log(`Load complete in ${totalTime}s`);
|
|
34047
34246
|
console.log("");
|
|
34048
34247
|
} catch (err) {
|
|
34049
34248
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -34418,12 +34617,396 @@ async function analyzeCommand(options) {
|
|
|
34418
34617
|
}
|
|
34419
34618
|
}
|
|
34420
34619
|
|
|
34421
|
-
// src/commands/
|
|
34620
|
+
// src/commands/run.ts
|
|
34422
34621
|
var import_node_fs12 = require("fs");
|
|
34423
34622
|
var import_node_path17 = require("path");
|
|
34623
|
+
var VERSION13 = "1.0.0";
|
|
34624
|
+
function strategyToSqlType(strategy) {
|
|
34625
|
+
switch (strategy) {
|
|
34626
|
+
case "uuid":
|
|
34627
|
+
case "foreign_key":
|
|
34628
|
+
return { dataType: "UUID", maxLength: null, numericPrecision: null, numericScale: null };
|
|
34629
|
+
case "full_name":
|
|
34630
|
+
case "first_name":
|
|
34631
|
+
case "last_name":
|
|
34632
|
+
case "email":
|
|
34633
|
+
case "phone":
|
|
34634
|
+
case "text":
|
|
34635
|
+
case "company_name":
|
|
34636
|
+
case "address":
|
|
34637
|
+
case "custom":
|
|
34638
|
+
return { dataType: "VARCHAR", maxLength: 255, numericPrecision: null, numericScale: null };
|
|
34639
|
+
case "integer":
|
|
34640
|
+
case "auto_increment":
|
|
34641
|
+
return { dataType: "INTEGER", maxLength: null, numericPrecision: null, numericScale: null };
|
|
34642
|
+
case "float":
|
|
34643
|
+
case "money":
|
|
34644
|
+
return { dataType: "NUMERIC", maxLength: null, numericPrecision: 12, numericScale: 2 };
|
|
34645
|
+
case "boolean":
|
|
34646
|
+
return { dataType: "BOOLEAN", maxLength: null, numericPrecision: null, numericScale: null };
|
|
34647
|
+
case "timestamp":
|
|
34648
|
+
return { dataType: "TIMESTAMPTZ", maxLength: null, numericPrecision: null, numericScale: null };
|
|
34649
|
+
case "enum":
|
|
34650
|
+
return { dataType: "VARCHAR", maxLength: 50, numericPrecision: null, numericScale: null };
|
|
34651
|
+
default:
|
|
34652
|
+
return { dataType: "VARCHAR", maxLength: 255, numericPrecision: null, numericScale: null };
|
|
34653
|
+
}
|
|
34654
|
+
}
|
|
34655
|
+
function collectNullableFromLifecycle(columns) {
|
|
34656
|
+
const nullableFields = /* @__PURE__ */ new Set();
|
|
34657
|
+
for (const col of Object.values(columns)) {
|
|
34658
|
+
const opts = col.options;
|
|
34659
|
+
if (opts?.lifecycleRules && Array.isArray(opts.lifecycleRules)) {
|
|
34660
|
+
for (const rule of opts.lifecycleRules) {
|
|
34661
|
+
const r = rule;
|
|
34662
|
+
if (r.nullFields) {
|
|
34663
|
+
for (const f of r.nullFields) {
|
|
34664
|
+
nullableFields.add(f);
|
|
34665
|
+
}
|
|
34666
|
+
}
|
|
34667
|
+
}
|
|
34668
|
+
}
|
|
34669
|
+
}
|
|
34670
|
+
return nullableFields;
|
|
34671
|
+
}
|
|
34672
|
+
function extractSchemaFromTemplate(template) {
|
|
34673
|
+
const tables = [];
|
|
34674
|
+
const foreignKeys = [];
|
|
34675
|
+
for (const [tableName, tableJson] of Object.entries(template.tables)) {
|
|
34676
|
+
const lifecycleNullable = collectNullableFromLifecycle(tableJson.columns);
|
|
34677
|
+
const columns = [];
|
|
34678
|
+
let ordinal = 1;
|
|
34679
|
+
for (const [colName, colJson] of Object.entries(tableJson.columns)) {
|
|
34680
|
+
const strategy = colJson.foreignKey ? "foreign_key" : colJson.strategy;
|
|
34681
|
+
const typeInfo = strategyToSqlType(strategy);
|
|
34682
|
+
const isPK = strategy === "uuid" && colName === "id";
|
|
34683
|
+
const isNullable = lifecycleNullable.has(colName);
|
|
34684
|
+
columns.push({
|
|
34685
|
+
name: colName,
|
|
34686
|
+
dataType: typeInfo.dataType,
|
|
34687
|
+
udtName: typeInfo.dataType.toLowerCase(),
|
|
34688
|
+
isNullable: isPK ? false : isNullable,
|
|
34689
|
+
hasDefault: false,
|
|
34690
|
+
defaultValue: null,
|
|
34691
|
+
maxLength: typeInfo.maxLength,
|
|
34692
|
+
numericPrecision: typeInfo.numericPrecision,
|
|
34693
|
+
numericScale: typeInfo.numericScale,
|
|
34694
|
+
isPrimaryKey: isPK,
|
|
34695
|
+
isUnique: isPK,
|
|
34696
|
+
ordinalPosition: ordinal++
|
|
34697
|
+
});
|
|
34698
|
+
if (colJson.foreignKey) {
|
|
34699
|
+
foreignKeys.push({
|
|
34700
|
+
constraintName: `fk_${tableName}_${colName}`,
|
|
34701
|
+
sourceTable: tableName,
|
|
34702
|
+
sourceColumn: colName,
|
|
34703
|
+
targetTable: colJson.foreignKey.table,
|
|
34704
|
+
targetColumn: colJson.foreignKey.column
|
|
34705
|
+
});
|
|
34706
|
+
}
|
|
34707
|
+
}
|
|
34708
|
+
tables.push({
|
|
34709
|
+
name: tableName,
|
|
34710
|
+
schema: "public",
|
|
34711
|
+
columns,
|
|
34712
|
+
primaryKey: columns.find((c) => c.isPrimaryKey) ? { columnName: "id", constraintName: `pk_${tableName}` } : null,
|
|
34713
|
+
estimatedRowCount: 0
|
|
34714
|
+
});
|
|
34715
|
+
}
|
|
34716
|
+
return {
|
|
34717
|
+
tables,
|
|
34718
|
+
foreignKeys,
|
|
34719
|
+
tableCount: tables.length,
|
|
34720
|
+
foreignKeyCount: foreignKeys.length
|
|
34721
|
+
};
|
|
34722
|
+
}
|
|
34723
|
+
function getDropOrder(schema) {
|
|
34724
|
+
const createOrder = getCreateOrder(schema);
|
|
34725
|
+
return [...createOrder].reverse();
|
|
34726
|
+
}
|
|
34727
|
+
function getCreateOrder(schema) {
|
|
34728
|
+
const tableNames = new Set(schema.tables.map((t) => t.name));
|
|
34729
|
+
const deps = /* @__PURE__ */ new Map();
|
|
34730
|
+
for (const name of tableNames) {
|
|
34731
|
+
deps.set(name, /* @__PURE__ */ new Set());
|
|
34732
|
+
}
|
|
34733
|
+
for (const fk of schema.foreignKeys) {
|
|
34734
|
+
if (fk.sourceTable !== fk.targetTable && tableNames.has(fk.targetTable)) {
|
|
34735
|
+
deps.get(fk.sourceTable).add(fk.targetTable);
|
|
34736
|
+
}
|
|
34737
|
+
}
|
|
34738
|
+
const result = [];
|
|
34739
|
+
const visited = /* @__PURE__ */ new Set();
|
|
34740
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
34741
|
+
function visit(name) {
|
|
34742
|
+
if (visited.has(name)) return;
|
|
34743
|
+
if (visiting.has(name)) return;
|
|
34744
|
+
visiting.add(name);
|
|
34745
|
+
for (const dep of deps.get(name) ?? []) {
|
|
34746
|
+
visit(dep);
|
|
34747
|
+
}
|
|
34748
|
+
visiting.delete(name);
|
|
34749
|
+
visited.add(name);
|
|
34750
|
+
result.push(name);
|
|
34751
|
+
}
|
|
34752
|
+
for (const name of tableNames) {
|
|
34753
|
+
visit(name);
|
|
34754
|
+
}
|
|
34755
|
+
return result;
|
|
34756
|
+
}
|
|
34757
|
+
async function runCommand(options) {
|
|
34758
|
+
const start = performance.now();
|
|
34759
|
+
const packPath = (0, import_node_path17.resolve)(options.pack);
|
|
34760
|
+
const masked = maskConnectionString(options.connection);
|
|
34761
|
+
const records = options.records ? parseInt(options.records, 10) : void 0;
|
|
34762
|
+
const seed = options.seed ? parseInt(options.seed, 10) : void 0;
|
|
34763
|
+
if (!(0, import_node_fs12.existsSync)(packPath)) {
|
|
34764
|
+
const msg = `Pack file not found: ${packPath}`;
|
|
34765
|
+
if (options.ci) {
|
|
34766
|
+
console.log(formatCIOutput({ success: false, command: "run", version: VERSION13, timestamp: (/* @__PURE__ */ new Date()).toISOString(), durationMs: 0, error: msg }));
|
|
34767
|
+
process.exit(1);
|
|
34768
|
+
}
|
|
34769
|
+
console.error(`[realitydb] ${msg}`);
|
|
34770
|
+
console.error("Hint: Provide the path to a Studio-exported template JSON file.");
|
|
34771
|
+
process.exit(1);
|
|
34772
|
+
}
|
|
34773
|
+
let raw;
|
|
34774
|
+
try {
|
|
34775
|
+
raw = (0, import_node_fs12.readFileSync)(packPath, "utf-8");
|
|
34776
|
+
} catch (err) {
|
|
34777
|
+
const msg = `Cannot read pack file: ${err instanceof Error ? err.message : String(err)}`;
|
|
34778
|
+
if (options.ci) {
|
|
34779
|
+
console.log(formatCIOutput({ success: false, command: "run", version: VERSION13, timestamp: (/* @__PURE__ */ new Date()).toISOString(), durationMs: 0, error: msg }));
|
|
34780
|
+
process.exit(1);
|
|
34781
|
+
}
|
|
34782
|
+
console.error(`[realitydb] ${msg}`);
|
|
34783
|
+
process.exit(1);
|
|
34784
|
+
}
|
|
34785
|
+
let json;
|
|
34786
|
+
try {
|
|
34787
|
+
json = JSON.parse(raw);
|
|
34788
|
+
} catch {
|
|
34789
|
+
const msg = `Pack file is not valid JSON: ${packPath}`;
|
|
34790
|
+
if (options.ci) {
|
|
34791
|
+
console.log(formatCIOutput({ success: false, command: "run", version: VERSION13, timestamp: (/* @__PURE__ */ new Date()).toISOString(), durationMs: 0, error: msg }));
|
|
34792
|
+
process.exit(1);
|
|
34793
|
+
}
|
|
34794
|
+
console.error(`[realitydb] ${msg}`);
|
|
34795
|
+
console.error("Hint: Ensure the file is a valid Studio-exported template JSON.");
|
|
34796
|
+
process.exit(1);
|
|
34797
|
+
}
|
|
34798
|
+
let template;
|
|
34799
|
+
try {
|
|
34800
|
+
template = assertValidTemplate(json);
|
|
34801
|
+
} catch (err) {
|
|
34802
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
34803
|
+
if (options.ci) {
|
|
34804
|
+
console.log(formatCIOutput({ success: false, command: "run", version: VERSION13, timestamp: (/* @__PURE__ */ new Date()).toISOString(), durationMs: 0, error: msg }));
|
|
34805
|
+
process.exit(1);
|
|
34806
|
+
}
|
|
34807
|
+
console.error(`[realitydb] ${msg}`);
|
|
34808
|
+
process.exit(1);
|
|
34809
|
+
}
|
|
34810
|
+
const schema = extractSchemaFromTemplate(template);
|
|
34811
|
+
const ddl = generateCreateTableDDL(schema);
|
|
34812
|
+
const effectiveRecords = records ?? template.generationConfig?.seed?.defaultRecords ?? 1e3;
|
|
34813
|
+
const effectiveSeed = seed ?? template.generationConfig?.seed?.randomSeed ?? 42;
|
|
34814
|
+
if (!options.ci) {
|
|
34815
|
+
console.log("");
|
|
34816
|
+
console.log("RealityDB Run");
|
|
34817
|
+
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");
|
|
34818
|
+
console.log(`Pack: ${packPath}`);
|
|
34819
|
+
console.log(`Database: ${masked}`);
|
|
34820
|
+
console.log(`Records per table: ${effectiveRecords}`);
|
|
34821
|
+
console.log(`Seed: ${effectiveSeed}`);
|
|
34822
|
+
if (options.dropExisting) console.log("Drop existing: yes");
|
|
34823
|
+
if (options.dryRun) console.log("Mode: dry run");
|
|
34824
|
+
console.log("");
|
|
34825
|
+
}
|
|
34826
|
+
if (options.dryRun) {
|
|
34827
|
+
if (options.ci) {
|
|
34828
|
+
const tableNames = Object.keys(template.tables);
|
|
34829
|
+
const planSummary = tableNames.map((name) => ({
|
|
34830
|
+
table: name,
|
|
34831
|
+
columns: Object.keys(template.tables[name].columns).length,
|
|
34832
|
+
records: effectiveRecords
|
|
34833
|
+
}));
|
|
34834
|
+
console.log(formatCIOutput({
|
|
34835
|
+
success: true,
|
|
34836
|
+
command: "run",
|
|
34837
|
+
version: VERSION13,
|
|
34838
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34839
|
+
durationMs: Math.round(performance.now() - start),
|
|
34840
|
+
data: { dryRun: true, ddl, plan: planSummary }
|
|
34841
|
+
}));
|
|
34842
|
+
return;
|
|
34843
|
+
}
|
|
34844
|
+
console.log("DDL that would be executed:");
|
|
34845
|
+
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
34846
|
+
if (options.dropExisting) {
|
|
34847
|
+
const dropOrder = getDropOrder(schema);
|
|
34848
|
+
for (const tableName of dropOrder) {
|
|
34849
|
+
console.log(`DROP TABLE IF EXISTS "${tableName}" CASCADE;`);
|
|
34850
|
+
}
|
|
34851
|
+
console.log("");
|
|
34852
|
+
}
|
|
34853
|
+
console.log(ddl);
|
|
34854
|
+
console.log("Generation Plan:");
|
|
34855
|
+
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
34856
|
+
for (const [tableName, tableJson] of Object.entries(template.tables)) {
|
|
34857
|
+
const colCount = Object.keys(tableJson.columns).length;
|
|
34858
|
+
const strategies = Object.values(tableJson.columns).map((c) => c.strategy);
|
|
34859
|
+
const uniqueStrategies = [...new Set(strategies)].join(", ");
|
|
34860
|
+
console.log(` ${tableName}: ${effectiveRecords} rows, ${colCount} columns [${uniqueStrategies}]`);
|
|
34861
|
+
}
|
|
34862
|
+
console.log("");
|
|
34863
|
+
console.log("Dry run complete. No changes were made.");
|
|
34864
|
+
return;
|
|
34865
|
+
}
|
|
34866
|
+
const clientType = template.generationConfig?.database?.client ?? "postgres";
|
|
34867
|
+
const pool = createDatabaseClient(clientType, options.connection);
|
|
34868
|
+
try {
|
|
34869
|
+
try {
|
|
34870
|
+
await testConnection(pool);
|
|
34871
|
+
} catch (err) {
|
|
34872
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
34873
|
+
if (options.ci) {
|
|
34874
|
+
console.log(formatCIOutput({ success: false, command: "run", version: VERSION13, timestamp: (/* @__PURE__ */ new Date()).toISOString(), durationMs: Math.round(performance.now() - start), error: msg }));
|
|
34875
|
+
process.exit(1);
|
|
34876
|
+
}
|
|
34877
|
+
console.error(`[realitydb] Cannot connect to database: ${msg}`);
|
|
34878
|
+
console.error("Hint: Check your connection string and ensure the database is running.");
|
|
34879
|
+
process.exit(1);
|
|
34880
|
+
}
|
|
34881
|
+
if (!options.dropExisting) {
|
|
34882
|
+
const existingTables = [];
|
|
34883
|
+
for (const table of schema.tables) {
|
|
34884
|
+
try {
|
|
34885
|
+
const client = await pool.connect();
|
|
34886
|
+
try {
|
|
34887
|
+
const result2 = await client.query(
|
|
34888
|
+
`SELECT to_regclass('"${table.name}"') AS exists_check`
|
|
34889
|
+
);
|
|
34890
|
+
if (result2.rows[0]?.exists_check) {
|
|
34891
|
+
existingTables.push(table.name);
|
|
34892
|
+
}
|
|
34893
|
+
} finally {
|
|
34894
|
+
client.release();
|
|
34895
|
+
}
|
|
34896
|
+
} catch {
|
|
34897
|
+
}
|
|
34898
|
+
}
|
|
34899
|
+
if (existingTables.length > 0) {
|
|
34900
|
+
const msg = `Tables already exist: ${existingTables.join(", ")}. Use --drop-existing to recreate them.`;
|
|
34901
|
+
if (options.ci) {
|
|
34902
|
+
console.log(formatCIOutput({ success: false, command: "run", version: VERSION13, timestamp: (/* @__PURE__ */ new Date()).toISOString(), durationMs: Math.round(performance.now() - start), error: msg }));
|
|
34903
|
+
process.exit(1);
|
|
34904
|
+
}
|
|
34905
|
+
console.error(`[realitydb] ${msg}`);
|
|
34906
|
+
process.exit(1);
|
|
34907
|
+
}
|
|
34908
|
+
}
|
|
34909
|
+
if (!options.ci) {
|
|
34910
|
+
console.log("Creating schema...");
|
|
34911
|
+
}
|
|
34912
|
+
try {
|
|
34913
|
+
await withTransaction(pool, async (client) => {
|
|
34914
|
+
if (options.dropExisting) {
|
|
34915
|
+
const dropOrder = getDropOrder(schema);
|
|
34916
|
+
for (const tableName of dropOrder) {
|
|
34917
|
+
await client.query(`DROP TABLE IF EXISTS "${tableName}" CASCADE`);
|
|
34918
|
+
}
|
|
34919
|
+
}
|
|
34920
|
+
const statements = ddl.split(";").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
34921
|
+
for (const stmt of statements) {
|
|
34922
|
+
await client.query(stmt + ";");
|
|
34923
|
+
}
|
|
34924
|
+
});
|
|
34925
|
+
} catch (err) {
|
|
34926
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
34927
|
+
if (options.ci) {
|
|
34928
|
+
console.log(formatCIOutput({ success: false, command: "run", version: VERSION13, timestamp: (/* @__PURE__ */ new Date()).toISOString(), durationMs: Math.round(performance.now() - start), error: `DDL failed: ${msg}` }));
|
|
34929
|
+
process.exit(1);
|
|
34930
|
+
}
|
|
34931
|
+
console.error(`[realitydb] DDL failed: ${msg}`);
|
|
34932
|
+
console.error("Database was not modified (transaction rolled back).");
|
|
34933
|
+
process.exit(1);
|
|
34934
|
+
}
|
|
34935
|
+
if (!options.ci) {
|
|
34936
|
+
for (const table of schema.tables) {
|
|
34937
|
+
console.log(` Created table: ${table.name} (${table.columns.length} columns)`);
|
|
34938
|
+
}
|
|
34939
|
+
console.log("");
|
|
34940
|
+
}
|
|
34941
|
+
if (!options.ci) {
|
|
34942
|
+
console.log("Seeding data...");
|
|
34943
|
+
}
|
|
34944
|
+
const config = {
|
|
34945
|
+
database: {
|
|
34946
|
+
client: clientType,
|
|
34947
|
+
connectionString: options.connection
|
|
34948
|
+
},
|
|
34949
|
+
seed: {
|
|
34950
|
+
defaultRecords: effectiveRecords,
|
|
34951
|
+
batchSize: 500,
|
|
34952
|
+
environment: "development",
|
|
34953
|
+
randomSeed: effectiveSeed
|
|
34954
|
+
},
|
|
34955
|
+
template: packPath
|
|
34956
|
+
};
|
|
34957
|
+
const result = await seedDatabase(config, {
|
|
34958
|
+
records: effectiveRecords,
|
|
34959
|
+
seed: effectiveSeed,
|
|
34960
|
+
template: packPath
|
|
34961
|
+
});
|
|
34962
|
+
const durationMs = Math.round(performance.now() - start);
|
|
34963
|
+
const totalTime = (durationMs / 1e3).toFixed(1);
|
|
34964
|
+
if (options.ci) {
|
|
34965
|
+
console.log(formatCIOutput({
|
|
34966
|
+
success: true,
|
|
34967
|
+
command: "run",
|
|
34968
|
+
version: VERSION13,
|
|
34969
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34970
|
+
durationMs,
|
|
34971
|
+
data: {
|
|
34972
|
+
tablesCreated: schema.tables.length,
|
|
34973
|
+
totalRows: result.totalRows,
|
|
34974
|
+
pack: packPath,
|
|
34975
|
+
database: masked,
|
|
34976
|
+
tables: result.insertResult.tables.map((t) => ({
|
|
34977
|
+
name: t.tableName,
|
|
34978
|
+
rowsInserted: t.rowsInserted,
|
|
34979
|
+
batchCount: t.batchCount,
|
|
34980
|
+
durationMs: t.durationMs
|
|
34981
|
+
}))
|
|
34982
|
+
}
|
|
34983
|
+
}));
|
|
34984
|
+
return;
|
|
34985
|
+
}
|
|
34986
|
+
for (const tableResult of result.insertResult.tables) {
|
|
34987
|
+
console.log(
|
|
34988
|
+
` ${tableResult.tableName}: ${tableResult.rowsInserted} rows inserted (${tableResult.batchCount} batches, ${tableResult.durationMs}ms)`
|
|
34989
|
+
);
|
|
34990
|
+
}
|
|
34991
|
+
console.log("");
|
|
34992
|
+
console.log("RealityDB Run Complete");
|
|
34993
|
+
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");
|
|
34994
|
+
console.log(`Schema: ${schema.tables.length} tables created`);
|
|
34995
|
+
console.log(`Data: ${result.totalRows} total rows in ${totalTime}s`);
|
|
34996
|
+
console.log(`Pack: ${packPath}`);
|
|
34997
|
+
console.log(`Database: ${masked}`);
|
|
34998
|
+
console.log("");
|
|
34999
|
+
} finally {
|
|
35000
|
+
await closeConnection(pool);
|
|
35001
|
+
}
|
|
35002
|
+
}
|
|
35003
|
+
|
|
35004
|
+
// src/commands/mask.ts
|
|
35005
|
+
var import_node_fs13 = require("fs");
|
|
35006
|
+
var import_node_path18 = require("path");
|
|
34424
35007
|
var import_node_readline2 = require("readline");
|
|
34425
35008
|
var import_node_process2 = require("process");
|
|
34426
|
-
var
|
|
35009
|
+
var VERSION14 = "1.3.1";
|
|
34427
35010
|
function askPassphrase(prompt) {
|
|
34428
35011
|
return new Promise((resolvePromise) => {
|
|
34429
35012
|
const rl = (0, import_node_readline2.createInterface)({ input: import_node_process2.stdin, output: import_node_process2.stdout });
|
|
@@ -34460,7 +35043,7 @@ async function maskCommand(options) {
|
|
|
34460
35043
|
console.log(formatCIOutput({
|
|
34461
35044
|
success: false,
|
|
34462
35045
|
command: "mask",
|
|
34463
|
-
version:
|
|
35046
|
+
version: VERSION14,
|
|
34464
35047
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34465
35048
|
durationMs: Math.round(performance.now() - start),
|
|
34466
35049
|
error: msg
|
|
@@ -34476,7 +35059,7 @@ async function maskCommand(options) {
|
|
|
34476
35059
|
console.log(formatCIOutput({
|
|
34477
35060
|
success: false,
|
|
34478
35061
|
command: "mask",
|
|
34479
|
-
version:
|
|
35062
|
+
version: VERSION14,
|
|
34480
35063
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34481
35064
|
durationMs: Math.round(performance.now() - start),
|
|
34482
35065
|
error: msg
|
|
@@ -34527,8 +35110,8 @@ async function maskCommand(options) {
|
|
|
34527
35110
|
});
|
|
34528
35111
|
const durationMs = Math.round(performance.now() - start);
|
|
34529
35112
|
if (options.auditLog) {
|
|
34530
|
-
const auditPath = (0,
|
|
34531
|
-
(0,
|
|
35113
|
+
const auditPath = (0, import_node_path18.resolve)(options.auditLog);
|
|
35114
|
+
(0, import_node_fs13.writeFileSync)(auditPath, serializeAuditLog(result.auditLog) + "\n", "utf-8");
|
|
34532
35115
|
}
|
|
34533
35116
|
if (options.tokenMap && result.tokenMap) {
|
|
34534
35117
|
const passphrase = await askPassphrase("Enter passphrase for token map encryption: ");
|
|
@@ -34536,8 +35119,8 @@ async function maskCommand(options) {
|
|
|
34536
35119
|
console.error("[realitydb] Passphrase cannot be empty. Token map not written.");
|
|
34537
35120
|
} else {
|
|
34538
35121
|
const encryptedData = encryptTokenMap(result.tokenMap, passphrase);
|
|
34539
|
-
const tokenMapPath = (0,
|
|
34540
|
-
(0,
|
|
35122
|
+
const tokenMapPath = (0, import_node_path18.resolve)(options.tokenMap);
|
|
35123
|
+
(0, import_node_fs13.writeFileSync)(tokenMapPath, encryptedData + "\n", "utf-8");
|
|
34541
35124
|
if (!options.ci) {
|
|
34542
35125
|
console.log(`Token map exported (AES-256-GCM encrypted) \u2192 ${tokenMapPath}`);
|
|
34543
35126
|
console.log(` ${result.tokenMap.totalTokens} unique tokens generated`);
|
|
@@ -34550,7 +35133,7 @@ async function maskCommand(options) {
|
|
|
34550
35133
|
console.log(formatCIOutput({
|
|
34551
35134
|
success: true,
|
|
34552
35135
|
command: "mask",
|
|
34553
|
-
version:
|
|
35136
|
+
version: VERSION14,
|
|
34554
35137
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34555
35138
|
durationMs,
|
|
34556
35139
|
data: {
|
|
@@ -34582,7 +35165,7 @@ async function maskCommand(options) {
|
|
|
34582
35165
|
console.log("");
|
|
34583
35166
|
}
|
|
34584
35167
|
if (options.auditLog) {
|
|
34585
|
-
console.log(`Audit log written to: ${(0,
|
|
35168
|
+
console.log(`Audit log written to: ${(0, import_node_path18.resolve)(options.auditLog)}`);
|
|
34586
35169
|
console.log("");
|
|
34587
35170
|
}
|
|
34588
35171
|
const totalTime = (durationMs / 1e3).toFixed(1);
|
|
@@ -34598,7 +35181,7 @@ async function maskCommand(options) {
|
|
|
34598
35181
|
console.log(formatCIOutput({
|
|
34599
35182
|
success: false,
|
|
34600
35183
|
command: "mask",
|
|
34601
|
-
version:
|
|
35184
|
+
version: VERSION14,
|
|
34602
35185
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34603
35186
|
durationMs: Math.round(performance.now() - start),
|
|
34604
35187
|
error: message
|
|
@@ -34619,8 +35202,8 @@ async function maskCommand(options) {
|
|
|
34619
35202
|
}
|
|
34620
35203
|
|
|
34621
35204
|
// src/commands/audit.ts
|
|
34622
|
-
var
|
|
34623
|
-
var
|
|
35205
|
+
var import_node_fs14 = require("fs");
|
|
35206
|
+
var import_node_path19 = require("path");
|
|
34624
35207
|
var import_node_readline3 = require("readline");
|
|
34625
35208
|
var import_node_process3 = require("process");
|
|
34626
35209
|
function askPassphrase2(prompt) {
|
|
@@ -34646,8 +35229,8 @@ function askPassphrase2(prompt) {
|
|
|
34646
35229
|
}
|
|
34647
35230
|
async function auditVerifyCommand(logFile, options) {
|
|
34648
35231
|
try {
|
|
34649
|
-
const filePath = (0,
|
|
34650
|
-
const raw = (0,
|
|
35232
|
+
const filePath = (0, import_node_path19.resolve)(logFile);
|
|
35233
|
+
const raw = (0, import_node_fs14.readFileSync)(filePath, "utf-8");
|
|
34651
35234
|
const log = JSON.parse(raw);
|
|
34652
35235
|
const result = verifyAuditLogIntegrity(log);
|
|
34653
35236
|
const entryCount = log.tables?.length ?? 0;
|
|
@@ -34681,8 +35264,8 @@ async function auditVerifyCommand(logFile, options) {
|
|
|
34681
35264
|
}
|
|
34682
35265
|
async function auditSummaryCommand(logFile, options) {
|
|
34683
35266
|
try {
|
|
34684
|
-
const filePath = (0,
|
|
34685
|
-
const raw = (0,
|
|
35267
|
+
const filePath = (0, import_node_path19.resolve)(logFile);
|
|
35268
|
+
const raw = (0, import_node_fs14.readFileSync)(filePath, "utf-8");
|
|
34686
35269
|
const log = JSON.parse(raw);
|
|
34687
35270
|
if (options.ci) {
|
|
34688
35271
|
console.log(JSON.stringify({
|
|
@@ -34712,8 +35295,8 @@ async function auditReIdentifyCommand(options) {
|
|
|
34712
35295
|
console.error("[realitydb] --token-map <file> is required for re-identify");
|
|
34713
35296
|
process.exit(1);
|
|
34714
35297
|
}
|
|
34715
|
-
const filePath = (0,
|
|
34716
|
-
const encryptedData = (0,
|
|
35298
|
+
const filePath = (0, import_node_path19.resolve)(options.tokenMap);
|
|
35299
|
+
const encryptedData = (0, import_node_fs14.readFileSync)(filePath, "utf-8").trim();
|
|
34717
35300
|
const passphrase = await askPassphrase2("Enter passphrase to decrypt token map: ");
|
|
34718
35301
|
if (!passphrase) {
|
|
34719
35302
|
console.error("[realitydb] Passphrase cannot be empty.");
|
|
@@ -34765,9 +35348,9 @@ async function auditReIdentifyCommand(options) {
|
|
|
34765
35348
|
}
|
|
34766
35349
|
|
|
34767
35350
|
// src/commands/classroom.ts
|
|
34768
|
-
var
|
|
34769
|
-
var
|
|
34770
|
-
var
|
|
35351
|
+
var import_node_fs15 = require("fs");
|
|
35352
|
+
var import_node_path20 = require("path");
|
|
35353
|
+
var VERSION15 = "1.3.1";
|
|
34771
35354
|
async function classroomListCommand(options) {
|
|
34772
35355
|
const start = performance.now();
|
|
34773
35356
|
try {
|
|
@@ -34777,7 +35360,7 @@ async function classroomListCommand(options) {
|
|
|
34777
35360
|
console.log(formatCIOutput({
|
|
34778
35361
|
success: true,
|
|
34779
35362
|
command: "classroom list",
|
|
34780
|
-
version:
|
|
35363
|
+
version: VERSION15,
|
|
34781
35364
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34782
35365
|
durationMs,
|
|
34783
35366
|
data: {
|
|
@@ -34813,7 +35396,7 @@ async function classroomListCommand(options) {
|
|
|
34813
35396
|
console.log(formatCIOutput({
|
|
34814
35397
|
success: false,
|
|
34815
35398
|
command: "classroom list",
|
|
34816
|
-
version:
|
|
35399
|
+
version: VERSION15,
|
|
34817
35400
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34818
35401
|
durationMs: Math.round(performance.now() - start),
|
|
34819
35402
|
error: message
|
|
@@ -34844,7 +35427,7 @@ async function classroomStartCommand(courseName, options) {
|
|
|
34844
35427
|
console.log(formatCIOutput({
|
|
34845
35428
|
success: true,
|
|
34846
35429
|
command: "classroom start",
|
|
34847
|
-
version:
|
|
35430
|
+
version: VERSION15,
|
|
34848
35431
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34849
35432
|
durationMs,
|
|
34850
35433
|
data: {
|
|
@@ -34878,7 +35461,7 @@ async function classroomStartCommand(courseName, options) {
|
|
|
34878
35461
|
console.log(formatCIOutput({
|
|
34879
35462
|
success: false,
|
|
34880
35463
|
command: "classroom start",
|
|
34881
|
-
version:
|
|
35464
|
+
version: VERSION15,
|
|
34882
35465
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34883
35466
|
durationMs: Math.round(performance.now() - start),
|
|
34884
35467
|
error: message
|
|
@@ -34908,7 +35491,7 @@ async function classroomStatusCommand(courseName, options) {
|
|
|
34908
35491
|
console.log(formatCIOutput({
|
|
34909
35492
|
success: true,
|
|
34910
35493
|
command: "classroom status",
|
|
34911
|
-
version:
|
|
35494
|
+
version: VERSION15,
|
|
34912
35495
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34913
35496
|
durationMs,
|
|
34914
35497
|
data: { courses: result.courses }
|
|
@@ -34935,7 +35518,7 @@ async function classroomStatusCommand(courseName, options) {
|
|
|
34935
35518
|
console.log(formatCIOutput({
|
|
34936
35519
|
success: false,
|
|
34937
35520
|
command: "classroom status",
|
|
34938
|
-
version:
|
|
35521
|
+
version: VERSION15,
|
|
34939
35522
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34940
35523
|
durationMs: Math.round(performance.now() - start),
|
|
34941
35524
|
error: message
|
|
@@ -34955,7 +35538,7 @@ async function classroomCompleteCommand(courseName, exerciseId, options) {
|
|
|
34955
35538
|
console.log(formatCIOutput({
|
|
34956
35539
|
success: true,
|
|
34957
35540
|
command: "classroom complete",
|
|
34958
|
-
version:
|
|
35541
|
+
version: VERSION15,
|
|
34959
35542
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34960
35543
|
durationMs,
|
|
34961
35544
|
data: { courseName, exerciseId, completed: true }
|
|
@@ -34978,7 +35561,7 @@ async function classroomCompleteCommand(courseName, exerciseId, options) {
|
|
|
34978
35561
|
console.log(formatCIOutput({
|
|
34979
35562
|
success: false,
|
|
34980
35563
|
command: "classroom complete",
|
|
34981
|
-
version:
|
|
35564
|
+
version: VERSION15,
|
|
34982
35565
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34983
35566
|
durationMs: Math.round(performance.now() - start),
|
|
34984
35567
|
error: message
|
|
@@ -34998,7 +35581,7 @@ async function classroomResetCommand(courseName, options) {
|
|
|
34998
35581
|
console.log(formatCIOutput({
|
|
34999
35582
|
success: true,
|
|
35000
35583
|
command: "classroom reset",
|
|
35001
|
-
version:
|
|
35584
|
+
version: VERSION15,
|
|
35002
35585
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35003
35586
|
durationMs,
|
|
35004
35587
|
data: { courseName, reset: true }
|
|
@@ -35013,7 +35596,7 @@ async function classroomResetCommand(courseName, options) {
|
|
|
35013
35596
|
console.log(formatCIOutput({
|
|
35014
35597
|
success: false,
|
|
35015
35598
|
command: "classroom reset",
|
|
35016
|
-
version:
|
|
35599
|
+
version: VERSION15,
|
|
35017
35600
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35018
35601
|
durationMs: Math.round(performance.now() - start),
|
|
35019
35602
|
error: message
|
|
@@ -35029,14 +35612,14 @@ async function classroomCreateCommand(name, options) {
|
|
|
35029
35612
|
try {
|
|
35030
35613
|
const content = classroomCreate(name);
|
|
35031
35614
|
const filename = `${name}.course.json`;
|
|
35032
|
-
const filePath = (0,
|
|
35033
|
-
(0,
|
|
35615
|
+
const filePath = (0, import_node_path20.resolve)(filename);
|
|
35616
|
+
(0, import_node_fs15.writeFileSync)(filePath, content + "\n", "utf-8");
|
|
35034
35617
|
const durationMs = Math.round(performance.now() - start);
|
|
35035
35618
|
if (options.ci) {
|
|
35036
35619
|
console.log(formatCIOutput({
|
|
35037
35620
|
success: true,
|
|
35038
35621
|
command: "classroom create",
|
|
35039
|
-
version:
|
|
35622
|
+
version: VERSION15,
|
|
35040
35623
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35041
35624
|
durationMs,
|
|
35042
35625
|
data: { name, file: filePath }
|
|
@@ -35055,7 +35638,7 @@ async function classroomCreateCommand(name, options) {
|
|
|
35055
35638
|
console.log(formatCIOutput({
|
|
35056
35639
|
success: false,
|
|
35057
35640
|
command: "classroom create",
|
|
35058
|
-
version:
|
|
35641
|
+
version: VERSION15,
|
|
35059
35642
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35060
35643
|
durationMs: Math.round(performance.now() - start),
|
|
35061
35644
|
error: message
|
|
@@ -35074,7 +35657,7 @@ function buildProgressBar(percent) {
|
|
|
35074
35657
|
}
|
|
35075
35658
|
|
|
35076
35659
|
// src/commands/simulate.ts
|
|
35077
|
-
var
|
|
35660
|
+
var VERSION16 = "1.3.1";
|
|
35078
35661
|
async function simulateRunCommand(options) {
|
|
35079
35662
|
const start = performance.now();
|
|
35080
35663
|
try {
|
|
@@ -35106,7 +35689,7 @@ async function simulateRunCommand(options) {
|
|
|
35106
35689
|
console.log(formatCIOutput({
|
|
35107
35690
|
success: true,
|
|
35108
35691
|
command: "simulate run",
|
|
35109
|
-
version:
|
|
35692
|
+
version: VERSION16,
|
|
35110
35693
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35111
35694
|
durationMs,
|
|
35112
35695
|
data: {
|
|
@@ -35130,7 +35713,7 @@ async function simulateRunCommand(options) {
|
|
|
35130
35713
|
console.log(formatCIOutput({
|
|
35131
35714
|
success: false,
|
|
35132
35715
|
command: "simulate run",
|
|
35133
|
-
version:
|
|
35716
|
+
version: VERSION16,
|
|
35134
35717
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35135
35718
|
durationMs: Math.round(performance.now() - start),
|
|
35136
35719
|
error: message
|
|
@@ -35150,7 +35733,7 @@ async function simulateProfilesCommand(options) {
|
|
|
35150
35733
|
console.log(formatCIOutput({
|
|
35151
35734
|
success: true,
|
|
35152
35735
|
command: "simulate profiles",
|
|
35153
|
-
version:
|
|
35736
|
+
version: VERSION16,
|
|
35154
35737
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35155
35738
|
durationMs,
|
|
35156
35739
|
data: {
|
|
@@ -35185,7 +35768,7 @@ async function simulateProfilesCommand(options) {
|
|
|
35185
35768
|
console.log(formatCIOutput({
|
|
35186
35769
|
success: false,
|
|
35187
35770
|
command: "simulate profiles",
|
|
35188
|
-
version:
|
|
35771
|
+
version: VERSION16,
|
|
35189
35772
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35190
35773
|
durationMs: Math.round(performance.now() - start),
|
|
35191
35774
|
error: message
|
|
@@ -35209,7 +35792,7 @@ async function simulateWebhooksCommand(options) {
|
|
|
35209
35792
|
console.log(formatCIOutput({
|
|
35210
35793
|
success: false,
|
|
35211
35794
|
command: "simulate webhooks",
|
|
35212
|
-
version:
|
|
35795
|
+
version: VERSION16,
|
|
35213
35796
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35214
35797
|
durationMs: Math.round(performance.now() - start),
|
|
35215
35798
|
error: msg
|
|
@@ -35242,7 +35825,7 @@ async function simulateWebhooksCommand(options) {
|
|
|
35242
35825
|
console.log(formatCIOutput({
|
|
35243
35826
|
success: true,
|
|
35244
35827
|
command: "simulate webhooks",
|
|
35245
|
-
version:
|
|
35828
|
+
version: VERSION16,
|
|
35246
35829
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35247
35830
|
durationMs,
|
|
35248
35831
|
data: {
|
|
@@ -35267,7 +35850,7 @@ async function simulateWebhooksCommand(options) {
|
|
|
35267
35850
|
console.log(formatCIOutput({
|
|
35268
35851
|
success: false,
|
|
35269
35852
|
command: "simulate webhooks",
|
|
35270
|
-
version:
|
|
35853
|
+
version: VERSION16,
|
|
35271
35854
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35272
35855
|
durationMs: Math.round(performance.now() - start),
|
|
35273
35856
|
error: message
|
|
@@ -35280,11 +35863,11 @@ async function simulateWebhooksCommand(options) {
|
|
|
35280
35863
|
}
|
|
35281
35864
|
|
|
35282
35865
|
// src/cli.ts
|
|
35283
|
-
var
|
|
35866
|
+
var VERSION17 = "2.0.0";
|
|
35284
35867
|
function run(argv) {
|
|
35285
35868
|
const program2 = new Command();
|
|
35286
|
-
program2.name("realitydb").description("RealityDB
|
|
35287
|
-
program2.command("init").description("Interactive setup wizard
|
|
35869
|
+
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);
|
|
35870
|
+
program2.command("init").description("Interactive setup wizard -- connect, scan, and seed in one step").action(async () => {
|
|
35288
35871
|
await initCommand();
|
|
35289
35872
|
});
|
|
35290
35873
|
program2.command("scan").description("Scan database schema").action(async () => {
|
|
@@ -35295,7 +35878,7 @@ function run(argv) {
|
|
|
35295
35878
|
const opts = program2.opts();
|
|
35296
35879
|
await analyzeCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
|
|
35297
35880
|
});
|
|
35298
|
-
program2.command("seed").description("Seed database with generated data").option("--records <count>", "Number of records per table").option("--template <name|path>", "Template name or path to custom .json file").option("--seed <number>", "Random seed for reproducibility").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("--lifecycle", "Enable lifecycle simulation for causally-connected data").option("--auto-template", "Run analyze
|
|
35881
|
+
program2.command("seed").description("Seed database with generated data").option("--records <count>", "Number of records per table").option("--template <name|path>", "Template name or path to custom .json file").option("--seed <number>", "Random seed for reproducibility").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("--lifecycle", "Enable lifecycle simulation for causally-connected data").option("--auto-template", "Run analyze, generate template, and seed in one command").action(async (cmdOpts) => {
|
|
35299
35882
|
const opts = program2.opts();
|
|
35300
35883
|
await seedCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
|
|
35301
35884
|
});
|
|
@@ -35311,6 +35894,10 @@ function run(argv) {
|
|
|
35311
35894
|
const opts = program2.opts();
|
|
35312
35895
|
await generateCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
|
|
35313
35896
|
});
|
|
35897
|
+
program2.command("run").description("Create schema and seed database from a Studio-exported template pack").requiredOption("--pack <path>", "Path to Studio template JSON file").requiredOption("--connection <url>", "Database connection string").option("--records <count>", "Number of records per table (overrides template config)").option("--seed <number>", "Random seed for reproducibility (overrides template config)").option("--drop-existing", "Drop and recreate tables if they already exist").option("--dry-run", "Show DDL and plan without executing").action(async (cmdOpts) => {
|
|
35898
|
+
const opts = program2.opts();
|
|
35899
|
+
await runCommand({ ...cmdOpts, ci: opts.ci });
|
|
35900
|
+
});
|
|
35314
35901
|
const templates = program2.command("templates").description("Template management");
|
|
35315
35902
|
templates.command("list", { isDefault: true }).description("List available domain templates").action(templatesCommand);
|
|
35316
35903
|
templates.command("init").description("Scaffold a new custom template JSON file").action(templatesInitCommand);
|
|
@@ -35378,7 +35965,7 @@ function run(argv) {
|
|
|
35378
35965
|
const opts = program2.opts();
|
|
35379
35966
|
await simulateWebhooksCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
|
|
35380
35967
|
});
|
|
35381
|
-
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) => {
|
|
35968
|
+
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) => {
|
|
35382
35969
|
const opts = program2.opts();
|
|
35383
35970
|
await captureCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
|
|
35384
35971
|
});
|
|
@@ -35386,7 +35973,7 @@ function run(argv) {
|
|
|
35386
35973
|
const opts = program2.opts();
|
|
35387
35974
|
await shareCommand(filePath, { ...cmdOpts, ci: opts.ci, configPath: opts.config });
|
|
35388
35975
|
});
|
|
35389
|
-
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) => {
|
|
35976
|
+
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) => {
|
|
35390
35977
|
const opts = program2.opts();
|
|
35391
35978
|
await loadCommand(filePath, { ...cmdOpts, ci: opts.ci, configPath: opts.config });
|
|
35392
35979
|
});
|
|
@@ -35407,10 +35994,10 @@ function run(argv) {
|
|
|
35407
35994
|
program2.action(() => {
|
|
35408
35995
|
const opts = program2.opts();
|
|
35409
35996
|
if (opts.ci) {
|
|
35410
|
-
console.log(JSON.stringify({ name: "realitydb", version:
|
|
35997
|
+
console.log(JSON.stringify({ name: "realitydb", version: VERSION17 }));
|
|
35411
35998
|
} else {
|
|
35412
35999
|
console.log("");
|
|
35413
|
-
console.log(`RealityDB v${
|
|
36000
|
+
console.log(`RealityDB v${VERSION17} -- Developer Reality Platform`);
|
|
35414
36001
|
console.log("Run `realitydb --help` for available commands.");
|
|
35415
36002
|
console.log("");
|
|
35416
36003
|
}
|