admindb 2.1.0 → 2.1.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/README.md +1 -1
- package/dist/app.d.ts +1 -69
- package/dist/app.js +1 -257
- package/dist/auth/config.d.ts +1 -19
- package/dist/auth/config.js +1 -147
- package/dist/auth/crypto.d.ts +1 -27
- package/dist/auth/crypto.js +1 -133
- package/dist/auth/index.d.ts +1 -5
- package/dist/auth/index.js +1 -22
- package/dist/auth/middleware.d.ts +1 -14
- package/dist/auth/middleware.js +1 -100
- package/dist/auth/routes.d.ts +1 -7
- package/dist/auth/routes.js +1 -78
- package/dist/auth/types.d.ts +1 -35
- package/dist/auth/types.js +1 -11
- package/dist/cli/args.d.ts +1 -45
- package/dist/cli/args.js +1 -328
- package/dist/cli/config.d.ts +1 -56
- package/dist/cli/config.js +1 -133
- package/dist/cli/index.d.ts +1 -4
- package/dist/cli/index.js +1 -21
- package/dist/cli/runner.d.ts +1 -1
- package/dist/cli/runner.js +1 -222
- package/dist/cli.d.ts +1 -2
- package/dist/cli.js +1 -5
- package/dist/data/datasets.d.ts +1 -17
- package/dist/data/datasets.js +1 -133
- package/dist/data/detector.d.ts +1 -30
- package/dist/data/detector.js +1 -472
- package/dist/data/engine.d.ts +1 -10
- package/dist/data/engine.js +1 -211
- package/dist/data/index.d.ts +1 -5
- package/dist/data/index.js +1 -22
- package/dist/data/strategies.d.ts +1 -30
- package/dist/data/strategies.js +1 -343
- package/dist/data/types.d.ts +1 -73
- package/dist/data/types.js +1 -8
- package/dist/db/database.d.ts +1 -119
- package/dist/db/database.js +1 -471
- package/dist/db/export.d.ts +1 -12
- package/dist/db/export.js +1 -42
- package/dist/db/filters.d.ts +1 -22
- package/dist/db/filters.js +1 -158
- package/dist/db/index.d.ts +1 -8
- package/dist/db/index.js +1 -25
- package/dist/db/introspection.d.ts +1 -6
- package/dist/db/introspection.js +1 -172
- package/dist/db/manager.d.ts +1 -81
- package/dist/db/manager.js +1 -397
- package/dist/db/migrations.d.ts +1 -5
- package/dist/db/migrations.js +1 -110
- package/dist/db/postgres.d.ts +1 -85
- package/dist/db/postgres.js +1 -745
- package/dist/db/types.d.ts +1 -206
- package/dist/db/types.js +1 -7
- package/dist/index.d.ts +1 -23
- package/dist/index.js +1 -66
- package/dist/public/js/api.js +1 -47
- package/dist/public/js/app.js +1 -262
- package/dist/public/js/browse.js +1 -1371
- package/dist/public/js/databases.js +1 -235
- package/dist/public/js/designer.js +1 -258
- package/dist/public/js/forms.js +1 -826
- package/dist/public/js/icons.js +1 -51
- package/dist/public/js/inspector.js +1 -638
- package/dist/public/js/query.js +1 -322
- package/dist/public/js/schema.js +1 -447
- package/dist/public/js/seed.js +1 -1090
- package/dist/routes/api/helpers.d.ts +1 -42
- package/dist/routes/api/helpers.js +1 -133
- package/dist/routes/api/import-export.d.ts +1 -3
- package/dist/routes/api/import-export.js +1 -85
- package/dist/routes/api/index.d.ts +1 -4
- package/dist/routes/api/index.js +1 -37
- package/dist/routes/api/query.d.ts +1 -3
- package/dist/routes/api/query.js +1 -76
- package/dist/routes/api/rows.d.ts +1 -3
- package/dist/routes/api/rows.js +1 -373
- package/dist/routes/api/seed.d.ts +1 -3
- package/dist/routes/api/seed.js +1 -82
- package/dist/routes/api/tables.d.ts +1 -3
- package/dist/routes/api/tables.js +1 -160
- package/dist/routes/databases.d.ts +1 -26
- package/dist/routes/databases.js +1 -230
- package/dist/routes/index.d.ts +1 -3
- package/dist/routes/index.js +1 -20
- package/dist/routes/pages.d.ts +1 -9
- package/dist/routes/pages.js +1 -390
- package/dist/serverless.d.ts +1 -40
- package/dist/serverless.js +1 -210
- package/dist/sql/classifier.d.ts +1 -19
- package/dist/sql/classifier.js +1 -37
- package/dist/sql/generator.d.ts +1 -81
- package/dist/sql/generator.js +1 -348
- package/dist/sql/index.d.ts +1 -2
- package/dist/sql/index.js +1 -19
- package/dist/types/api.d.ts +1 -412
- package/dist/types/api.js +1 -9
- package/dist/utils/colors.d.ts +1 -40
- package/dist/utils/colors.js +1 -64
- package/dist/utils/common.d.ts +1 -50
- package/dist/utils/common.js +1 -229
- package/dist/utils/csv.d.ts +1 -15
- package/dist/utils/csv.js +1 -80
- package/dist/utils/datatype.d.ts +1 -49
- package/dist/utils/datatype.js +1 -222
- package/dist/utils/icons.d.ts +1 -11
- package/dist/utils/icons.js +1 -72
- package/dist/utils/index.d.ts +1 -4
- package/dist/utils/index.js +1 -21
- package/dist/utils/logger.d.ts +1 -10
- package/dist/utils/logger.js +1 -40
- package/dist/views/layouts/main.hbs +0 -4
- package/dist/views/pages/databases.hbs +0 -18
- package/dist/views/pages/designer.hbs +0 -10
- package/dist/views/pages/error.hbs +0 -2
- package/dist/views/pages/form.hbs +0 -5
- package/dist/views/pages/home.hbs +0 -8
- package/dist/views/pages/login.hbs +0 -13
- package/dist/views/pages/query.hbs +0 -9
- package/dist/views/pages/schema.hbs +0 -20
- package/dist/views/pages/seed.hbs +0 -31
- package/dist/views/pages/table.hbs +0 -14
- package/dist/views/partials/icon.hbs +0 -1
- package/dist/views/partials/navbar.hbs +0 -6
- package/dist/views/partials/sidebar.hbs +0 -8
- package/package.json +3 -2
- package/dist/app.js.map +0 -1
- package/dist/auth/config.js.map +0 -1
- package/dist/auth/crypto.js.map +0 -1
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/middleware.js.map +0 -1
- package/dist/auth/routes.js.map +0 -1
- package/dist/auth/types.js.map +0 -1
- package/dist/cli/args.js.map +0 -1
- package/dist/cli/config.js.map +0 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/runner.js.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/data/datasets.js.map +0 -1
- package/dist/data/detector.js.map +0 -1
- package/dist/data/engine.js.map +0 -1
- package/dist/data/index.js.map +0 -1
- package/dist/data/strategies.js.map +0 -1
- package/dist/data/types.js.map +0 -1
- package/dist/db/database.js.map +0 -1
- package/dist/db/export.js.map +0 -1
- package/dist/db/filters.js.map +0 -1
- package/dist/db/index.js.map +0 -1
- package/dist/db/introspection.js.map +0 -1
- package/dist/db/manager.js.map +0 -1
- package/dist/db/migrations.js.map +0 -1
- package/dist/db/postgres.js.map +0 -1
- package/dist/db/types.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/public/css/input.css +0 -302
- package/dist/routes/api/helpers.js.map +0 -1
- package/dist/routes/api/import-export.js.map +0 -1
- package/dist/routes/api/index.js.map +0 -1
- package/dist/routes/api/query.js.map +0 -1
- package/dist/routes/api/rows.js.map +0 -1
- package/dist/routes/api/seed.js.map +0 -1
- package/dist/routes/api/tables.js.map +0 -1
- package/dist/routes/databases.js.map +0 -1
- package/dist/routes/index.js.map +0 -1
- package/dist/routes/pages.js.map +0 -1
- package/dist/serverless.js.map +0 -1
- package/dist/sql/classifier.js.map +0 -1
- package/dist/sql/generator.js.map +0 -1
- package/dist/sql/index.js.map +0 -1
- package/dist/types/api.js.map +0 -1
- package/dist/utils/colors.js.map +0 -1
- package/dist/utils/common.js.map +0 -1
- package/dist/utils/csv.js.map +0 -1
- package/dist/utils/datatype.js.map +0 -1
- package/dist/utils/icons.js.map +0 -1
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/logger.js.map +0 -1
package/dist/data/strategies.js
CHANGED
|
@@ -1,343 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.randomTime = exports.makeParagraph = exports.makeColor = exports.makeAvatar = exports.makeCreditCard = exports.makeIp = exports.makeAddress = exports.makePhone = exports.makeUsername = exports.makeEmail = exports.makeSlug = exports.pick = exports.randFloat = exports.randInt = void 0;
|
|
4
|
-
exports.makeMacAddress = makeMacAddress;
|
|
5
|
-
exports.makeUuid = makeUuid;
|
|
6
|
-
exports.makeWords = makeWords;
|
|
7
|
-
exports.makeSentences = makeSentences;
|
|
8
|
-
exports.formatPattern = formatPattern;
|
|
9
|
-
exports.randomDate = randomDate;
|
|
10
|
-
exports.randomUnixTimestamp = randomUnixTimestamp;
|
|
11
|
-
exports.randomAlnum = randomAlnum;
|
|
12
|
-
exports.makeJsonObject = makeJsonObject;
|
|
13
|
-
exports.isTextishType = isTextishType;
|
|
14
|
-
exports.strategiesFor = strategiesFor;
|
|
15
|
-
exports.fallbackPlanFor = fallbackPlanFor;
|
|
16
|
-
exports.generateOne = generateOne;
|
|
17
|
-
exports.generateSampleValue = generateSampleValue;
|
|
18
|
-
const node_crypto_1 = require("node:crypto");
|
|
19
|
-
const common_1 = require("../utils/common");
|
|
20
|
-
const datasets_1 = require("./datasets");
|
|
21
|
-
const types_1 = require("./types");
|
|
22
|
-
// ---- Random helpers -------------------------------------------------------
|
|
23
|
-
const randInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
|
|
24
|
-
exports.randInt = randInt;
|
|
25
|
-
const randFloat = (min, max) => Math.random() * (max - min) + min;
|
|
26
|
-
exports.randFloat = randFloat;
|
|
27
|
-
const pick = (arr) => arr[(0, exports.randInt)(0, arr.length - 1)];
|
|
28
|
-
exports.pick = pick;
|
|
29
|
-
const makeSlug = () => `${(0, exports.pick)(datasets_1.LOREM_WORDS)}-${(0, exports.pick)(datasets_1.LOREM_WORDS)}-${(0, exports.randInt)(100, 999)}`;
|
|
30
|
-
exports.makeSlug = makeSlug;
|
|
31
|
-
const makeEmail = () => `${(0, exports.pick)(datasets_1.FIRST_NAMES).toLowerCase()}.${(0, exports.pick)(datasets_1.LAST_NAMES).toLowerCase()}${(0, exports.randInt)(1, 99)}@${(0, exports.pick)(datasets_1.DOMAINS)}`;
|
|
32
|
-
exports.makeEmail = makeEmail;
|
|
33
|
-
const makeUsername = () => `${(0, exports.pick)(datasets_1.FIRST_NAMES).toLowerCase()}${(0, exports.pick)(datasets_1.LAST_NAMES).toLowerCase()}${(0, exports.randInt)(1, 9999)}`;
|
|
34
|
-
exports.makeUsername = makeUsername;
|
|
35
|
-
const makePhone = () => `+1 (${(0, exports.randInt)(200, 999)}) ${(0, exports.randInt)(200, 999)}-${String((0, exports.randInt)(0, 9999)).padStart(4, '0')}`;
|
|
36
|
-
exports.makePhone = makePhone;
|
|
37
|
-
const makeAddress = () => `${(0, exports.randInt)(10, 9999)} ${(0, exports.pick)(datasets_1.LOREM_WORDS)} ${(0, exports.pick)(['St', 'Ave', 'Rd', 'Blvd', 'Ln', 'Dr'])}, ${(0, exports.pick)(datasets_1.CITIES)}`;
|
|
38
|
-
exports.makeAddress = makeAddress;
|
|
39
|
-
const makeIp = () => `${(0, exports.randInt)(1, 223)}.${(0, exports.randInt)(0, 255)}.${(0, exports.randInt)(0, 255)}.${(0, exports.randInt)(1, 254)}`;
|
|
40
|
-
exports.makeIp = makeIp;
|
|
41
|
-
function makeMacAddress() {
|
|
42
|
-
const b = () => (0, exports.randInt)(0, 255).toString(16).padStart(2, '0').toUpperCase();
|
|
43
|
-
return `${b()}:${b()}:${b()}:${b()}:${b()}:${b()}`;
|
|
44
|
-
}
|
|
45
|
-
const makeCreditCard = () => `4532-${(0, exports.randInt)(1000, 9999)}-${(0, exports.randInt)(1000, 9999)}-${(0, exports.randInt)(1000, 9999)}`;
|
|
46
|
-
exports.makeCreditCard = makeCreditCard;
|
|
47
|
-
const makeAvatar = (seedVal) => `https://api.dicebear.com/7.x/avataaars/svg?seed=${encodeURIComponent(seedVal || (0, exports.makeUsername)())}`;
|
|
48
|
-
exports.makeAvatar = makeAvatar;
|
|
49
|
-
const makeColor = (format = 'hex') => (format === 'name' ? (0, exports.pick)(datasets_1.NAMED_COLORS) : (0, exports.pick)(datasets_1.HEX_COLORS));
|
|
50
|
-
exports.makeColor = makeColor;
|
|
51
|
-
function makeUuid() {
|
|
52
|
-
const h = (n) => (0, exports.randInt)(0, 0xffffffff).toString(16).padStart(n, '0');
|
|
53
|
-
return `${h(8)}-${h(4).slice(0, 4)}-4${h(3).slice(0, 3)}-${['8', '9', 'a', 'b'][(0, exports.randInt)(0, 3)]}${h(3).slice(0, 3)}-${h(12).slice(0, 12)}`;
|
|
54
|
-
}
|
|
55
|
-
function makeWords(minLen, maxLen) {
|
|
56
|
-
const n = (0, exports.randInt)(minLen, maxLen);
|
|
57
|
-
const parts = [];
|
|
58
|
-
for (let i = 0; i < n; i++)
|
|
59
|
-
parts.push((0, exports.pick)(datasets_1.LOREM_WORDS));
|
|
60
|
-
return parts.join(' ');
|
|
61
|
-
}
|
|
62
|
-
function makeSentences(minLen, maxLen) {
|
|
63
|
-
const n = (0, exports.randInt)(minLen, maxLen);
|
|
64
|
-
const sentences = [];
|
|
65
|
-
for (let i = 0; i < n; i++) {
|
|
66
|
-
const words = makeWords(6, 14).split(' ');
|
|
67
|
-
words[0] = words[0].charAt(0).toUpperCase() + words[0].slice(1);
|
|
68
|
-
sentences.push(words.join(' ') + '.');
|
|
69
|
-
}
|
|
70
|
-
return sentences.join(' ');
|
|
71
|
-
}
|
|
72
|
-
const makeParagraph = () => makeSentences(3, 5);
|
|
73
|
-
exports.makeParagraph = makeParagraph;
|
|
74
|
-
function formatPattern(pattern) {
|
|
75
|
-
if (!pattern)
|
|
76
|
-
return '';
|
|
77
|
-
const now = new Date();
|
|
78
|
-
const year = String(now.getFullYear());
|
|
79
|
-
const s = pattern
|
|
80
|
-
.replace(/\{YYYY\}/g, year)
|
|
81
|
-
.replace(/\{YY\}/g, year.slice(-2))
|
|
82
|
-
.replace(/\{MM\}/g, String((0, exports.randInt)(1, 12)).padStart(2, '0'))
|
|
83
|
-
.replace(/\{DD\}/g, String((0, exports.randInt)(1, 28)).padStart(2, '0'));
|
|
84
|
-
const upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
85
|
-
const lower = 'abcdefghijklmnopqrstuvwxyz';
|
|
86
|
-
let res = '';
|
|
87
|
-
for (let i = 0; i < s.length; i++) {
|
|
88
|
-
const ch = s[i];
|
|
89
|
-
if (ch === '#')
|
|
90
|
-
res += (0, exports.randInt)(0, 9);
|
|
91
|
-
else if (ch === 'A' || ch === '?')
|
|
92
|
-
res += upper[(0, exports.randInt)(0, 25)];
|
|
93
|
-
else if (ch === 'a')
|
|
94
|
-
res += lower[(0, exports.randInt)(0, 25)];
|
|
95
|
-
else
|
|
96
|
-
res += ch;
|
|
97
|
-
}
|
|
98
|
-
return res;
|
|
99
|
-
}
|
|
100
|
-
function randomDate(from, to, kind = 'date') {
|
|
101
|
-
const now = Date.now();
|
|
102
|
-
const lo = from ? Date.parse(from) : now - 730 * 86400_000;
|
|
103
|
-
const hi = to ? Date.parse(to) : now;
|
|
104
|
-
const d = new Date((0, exports.randInt)(Number.isFinite(lo) ? lo : now - 730 * 86400_000, Number.isFinite(hi) ? hi : now));
|
|
105
|
-
if (kind === 'datetime')
|
|
106
|
-
return d.toISOString();
|
|
107
|
-
const p = (n) => String(n).padStart(2, '0');
|
|
108
|
-
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
|
|
109
|
-
}
|
|
110
|
-
const randomTime = () => `${String((0, exports.randInt)(0, 23)).padStart(2, '0')}:${String((0, exports.randInt)(0, 59)).padStart(2, '0')}:${String((0, exports.randInt)(0, 59)).padStart(2, '0')}`;
|
|
111
|
-
exports.randomTime = randomTime;
|
|
112
|
-
function randomUnixTimestamp(format = 'sec', from, to) {
|
|
113
|
-
const now = Date.now();
|
|
114
|
-
const lo = from ? Date.parse(from) : now - 730 * 86400_000;
|
|
115
|
-
const hi = to ? Date.parse(to) : now;
|
|
116
|
-
const t = (0, exports.randInt)(Number.isFinite(lo) ? lo : now - 730 * 86400_000, Number.isFinite(hi) ? hi : now);
|
|
117
|
-
return format === 'ms' ? t : Math.floor(t / 1000);
|
|
118
|
-
}
|
|
119
|
-
const ALNUM = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
120
|
-
function randomAlnum(minLen, maxLen) {
|
|
121
|
-
const len = (0, exports.randInt)(minLen, maxLen);
|
|
122
|
-
let s = '';
|
|
123
|
-
for (let i = 0; i < len; i++)
|
|
124
|
-
s += ALNUM[(0, exports.randInt)(0, ALNUM.length - 1)];
|
|
125
|
-
return s;
|
|
126
|
-
}
|
|
127
|
-
const JSON_ROLES = ['admin', 'editor', 'viewer', 'billing', 'member', 'owner', 'guest'];
|
|
128
|
-
const JSON_APPS = ['dashboard', 'api', 'mobile', 'cli', 'webhook', 'cron', 'importer'];
|
|
129
|
-
function jsonValueForKey(key) {
|
|
130
|
-
const lk = key.toLowerCase();
|
|
131
|
-
if (lk.includes('role'))
|
|
132
|
-
return (0, exports.pick)(JSON_ROLES);
|
|
133
|
-
if (lk.includes('app'))
|
|
134
|
-
return [(0, exports.pick)(JSON_APPS)];
|
|
135
|
-
const roll = Math.random();
|
|
136
|
-
if (roll < 0.45)
|
|
137
|
-
return (0, exports.pick)(['alpha', 'beta', 'stable', 'draft', 'on', 'off', 'default', 'custom']);
|
|
138
|
-
if (roll < 0.6)
|
|
139
|
-
return (0, exports.randInt)(0, 1000);
|
|
140
|
-
if (roll < 0.75)
|
|
141
|
-
return Math.random() < 0.5;
|
|
142
|
-
if (roll < 0.9)
|
|
143
|
-
return null;
|
|
144
|
-
return makeUuid();
|
|
145
|
-
}
|
|
146
|
-
function makeJsonObject(keys, jsonValues) {
|
|
147
|
-
const k = (keys && keys.length ? keys : ['scope', 'enabled', 'flags']).slice(0, 16);
|
|
148
|
-
const obj = {};
|
|
149
|
-
for (const key of k) {
|
|
150
|
-
const allowed = jsonValues ? jsonValues[key] : undefined;
|
|
151
|
-
obj[key] = allowed && allowed.length ? (0, exports.pick)(allowed) : jsonValueForKey(key);
|
|
152
|
-
}
|
|
153
|
-
return JSON.stringify(obj);
|
|
154
|
-
}
|
|
155
|
-
function isTextishType(type) {
|
|
156
|
-
const t = (type || '').toUpperCase();
|
|
157
|
-
return t === 'TEXT' || t === '' || t.includes('JSON') || t.includes('CHAR') || t.includes('CLOB') || t.includes('VARCHAR');
|
|
158
|
-
}
|
|
159
|
-
/** Registry of strategy descriptors and their supported type categories. */
|
|
160
|
-
const STRATEGY_METADATA = [
|
|
161
|
-
['skip', 'Skip (DB default or NULL applies)', 'custom_control', 'all'],
|
|
162
|
-
['null', 'Set NULL explicitly', 'custom_control', 'all'],
|
|
163
|
-
['fixed', 'Fixed constant value', 'custom_control', 'all'],
|
|
164
|
-
['list', 'Random item from custom list', 'custom_control', 'all'],
|
|
165
|
-
['pattern', 'Custom pattern template (e.g. INV-####)', 'custom_control', 'all'],
|
|
166
|
-
['fullname', 'Full name (e.g. John Smith)', 'identity', 'text'],
|
|
167
|
-
['first', 'First name', 'identity', 'text'],
|
|
168
|
-
['last', 'Last name / Surname', 'identity', 'text'],
|
|
169
|
-
['username', 'Username handle', 'identity', 'text'],
|
|
170
|
-
['job', 'Job title / Profession', 'identity', 'text'],
|
|
171
|
-
['email', 'Email address', 'contact_web', 'text'],
|
|
172
|
-
['phone', 'Phone number', 'contact_web', 'text'],
|
|
173
|
-
['url', 'Website URL', 'contact_web', 'text'],
|
|
174
|
-
['domain', 'Domain name', 'contact_web', 'text'],
|
|
175
|
-
['ip', 'IPv4 address', 'contact_web', 'text'],
|
|
176
|
-
['avatar', 'Avatar image URL', 'contact_web', 'text'],
|
|
177
|
-
['company', 'Company / Organization name', 'commerce', 'text'],
|
|
178
|
-
['currency', 'Currency code (USD, EUR...)', 'commerce', 'text'],
|
|
179
|
-
['status', 'Status badge (active, pending...)', 'commerce', 'text'],
|
|
180
|
-
['creditCard', 'Masked test credit card', 'commerce', 'text'],
|
|
181
|
-
['address', 'Street address', 'location', 'text'],
|
|
182
|
-
['city', 'City name', 'location', 'text'],
|
|
183
|
-
['state', 'State / Province', 'location', 'text'],
|
|
184
|
-
['country', 'Country name', 'location', 'text'],
|
|
185
|
-
['countryCode', 'Country code (ISO-2 e.g. US)', 'location', 'text'],
|
|
186
|
-
['postal', 'Postal / Zip code', 'location', 'text'],
|
|
187
|
-
['latitude', 'Latitude (-90 to 90)', 'location', 'all'],
|
|
188
|
-
['longitude', 'Longitude (-180 to 180)', 'location', 'all'],
|
|
189
|
-
['int', 'Random integer in range', 'numeric', 'numeric'],
|
|
190
|
-
['decimal', 'Random decimal / price', 'numeric', 'numeric'],
|
|
191
|
-
['sequence', 'Sequential numbering (1, 2, 3...)', 'numeric', 'numeric'],
|
|
192
|
-
['date', 'Random date (YYYY-MM-DD)', 'datetime', 'all'],
|
|
193
|
-
['datetime', 'Random datetime (ISO-8601)', 'datetime', 'all'],
|
|
194
|
-
['time', 'Random time (HH:MM:SS)', 'datetime', 'all'],
|
|
195
|
-
['timestampUnix', 'Unix timestamp (epoch)', 'datetime', 'all'],
|
|
196
|
-
['words', 'Short words / Tags', 'system_crypto', 'text'],
|
|
197
|
-
['sentence', 'Sentences', 'system_crypto', 'text'],
|
|
198
|
-
['paragraph', 'Paragraph (multi-sentence text)', 'system_crypto', 'text'],
|
|
199
|
-
['slug', 'URL slug (e.g. tech-news-402)', 'system_crypto', 'text'],
|
|
200
|
-
['bool', 'Boolean flag (1/0 or true/false)', 'system_crypto', 'all'],
|
|
201
|
-
['bytes', 'Random hex bytes (BLOB)', 'system_crypto', 'blob'],
|
|
202
|
-
['uuid', 'UUID v4', 'system_crypto', 'text'],
|
|
203
|
-
['token', 'Short alphanumeric token', 'system_crypto', 'text'],
|
|
204
|
-
['hash', 'Hexadecimal hash (MD5/SHA)', 'system_crypto', 'text'],
|
|
205
|
-
['json', 'Valid JSON object', 'system_crypto', 'text'],
|
|
206
|
-
['color', 'Color (Hex code or name)', 'system_crypto', 'text'],
|
|
207
|
-
['mac', 'MAC network address', 'system_crypto', 'text'],
|
|
208
|
-
];
|
|
209
|
-
function strategiesFor(col, fk) {
|
|
210
|
-
const type = (col.type || '').toUpperCase();
|
|
211
|
-
const isText = isTextishType(type);
|
|
212
|
-
const isNum = type.startsWith('INTEGER') || type === 'REAL' || type.includes('DECIMAL') || type.includes('NUMERIC') || isText;
|
|
213
|
-
const isBlob = type === 'BLOB' || isText;
|
|
214
|
-
const out = [];
|
|
215
|
-
if (fk) {
|
|
216
|
-
out.push({ id: 'fk', label: `Foreign Key: Sample from ${fk.table}${fk.to ? `.${fk.to}` : ''}`, category: 'relational' });
|
|
217
|
-
}
|
|
218
|
-
for (const [id, label, category, target] of STRATEGY_METADATA) {
|
|
219
|
-
if (target === 'all' || (target === 'text' && isText) || (target === 'numeric' && isNum) || (target === 'blob' && isBlob)) {
|
|
220
|
-
out.push({ id, label, category });
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
return out;
|
|
224
|
-
}
|
|
225
|
-
function fallbackPlanFor(col) {
|
|
226
|
-
const type = (col.type || '').toUpperCase();
|
|
227
|
-
if (type === 'BOOLEAN' || type === 'BOOL')
|
|
228
|
-
return { strategy: 'bool' };
|
|
229
|
-
if (type === 'UUID')
|
|
230
|
-
return { strategy: 'uuid' };
|
|
231
|
-
if (type === 'JSON' || type === 'JSONB')
|
|
232
|
-
return { strategy: 'json' };
|
|
233
|
-
if (type.startsWith('INT') || type === 'BIGINT' || type === 'SMALLINT' || type === 'SERIAL' || type === 'BIGSERIAL')
|
|
234
|
-
return { strategy: 'int', min: 1, max: 1000 };
|
|
235
|
-
if (type === 'REAL' || type.includes('DECIMAL') || type === 'NUMERIC' || type.includes('FLOAT') || type.includes('DOUBLE'))
|
|
236
|
-
return { strategy: 'decimal', min: 1, max: 1000, precision: 2 };
|
|
237
|
-
if (type === 'DATE')
|
|
238
|
-
return { strategy: 'date', from: '2020-01-01', to: '2026-12-31' };
|
|
239
|
-
if (type.includes('TIMESTAMP') || type === 'DATETIME')
|
|
240
|
-
return { strategy: 'datetime', from: '2024-01-01T00:00:00', to: '2026-12-31T23:59:59' };
|
|
241
|
-
if (type === 'TIME')
|
|
242
|
-
return { strategy: 'time' };
|
|
243
|
-
if (type === 'BLOB' || type === 'BYTEA')
|
|
244
|
-
return { strategy: 'bytes', minLen: 8, maxLen: 32 };
|
|
245
|
-
if (type === 'INET')
|
|
246
|
-
return { strategy: 'ip' };
|
|
247
|
-
return { strategy: 'words', minLen: 1, maxLen: 4 };
|
|
248
|
-
}
|
|
249
|
-
/** Dispatch table for simple strategy generators. */
|
|
250
|
-
const BASIC_STRATEGIES = {
|
|
251
|
-
first: () => (0, exports.pick)(datasets_1.FIRST_NAMES),
|
|
252
|
-
last: () => (0, exports.pick)(datasets_1.LAST_NAMES),
|
|
253
|
-
fullname: () => `${(0, exports.pick)(datasets_1.FIRST_NAMES)} ${(0, exports.pick)(datasets_1.LAST_NAMES)}`,
|
|
254
|
-
email: () => (0, exports.makeEmail)(),
|
|
255
|
-
username: () => (0, exports.makeUsername)(),
|
|
256
|
-
job: () => (0, exports.pick)(datasets_1.JOB_TITLES),
|
|
257
|
-
company: () => (0, exports.pick)(datasets_1.COMPANIES),
|
|
258
|
-
currency: () => (0, exports.pick)(datasets_1.CURRENCIES),
|
|
259
|
-
status: () => (0, exports.pick)(datasets_1.STATUSES),
|
|
260
|
-
creditCard: () => (0, exports.makeCreditCard)(),
|
|
261
|
-
avatar: () => (0, exports.makeAvatar)(),
|
|
262
|
-
color: (p) => (0, exports.makeColor)(p.format),
|
|
263
|
-
phone: () => (0, exports.makePhone)(),
|
|
264
|
-
city: () => (0, exports.pick)(datasets_1.CITIES),
|
|
265
|
-
state: () => (0, exports.pick)(datasets_1.US_STATES),
|
|
266
|
-
country: () => (0, exports.pick)(datasets_1.COUNTRIES),
|
|
267
|
-
countryCode: () => (0, exports.pick)(datasets_1.COUNTRY_CODES),
|
|
268
|
-
postal: () => String((0, exports.randInt)(10000, 99999)),
|
|
269
|
-
address: () => (0, exports.makeAddress)(),
|
|
270
|
-
url: () => `https://www.${(0, exports.pick)(datasets_1.DOMAINS)}/${(0, exports.makeSlug)()}`,
|
|
271
|
-
domain: () => (0, exports.pick)(datasets_1.DOMAINS),
|
|
272
|
-
ip: () => (0, exports.makeIp)(),
|
|
273
|
-
mac: () => makeMacAddress(),
|
|
274
|
-
uuid: () => makeUuid(),
|
|
275
|
-
slug: () => (0, exports.makeSlug)(),
|
|
276
|
-
paragraph: () => (0, exports.makeParagraph)(),
|
|
277
|
-
time: () => (0, exports.randomTime)(),
|
|
278
|
-
bool: () => (0, exports.pick)(['1', '0']),
|
|
279
|
-
json: (p) => makeJsonObject(p.jsonKeys, p.jsonValues),
|
|
280
|
-
words: (p) => makeWords(p.minLen ?? 1, p.maxLen ?? 4),
|
|
281
|
-
sentence: (p) => makeSentences(p.minLen ?? 1, p.maxLen ?? 2),
|
|
282
|
-
date: (p) => randomDate(p.from, p.to, 'date'),
|
|
283
|
-
datetime: (p) => randomDate(p.from, p.to, 'datetime'),
|
|
284
|
-
timestampUnix: (p) => randomUnixTimestamp(p.format, p.from, p.to),
|
|
285
|
-
latitude: (p) => Number((0, exports.randFloat)(p.min ?? -90, p.max ?? 90).toFixed(6)),
|
|
286
|
-
longitude: (p) => Number((0, exports.randFloat)(p.min ?? -180, p.max ?? 180).toFixed(6)),
|
|
287
|
-
sequence: (p, idx) => (p.start ?? 1) + idx * (p.step ?? 1),
|
|
288
|
-
int: (p) => (0, exports.randInt)(p.min ?? 1, Math.max(p.min ?? 1, p.max ?? 1000)),
|
|
289
|
-
decimal: (p) => (0, exports.randFloat)(p.min ?? 1, Math.max(p.min ?? 1, p.max ?? 1000)).toFixed(Math.max(0, Math.min(10, p.precision ?? 2))),
|
|
290
|
-
pattern: (p) => formatPattern(p.pattern || 'INV-2026-####'),
|
|
291
|
-
fixed: (p) => p.value ?? '',
|
|
292
|
-
token: (p) => randomAlnum(Math.max(2, p.minLen ?? 6), Math.max(2, p.maxLen ?? 12)),
|
|
293
|
-
hash: (p) => {
|
|
294
|
-
const len = (0, exports.randInt)(Math.max(8, p.minLen ?? 32), Math.max(8, p.maxLen ?? 64));
|
|
295
|
-
return (0, node_crypto_1.randomBytes)(Math.ceil(len / 2)).toString('hex').slice(0, len);
|
|
296
|
-
},
|
|
297
|
-
};
|
|
298
|
-
function generateOne(col, p, fkPool, rowIndex = 0) {
|
|
299
|
-
const type = (col.type || '').toUpperCase();
|
|
300
|
-
if (!col.pk && !col.notnull && p.nullPct && p.nullPct > 0) {
|
|
301
|
-
if (Math.random() * 100 < p.nullPct)
|
|
302
|
-
return null;
|
|
303
|
-
}
|
|
304
|
-
if (p.strategy === 'skip')
|
|
305
|
-
return types_1.SKIP;
|
|
306
|
-
if (p.strategy === 'null')
|
|
307
|
-
return null;
|
|
308
|
-
if (p.strategy === 'list') {
|
|
309
|
-
const vals = (p.values ?? []).filter((v) => String(v).trim() !== '');
|
|
310
|
-
if (!vals.length)
|
|
311
|
-
return types_1.SKIP;
|
|
312
|
-
return (0, common_1.coerceFormValue)(String((0, exports.pick)(vals)), type || 'TEXT');
|
|
313
|
-
}
|
|
314
|
-
if (p.strategy === 'fk') {
|
|
315
|
-
return fkPool && fkPool.length ? fkPool[(0, exports.randInt)(0, fkPool.length - 1)] : null;
|
|
316
|
-
}
|
|
317
|
-
if (p.strategy === 'bytes') {
|
|
318
|
-
const len = (0, exports.randInt)(Math.max(0, p.minLen ?? 8), Math.max(1, p.maxLen ?? 32));
|
|
319
|
-
const buf = Buffer.alloc(len);
|
|
320
|
-
for (let i = 0; i < len; i++)
|
|
321
|
-
buf[i] = (0, exports.randInt)(0, 255);
|
|
322
|
-
return (0, common_1.coerceFormValue)(`0x${buf.toString('hex')}`, type || 'BLOB');
|
|
323
|
-
}
|
|
324
|
-
const gen = BASIC_STRATEGIES[p.strategy];
|
|
325
|
-
if (!gen)
|
|
326
|
-
return types_1.SKIP;
|
|
327
|
-
let rawVal = gen(p, rowIndex);
|
|
328
|
-
if (rawVal != null && (p.prefix || p.suffix) && typeof rawVal === 'string') {
|
|
329
|
-
rawVal = `${p.prefix || ''}${rawVal}${p.suffix || ''}`;
|
|
330
|
-
}
|
|
331
|
-
return (0, common_1.coerceFormValue)(String(rawVal), type || 'TEXT');
|
|
332
|
-
}
|
|
333
|
-
function generateSampleValue(col, plan, fkPool) {
|
|
334
|
-
const v = generateOne(col, plan, fkPool || ['[FK sample]'], 0);
|
|
335
|
-
if (v === types_1.SKIP)
|
|
336
|
-
return '(omitted / default)';
|
|
337
|
-
if (v === null)
|
|
338
|
-
return 'NULL';
|
|
339
|
-
if (v instanceof Uint8Array || Buffer.isBuffer(v))
|
|
340
|
-
return `0x${Buffer.from(v).toString('hex').slice(0, 16)}...`;
|
|
341
|
-
return v;
|
|
342
|
-
}
|
|
343
|
-
//# sourceMappingURL=strategies.js.map
|
|
1
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.randomTime=exports.makeParagraph=exports.makeColor=exports.makeAvatar=exports.makeCreditCard=exports.makeIp=exports.makeAddress=exports.makePhone=exports.makeUsername=exports.makeEmail=exports.makeSlug=exports.pick=exports.randFloat=exports.randInt=void 0,exports.makeMacAddress=makeMacAddress,exports.makeUuid=makeUuid,exports.makeWords=makeWords,exports.makeSentences=makeSentences,exports.formatPattern=formatPattern,exports.randomDate=randomDate,exports.randomUnixTimestamp=randomUnixTimestamp,exports.randomAlnum=randomAlnum,exports.makeJsonObject=makeJsonObject,exports.isTextishType=isTextishType,exports.strategiesFor=function(col,fk){const type=(col.type||"").toUpperCase(),isText=isTextishType(type),isNum=type.startsWith("INTEGER")||"REAL"===type||type.includes("DECIMAL")||type.includes("NUMERIC")||isText,isBlob="BLOB"===type||isText,out=[];fk&&out.push({id:"fk",label:`Foreign Key: Sample from ${fk.table}${fk.to?`.${fk.to}`:""}`,category:"relational"});for(const[id,label,category,target]of STRATEGY_METADATA)("all"===target||"text"===target&&isText||"numeric"===target&&isNum||"blob"===target&&isBlob)&&out.push({id:id,label:label,category:category});return out},exports.fallbackPlanFor=function(col){const type=(col.type||"").toUpperCase();return"BOOLEAN"===type||"BOOL"===type?{strategy:"bool"}:"UUID"===type?{strategy:"uuid"}:"JSON"===type||"JSONB"===type?{strategy:"json"}:type.startsWith("INT")||"BIGINT"===type||"SMALLINT"===type||"SERIAL"===type||"BIGSERIAL"===type?{strategy:"int",min:1,max:1e3}:"REAL"===type||type.includes("DECIMAL")||"NUMERIC"===type||type.includes("FLOAT")||type.includes("DOUBLE")?{strategy:"decimal",min:1,max:1e3,precision:2}:"DATE"===type?{strategy:"date",from:"2020-01-01",to:"2026-12-31"}:type.includes("TIMESTAMP")||"DATETIME"===type?{strategy:"datetime",from:"2024-01-01T00:00:00",to:"2026-12-31T23:59:59"}:"TIME"===type?{strategy:"time"}:"BLOB"===type||"BYTEA"===type?{strategy:"bytes",minLen:8,maxLen:32}:"INET"===type?{strategy:"ip"}:{strategy:"words",minLen:1,maxLen:4}},exports.generateOne=generateOne,exports.generateSampleValue=function(col,plan,fkPool){const v=generateOne(col,plan,fkPool||["[FK sample]"],0);return v===types_1.SKIP?"(omitted / default)":null===v?"NULL":v instanceof Uint8Array||Buffer.isBuffer(v)?`0x${Buffer.from(v).toString("hex").slice(0,16)}...`:v};const node_crypto_1=require("node:crypto"),common_1=require("../utils/common"),datasets_1=require("./datasets"),types_1=require("./types");exports.randInt=(min,max)=>Math.floor(Math.random()*(max-min+1))+min;exports.randFloat=(min,max)=>Math.random()*(max-min)+min;exports.pick=arr=>arr[(0,exports.randInt)(0,arr.length-1)];exports.makeSlug=()=>`${(0,exports.pick)(datasets_1.LOREM_WORDS)}-${(0,exports.pick)(datasets_1.LOREM_WORDS)}-${(0,exports.randInt)(100,999)}`;exports.makeEmail=()=>`${(0,exports.pick)(datasets_1.FIRST_NAMES).toLowerCase()}.${(0,exports.pick)(datasets_1.LAST_NAMES).toLowerCase()}${(0,exports.randInt)(1,99)}@${(0,exports.pick)(datasets_1.DOMAINS)}`;exports.makeUsername=()=>`${(0,exports.pick)(datasets_1.FIRST_NAMES).toLowerCase()}${(0,exports.pick)(datasets_1.LAST_NAMES).toLowerCase()}${(0,exports.randInt)(1,9999)}`;exports.makePhone=()=>`+1 (${(0,exports.randInt)(200,999)}) ${(0,exports.randInt)(200,999)}-${String((0,exports.randInt)(0,9999)).padStart(4,"0")}`;exports.makeAddress=()=>`${(0,exports.randInt)(10,9999)} ${(0,exports.pick)(datasets_1.LOREM_WORDS)} ${(0,exports.pick)(["St","Ave","Rd","Blvd","Ln","Dr"])}, ${(0,exports.pick)(datasets_1.CITIES)}`;function makeMacAddress(){const b=()=>(0,exports.randInt)(0,255).toString(16).padStart(2,"0").toUpperCase();return`${b()}:${b()}:${b()}:${b()}:${b()}:${b()}`}exports.makeIp=()=>`${(0,exports.randInt)(1,223)}.${(0,exports.randInt)(0,255)}.${(0,exports.randInt)(0,255)}.${(0,exports.randInt)(1,254)}`;exports.makeCreditCard=()=>`4532-${(0,exports.randInt)(1e3,9999)}-${(0,exports.randInt)(1e3,9999)}-${(0,exports.randInt)(1e3,9999)}`;exports.makeAvatar=seedVal=>`https://api.dicebear.com/7.x/avataaars/svg?seed=${encodeURIComponent(seedVal||(0,exports.makeUsername)())}`;function makeUuid(){const h=n=>(0,exports.randInt)(0,4294967295).toString(16).padStart(n,"0");return`${h(8)}-${h(4).slice(0,4)}-4${h(3).slice(0,3)}-${["8","9","a","b"][(0,exports.randInt)(0,3)]}${h(3).slice(0,3)}-${h(12).slice(0,12)}`}function makeWords(minLen,maxLen){const n=(0,exports.randInt)(minLen,maxLen),parts=[];for(let i=0;i<n;i++)parts.push((0,exports.pick)(datasets_1.LOREM_WORDS));return parts.join(" ")}function makeSentences(minLen,maxLen){const n=(0,exports.randInt)(minLen,maxLen),sentences=[];for(let i=0;i<n;i++){const words=makeWords(6,14).split(" ");words[0]=words[0].charAt(0).toUpperCase()+words[0].slice(1),sentences.push(words.join(" ")+".")}return sentences.join(" ")}exports.makeColor=(format="hex")=>"name"===format?(0,exports.pick)(datasets_1.NAMED_COLORS):(0,exports.pick)(datasets_1.HEX_COLORS);function formatPattern(pattern){if(!pattern)return"";const now=new Date,year=String(now.getFullYear()),s=pattern.replace(/\{YYYY\}/g,year).replace(/\{YY\}/g,year.slice(-2)).replace(/\{MM\}/g,String((0,exports.randInt)(1,12)).padStart(2,"0")).replace(/\{DD\}/g,String((0,exports.randInt)(1,28)).padStart(2,"0"));let res="";for(let i=0;i<s.length;i++){const ch=s[i];res+="#"===ch?(0,exports.randInt)(0,9):"A"===ch||"?"===ch?"ABCDEFGHIJKLMNOPQRSTUVWXYZ"[(0,exports.randInt)(0,25)]:"a"===ch?"abcdefghijklmnopqrstuvwxyz"[(0,exports.randInt)(0,25)]:ch}return res}function randomDate(from,to,kind="date"){const now=Date.now(),lo=from?Date.parse(from):now-63072e6,hi=to?Date.parse(to):now,d=new Date((0,exports.randInt)(Number.isFinite(lo)?lo:now-63072e6,Number.isFinite(hi)?hi:now));if("datetime"===kind)return d.toISOString();const p=n=>String(n).padStart(2,"0");return`${d.getFullYear()}-${p(d.getMonth()+1)}-${p(d.getDate())}`}exports.makeParagraph=()=>makeSentences(3,5);function randomUnixTimestamp(format="sec",from,to){const now=Date.now(),lo=from?Date.parse(from):now-63072e6,hi=to?Date.parse(to):now,t=(0,exports.randInt)(Number.isFinite(lo)?lo:now-63072e6,Number.isFinite(hi)?hi:now);return"ms"===format?t:Math.floor(t/1e3)}exports.randomTime=()=>`${String((0,exports.randInt)(0,23)).padStart(2,"0")}:${String((0,exports.randInt)(0,59)).padStart(2,"0")}:${String((0,exports.randInt)(0,59)).padStart(2,"0")}`;const ALNUM="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";function randomAlnum(minLen,maxLen){const len=(0,exports.randInt)(minLen,maxLen);let s="";for(let i=0;i<len;i++)s+=ALNUM[(0,exports.randInt)(0,ALNUM.length-1)];return s}const JSON_ROLES=["admin","editor","viewer","billing","member","owner","guest"],JSON_APPS=["dashboard","api","mobile","cli","webhook","cron","importer"];function jsonValueForKey(key){const lk=key.toLowerCase();if(lk.includes("role"))return(0,exports.pick)(JSON_ROLES);if(lk.includes("app"))return[(0,exports.pick)(JSON_APPS)];const roll=Math.random();return roll<.45?(0,exports.pick)(["alpha","beta","stable","draft","on","off","default","custom"]):roll<.6?(0,exports.randInt)(0,1e3):roll<.75?Math.random()<.5:roll<.9?null:makeUuid()}function makeJsonObject(keys,jsonValues){const k=(keys&&keys.length?keys:["scope","enabled","flags"]).slice(0,16),obj={};for(const key of k){const allowed=jsonValues?jsonValues[key]:void 0;obj[key]=allowed&&allowed.length?(0,exports.pick)(allowed):jsonValueForKey(key)}return JSON.stringify(obj)}function isTextishType(type){const t=(type||"").toUpperCase();return"TEXT"===t||""===t||t.includes("JSON")||t.includes("CHAR")||t.includes("CLOB")||t.includes("VARCHAR")}const STRATEGY_METADATA=[["skip","Skip (DB default or NULL applies)","custom_control","all"],["null","Set NULL explicitly","custom_control","all"],["fixed","Fixed constant value","custom_control","all"],["list","Random item from custom list","custom_control","all"],["pattern","Custom pattern template (e.g. INV-####)","custom_control","all"],["fullname","Full name (e.g. John Smith)","identity","text"],["first","First name","identity","text"],["last","Last name / Surname","identity","text"],["username","Username handle","identity","text"],["job","Job title / Profession","identity","text"],["email","Email address","contact_web","text"],["phone","Phone number","contact_web","text"],["url","Website URL","contact_web","text"],["domain","Domain name","contact_web","text"],["ip","IPv4 address","contact_web","text"],["avatar","Avatar image URL","contact_web","text"],["company","Company / Organization name","commerce","text"],["currency","Currency code (USD, EUR...)","commerce","text"],["status","Status badge (active, pending...)","commerce","text"],["creditCard","Masked test credit card","commerce","text"],["address","Street address","location","text"],["city","City name","location","text"],["state","State / Province","location","text"],["country","Country name","location","text"],["countryCode","Country code (ISO-2 e.g. US)","location","text"],["postal","Postal / Zip code","location","text"],["latitude","Latitude (-90 to 90)","location","all"],["longitude","Longitude (-180 to 180)","location","all"],["int","Random integer in range","numeric","numeric"],["decimal","Random decimal / price","numeric","numeric"],["sequence","Sequential numbering (1, 2, 3...)","numeric","numeric"],["date","Random date (YYYY-MM-DD)","datetime","all"],["datetime","Random datetime (ISO-8601)","datetime","all"],["time","Random time (HH:MM:SS)","datetime","all"],["timestampUnix","Unix timestamp (epoch)","datetime","all"],["words","Short words / Tags","system_crypto","text"],["sentence","Sentences","system_crypto","text"],["paragraph","Paragraph (multi-sentence text)","system_crypto","text"],["slug","URL slug (e.g. tech-news-402)","system_crypto","text"],["bool","Boolean flag (1/0 or true/false)","system_crypto","all"],["bytes","Random hex bytes (BLOB)","system_crypto","blob"],["uuid","UUID v4","system_crypto","text"],["token","Short alphanumeric token","system_crypto","text"],["hash","Hexadecimal hash (MD5/SHA)","system_crypto","text"],["json","Valid JSON object","system_crypto","text"],["color","Color (Hex code or name)","system_crypto","text"],["mac","MAC network address","system_crypto","text"]];const BASIC_STRATEGIES={first:()=>(0,exports.pick)(datasets_1.FIRST_NAMES),last:()=>(0,exports.pick)(datasets_1.LAST_NAMES),fullname:()=>`${(0,exports.pick)(datasets_1.FIRST_NAMES)} ${(0,exports.pick)(datasets_1.LAST_NAMES)}`,email:()=>(0,exports.makeEmail)(),username:()=>(0,exports.makeUsername)(),job:()=>(0,exports.pick)(datasets_1.JOB_TITLES),company:()=>(0,exports.pick)(datasets_1.COMPANIES),currency:()=>(0,exports.pick)(datasets_1.CURRENCIES),status:()=>(0,exports.pick)(datasets_1.STATUSES),creditCard:()=>(0,exports.makeCreditCard)(),avatar:()=>(0,exports.makeAvatar)(),color:p=>(0,exports.makeColor)(p.format),phone:()=>(0,exports.makePhone)(),city:()=>(0,exports.pick)(datasets_1.CITIES),state:()=>(0,exports.pick)(datasets_1.US_STATES),country:()=>(0,exports.pick)(datasets_1.COUNTRIES),countryCode:()=>(0,exports.pick)(datasets_1.COUNTRY_CODES),postal:()=>String((0,exports.randInt)(1e4,99999)),address:()=>(0,exports.makeAddress)(),url:()=>`https://www.${(0,exports.pick)(datasets_1.DOMAINS)}/${(0,exports.makeSlug)()}`,domain:()=>(0,exports.pick)(datasets_1.DOMAINS),ip:()=>(0,exports.makeIp)(),mac:()=>makeMacAddress(),uuid:()=>makeUuid(),slug:()=>(0,exports.makeSlug)(),paragraph:()=>(0,exports.makeParagraph)(),time:()=>(0,exports.randomTime)(),bool:()=>(0,exports.pick)(["1","0"]),json:p=>makeJsonObject(p.jsonKeys,p.jsonValues),words:p=>makeWords(p.minLen??1,p.maxLen??4),sentence:p=>makeSentences(p.minLen??1,p.maxLen??2),date:p=>randomDate(p.from,p.to,"date"),datetime:p=>randomDate(p.from,p.to,"datetime"),timestampUnix:p=>randomUnixTimestamp(p.format,p.from,p.to),latitude:p=>Number((0,exports.randFloat)(p.min??-90,p.max??90).toFixed(6)),longitude:p=>Number((0,exports.randFloat)(p.min??-180,p.max??180).toFixed(6)),sequence:(p,idx)=>(p.start??1)+idx*(p.step??1),int:p=>(0,exports.randInt)(p.min??1,Math.max(p.min??1,p.max??1e3)),decimal:p=>(0,exports.randFloat)(p.min??1,Math.max(p.min??1,p.max??1e3)).toFixed(Math.max(0,Math.min(10,p.precision??2))),pattern:p=>formatPattern(p.pattern||"INV-2026-####"),fixed:p=>p.value??"",token:p=>randomAlnum(Math.max(2,p.minLen??6),Math.max(2,p.maxLen??12)),hash:p=>{const len=(0,exports.randInt)(Math.max(8,p.minLen??32),Math.max(8,p.maxLen??64));return(0,node_crypto_1.randomBytes)(Math.ceil(len/2)).toString("hex").slice(0,len)}};function generateOne(col,p,fkPool,rowIndex=0){const type=(col.type||"").toUpperCase();if(!col.pk&&!col.notnull&&p.nullPct&&p.nullPct>0&&100*Math.random()<p.nullPct)return null;if("skip"===p.strategy)return types_1.SKIP;if("null"===p.strategy)return null;if("list"===p.strategy){const vals=(p.values??[]).filter(v=>""!==String(v).trim());return vals.length?(0,common_1.coerceFormValue)(String((0,exports.pick)(vals)),type||"TEXT"):types_1.SKIP}if("fk"===p.strategy)return fkPool&&fkPool.length?fkPool[(0,exports.randInt)(0,fkPool.length-1)]:null;if("bytes"===p.strategy){const len=(0,exports.randInt)(Math.max(0,p.minLen??8),Math.max(1,p.maxLen??32)),buf=Buffer.alloc(len);for(let i=0;i<len;i++)buf[i]=(0,exports.randInt)(0,255);return(0,common_1.coerceFormValue)(`0x${buf.toString("hex")}`,type||"BLOB")}const gen=BASIC_STRATEGIES[p.strategy];if(!gen)return types_1.SKIP;let rawVal=gen(p,rowIndex);return null!=rawVal&&(p.prefix||p.suffix)&&"string"==typeof rawVal&&(rawVal=`${p.prefix||""}${rawVal}${p.suffix||""}`),(0,common_1.coerceFormValue)(String(rawVal),type||"TEXT")}
|
package/dist/data/types.d.ts
CHANGED
|
@@ -1,73 +1 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
/** Hard cap on how many rows a single seed run may generate. */
|
|
3
|
-
export declare const MAX_SEED_ROWS = 5000;
|
|
4
|
-
export type StrategyCategory = 'identity' | 'contact_web' | 'commerce' | 'location' | 'numeric' | 'datetime' | 'system_crypto' | 'custom_control' | 'relational';
|
|
5
|
-
export type GeneratorStrategyId = 'skip' | 'null' | 'fixed' | 'list' | 'pattern' | 'first' | 'last' | 'fullname' | 'username' | 'job' | 'email' | 'phone' | 'url' | 'domain' | 'ip' | 'avatar' | 'company' | 'currency' | 'status' | 'creditCard' | 'city' | 'country' | 'state' | 'postal' | 'address' | 'countryCode' | 'latitude' | 'longitude' | 'words' | 'sentence' | 'paragraph' | 'slug' | 'int' | 'decimal' | 'sequence' | 'date' | 'datetime' | 'time' | 'timestampUnix' | 'bool' | 'bytes' | 'json' | 'hash' | 'token' | 'uuid' | 'color' | 'mac' | 'fk';
|
|
6
|
-
/** Per-column generator settings. Which options are meaningful depends on `strategy`. */
|
|
7
|
-
export interface ColumnPlan {
|
|
8
|
-
strategy: GeneratorStrategyId;
|
|
9
|
-
/** `fixed` / `list` and the string-ish options. */
|
|
10
|
-
value?: string;
|
|
11
|
-
/** `list` — random value picked from this set. */
|
|
12
|
-
values?: string[];
|
|
13
|
-
/** `int` / `decimal` / `latitude` / `longitude` range. */
|
|
14
|
-
min?: number;
|
|
15
|
-
max?: number;
|
|
16
|
-
/** `decimal` — digits after the decimal point. */
|
|
17
|
-
precision?: number;
|
|
18
|
-
/** `date` / `datetime` / `timestampUnix` bounds (ISO strings). */
|
|
19
|
-
from?: string;
|
|
20
|
-
to?: string;
|
|
21
|
-
/** `words` / `bytes` / `hash` / `token` / `sentence` — length bounds. */
|
|
22
|
-
minLen?: number;
|
|
23
|
-
maxLen?: number;
|
|
24
|
-
/** `json` — object keys to include (comma-separated in the UI). */
|
|
25
|
-
jsonKeys?: string[];
|
|
26
|
-
/** `json` — per-key allowed values, derived from CHECK constraints. */
|
|
27
|
-
jsonValues?: Record<string, string[]>;
|
|
28
|
-
/** Percentage chance (0 to 100) to generate NULL for nullable columns. */
|
|
29
|
-
nullPct?: number;
|
|
30
|
-
/** Optional string prefix to prepend to generated string/text values. */
|
|
31
|
-
prefix?: string;
|
|
32
|
-
/** Optional string suffix to append to generated string/text values. */
|
|
33
|
-
suffix?: string;
|
|
34
|
-
/** Sequence start (for `sequence` strategy). */
|
|
35
|
-
start?: number;
|
|
36
|
-
/** Sequence step increment (for `sequence` strategy). */
|
|
37
|
-
step?: number;
|
|
38
|
-
/** Custom pattern template with tokens (for `pattern` strategy). */
|
|
39
|
-
pattern?: string;
|
|
40
|
-
/** Format variation (e.g. 'hex' | 'name' for color, 'sec' | 'ms' for unix timestamp). */
|
|
41
|
-
format?: string;
|
|
42
|
-
}
|
|
43
|
-
/** A strategy choice offered to the UI for a column. */
|
|
44
|
-
export interface StrategyDescriptor {
|
|
45
|
-
id: GeneratorStrategyId;
|
|
46
|
-
label: string;
|
|
47
|
-
category: StrategyCategory;
|
|
48
|
-
description?: string;
|
|
49
|
-
}
|
|
50
|
-
/** Everything the "Seed data" page needs to render one column's controls. */
|
|
51
|
-
export interface ColumnGeneratorConfig {
|
|
52
|
-
name: string;
|
|
53
|
-
type: string;
|
|
54
|
-
pk: boolean;
|
|
55
|
-
notnull: boolean;
|
|
56
|
-
hasDefault: boolean;
|
|
57
|
-
/** True when a single-column UNIQUE index enforces uniqueness on this column. */
|
|
58
|
-
unique: boolean;
|
|
59
|
-
/** The foreign key this column participates in (as the child), if any. */
|
|
60
|
-
fk: ForeignKeyInfo | null;
|
|
61
|
-
strategies: StrategyDescriptor[];
|
|
62
|
-
defaultPlan: ColumnPlan;
|
|
63
|
-
}
|
|
64
|
-
export interface GenerateResult {
|
|
65
|
-
/** One entry per generated row: the columns/values to bind (skipped columns are absent). */
|
|
66
|
-
rows: WhereClause[][];
|
|
67
|
-
/** Structured row records for interactive UI table preview. */
|
|
68
|
-
previewRows: Record<string, unknown>[];
|
|
69
|
-
/** Non-fatal notes surfaced to the user (e.g. a NOT NULL column being skipped). */
|
|
70
|
-
warnings: string[];
|
|
71
|
-
}
|
|
72
|
-
/** Sentinel returned by value generation when the column should be omitted from the row. */
|
|
73
|
-
export declare const SKIP: unique symbol;
|
|
1
|
+
import type {ForeignKeyInfo,WhereClause} from '../db/database';export declare const MAX_SEED_ROWS=5000;export type StrategyCategory='identity'|'contact_web'|'commerce'|'location'|'numeric'|'datetime'|'system_crypto'|'custom_control'|'relational';export type GeneratorStrategyId='skip'|'null'|'fixed'|'list'|'pattern'|'first'|'last'|'fullname'|'username'|'job'|'email'|'phone'|'url'|'domain'|'ip'|'avatar'|'company'|'currency'|'status'|'creditCard'|'city'|'country'|'state'|'postal'|'address'|'countryCode'|'latitude'|'longitude'|'words'|'sentence'|'paragraph'|'slug'|'int'|'decimal'|'sequence'|'date'|'datetime'|'time'|'timestampUnix'|'bool'|'bytes'|'json'|'hash'|'token'|'uuid'|'color'|'mac'|'fk';export interface ColumnPlan{strategy:GeneratorStrategyId;value?:string;values?:string[];min?:number;max?:number;precision?:number; from ?:string;to?:string;minLen?:number;maxLen?:number;jsonKeys?:string[];jsonValues?:Record<string,string[]>;nullPct?:number;prefix?:string;suffix?:string;start?:number;step?:number;pattern?:string;format?:string;}export interface StrategyDescriptor{id:GeneratorStrategyId;label:string;category:StrategyCategory;description?:string;}export interface ColumnGeneratorConfig{name:string;type:string;pk:boolean;notnull:boolean;hasDefault:boolean;unique:boolean;fk:ForeignKeyInfo|null;strategies:StrategyDescriptor[];defaultPlan:ColumnPlan;}export interface GenerateResult{rows:WhereClause[][];previewRows:Record<string,unknown>[];warnings:string[];}export declare const SKIP:unique symbol;
|
package/dist/data/types.js
CHANGED
|
@@ -1,8 +1 @@
|
|
|
1
|
-
"
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SKIP = exports.MAX_SEED_ROWS = void 0;
|
|
4
|
-
/** Hard cap on how many rows a single seed run may generate. */
|
|
5
|
-
exports.MAX_SEED_ROWS = 5000;
|
|
6
|
-
/** Sentinel returned by value generation when the column should be omitted from the row. */
|
|
7
|
-
exports.SKIP = Symbol('skip');
|
|
8
|
-
//# sourceMappingURL=types.js.map
|
|
1
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.SKIP=exports.MAX_SEED_ROWS=void 0,exports.MAX_SEED_ROWS=5e3,exports.SKIP=Symbol("skip");
|
package/dist/db/database.d.ts
CHANGED
|
@@ -1,119 +1 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import { type ColumnDef, type IndexDef } from '../sql/generator';
|
|
3
|
-
import type { DatabaseDialect, DbOpenOptions, IDatabase, ReferencingTableInfo, Result, RowFilters, SavedQuery, SchemaInfo, SQLInputValue, TableInfoData, TableListItem, WhereClause } from './types';
|
|
4
|
-
export * from './types';
|
|
5
|
-
export * from './filters';
|
|
6
|
-
/**
|
|
7
|
-
* Promise-style wrapper around the better-sqlite3 driver.
|
|
8
|
-
* Every call returns a consistent `{ success, data?, error? }` shape and
|
|
9
|
-
* performs one-time, idempotent schema initialization.
|
|
10
|
-
*/
|
|
11
|
-
export declare class SqliteDatabase implements IDatabase {
|
|
12
|
-
private db;
|
|
13
|
-
private logger;
|
|
14
|
-
readonly path: string;
|
|
15
|
-
readonly isReadOnly: boolean;
|
|
16
|
-
readonly dialect: DatabaseDialect;
|
|
17
|
-
constructor(dbPath: string, logger: Logger, options?: DbOpenOptions);
|
|
18
|
-
private readonlyBlocked;
|
|
19
|
-
close(): void;
|
|
20
|
-
private initSchema;
|
|
21
|
-
private tryRun;
|
|
22
|
-
/** Run an atomic transaction. Reverts on any error and enforces read-only mode. */
|
|
23
|
-
private transaction;
|
|
24
|
-
private toBind;
|
|
25
|
-
all(sql: string, params?: SQLInputValue[]): Promise<Result<unknown[]>>;
|
|
26
|
-
run(sql: string, params?: SQLInputValue[]): Promise<Result<{
|
|
27
|
-
changes: number;
|
|
28
|
-
lastInsertRowid: number | null;
|
|
29
|
-
}>>;
|
|
30
|
-
execResult(sql: string): Promise<Result<{
|
|
31
|
-
changes?: number;
|
|
32
|
-
}>>;
|
|
33
|
-
hasMultipleStatements(sql: string): boolean;
|
|
34
|
-
runWrite(sql: string): Promise<Result<{
|
|
35
|
-
changes?: number;
|
|
36
|
-
}>>;
|
|
37
|
-
listTables(): Promise<Result<TableListItem[]>>;
|
|
38
|
-
getTableInfo(table: string): Promise<Result<TableInfoData>>;
|
|
39
|
-
getRowCount(table: string, filters?: RowFilters): Promise<Result<number>>;
|
|
40
|
-
getRows(table: string, opts?: {
|
|
41
|
-
page?: number;
|
|
42
|
-
limit?: number;
|
|
43
|
-
orderBy?: string;
|
|
44
|
-
orderDir?: 'asc' | 'desc';
|
|
45
|
-
filters?: RowFilters;
|
|
46
|
-
}): Promise<Result<Record<string, unknown>[]>>;
|
|
47
|
-
getAllRows(table: string): Promise<Result<Record<string, unknown>[]>>;
|
|
48
|
-
getRow(table: string, where: WhereClause[]): Promise<Result<Record<string, unknown> | null>>;
|
|
49
|
-
insertRow(table: string, fields: WhereClause[]): Promise<Result<{
|
|
50
|
-
changes: number;
|
|
51
|
-
lastInsertRowid: number | null;
|
|
52
|
-
}>>;
|
|
53
|
-
/** Insert many rows inside a single atomic transaction. */
|
|
54
|
-
insertRows(table: string, rows: WhereClause[][]): Promise<Result<{
|
|
55
|
-
inserted: number;
|
|
56
|
-
skipped: number;
|
|
57
|
-
}>>;
|
|
58
|
-
updateRow(table: string, fields: WhereClause[], where: WhereClause[]): Promise<Result<{
|
|
59
|
-
changes: number;
|
|
60
|
-
lastInsertRowid: number | null;
|
|
61
|
-
}>>;
|
|
62
|
-
/** Apply many row updates inside a single atomic transaction. */
|
|
63
|
-
updateRows(table: string, rows: {
|
|
64
|
-
fields: WhereClause[];
|
|
65
|
-
where: WhereClause[];
|
|
66
|
-
}[]): Promise<Result<{
|
|
67
|
-
updated: number;
|
|
68
|
-
}>>;
|
|
69
|
-
deleteRow(table: string, where: WhereClause[]): Promise<Result<{
|
|
70
|
-
changes: number;
|
|
71
|
-
lastInsertRowid: number | null;
|
|
72
|
-
}>>;
|
|
73
|
-
/** Delete many rows inside a single atomic transaction. */
|
|
74
|
-
deleteRows(table: string, rows: WhereClause[][]): Promise<Result<{
|
|
75
|
-
deleted: number;
|
|
76
|
-
}>>;
|
|
77
|
-
getRowsByPks(table: string, pks: WhereClause[][]): Promise<Result<Record<string, unknown>[]>>;
|
|
78
|
-
getCreateStatement(table: string): Promise<Result<string | null>>;
|
|
79
|
-
listSavedQueries(): Promise<Result<SavedQuery[]>>;
|
|
80
|
-
saveQuery(name: string, sql: string): Promise<Result<{
|
|
81
|
-
changes: number;
|
|
82
|
-
lastInsertRowid: number | null;
|
|
83
|
-
}>>;
|
|
84
|
-
deleteSavedQuery(id: string | number): Promise<Result<{
|
|
85
|
-
changes: number;
|
|
86
|
-
lastInsertRowid: number | null;
|
|
87
|
-
}>>;
|
|
88
|
-
getSchema(table: string): Promise<Result<SchemaInfo>>;
|
|
89
|
-
getReferencingTables(table: string): Promise<Result<ReferencingTableInfo[]>>;
|
|
90
|
-
getRowsByFk(table: string, column: string, value: unknown, limit?: number): Promise<Result<{
|
|
91
|
-
rows: Record<string, unknown>[];
|
|
92
|
-
total: number;
|
|
93
|
-
}>>;
|
|
94
|
-
renameTable(oldName: string, newName: string): Promise<Result<{
|
|
95
|
-
changes?: number;
|
|
96
|
-
}>>;
|
|
97
|
-
addColumn(table: string, col: ColumnDef): Promise<Result<{
|
|
98
|
-
changes?: number;
|
|
99
|
-
}>>;
|
|
100
|
-
modifyColumn(table: string, oldColName: string, newColDef: ColumnDef): Promise<Result<{
|
|
101
|
-
changes?: number;
|
|
102
|
-
}>>;
|
|
103
|
-
renameColumn(table: string, oldName: string, newName: string): Promise<Result<{
|
|
104
|
-
changes?: number;
|
|
105
|
-
}>>;
|
|
106
|
-
dropColumn(table: string, column: string): Promise<Result<{
|
|
107
|
-
changes?: number;
|
|
108
|
-
}>>;
|
|
109
|
-
dropTable(table: string): Promise<Result<{
|
|
110
|
-
changes?: number;
|
|
111
|
-
}>>;
|
|
112
|
-
createIndex(table: string, index: IndexDef): Promise<Result<{
|
|
113
|
-
changes?: number;
|
|
114
|
-
}>>;
|
|
115
|
-
dropIndex(indexName: string): Promise<Result<{
|
|
116
|
-
changes?: number;
|
|
117
|
-
}>>;
|
|
118
|
-
private getTableInfoSync;
|
|
119
|
-
}
|
|
1
|
+
import type {Logger} from '../utils/logger';import{type ColumnDef,type IndexDef} from '../sql/generator';import type {DatabaseDialect,DbOpenOptions,IDatabase,ReferencingTableInfo,Result,RowFilters,SavedQuery,SchemaInfo,SQLInputValue,TableInfoData,TableListItem,WhereClause} from './types';export * from './types';export * from './filters';export declare class SqliteDatabase implements IDatabase{private db;private logger;readonly path:string;readonly isReadOnly:boolean;readonly dialect:DatabaseDialect;constructor(dbPath:string,logger:Logger,options?:DbOpenOptions);private readonlyBlocked;close():void;private initSchema;private tryRun;private transaction;private toBind;all(sql:string,params?:SQLInputValue[]):Promise<Result<unknown[]>>;run(sql:string,params?:SQLInputValue[]):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;execResult(sql:string):Promise<Result<{changes?:number;}>>;hasMultipleStatements(sql:string):boolean;runWrite(sql:string):Promise<Result<{changes?:number;}>>;listTables():Promise<Result<TableListItem[]>>;getTableInfo(table:string):Promise<Result<TableInfoData>>;getRowCount(table:string,filters?:RowFilters):Promise<Result<number>>;getRows(table:string,opts?:{page?:number;limit?:number;orderBy?:string;orderDir?:'asc'|'desc';filters?:RowFilters;}):Promise<Result<Record<string,unknown>[]>>;getAllRows(table:string):Promise<Result<Record<string,unknown>[]>>;getRow(table:string,where:WhereClause[]):Promise<Result<Record<string,unknown>|null>>;insertRow(table:string,fields:WhereClause[]):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;insertRows(table:string,rows:WhereClause[][]):Promise<Result<{inserted:number;skipped:number;}>>;updateRow(table:string,fields:WhereClause[],where:WhereClause[]):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;updateRows(table:string,rows:{fields:WhereClause[];where:WhereClause[];}[]):Promise<Result<{updated:number;}>>;deleteRow(table:string,where:WhereClause[]):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;deleteRows(table:string,rows:WhereClause[][]):Promise<Result<{deleted:number;}>>;getRowsByPks(table:string,pks:WhereClause[][]):Promise<Result<Record<string,unknown>[]>>;getCreateStatement(table:string):Promise<Result<string|null>>;listSavedQueries():Promise<Result<SavedQuery[]>>;saveQuery(name:string,sql:string):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;deleteSavedQuery(id:string|number):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;getSchema(table:string):Promise<Result<SchemaInfo>>;getReferencingTables(table:string):Promise<Result<ReferencingTableInfo[]>>;getRowsByFk(table:string,column:string,value:unknown,limit?:number):Promise<Result<{rows:Record<string,unknown>[];total:number;}>>;renameTable(oldName:string,newName:string):Promise<Result<{changes?:number;}>>;addColumn(table:string,col:ColumnDef):Promise<Result<{changes?:number;}>>;modifyColumn(table:string,oldColName:string,newColDef:ColumnDef):Promise<Result<{changes?:number;}>>;renameColumn(table:string,oldName:string,newName:string):Promise<Result<{changes?:number;}>>;dropColumn(table:string,column:string):Promise<Result<{changes?:number;}>>;dropTable(table:string):Promise<Result<{changes?:number;}>>;createIndex(table:string,index:IndexDef):Promise<Result<{changes?:number;}>>;dropIndex(indexName:string):Promise<Result<{changes?:number;}>>;private getTableInfoSync;}
|