admindb 2.1.0 → 2.2.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.
Files changed (191) hide show
  1. package/README.md +41 -12
  2. package/dist/app.d.ts +1 -69
  3. package/dist/app.js +3 -30
  4. package/dist/auth/config.d.ts +1 -19
  5. package/dist/auth/config.js +0 -26
  6. package/dist/auth/crypto.d.ts +1 -27
  7. package/dist/auth/crypto.js +1 -26
  8. package/dist/auth/index.d.ts +1 -5
  9. package/dist/auth/index.js +0 -1
  10. package/dist/auth/middleware.d.ts +1 -14
  11. package/dist/auth/middleware.js +0 -15
  12. package/dist/auth/routes.d.ts +1 -7
  13. package/dist/auth/routes.js +0 -8
  14. package/dist/auth/types.d.ts +1 -35
  15. package/dist/auth/types.js +1 -5
  16. package/dist/cli/args.d.ts +1 -45
  17. package/dist/cli/args.js +3 -11
  18. package/dist/cli/config.d.ts +1 -56
  19. package/dist/cli/config.js +0 -5
  20. package/dist/cli/index.d.ts +1 -4
  21. package/dist/cli/index.js +0 -1
  22. package/dist/cli/runner.d.ts +1 -1
  23. package/dist/cli/runner.js +6 -17
  24. package/dist/cli.d.ts +1 -2
  25. package/dist/cli.js +0 -1
  26. package/dist/data/chain.d.ts +1 -0
  27. package/dist/data/chain.js +707 -0
  28. package/dist/data/datasets.d.ts +1 -17
  29. package/dist/data/datasets.js +0 -4
  30. package/dist/data/detector.d.ts +1 -30
  31. package/dist/data/detector.js +53 -14
  32. package/dist/data/engine.d.ts +1 -10
  33. package/dist/data/engine.js +82 -48
  34. package/dist/data/index.d.ts +1 -5
  35. package/dist/data/index.js +1 -1
  36. package/dist/data/strategies.d.ts +1 -30
  37. package/dist/data/strategies.js +4 -8
  38. package/dist/data/types.d.ts +1 -73
  39. package/dist/data/types.js +0 -3
  40. package/dist/db/database.d.ts +1 -119
  41. package/dist/db/database.js +20 -14
  42. package/dist/db/export.d.ts +1 -12
  43. package/dist/db/export.js +54 -6
  44. package/dist/db/filters.d.ts +1 -22
  45. package/dist/db/filters.js +0 -16
  46. package/dist/db/index.d.ts +1 -8
  47. package/dist/db/index.js +0 -1
  48. package/dist/db/introspection.d.ts +1 -6
  49. package/dist/db/introspection.js +0 -5
  50. package/dist/db/manager.d.ts +1 -81
  51. package/dist/db/manager.js +13 -59
  52. package/dist/db/migrations.d.ts +1 -5
  53. package/dist/db/migrations.js +2 -5
  54. package/dist/db/postgres.d.ts +1 -85
  55. package/dist/db/postgres.js +21 -31
  56. package/dist/db/types.d.ts +1 -206
  57. package/dist/db/types.js +0 -1
  58. package/dist/index.d.ts +1 -23
  59. package/dist/index.js +0 -14
  60. package/dist/public/css/app.css +1 -1
  61. package/dist/public/js/api.js +1 -47
  62. package/dist/public/js/app.js +1 -262
  63. package/dist/public/js/browse.js +1 -1371
  64. package/dist/public/js/common.js +1 -0
  65. package/dist/public/js/databases.js +1 -235
  66. package/dist/public/js/designer.js +1 -258
  67. package/dist/public/js/forms.js +1 -826
  68. package/dist/public/js/home.js +1 -0
  69. package/dist/public/js/inspector.js +1 -638
  70. package/dist/public/js/query.js +1 -322
  71. package/dist/public/js/schema.js +1 -447
  72. package/dist/public/js/seed.js +1 -1090
  73. package/dist/routes/api/erd.d.ts +1 -0
  74. package/dist/routes/api/erd.js +50 -0
  75. package/dist/routes/api/helpers.d.ts +1 -42
  76. package/dist/routes/api/helpers.js +33 -3
  77. package/dist/routes/api/import-export.d.ts +1 -3
  78. package/dist/routes/api/import-export.js +0 -2
  79. package/dist/routes/api/index.d.ts +1 -4
  80. package/dist/routes/api/index.js +15 -4
  81. package/dist/routes/api/query.d.ts +1 -3
  82. package/dist/routes/api/query.js +13 -11
  83. package/dist/routes/api/rows.d.ts +1 -3
  84. package/dist/routes/api/rows.js +0 -11
  85. package/dist/routes/api/seed.d.ts +1 -3
  86. package/dist/routes/api/seed.js +79 -8
  87. package/dist/routes/api/tables.d.ts +1 -3
  88. package/dist/routes/api/tables.js +77 -6
  89. package/dist/routes/databases.d.ts +1 -26
  90. package/dist/routes/databases.js +1 -3
  91. package/dist/routes/index.d.ts +1 -3
  92. package/dist/routes/index.js +0 -1
  93. package/dist/routes/pages.d.ts +1 -9
  94. package/dist/routes/pages.js +18 -11
  95. package/dist/serverless.d.ts +1 -40
  96. package/dist/serverless.js +3 -39
  97. package/dist/sql/classifier.d.ts +1 -19
  98. package/dist/sql/classifier.js +0 -13
  99. package/dist/sql/error-analyzer.d.ts +1 -0
  100. package/dist/sql/error-analyzer.js +550 -0
  101. package/dist/sql/generator.d.ts +1 -81
  102. package/dist/sql/generator.js +0 -29
  103. package/dist/sql/index.d.ts +1 -2
  104. package/dist/sql/index.js +0 -1
  105. package/dist/types/api.d.ts +1 -412
  106. package/dist/types/api.js +0 -7
  107. package/dist/utils/colors.d.ts +1 -40
  108. package/dist/utils/colors.js +0 -10
  109. package/dist/utils/common.d.ts +1 -50
  110. package/dist/utils/common.js +19 -23
  111. package/dist/utils/csv.d.ts +1 -15
  112. package/dist/utils/csv.js +0 -13
  113. package/dist/utils/datatype.d.ts +1 -49
  114. package/dist/utils/datatype.js +0 -41
  115. package/dist/utils/icons.d.ts +1 -11
  116. package/dist/utils/icons.js +25 -16
  117. package/dist/utils/index.d.ts +1 -4
  118. package/dist/utils/index.js +0 -1
  119. package/dist/utils/logger.d.ts +1 -10
  120. package/dist/utils/logger.js +0 -4
  121. package/dist/views/layouts/main.hbs +14 -5
  122. package/dist/views/pages/databases.hbs +0 -18
  123. package/dist/views/pages/designer.hbs +0 -10
  124. package/dist/views/pages/erd.hbs +1241 -0
  125. package/dist/views/pages/error.hbs +0 -2
  126. package/dist/views/pages/form.hbs +0 -5
  127. package/dist/views/pages/home.hbs +98 -10
  128. package/dist/views/pages/info.hbs +107 -0
  129. package/dist/views/pages/login.hbs +0 -13
  130. package/dist/views/pages/query.hbs +54 -21
  131. package/dist/views/pages/schema.hbs +0 -20
  132. package/dist/views/pages/seed.hbs +435 -202
  133. package/dist/views/pages/table.hbs +0 -14
  134. package/dist/views/partials/icon.hbs +0 -1
  135. package/dist/views/partials/navbar.hbs +0 -6
  136. package/dist/views/partials/sidebar.hbs +12 -8
  137. package/docs/API.md +6 -1
  138. package/docs/EXAMPLES.md +3 -0
  139. package/package.json +7 -5
  140. package/dist/app.js.map +0 -1
  141. package/dist/auth/config.js.map +0 -1
  142. package/dist/auth/crypto.js.map +0 -1
  143. package/dist/auth/index.js.map +0 -1
  144. package/dist/auth/middleware.js.map +0 -1
  145. package/dist/auth/routes.js.map +0 -1
  146. package/dist/auth/types.js.map +0 -1
  147. package/dist/cli/args.js.map +0 -1
  148. package/dist/cli/config.js.map +0 -1
  149. package/dist/cli/index.js.map +0 -1
  150. package/dist/cli/runner.js.map +0 -1
  151. package/dist/cli.js.map +0 -1
  152. package/dist/data/datasets.js.map +0 -1
  153. package/dist/data/detector.js.map +0 -1
  154. package/dist/data/engine.js.map +0 -1
  155. package/dist/data/index.js.map +0 -1
  156. package/dist/data/strategies.js.map +0 -1
  157. package/dist/data/types.js.map +0 -1
  158. package/dist/db/database.js.map +0 -1
  159. package/dist/db/export.js.map +0 -1
  160. package/dist/db/filters.js.map +0 -1
  161. package/dist/db/index.js.map +0 -1
  162. package/dist/db/introspection.js.map +0 -1
  163. package/dist/db/manager.js.map +0 -1
  164. package/dist/db/migrations.js.map +0 -1
  165. package/dist/db/postgres.js.map +0 -1
  166. package/dist/db/types.js.map +0 -1
  167. package/dist/index.js.map +0 -1
  168. package/dist/public/css/input.css +0 -302
  169. package/dist/public/js/icons.js +0 -51
  170. package/dist/routes/api/helpers.js.map +0 -1
  171. package/dist/routes/api/import-export.js.map +0 -1
  172. package/dist/routes/api/index.js.map +0 -1
  173. package/dist/routes/api/query.js.map +0 -1
  174. package/dist/routes/api/rows.js.map +0 -1
  175. package/dist/routes/api/seed.js.map +0 -1
  176. package/dist/routes/api/tables.js.map +0 -1
  177. package/dist/routes/databases.js.map +0 -1
  178. package/dist/routes/index.js.map +0 -1
  179. package/dist/routes/pages.js.map +0 -1
  180. package/dist/serverless.js.map +0 -1
  181. package/dist/sql/classifier.js.map +0 -1
  182. package/dist/sql/generator.js.map +0 -1
  183. package/dist/sql/index.js.map +0 -1
  184. package/dist/types/api.js.map +0 -1
  185. package/dist/utils/colors.js.map +0 -1
  186. package/dist/utils/common.js.map +0 -1
  187. package/dist/utils/csv.js.map +0 -1
  188. package/dist/utils/datatype.js.map +0 -1
  189. package/dist/utils/icons.js.map +0 -1
  190. package/dist/utils/index.js.map +0 -1
  191. package/dist/utils/logger.js.map +0 -1
@@ -1,17 +1 @@
1
- /**
2
- * Curated static datasets and wordlists used by the data generator.
3
- */
4
- export declare const FIRST_NAMES: string[];
5
- export declare const LAST_NAMES: string[];
6
- export declare const CITIES: string[];
7
- export declare const COUNTRIES: string[];
8
- export declare const DOMAINS: string[];
9
- export declare const LOREM_WORDS: string[];
10
- export declare const COMPANIES: string[];
11
- export declare const JOB_TITLES: string[];
12
- export declare const US_STATES: string[];
13
- export declare const CURRENCIES: string[];
14
- export declare const COUNTRY_CODES: string[];
15
- export declare const STATUSES: string[];
16
- export declare const HEX_COLORS: string[];
17
- export declare const NAMED_COLORS: string[];
1
+ export declare const FIRST_NAMES:string[];export declare const LAST_NAMES:string[];export declare const CITIES:string[];export declare const COUNTRIES:string[];export declare const DOMAINS:string[];export declare const LOREM_WORDS:string[];export declare const COMPANIES:string[];export declare const JOB_TITLES:string[];export declare const US_STATES:string[];export declare const CURRENCIES:string[];export declare const COUNTRY_CODES:string[];export declare const STATUSES:string[];export declare const HEX_COLORS:string[];export declare const NAMED_COLORS:string[];
@@ -1,7 +1,4 @@
1
1
  "use strict";
2
- /**
3
- * Curated static datasets and wordlists used by the data generator.
4
- */
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.NAMED_COLORS = exports.HEX_COLORS = exports.STATUSES = exports.COUNTRY_CODES = exports.CURRENCIES = exports.US_STATES = exports.JOB_TITLES = exports.COMPANIES = exports.LOREM_WORDS = exports.DOMAINS = exports.COUNTRIES = exports.CITIES = exports.LAST_NAMES = exports.FIRST_NAMES = void 0;
7
4
  exports.FIRST_NAMES = [
@@ -130,4 +127,3 @@ exports.NAMED_COLORS = [
130
127
  "Sky", "Slate", "Teal", "Fuchsia", "Crimson", "Navy",
131
128
  "Coral", "Bronze", "Charcoal", "Mint", "Lavender", "Ruby", "Cobalt"
132
129
  ];
133
- //# sourceMappingURL=datasets.js.map
@@ -1,30 +1 @@
1
- import type { ColumnInfo, ForeignKeyInfo, TableInfoData } from '../db/index';
2
- import { type ColumnGeneratorConfig, type ColumnPlan } from './types';
3
- export interface OrderingConstraint {
4
- after?: {
5
- column: string;
6
- orEqual: boolean;
7
- };
8
- before?: {
9
- column: string;
10
- orEqual: boolean;
11
- };
12
- }
13
- export interface NumericConstraint {
14
- min?: number;
15
- max?: number;
16
- }
17
- export interface CheckInfo {
18
- columnAllowed: Map<string, string[]>;
19
- columnRange: Map<string, NumericConstraint>;
20
- jsonAllowed: Map<string, Map<string, string[]>>;
21
- ordering: Map<string, OrderingConstraint>;
22
- }
23
- export declare const normName: (s: string) => string;
24
- export declare function isTimestampName(name: string): boolean;
25
- export declare function findInMap<T>(map: Map<string, T>, colName: string): T | undefined;
26
- export declare function extractCheckExprs(sql: string): string[];
27
- export declare function parseChecks(sql: string | null): CheckInfo;
28
- export declare function detectPlan(col: ColumnInfo, fk: ForeignKeyInfo | null): ColumnPlan;
29
- export declare function buildColumnConfigs(info: TableInfoData): ColumnGeneratorConfig[];
30
- export declare function sanitizeColumnPlan(raw: unknown): ColumnPlan | null;
1
+ import type {ColumnInfo,ForeignKeyInfo,TableInfoData} from '../db/index';import{type ColumnGeneratorConfig,type ColumnPlan} from './types';export interface OrderingConstraint{after?:{column:string;orEqual:boolean;};before?:{column:string;orEqual:boolean;};}export interface NumericConstraint{min?:number;max?:number;}export interface LengthConstraint{min?:number;max?:number;exact?:number;}export interface CheckInfo{columnAllowed:Map<string,string[]>;columnRange:Map<string,NumericConstraint>;columnLength:Map<string,LengthConstraint>;jsonAllowed:Map<string,Map<string,string[]>>;ordering:Map<string,OrderingConstraint>;}export declare const normName:(s:string)=>string;export declare function isTimestampName(name:string):boolean;export declare function findInMap<T>(map:Map<string,T>,colName:string):T|undefined;export declare function extractCheckExprs(sql:string):string[];export declare function parseChecks(sql:string|null):CheckInfo;export declare function detectPlan(col:ColumnInfo,fk:ForeignKeyInfo|null):ColumnPlan;export declare function buildColumnConfigs(info:TableInfoData):ColumnGeneratorConfig[];export declare function sanitizeColumnPlan(raw:unknown):ColumnPlan|null;
@@ -80,6 +80,7 @@ function parseChecks(sql) {
80
80
  const info = {
81
81
  columnAllowed: new Map(),
82
82
  columnRange: new Map(),
83
+ columnLength: new Map(),
83
84
  jsonAllowed: new Map(),
84
85
  ordering: new Map(),
85
86
  };
@@ -104,9 +105,8 @@ function parseChecks(sql) {
104
105
  }
105
106
  };
106
107
  for (const expr of extractCheckExprs(sql)) {
107
- // 1. JSON whitelists
108
- const jw1 = /(?:"([^"]+)"|`([^`]+)`|\[([^\]]+)\]|([A-Za-z_][A-Za-z0-9_]*))\s*(?:->>|->)\s*'([^']+)'\s*\)*\s*IN\s*\(([^)]*)\)/gi;
109
- const jw2 = /json_extract\s*\(\s*(?:"([^"]+)"|`([^`]+)`|\[([^\]]+)\]|([A-Za-z_][A-Za-z0-9_]*))\s*,\s*'(?:\$\??|\.)?\.?([^']+)'\s*\)\s*\)*\s*IN\s*\(([^)]*)\)/gi;
108
+ const jw1 = /(?:"([^"]+)"|`([^`]+)`|\[([^\]]+)\]|([A-Za-z_][A-Za-z0-9_]*))\s*(?:->>|->)\s*'([^']+)'\s*(?:\)\s*)*IN\s*\(([^)]*)\)/gi;
109
+ const jw2 = /json_extract\s*\(\s*(?:"([^"]+)"|`([^`]+)`|\[([^\]]+)\]|([A-Za-z_][A-Za-z0-9_]*))\s*,\s*'(?:\$\??|\.)?\.?([^']+)'\s*\)\s*(?:\)\s*)*IN\s*\(([^)]*)\)/gi;
110
110
  for (const re of [jw1, jw2]) {
111
111
  let m;
112
112
  while ((m = re.exec(expr))) {
@@ -122,8 +122,7 @@ function parseChecks(sql) {
122
122
  }
123
123
  }
124
124
  }
125
- // 2. Direct column IN lists
126
- const colIn = /(?:^|[^(->>\w])(?:\(\s*)?(?:(?:lower|upper|trim|coalesce)\s*\(\s*)?(?:"([^"]+)"|`([^`]+)`|\[([^\]]+)\]|([A-Za-z_][A-Za-z0-9_]*))(?:\s*,\s*[^)]+)?\s*\)?\s*\)?\s*IN\s*\(([^)]*)\)/gi;
125
+ const colIn = /(?:^|[^\w"'\`\[])(?:\s*\(\s*)*(?:(?:lower|upper|trim|coalesce)\s*\(\s*)?(?:"([^"]+)"|`([^`]+)`|\[([^\]]+)\]|([A-Za-z_][A-Za-z0-9_]*))(?:\s*,\s*[^)]+)?(?:\s*\)\s*)*\s*IN\s*\(([^)]*)\)/gi;
127
126
  let mColIn;
128
127
  while ((mColIn = colIn.exec(expr))) {
129
128
  const col = mColIn[1] || mColIn[2] || mColIn[3] || mColIn[4];
@@ -138,8 +137,7 @@ function parseChecks(sql) {
138
137
  if (values.length)
139
138
  setColumnAllowed(col, values);
140
139
  }
141
- // 3. Direct column equality
142
- const eqOr = /(?:"([^"]+)"|`([^`]+)`|\[([^\]]+)\]|([A-Za-z_][A-Za-z0-9_]*))\s*=\s*'((?:[^']|'')*)'/gi;
140
+ const eqOr = /(?:^|[^\w"'\`\[])(?:\s*\(\s*)*(?:"([^"]+)"|`([^`]+)`|\[([^\]]+)\]|([A-Za-z_][A-Za-z0-9_]*))(?:\s*\)\s*)*\s*=\s*'((?:[^']|'')*)'/gi;
143
141
  let mEq;
144
142
  const eqByCol = new Map();
145
143
  while ((mEq = eqOr.exec(expr))) {
@@ -154,8 +152,7 @@ function parseChecks(sql) {
154
152
  }
155
153
  for (const [col, vals] of eqByCol.entries())
156
154
  setColumnAllowed(col, vals);
157
- // 4. Numeric range constraints
158
- const numCmp1 = /(?:"([^"]+)"|`([^`]+)`|\[([^\]]+)\]|([A-Za-z_][A-Za-z0-9_]*))\s*(>=|>|<=|<)\s*(-?\d+(?:\.\d+)?)/g;
155
+ const numCmp1 = /(?:^|[^\w"'\`\[])(?:\s*\(\s*)*(?:"([^"]+)"|`([^`]+)`|\[([^\]]+)\]|([A-Za-z_][A-Za-z0-9_]*))(?:\s*\)\s*)*\s*(>=|>|<=|<)\s*(-?\d+(?:\.\d+)?)/g;
159
156
  let mNum1;
160
157
  while ((mNum1 = numCmp1.exec(expr))) {
161
158
  const col = mNum1[1] || mNum1[2] || mNum1[3] || mNum1[4];
@@ -170,7 +167,28 @@ function parseChecks(sql) {
170
167
  info.columnRange.set(col, cur);
171
168
  }
172
169
  }
173
- // 5. Column ordering
170
+ const lenRe1 = /length\s*\(\s*(?:\s*\(\s*)*(?:"([^"]+)"|`([^`]+)`|\[([^\]]+)\]|([A-Za-z_][A-Za-z0-9_]*))(?:\s*\)\s*)*\s*\)\s*(=|==|>=|>|<=|<)\s*(\d+)/gi;
171
+ let mLen1;
172
+ while ((mLen1 = lenRe1.exec(expr))) {
173
+ const col = mLen1[1] || mLen1[2] || mLen1[3] || mLen1[4];
174
+ const op = mLen1[5];
175
+ const val = Number(mLen1[6]);
176
+ if (col && Number.isFinite(val)) {
177
+ const cur = findInMap(info.columnLength, col) ?? {};
178
+ if (op === '=' || op === '==') {
179
+ cur.exact = val;
180
+ cur.min = val;
181
+ cur.max = val;
182
+ }
183
+ else if (op === '>=' || op === '>') {
184
+ cur.min = op === '>' ? val + 1 : val;
185
+ }
186
+ else if (op === '<=' || op === '<') {
187
+ cur.max = op === '<' ? val - 1 : val;
188
+ }
189
+ info.columnLength.set(col, cur);
190
+ }
191
+ }
174
192
  const ord = /(?:"([^"]+)"|`([^`]+)`|\[([^\]]+)\]|([A-Za-z_][A-Za-z0-9_]*))\s*(>=|<=|>|<)\s*(?:"([^"]+)"|`([^`]+)`|\[([^\]]+)\]|([A-Za-z_][A-Za-z0-9_]*))/g;
175
193
  let m2;
176
194
  while ((m2 = ord.exec(expr))) {
@@ -232,7 +250,6 @@ function extractJsonColumns(sql) {
232
250
  push(m[1] || m[2], m[3]);
233
251
  return out;
234
252
  }
235
- /** Name heuristics pattern table for text-ish columns. */
236
253
  const TEXT_PATTERNS = [
237
254
  [/avatar|picture|photo|image|img|thumbnail|icon|logo/, () => ({ strategy: 'avatar' })],
238
255
  [/company|organization|org|firm|corp|employer|agency/, () => ({ strategy: 'company' })],
@@ -269,7 +286,9 @@ function detectPlan(col, fk) {
269
286
  if (col.pk) {
270
287
  if (type.startsWith('INT') || type === 'SERIAL' || type === 'BIGSERIAL')
271
288
  return { strategy: 'skip' };
272
- if (type === 'TEXT' || type === 'BLOB' || type === 'UUID')
289
+ if (type.includes('TEXT') || type.includes('CHAR') || type.includes('VARCHAR') || type.includes('STRING') || type === 'BLOB' || type === 'UUID')
290
+ return { strategy: 'uuid' };
291
+ if (col.notnull && col.dflt_value == null)
273
292
  return { strategy: 'uuid' };
274
293
  return { strategy: 'skip' };
275
294
  }
@@ -323,7 +342,6 @@ function detectPlan(col, fk) {
323
342
  }
324
343
  if (type === 'BLOB')
325
344
  return { strategy: 'bytes', minLen: 8, maxLen: 32 };
326
- // Explicit text heuristics checked in exact order
327
345
  if (/currency|curr|currencycode/.test(name))
328
346
  return { strategy: 'currency' };
329
347
  if (/countrycode|countryiso|isocountry|cca2/.test(name))
@@ -375,6 +393,16 @@ function buildColumnConfigs(info) {
375
393
  }
376
394
  }
377
395
  }
396
+ if (info.sql) {
397
+ const uqRe = /UNIQUE\s*\(\s*([^)]+)\s*\)/gi;
398
+ let uqM;
399
+ while ((uqM = uqRe.exec(info.sql))) {
400
+ const rawCols = uqM[1].split(',').map((s) => s.trim().replace(/[`"\[\]]/g, ''));
401
+ if (rawCols.length === 1 && rawCols[0]) {
402
+ uniqueCols.add(rawCols[0]);
403
+ }
404
+ }
405
+ }
378
406
  const checkInfo = parseChecks(info.sql ?? null);
379
407
  return info.columns.map((col) => {
380
408
  const fk = fkByColumn.get(col.name) ?? null;
@@ -410,6 +438,18 @@ function buildColumnConfigs(info) {
410
438
  if (colRange.max != null)
411
439
  defaultPlan.max = colRange.max;
412
440
  }
441
+ const colLen = findInMap(checkInfo.columnLength, col.name);
442
+ if (colLen && defaultPlan.strategy !== 'fk' && !col.pk) {
443
+ if (colLen.exact != null) {
444
+ defaultPlan = { strategy: 'token', minLen: colLen.exact, maxLen: colLen.exact };
445
+ }
446
+ else {
447
+ if (colLen.min != null)
448
+ defaultPlan.minLen = colLen.min;
449
+ if (colLen.max != null)
450
+ defaultPlan.maxLen = colLen.max;
451
+ }
452
+ }
413
453
  if (!strategies.some((s) => s.id === defaultPlan.strategy) || (!col.pk && col.notnull && col.dflt_value == null && (defaultPlan.strategy === 'skip' || defaultPlan.strategy === 'null'))) {
414
454
  defaultPlan = (0, strategies_1.fallbackPlanFor)(col);
415
455
  }
@@ -469,4 +509,3 @@ function sanitizeColumnPlan(raw) {
469
509
  }
470
510
  return out;
471
511
  }
472
- //# sourceMappingURL=detector.js.map
@@ -1,10 +1 @@
1
- import type { IDatabase, TableInfoData, WhereClause } from '../db/index';
2
- import { type ColumnGeneratorConfig, type ColumnPlan, type GenerateResult } from './types';
3
- /**
4
- * Generate `count` rows for a table with structured previews.
5
- */
6
- export declare function generateRows(db: IDatabase, info: TableInfoData, configs: ColumnGeneratorConfig[], count: number, plan?: Record<string, ColumnPlan>): Promise<GenerateResult>;
7
- /**
8
- * Render generated rows as a sequence of INSERT statements for preview.
9
- */
10
- export declare function buildSeedInsertSql(table: string, rows: WhereClause[][]): string;
1
+ import type {IDatabase,TableInfoData,WhereClause} from '../db/index';import{type ColumnGeneratorConfig,type ColumnPlan,type GenerateResult} from './types';export declare function generateRows(db:IDatabase,info:TableInfoData,configs:ColumnGeneratorConfig[],count:number,plan?:Record<string,ColumnPlan>,truncate?:boolean):Promise<GenerateResult>;export declare function buildSeedInsertSql(table:string,rows:WhereClause[][]):string;
@@ -6,7 +6,6 @@ const generator_1 = require("../sql/generator");
6
6
  const types_1 = require("./types");
7
7
  const detector_1 = require("./detector");
8
8
  const strategies_1 = require("./strategies");
9
- /** Distinct non-null values of a foreign key's referenced column. */
10
9
  async function sampleFkValues(db, fk) {
11
10
  if (!fk)
12
11
  return [];
@@ -29,21 +28,6 @@ function stringifyKey(v) {
29
28
  return `buf:${Buffer.from(v).toString('hex')}`;
30
29
  return `${typeof v}:${String(v)}`;
31
30
  }
32
- function uniqueSuffix(base, seen) {
33
- if (typeof base === 'number' && Number.isFinite(base)) {
34
- let n = Number(base);
35
- while (seen.has(stringifyKey(n)))
36
- n += 1;
37
- return n;
38
- }
39
- let i = 1;
40
- let cand = `${String(base)}-${i}`;
41
- while (seen.has(stringifyKey(cand))) {
42
- i += 1;
43
- cand = `${String(base)}-${i}`;
44
- }
45
- return cand;
46
- }
47
31
  function orderedValue(value, base, dir, orEqual) {
48
32
  const v = value;
49
33
  const b = base;
@@ -80,6 +64,30 @@ function orderedValue(value, base, dir, orEqual) {
80
64
  }
81
65
  return v;
82
66
  }
67
+ function fitStringLength(val, len) {
68
+ if (!len || typeof val !== 'string')
69
+ return val;
70
+ let v = val;
71
+ if (len.exact != null) {
72
+ if (v.length > len.exact)
73
+ v = v.slice(0, len.exact);
74
+ const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
75
+ while (v.length < len.exact) {
76
+ v += chars[Math.floor(Math.random() * chars.length)];
77
+ }
78
+ return v;
79
+ }
80
+ if (len.max != null && v.length > len.max) {
81
+ v = v.slice(0, len.max);
82
+ }
83
+ if (len.min != null && v.length < len.min) {
84
+ const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
85
+ while (v.length < len.min) {
86
+ v += chars[Math.floor(Math.random() * chars.length)];
87
+ }
88
+ }
89
+ return v;
90
+ }
83
91
  function applyOrdering(fields, ordering) {
84
92
  if (!ordering.size)
85
93
  return;
@@ -100,10 +108,7 @@ function applyOrdering(fields, ordering) {
100
108
  }
101
109
  }
102
110
  }
103
- /**
104
- * Generate `count` rows for a table with structured previews.
105
- */
106
- async function generateRows(db, info, configs, count, plan = {}) {
111
+ async function generateRows(db, info, configs, count, plan = {}, truncate = false) {
107
112
  const fkByColumn = new Map();
108
113
  for (const fk of info.foreignKeys)
109
114
  fkByColumn.set(fk.from, fk);
@@ -154,37 +159,70 @@ async function generateRows(db, info, configs, count, plan = {}) {
154
159
  const rows = [];
155
160
  const previewRows = [];
156
161
  const uniqueSeen = new Map();
162
+ if (!truncate) {
163
+ for (const col of uniqueCols) {
164
+ try {
165
+ const existing = await db.all(`SELECT ${(0, generator_1.quoteIdentifier)(col)} AS v FROM ${(0, generator_1.quoteIdentifier)(info.table)} WHERE ${(0, generator_1.quoteIdentifier)(col)} IS NOT NULL LIMIT 10000`);
166
+ const seen = new Set();
167
+ for (const r of (existing.data ?? [])) {
168
+ if (r.v != null)
169
+ seen.add(stringifyKey(r.v));
170
+ }
171
+ uniqueSeen.set(col, seen);
172
+ }
173
+ catch { }
174
+ }
175
+ }
157
176
  for (let i = 0; i < count; i++) {
158
177
  const fields = [];
159
178
  const previewRow = {};
160
- for (const { col, plan: p } of prepared) {
161
- if (p.strategy === 'fk' && fkOmit.has(col.name)) {
162
- previewRow[col.name] = null;
163
- continue;
164
- }
165
- let v = (0, strategies_1.generateOne)(col, p, fkPools.get(col.name), i);
166
- if (v === types_1.SKIP) {
167
- previewRow[col.name] = '(default)';
168
- continue;
169
- }
170
- if (uniqueCols.has(col.name)) {
171
- const seen = uniqueSeen.get(col.name) ?? new Set();
172
- let attempts = 0;
173
- while (seen.has(stringifyKey(v)) && attempts < 20) {
174
- v = (0, strategies_1.generateOne)(col, p, fkPools.get(col.name), i);
175
- attempts += 1;
179
+ let rowValid = true;
180
+ let attempt = 0;
181
+ while (attempt < 100 && rowValid) {
182
+ fields.length = 0;
183
+ let allColsValid = true;
184
+ for (const { col, plan: p } of prepared) {
185
+ if (p.strategy === 'fk' && fkOmit.has(col.name)) {
186
+ previewRow[col.name] = null;
187
+ continue;
188
+ }
189
+ let v = (0, strategies_1.generateOne)(col, p, fkPools.get(col.name), i + attempt * count);
190
+ if (v === types_1.SKIP) {
191
+ previewRow[col.name] = '(default)';
192
+ continue;
176
193
  }
177
- if (seen.has(stringifyKey(v))) {
178
- warnings.push(`Column "${col.name}" is UNIQUE but the generator kept colliding — appended a suffix to keep rows insertable.`);
179
- v = uniqueSuffix(v, seen);
194
+ if (uniqueCols.has(col.name)) {
195
+ const seen = uniqueSeen.get(col.name) ?? new Set();
196
+ let singleAtt = 0;
197
+ while (seen.has(stringifyKey(v)) && singleAtt < 100) {
198
+ v = (0, strategies_1.generateOne)(col, p, fkPools.get(col.name), i + attempt * count + singleAtt * 100);
199
+ singleAtt += 1;
200
+ }
201
+ if (seen.has(stringifyKey(v))) {
202
+ allColsValid = false;
203
+ break;
204
+ }
180
205
  }
181
- seen.add(stringifyKey(v));
182
- uniqueSeen.set(col.name, seen);
206
+ v = fitStringLength(v, (0, detector_1.findInMap)(checkInfo.columnLength, col.name));
207
+ fields.push({ column: col.name, value: v });
208
+ previewRow[col.name] = v;
209
+ }
210
+ if (allColsValid) {
211
+ break;
212
+ }
213
+ attempt += 1;
214
+ }
215
+ if (attempt >= 100) {
216
+ warnings.push(`Stopped generating rows early at row ${i} because unique generator exhausted possible values without collision.`);
217
+ break;
218
+ }
219
+ for (const f of fields) {
220
+ if (uniqueCols.has(f.column)) {
221
+ const seen = uniqueSeen.get(f.column) ?? new Set();
222
+ seen.add(stringifyKey(f.value));
223
+ uniqueSeen.set(f.column, seen);
183
224
  }
184
- fields.push({ column: col.name, value: v });
185
- previewRow[col.name] = v;
186
225
  }
187
- // Honor CHECK ordering constraints
188
226
  applyOrdering(fields, checkInfo.ordering);
189
227
  for (const f of fields) {
190
228
  previewRow[f.column] = f.value;
@@ -196,9 +234,6 @@ async function generateRows(db, info, configs, count, plan = {}) {
196
234
  }
197
235
  return { rows, previewRows, warnings };
198
236
  }
199
- /**
200
- * Render generated rows as a sequence of INSERT statements for preview.
201
- */
202
237
  function buildSeedInsertSql(table, rows) {
203
238
  return rows
204
239
  .map((fields) => {
@@ -208,4 +243,3 @@ function buildSeedInsertSql(table, rows) {
208
243
  })
209
244
  .join('\n');
210
245
  }
211
- //# sourceMappingURL=engine.js.map
@@ -1,5 +1 @@
1
- export * from './types';
2
- export * from './datasets';
3
- export * from './strategies';
4
- export * from './detector';
5
- export * from './engine';
1
+ export * from './types';export * from './datasets';export * from './strategies';export * from './detector';export * from './engine';export * from './chain';
@@ -19,4 +19,4 @@ __exportStar(require("./datasets"), exports);
19
19
  __exportStar(require("./strategies"), exports);
20
20
  __exportStar(require("./detector"), exports);
21
21
  __exportStar(require("./engine"), exports);
22
- //# sourceMappingURL=index.js.map
22
+ __exportStar(require("./chain"), exports);
@@ -1,30 +1 @@
1
- import type { ColumnInfo, ForeignKeyInfo } from '../db/index';
2
- import { type ColumnPlan, type StrategyDescriptor } from './types';
3
- export declare const randInt: (min: number, max: number) => number;
4
- export declare const randFloat: (min: number, max: number) => number;
5
- export declare const pick: <T>(arr: T[]) => T;
6
- export declare const makeSlug: () => string;
7
- export declare const makeEmail: () => string;
8
- export declare const makeUsername: () => string;
9
- export declare const makePhone: () => string;
10
- export declare const makeAddress: () => string;
11
- export declare const makeIp: () => string;
12
- export declare function makeMacAddress(): string;
13
- export declare const makeCreditCard: () => string;
14
- export declare const makeAvatar: (seedVal?: string) => string;
15
- export declare const makeColor: (format?: string) => string;
16
- export declare function makeUuid(): string;
17
- export declare function makeWords(minLen: number, maxLen: number): string;
18
- export declare function makeSentences(minLen: number, maxLen: number): string;
19
- export declare const makeParagraph: () => string;
20
- export declare function formatPattern(pattern: string): string;
21
- export declare function randomDate(from?: string, to?: string, kind?: 'date' | 'datetime'): string;
22
- export declare const randomTime: () => string;
23
- export declare function randomUnixTimestamp(format?: string, from?: string, to?: string): number;
24
- export declare function randomAlnum(minLen: number, maxLen: number): string;
25
- export declare function makeJsonObject(keys?: string[], jsonValues?: Record<string, string[]>): string;
26
- export declare function isTextishType(type: string): boolean;
27
- export declare function strategiesFor(col: ColumnInfo, fk: ForeignKeyInfo | null): StrategyDescriptor[];
28
- export declare function fallbackPlanFor(col: ColumnInfo): ColumnPlan;
29
- export declare function generateOne(col: ColumnInfo, p: ColumnPlan, fkPool?: unknown[], rowIndex?: number): unknown;
30
- export declare function generateSampleValue(col: ColumnInfo, plan: ColumnPlan, fkPool?: unknown[]): unknown;
1
+ import type {ColumnInfo,ForeignKeyInfo} from '../db/index';import{type ColumnPlan,type StrategyDescriptor} from './types';export declare const randInt:(min:number,max:number)=>number;export declare const randFloat:(min:number,max:number)=>number;export declare const pick:<T>(arr:T[])=>T;export declare const makeSlug:()=>string;export declare const makeEmail:(idx?:number)=>string;export declare const makeUsername:(idx?:number)=>string;export declare const makePhone:()=>string;export declare const makeAddress:()=>string;export declare const makeIp:()=>string;export declare function makeMacAddress():string;export declare const makeCreditCard:()=>string;export declare const makeAvatar:(seedVal?:string)=>string;export declare const makeColor:(format?:string)=>string;export declare function makeUuid():string;export declare function makeWords(minLen:number,maxLen:number):string;export declare function makeSentences(minLen:number,maxLen:number):string;export declare const makeParagraph:()=>string;export declare function formatPattern(pattern:string):string;export declare function randomDate( from ?:string,to?:string,kind?:'date'|'datetime'):string;export declare const randomTime:()=>string;export declare function randomUnixTimestamp(format?:string, from ?:string,to?:string):number;export declare function randomAlnum(minLen:number,maxLen:number):string;export declare function makeJsonObject(keys?:string[],jsonValues?:Record<string,string[]>):string;export declare function isTextishType(type:string):boolean;export declare function strategiesFor(col:ColumnInfo,fk:ForeignKeyInfo|null):StrategyDescriptor[];export declare function fallbackPlanFor(col:ColumnInfo):ColumnPlan;export declare function generateOne(col:ColumnInfo,p:ColumnPlan,fkPool?:unknown[],rowIndex?:number):unknown;export declare function generateSampleValue(col:ColumnInfo,plan:ColumnPlan,fkPool?:unknown[]):unknown;
@@ -19,7 +19,6 @@ const node_crypto_1 = require("node:crypto");
19
19
  const common_1 = require("../utils/common");
20
20
  const datasets_1 = require("./datasets");
21
21
  const types_1 = require("./types");
22
- // ---- Random helpers -------------------------------------------------------
23
22
  const randInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
24
23
  exports.randInt = randInt;
25
24
  const randFloat = (min, max) => Math.random() * (max - min) + min;
@@ -28,9 +27,9 @@ const pick = (arr) => arr[(0, exports.randInt)(0, arr.length - 1)];
28
27
  exports.pick = pick;
29
28
  const makeSlug = () => `${(0, exports.pick)(datasets_1.LOREM_WORDS)}-${(0, exports.pick)(datasets_1.LOREM_WORDS)}-${(0, exports.randInt)(100, 999)}`;
30
29
  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)}`;
30
+ const makeEmail = (idx) => `${(0, exports.pick)(datasets_1.FIRST_NAMES).toLowerCase()}.${(0, exports.pick)(datasets_1.LAST_NAMES).toLowerCase()}${idx != null ? idx + 1 : ''}${(0, exports.randInt)(10, 9999)}@${(0, exports.pick)(datasets_1.DOMAINS)}`;
32
31
  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)}`;
32
+ const makeUsername = (idx) => `${(0, exports.pick)(datasets_1.FIRST_NAMES).toLowerCase()}${(0, exports.pick)(datasets_1.LAST_NAMES).toLowerCase()}${idx != null ? idx + 1 : ''}${(0, exports.randInt)(10, 9999)}`;
34
33
  exports.makeUsername = makeUsername;
35
34
  const makePhone = () => `+1 (${(0, exports.randInt)(200, 999)}) ${(0, exports.randInt)(200, 999)}-${String((0, exports.randInt)(0, 9999)).padStart(4, '0')}`;
36
35
  exports.makePhone = makePhone;
@@ -156,7 +155,6 @@ function isTextishType(type) {
156
155
  const t = (type || '').toUpperCase();
157
156
  return t === 'TEXT' || t === '' || t.includes('JSON') || t.includes('CHAR') || t.includes('CLOB') || t.includes('VARCHAR');
158
157
  }
159
- /** Registry of strategy descriptors and their supported type categories. */
160
158
  const STRATEGY_METADATA = [
161
159
  ['skip', 'Skip (DB default or NULL applies)', 'custom_control', 'all'],
162
160
  ['null', 'Set NULL explicitly', 'custom_control', 'all'],
@@ -246,13 +244,12 @@ function fallbackPlanFor(col) {
246
244
  return { strategy: 'ip' };
247
245
  return { strategy: 'words', minLen: 1, maxLen: 4 };
248
246
  }
249
- /** Dispatch table for simple strategy generators. */
250
247
  const BASIC_STRATEGIES = {
251
248
  first: () => (0, exports.pick)(datasets_1.FIRST_NAMES),
252
249
  last: () => (0, exports.pick)(datasets_1.LAST_NAMES),
253
250
  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)(),
251
+ email: (_, idx) => (0, exports.makeEmail)(idx),
252
+ username: (_, idx) => (0, exports.makeUsername)(idx),
256
253
  job: () => (0, exports.pick)(datasets_1.JOB_TITLES),
257
254
  company: () => (0, exports.pick)(datasets_1.COMPANIES),
258
255
  currency: () => (0, exports.pick)(datasets_1.CURRENCIES),
@@ -340,4 +337,3 @@ function generateSampleValue(col, plan, fkPool) {
340
337
  return `0x${Buffer.from(v).toString('hex').slice(0, 16)}...`;
341
338
  return v;
342
339
  }
343
- //# sourceMappingURL=strategies.js.map
@@ -1,73 +1 @@
1
- import type { ForeignKeyInfo, WhereClause } from '../db/database';
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 type ErChainScope='chain'|'ancestors'|'descendants'|'all'|'single';export interface ErChainTableNode{name:string;order:number;depth:number;parents:{table:string; from :string;to:string;}[];children:{table:string; from :string;to:string;}[];columns:ColumnGeneratorConfig[];suggestedCount:number;rowCount:number;isRoot:boolean;hasSelfRef:boolean;}export interface ErChainConfig{rootTable:string;scope:ErChainScope;tables:ErChainTableNode[];cycleDetected:boolean;cycleTables?:string[];maxTotalRows:number;}export interface ErChainResult{rootTable:string;scope:ErChainScope;executionOrder:string[];tableResults:Record<string,{count:number;rows:WhereClause[][];previewRows:Record<string,unknown>[];warnings:string[];}>;totalRows:number;sql:string;warnings:string[];}export declare const SKIP:unique symbol;
@@ -1,8 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SKIP = exports.MAX_SEED_ROWS = void 0;
4
- /** Hard cap on how many rows a single seed run may generate. */
5
4
  exports.MAX_SEED_ROWS = 5000;
6
- /** Sentinel returned by value generation when the column should be omitted from the row. */
7
5
  exports.SKIP = Symbol('skip');
8
- //# sourceMappingURL=types.js.map