@drzl/validation-core 3.8.0 → 3.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -84591,14 +84591,21 @@ function parseCheck(expression, name) {
84591
84591
  if (parts.length > 1) {
84592
84592
  const checks = [];
84593
84593
  const sets = [];
84594
+ const rows = [];
84594
84595
  for (const part of parts) {
84595
84596
  const parsed = parseCheck(part, name);
84596
84597
  if (!parsed.ok)
84597
84598
  return { ok: false, reason: `part of an AND was not understood: ${parsed.reason}` };
84598
84599
  checks.push(...parsed.checks);
84599
84600
  if (parsed.sets) sets.push(...parsed.sets);
84601
+ if (parsed.rows) rows.push(...parsed.rows);
84600
84602
  }
84601
- return sets.length ? { ok: true, checks, sets } : { ok: true, checks };
84603
+ return {
84604
+ ok: true,
84605
+ checks,
84606
+ ...sets.length ? { sets } : {},
84607
+ ...rows.length ? { rows } : {}
84608
+ };
84602
84609
  }
84603
84610
  const inList = expr.match(IN_LIST);
84604
84611
  if (inList) {
@@ -84625,6 +84632,11 @@ function parseCheck(expression, name) {
84625
84632
  if (!cmp) return { ok: false, reason: "not a single comparison this version understands" };
84626
84633
  const value = literal(cmp[3]);
84627
84634
  if (!value) {
84635
+ const right = cmp[3].trim();
84636
+ if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(right)) {
84637
+ const op4 = cmp[2] === "!=" ? "<>" : cmp[2];
84638
+ return { ok: true, checks: [], rows: [{ left: cmp[1], right, operator: op4, name }] };
84639
+ }
84628
84640
  return { ok: false, reason: "right side is not a literal" };
84629
84641
  }
84630
84642
  const op3 = cmp[2] === "!=" ? "<>" : cmp[2];
package/dist/index.d.cts CHANGED
@@ -218,11 +218,24 @@ interface ColumnSet {
218
218
  kind: 'number' | 'string';
219
219
  name?: string;
220
220
  }
221
+ /**
222
+ * A comparison between two columns of the same row, from `CHECK (start_date < end_date)`.
223
+ *
224
+ * It cannot live on a field, because it is a statement about the row: neither column alone can
225
+ * say whether it holds. It can live on the *object* schema, which is where this ends up.
226
+ */
227
+ interface RowCheck {
228
+ left: string;
229
+ right: string;
230
+ operator: ColumnCheck['operator'];
231
+ name?: string;
232
+ }
221
233
  /** A check that was understood, or the reason it was not. */
222
234
  type ParsedCheck = {
223
235
  ok: true;
224
236
  checks: ColumnCheck[];
225
237
  sets?: ColumnSet[];
238
+ rows?: RowCheck[];
226
239
  } | {
227
240
  ok: false;
228
241
  reason: string;
@@ -383,4 +396,4 @@ declare function updateColumns(table: Table): Column[];
383
396
  declare function selectColumns(table: Table): Column[];
384
397
  declare function formatCode(code: string, filePath: string, fmt?: FormatOptions): Promise<any>;
385
398
 
386
- export { AFFIX_PROBE_TABLE, type AffixIssue, type AffixOptions, type AffixValue, COLUMN_FORMATS, type ColumnCheck, type ColumnSet, DEFAULT_IMPORT_EXTENSION, DEFAULT_MODE_PREFIX, DEFAULT_SCHEMA_SUFFIX, DEFAULT_TYPE_SUFFIX, type FormatOptions, IMPORT_EXTENSIONS, type ImportExtension, NAME_MODES, type NameMode, type ParsedCheck, type ResolvedAffix, type Table, type TableCase, type ValidationGenerateOptions, type ValidationLibrary, type ValidationRenderer, applyTableCase, describeSet, formatCode, importSpecifier, insertColumns, isGeneratedColumn, isIntegerColumn, moduleFileName, moduleSpecifier, parseCheck, pascalCase, resolveAffix, resolveConfiguredImport, schemaName, selectColumns, typeName, updateColumns, validateAffix };
399
+ export { AFFIX_PROBE_TABLE, type AffixIssue, type AffixOptions, type AffixValue, COLUMN_FORMATS, type ColumnCheck, type ColumnSet, DEFAULT_IMPORT_EXTENSION, DEFAULT_MODE_PREFIX, DEFAULT_SCHEMA_SUFFIX, DEFAULT_TYPE_SUFFIX, type FormatOptions, IMPORT_EXTENSIONS, type ImportExtension, NAME_MODES, type NameMode, type ParsedCheck, type ResolvedAffix, type RowCheck, type Table, type TableCase, type ValidationGenerateOptions, type ValidationLibrary, type ValidationRenderer, applyTableCase, describeSet, formatCode, importSpecifier, insertColumns, isGeneratedColumn, isIntegerColumn, moduleFileName, moduleSpecifier, parseCheck, pascalCase, resolveAffix, resolveConfiguredImport, schemaName, selectColumns, typeName, updateColumns, validateAffix };
package/dist/index.d.ts CHANGED
@@ -218,11 +218,24 @@ interface ColumnSet {
218
218
  kind: 'number' | 'string';
219
219
  name?: string;
220
220
  }
221
+ /**
222
+ * A comparison between two columns of the same row, from `CHECK (start_date < end_date)`.
223
+ *
224
+ * It cannot live on a field, because it is a statement about the row: neither column alone can
225
+ * say whether it holds. It can live on the *object* schema, which is where this ends up.
226
+ */
227
+ interface RowCheck {
228
+ left: string;
229
+ right: string;
230
+ operator: ColumnCheck['operator'];
231
+ name?: string;
232
+ }
221
233
  /** A check that was understood, or the reason it was not. */
222
234
  type ParsedCheck = {
223
235
  ok: true;
224
236
  checks: ColumnCheck[];
225
237
  sets?: ColumnSet[];
238
+ rows?: RowCheck[];
226
239
  } | {
227
240
  ok: false;
228
241
  reason: string;
@@ -383,4 +396,4 @@ declare function updateColumns(table: Table): Column[];
383
396
  declare function selectColumns(table: Table): Column[];
384
397
  declare function formatCode(code: string, filePath: string, fmt?: FormatOptions): Promise<any>;
385
398
 
386
- export { AFFIX_PROBE_TABLE, type AffixIssue, type AffixOptions, type AffixValue, COLUMN_FORMATS, type ColumnCheck, type ColumnSet, DEFAULT_IMPORT_EXTENSION, DEFAULT_MODE_PREFIX, DEFAULT_SCHEMA_SUFFIX, DEFAULT_TYPE_SUFFIX, type FormatOptions, IMPORT_EXTENSIONS, type ImportExtension, NAME_MODES, type NameMode, type ParsedCheck, type ResolvedAffix, type Table, type TableCase, type ValidationGenerateOptions, type ValidationLibrary, type ValidationRenderer, applyTableCase, describeSet, formatCode, importSpecifier, insertColumns, isGeneratedColumn, isIntegerColumn, moduleFileName, moduleSpecifier, parseCheck, pascalCase, resolveAffix, resolveConfiguredImport, schemaName, selectColumns, typeName, updateColumns, validateAffix };
399
+ export { AFFIX_PROBE_TABLE, type AffixIssue, type AffixOptions, type AffixValue, COLUMN_FORMATS, type ColumnCheck, type ColumnSet, DEFAULT_IMPORT_EXTENSION, DEFAULT_MODE_PREFIX, DEFAULT_SCHEMA_SUFFIX, DEFAULT_TYPE_SUFFIX, type FormatOptions, IMPORT_EXTENSIONS, type ImportExtension, NAME_MODES, type NameMode, type ParsedCheck, type ResolvedAffix, type RowCheck, type Table, type TableCase, type ValidationGenerateOptions, type ValidationLibrary, type ValidationRenderer, applyTableCase, describeSet, formatCode, importSpecifier, insertColumns, isGeneratedColumn, isIntegerColumn, moduleFileName, moduleSpecifier, parseCheck, pascalCase, resolveAffix, resolveConfiguredImport, schemaName, selectColumns, typeName, updateColumns, validateAffix };
package/dist/index.js CHANGED
@@ -122,14 +122,21 @@ function parseCheck(expression, name) {
122
122
  if (parts.length > 1) {
123
123
  const checks = [];
124
124
  const sets = [];
125
+ const rows = [];
125
126
  for (const part of parts) {
126
127
  const parsed = parseCheck(part, name);
127
128
  if (!parsed.ok)
128
129
  return { ok: false, reason: `part of an AND was not understood: ${parsed.reason}` };
129
130
  checks.push(...parsed.checks);
130
131
  if (parsed.sets) sets.push(...parsed.sets);
132
+ if (parsed.rows) rows.push(...parsed.rows);
131
133
  }
132
- return sets.length ? { ok: true, checks, sets } : { ok: true, checks };
134
+ return {
135
+ ok: true,
136
+ checks,
137
+ ...sets.length ? { sets } : {},
138
+ ...rows.length ? { rows } : {}
139
+ };
133
140
  }
134
141
  const inList = expr.match(IN_LIST);
135
142
  if (inList) {
@@ -156,6 +163,11 @@ function parseCheck(expression, name) {
156
163
  if (!cmp) return { ok: false, reason: "not a single comparison this version understands" };
157
164
  const value = literal(cmp[3]);
158
165
  if (!value) {
166
+ const right = cmp[3].trim();
167
+ if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(right)) {
168
+ const op2 = cmp[2] === "!=" ? "<>" : cmp[2];
169
+ return { ok: true, checks: [], rows: [{ left: cmp[1], right, operator: op2, name }] };
170
+ }
159
171
  return { ok: false, reason: "right side is not a literal" };
160
172
  }
161
173
  const op = cmp[2] === "!=" ? "<>" : cmp[2];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drzl/validation-core",
3
- "version": "3.8.0",
3
+ "version": "3.9.0",
4
4
  "private": false,
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -11,7 +11,7 @@
11
11
  ],
12
12
  "sideEffects": false,
13
13
  "dependencies": {
14
- "@drzl/analyzer": "^1.9.0"
14
+ "@drzl/analyzer": "^1.10.0"
15
15
  },
16
16
  "devDependencies": {
17
17
  "tsup": "^8.5.1",