@drzl/analyzer 1.11.0 → 1.13.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 +62 -10
- package/dist/index.d.cts +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +61 -10
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -33,6 +33,7 @@ __export(index_exports, {
|
|
|
33
33
|
SchemaAnalyzer: () => SchemaAnalyzer,
|
|
34
34
|
default: () => index_default,
|
|
35
35
|
describeV1Column: () => describeV1Column,
|
|
36
|
+
isReadOnlyRelation: () => isReadOnlyRelation,
|
|
36
37
|
isRelationsV2: () => isRelationsV2,
|
|
37
38
|
readRelationsV2: () => readRelationsV2
|
|
38
39
|
});
|
|
@@ -214,6 +215,15 @@ function describeV1Column(column) {
|
|
|
214
215
|
if (typeof dims === "number" && dims >= 1) out.arrayDimensions = dims;
|
|
215
216
|
return out;
|
|
216
217
|
}
|
|
218
|
+
function unwrapArrayColumn(column) {
|
|
219
|
+
let element = column;
|
|
220
|
+
let dimensions = 0;
|
|
221
|
+
while (element?.baseColumn && String(element?.constructor?.name ?? "").endsWith("Array")) {
|
|
222
|
+
element = element.baseColumn;
|
|
223
|
+
dimensions++;
|
|
224
|
+
}
|
|
225
|
+
return { element, dimensions };
|
|
226
|
+
}
|
|
217
227
|
function declaredLength(column) {
|
|
218
228
|
const n = column?.length ?? column?.config?.length ?? column?.config?.dimensions;
|
|
219
229
|
return typeof n === "number" && Number.isFinite(n) && n > 0 ? n : void 0;
|
|
@@ -228,6 +238,12 @@ function getSymbolOf(target, key) {
|
|
|
228
238
|
}
|
|
229
239
|
return target[Symbol.for(key)];
|
|
230
240
|
}
|
|
241
|
+
function isReadOnlyRelation(val) {
|
|
242
|
+
if (!val || typeof val !== "object") return false;
|
|
243
|
+
return Object.getOwnPropertySymbols(val).some(
|
|
244
|
+
(sym) => String(sym.description).includes("MaterializedViewConfig")
|
|
245
|
+
);
|
|
246
|
+
}
|
|
231
247
|
function isRelationsV2(val) {
|
|
232
248
|
if (!val || typeof val !== "object" || Array.isArray(val)) return false;
|
|
233
249
|
const entries = Object.values(val);
|
|
@@ -508,10 +524,23 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
|
|
|
508
524
|
return { tsType: "number", dbType: "REAL" };
|
|
509
525
|
case "SQLiteBlob":
|
|
510
526
|
return { tsType: "Uint8Array", dbType: "BLOB" };
|
|
527
|
+
// SQLite spells a mode as a distinct class rather than as config, so `text({mode:'json'})`
|
|
528
|
+
// is a `SQLiteTextJson` and matched no arm at all: the column came back UNKNOWN, which is
|
|
529
|
+
// wider than the `any` a json column at least used to get.
|
|
530
|
+
case "SQLiteTextJson":
|
|
531
|
+
case "SQLiteBlobJson":
|
|
532
|
+
return { tsType: "any", dbType: "JSON" };
|
|
533
|
+
case "SQLiteBigInt":
|
|
534
|
+
return { tsType: "bigint", dbType: "BIGINT" };
|
|
511
535
|
case "SQLiteNumeric":
|
|
512
536
|
return { tsType: "string", dbType: "NUMERIC" };
|
|
513
537
|
case "SQLiteBoolean":
|
|
514
538
|
return { tsType: "boolean", dbType: "INTEGER" };
|
|
539
|
+
// 0.4x gives an enum its own class, which had no arm here at all, so an enum column came
|
|
540
|
+
// back `unknown` and every generator emitted a schema that accepted anything. The values
|
|
541
|
+
// were on the column the whole time, in `enumValues`, waiting for a type to attach to.
|
|
542
|
+
case "PgEnumColumn":
|
|
543
|
+
return { tsType: "string", dbType: "TEXT" };
|
|
515
544
|
case "PgInteger":
|
|
516
545
|
case "PgSmallInt":
|
|
517
546
|
return { tsType: "number", dbType: "INTEGER" };
|
|
@@ -643,25 +672,26 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
|
|
|
643
672
|
const foreignKeys = [];
|
|
644
673
|
const pkCols = [];
|
|
645
674
|
const uniqueGroups = /* @__PURE__ */ new Map();
|
|
646
|
-
for (const [colName,
|
|
675
|
+
for (const [colName, outerCol] of Object.entries(columnsObj)) {
|
|
676
|
+
const { element: col, dimensions: arrayDims } = unwrapArrayColumn(outerCol);
|
|
647
677
|
let { tsType, dbType } = this.mapColumnType(col);
|
|
648
678
|
if (tsType === "unknown" && /At$/.test(colName)) {
|
|
649
679
|
tsType = "Date";
|
|
650
680
|
dbType = "INTEGER";
|
|
651
681
|
}
|
|
652
682
|
const ev = col?.enumValues;
|
|
653
|
-
const nullable = !
|
|
654
|
-
const rawDefault =
|
|
683
|
+
const nullable = !outerCol?.notNull && !outerCol?.config?.notNull;
|
|
684
|
+
const rawDefault = outerCol?.default;
|
|
655
685
|
const defaultValue = rawDefault !== void 0 && !(rawDefault && typeof rawDefault === "object" && "queryChunks" in rawDefault) ? rawDefault : void 0;
|
|
656
|
-
const generatedIdentity =
|
|
657
|
-
const isGenerated = !!(
|
|
658
|
-
const hasDefault =
|
|
686
|
+
const generatedIdentity = outerCol?.generatedIdentity;
|
|
687
|
+
const isGenerated = !!(outerCol?.generated || generatedIdentity?.type === "always" || outerCol?.isGenerated);
|
|
688
|
+
const hasDefault = outerCol?.hasDefault === true || outerCol?.default !== void 0 || outerCol?.config?.default !== void 0 || outerCol?.defaultFn !== void 0 || isGenerated;
|
|
659
689
|
const references = void 0;
|
|
660
|
-
const isUnique = !!(
|
|
661
|
-
const isPk = !!(
|
|
690
|
+
const isUnique = !!(outerCol?.isUnique || outerCol?.config?.isUnique);
|
|
691
|
+
const isPk = !!(outerCol?.primary || outerCol?.config?.primaryKey);
|
|
662
692
|
if (isPk) pkCols.push(colName);
|
|
663
693
|
if (isUnique) unique.push({ columns: [colName] });
|
|
664
|
-
const uName =
|
|
694
|
+
const uName = outerCol?.uniqueName || outerCol?.config?.uniqueName;
|
|
665
695
|
if (uName) {
|
|
666
696
|
const arr = uniqueGroups.get(uName) ?? [];
|
|
667
697
|
arr.push(colName);
|
|
@@ -670,6 +700,19 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
|
|
|
670
700
|
const v1 = describeV1Column(col);
|
|
671
701
|
const constraints = this.columnConstraints(col);
|
|
672
702
|
if (v1?.shape) delete constraints.maxLength;
|
|
703
|
+
const jsonShape = dbType === "JSON" || dbType === "JSONB" || col?.config?.mode === "json" ? { kind: "json" } : void 0;
|
|
704
|
+
const shape = (v1?.shape ?? jsonShape)?.kind;
|
|
705
|
+
const finalTs = v1?.tsType ?? tsType;
|
|
706
|
+
const wide = (finalTs === "unknown" || finalTs === "any") && (!shape || shape === "custom");
|
|
707
|
+
if (wide) {
|
|
708
|
+
const sqlType = typeof col?.getSQLType === "function" ? col.getSQLType() : void 0;
|
|
709
|
+
issues.push({
|
|
710
|
+
code: "DRZL_ANL_UNKNOWN_COLUMN",
|
|
711
|
+
level: "warn",
|
|
712
|
+
message: `Column "${colName}" on table "${tsName}" has no known type${sqlType ? ` (SQL type ${sqlType})` : ""}, so its validator will accept any value.`,
|
|
713
|
+
hint: shape === "custom" ? "A customType has no runtime shape to read. Declare it with .$type<T>() and turn on typedColumns to give the validator the type." : "Open an issue naming the column type so it can be modelled, or declare it with .$type<T>() and turn on typedColumns."
|
|
714
|
+
});
|
|
715
|
+
}
|
|
673
716
|
columns.push({
|
|
674
717
|
name: colName,
|
|
675
718
|
tsType,
|
|
@@ -682,7 +725,12 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
|
|
|
682
725
|
enumValues: Array.isArray(ev) ? ev : void 0,
|
|
683
726
|
...defaultValue !== void 0 ? { defaultValue } : {},
|
|
684
727
|
...constraints,
|
|
685
|
-
...v1 ?? {}
|
|
728
|
+
...v1 ?? {},
|
|
729
|
+
// After the v1 spread, which sets its own `arrayDimensions` from `dimensions`. On 0.4x
|
|
730
|
+
// that spread has nothing to say and this is the only source.
|
|
731
|
+
...arrayDims ? { arrayDimensions: arrayDims } : {},
|
|
732
|
+
// Only where v1 did not already describe the value, so a shaped column keeps its shape.
|
|
733
|
+
...jsonShape && !v1?.shape ? { shape: jsonShape } : {}
|
|
686
734
|
});
|
|
687
735
|
}
|
|
688
736
|
const name = this.getSymbol(tbl, "drizzle:Name") || tsName;
|
|
@@ -757,6 +805,9 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
|
|
|
757
805
|
indexes: [...pkCols.length ? [{ columns: pkCols }] : [], ...indexes],
|
|
758
806
|
checks,
|
|
759
807
|
foreignKeys,
|
|
808
|
+
// A materialized view refuses every write, so the generators skip its insert and update
|
|
809
|
+
// schemas rather than describe an operation the database will always reject.
|
|
810
|
+
...isReadOnlyRelation(tbl) ? { readOnly: true } : {},
|
|
760
811
|
meta: {}
|
|
761
812
|
};
|
|
762
813
|
}
|
|
@@ -957,6 +1008,7 @@ var index_default = SchemaAnalyzer;
|
|
|
957
1008
|
0 && (module.exports = {
|
|
958
1009
|
SchemaAnalyzer,
|
|
959
1010
|
describeV1Column,
|
|
1011
|
+
isReadOnlyRelation,
|
|
960
1012
|
isRelationsV2,
|
|
961
1013
|
readRelationsV2
|
|
962
1014
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -182,6 +182,12 @@ interface Table {
|
|
|
182
182
|
indexes: Index[];
|
|
183
183
|
checks?: Check[];
|
|
184
184
|
foreignKeys?: ForeignKey[];
|
|
185
|
+
/**
|
|
186
|
+
* Set when the relation refuses writes, which today means a materialized view. Insert and
|
|
187
|
+
* update schemas are not emitted for one, because the database will always refuse the
|
|
188
|
+
* operation they describe.
|
|
189
|
+
*/
|
|
190
|
+
readOnly?: boolean;
|
|
185
191
|
meta?: Record<string, unknown>;
|
|
186
192
|
}
|
|
187
193
|
interface Enum {
|
|
@@ -223,6 +229,18 @@ declare function describeV1Column(column: any): Partial<Column> | null;
|
|
|
223
229
|
* `relations` record whose entries carry a `relationType`. That is specific enough not to
|
|
224
230
|
* collide with a table or an enum, both of which are checked before this.
|
|
225
231
|
*/
|
|
232
|
+
/**
|
|
233
|
+
* Whether a relation refuses writes outright.
|
|
234
|
+
*
|
|
235
|
+
* A materialized view does: `INSERT INTO mv ...` fails with `cannot change materialized view`,
|
|
236
|
+
* verified against Postgres. An insert or update schema for one describes an operation the
|
|
237
|
+
* database will always refuse.
|
|
238
|
+
*
|
|
239
|
+
* An ordinary view is deliberately not included. Postgres accepts an INSERT into a simple
|
|
240
|
+
* auto-updatable view, and whether a given view qualifies depends on its query rather than on
|
|
241
|
+
* anything the schema file states, so refusing them all would take away something that works.
|
|
242
|
+
*/
|
|
243
|
+
declare function isReadOnlyRelation(val: any): boolean;
|
|
226
244
|
declare function isRelationsV2(val: any): boolean;
|
|
227
245
|
/**
|
|
228
246
|
* Read the relations declared by `defineRelations`.
|
|
@@ -338,4 +356,4 @@ declare class SchemaAnalyzer {
|
|
|
338
356
|
analyze(opts?: AnalyzeOptions): Promise<Analysis>;
|
|
339
357
|
}
|
|
340
358
|
|
|
341
|
-
export { type Analysis, type AnalyzeOptions, type Check, type Column, type ColumnRef, type ColumnShape, type Dialect, type Enum, type ForeignKey, type Index, type Issue, type Key, type Relation, SchemaAnalyzer, type Table, SchemaAnalyzer as default, describeV1Column, isRelationsV2, readRelationsV2 };
|
|
359
|
+
export { type Analysis, type AnalyzeOptions, type Check, type Column, type ColumnRef, type ColumnShape, type Dialect, type Enum, type ForeignKey, type Index, type Issue, type Key, type Relation, SchemaAnalyzer, type Table, SchemaAnalyzer as default, describeV1Column, isReadOnlyRelation, isRelationsV2, readRelationsV2 };
|
package/dist/index.d.ts
CHANGED
|
@@ -182,6 +182,12 @@ interface Table {
|
|
|
182
182
|
indexes: Index[];
|
|
183
183
|
checks?: Check[];
|
|
184
184
|
foreignKeys?: ForeignKey[];
|
|
185
|
+
/**
|
|
186
|
+
* Set when the relation refuses writes, which today means a materialized view. Insert and
|
|
187
|
+
* update schemas are not emitted for one, because the database will always refuse the
|
|
188
|
+
* operation they describe.
|
|
189
|
+
*/
|
|
190
|
+
readOnly?: boolean;
|
|
185
191
|
meta?: Record<string, unknown>;
|
|
186
192
|
}
|
|
187
193
|
interface Enum {
|
|
@@ -223,6 +229,18 @@ declare function describeV1Column(column: any): Partial<Column> | null;
|
|
|
223
229
|
* `relations` record whose entries carry a `relationType`. That is specific enough not to
|
|
224
230
|
* collide with a table or an enum, both of which are checked before this.
|
|
225
231
|
*/
|
|
232
|
+
/**
|
|
233
|
+
* Whether a relation refuses writes outright.
|
|
234
|
+
*
|
|
235
|
+
* A materialized view does: `INSERT INTO mv ...` fails with `cannot change materialized view`,
|
|
236
|
+
* verified against Postgres. An insert or update schema for one describes an operation the
|
|
237
|
+
* database will always refuse.
|
|
238
|
+
*
|
|
239
|
+
* An ordinary view is deliberately not included. Postgres accepts an INSERT into a simple
|
|
240
|
+
* auto-updatable view, and whether a given view qualifies depends on its query rather than on
|
|
241
|
+
* anything the schema file states, so refusing them all would take away something that works.
|
|
242
|
+
*/
|
|
243
|
+
declare function isReadOnlyRelation(val: any): boolean;
|
|
226
244
|
declare function isRelationsV2(val: any): boolean;
|
|
227
245
|
/**
|
|
228
246
|
* Read the relations declared by `defineRelations`.
|
|
@@ -338,4 +356,4 @@ declare class SchemaAnalyzer {
|
|
|
338
356
|
analyze(opts?: AnalyzeOptions): Promise<Analysis>;
|
|
339
357
|
}
|
|
340
358
|
|
|
341
|
-
export { type Analysis, type AnalyzeOptions, type Check, type Column, type ColumnRef, type ColumnShape, type Dialect, type Enum, type ForeignKey, type Index, type Issue, type Key, type Relation, SchemaAnalyzer, type Table, SchemaAnalyzer as default, describeV1Column, isRelationsV2, readRelationsV2 };
|
|
359
|
+
export { type Analysis, type AnalyzeOptions, type Check, type Column, type ColumnRef, type ColumnShape, type Dialect, type Enum, type ForeignKey, type Index, type Issue, type Key, type Relation, SchemaAnalyzer, type Table, SchemaAnalyzer as default, describeV1Column, isReadOnlyRelation, isRelationsV2, readRelationsV2 };
|
package/dist/index.js
CHANGED
|
@@ -175,6 +175,15 @@ function describeV1Column(column) {
|
|
|
175
175
|
if (typeof dims === "number" && dims >= 1) out.arrayDimensions = dims;
|
|
176
176
|
return out;
|
|
177
177
|
}
|
|
178
|
+
function unwrapArrayColumn(column) {
|
|
179
|
+
let element = column;
|
|
180
|
+
let dimensions = 0;
|
|
181
|
+
while (element?.baseColumn && String(element?.constructor?.name ?? "").endsWith("Array")) {
|
|
182
|
+
element = element.baseColumn;
|
|
183
|
+
dimensions++;
|
|
184
|
+
}
|
|
185
|
+
return { element, dimensions };
|
|
186
|
+
}
|
|
178
187
|
function declaredLength(column) {
|
|
179
188
|
const n = column?.length ?? column?.config?.length ?? column?.config?.dimensions;
|
|
180
189
|
return typeof n === "number" && Number.isFinite(n) && n > 0 ? n : void 0;
|
|
@@ -189,6 +198,12 @@ function getSymbolOf(target, key) {
|
|
|
189
198
|
}
|
|
190
199
|
return target[Symbol.for(key)];
|
|
191
200
|
}
|
|
201
|
+
function isReadOnlyRelation(val) {
|
|
202
|
+
if (!val || typeof val !== "object") return false;
|
|
203
|
+
return Object.getOwnPropertySymbols(val).some(
|
|
204
|
+
(sym) => String(sym.description).includes("MaterializedViewConfig")
|
|
205
|
+
);
|
|
206
|
+
}
|
|
192
207
|
function isRelationsV2(val) {
|
|
193
208
|
if (!val || typeof val !== "object" || Array.isArray(val)) return false;
|
|
194
209
|
const entries = Object.values(val);
|
|
@@ -469,10 +484,23 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
|
|
|
469
484
|
return { tsType: "number", dbType: "REAL" };
|
|
470
485
|
case "SQLiteBlob":
|
|
471
486
|
return { tsType: "Uint8Array", dbType: "BLOB" };
|
|
487
|
+
// SQLite spells a mode as a distinct class rather than as config, so `text({mode:'json'})`
|
|
488
|
+
// is a `SQLiteTextJson` and matched no arm at all: the column came back UNKNOWN, which is
|
|
489
|
+
// wider than the `any` a json column at least used to get.
|
|
490
|
+
case "SQLiteTextJson":
|
|
491
|
+
case "SQLiteBlobJson":
|
|
492
|
+
return { tsType: "any", dbType: "JSON" };
|
|
493
|
+
case "SQLiteBigInt":
|
|
494
|
+
return { tsType: "bigint", dbType: "BIGINT" };
|
|
472
495
|
case "SQLiteNumeric":
|
|
473
496
|
return { tsType: "string", dbType: "NUMERIC" };
|
|
474
497
|
case "SQLiteBoolean":
|
|
475
498
|
return { tsType: "boolean", dbType: "INTEGER" };
|
|
499
|
+
// 0.4x gives an enum its own class, which had no arm here at all, so an enum column came
|
|
500
|
+
// back `unknown` and every generator emitted a schema that accepted anything. The values
|
|
501
|
+
// were on the column the whole time, in `enumValues`, waiting for a type to attach to.
|
|
502
|
+
case "PgEnumColumn":
|
|
503
|
+
return { tsType: "string", dbType: "TEXT" };
|
|
476
504
|
case "PgInteger":
|
|
477
505
|
case "PgSmallInt":
|
|
478
506
|
return { tsType: "number", dbType: "INTEGER" };
|
|
@@ -604,25 +632,26 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
|
|
|
604
632
|
const foreignKeys = [];
|
|
605
633
|
const pkCols = [];
|
|
606
634
|
const uniqueGroups = /* @__PURE__ */ new Map();
|
|
607
|
-
for (const [colName,
|
|
635
|
+
for (const [colName, outerCol] of Object.entries(columnsObj)) {
|
|
636
|
+
const { element: col, dimensions: arrayDims } = unwrapArrayColumn(outerCol);
|
|
608
637
|
let { tsType, dbType } = this.mapColumnType(col);
|
|
609
638
|
if (tsType === "unknown" && /At$/.test(colName)) {
|
|
610
639
|
tsType = "Date";
|
|
611
640
|
dbType = "INTEGER";
|
|
612
641
|
}
|
|
613
642
|
const ev = col?.enumValues;
|
|
614
|
-
const nullable = !
|
|
615
|
-
const rawDefault =
|
|
643
|
+
const nullable = !outerCol?.notNull && !outerCol?.config?.notNull;
|
|
644
|
+
const rawDefault = outerCol?.default;
|
|
616
645
|
const defaultValue = rawDefault !== void 0 && !(rawDefault && typeof rawDefault === "object" && "queryChunks" in rawDefault) ? rawDefault : void 0;
|
|
617
|
-
const generatedIdentity =
|
|
618
|
-
const isGenerated = !!(
|
|
619
|
-
const hasDefault =
|
|
646
|
+
const generatedIdentity = outerCol?.generatedIdentity;
|
|
647
|
+
const isGenerated = !!(outerCol?.generated || generatedIdentity?.type === "always" || outerCol?.isGenerated);
|
|
648
|
+
const hasDefault = outerCol?.hasDefault === true || outerCol?.default !== void 0 || outerCol?.config?.default !== void 0 || outerCol?.defaultFn !== void 0 || isGenerated;
|
|
620
649
|
const references = void 0;
|
|
621
|
-
const isUnique = !!(
|
|
622
|
-
const isPk = !!(
|
|
650
|
+
const isUnique = !!(outerCol?.isUnique || outerCol?.config?.isUnique);
|
|
651
|
+
const isPk = !!(outerCol?.primary || outerCol?.config?.primaryKey);
|
|
623
652
|
if (isPk) pkCols.push(colName);
|
|
624
653
|
if (isUnique) unique.push({ columns: [colName] });
|
|
625
|
-
const uName =
|
|
654
|
+
const uName = outerCol?.uniqueName || outerCol?.config?.uniqueName;
|
|
626
655
|
if (uName) {
|
|
627
656
|
const arr = uniqueGroups.get(uName) ?? [];
|
|
628
657
|
arr.push(colName);
|
|
@@ -631,6 +660,19 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
|
|
|
631
660
|
const v1 = describeV1Column(col);
|
|
632
661
|
const constraints = this.columnConstraints(col);
|
|
633
662
|
if (v1?.shape) delete constraints.maxLength;
|
|
663
|
+
const jsonShape = dbType === "JSON" || dbType === "JSONB" || col?.config?.mode === "json" ? { kind: "json" } : void 0;
|
|
664
|
+
const shape = (v1?.shape ?? jsonShape)?.kind;
|
|
665
|
+
const finalTs = v1?.tsType ?? tsType;
|
|
666
|
+
const wide = (finalTs === "unknown" || finalTs === "any") && (!shape || shape === "custom");
|
|
667
|
+
if (wide) {
|
|
668
|
+
const sqlType = typeof col?.getSQLType === "function" ? col.getSQLType() : void 0;
|
|
669
|
+
issues.push({
|
|
670
|
+
code: "DRZL_ANL_UNKNOWN_COLUMN",
|
|
671
|
+
level: "warn",
|
|
672
|
+
message: `Column "${colName}" on table "${tsName}" has no known type${sqlType ? ` (SQL type ${sqlType})` : ""}, so its validator will accept any value.`,
|
|
673
|
+
hint: shape === "custom" ? "A customType has no runtime shape to read. Declare it with .$type<T>() and turn on typedColumns to give the validator the type." : "Open an issue naming the column type so it can be modelled, or declare it with .$type<T>() and turn on typedColumns."
|
|
674
|
+
});
|
|
675
|
+
}
|
|
634
676
|
columns.push({
|
|
635
677
|
name: colName,
|
|
636
678
|
tsType,
|
|
@@ -643,7 +685,12 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
|
|
|
643
685
|
enumValues: Array.isArray(ev) ? ev : void 0,
|
|
644
686
|
...defaultValue !== void 0 ? { defaultValue } : {},
|
|
645
687
|
...constraints,
|
|
646
|
-
...v1 ?? {}
|
|
688
|
+
...v1 ?? {},
|
|
689
|
+
// After the v1 spread, which sets its own `arrayDimensions` from `dimensions`. On 0.4x
|
|
690
|
+
// that spread has nothing to say and this is the only source.
|
|
691
|
+
...arrayDims ? { arrayDimensions: arrayDims } : {},
|
|
692
|
+
// Only where v1 did not already describe the value, so a shaped column keeps its shape.
|
|
693
|
+
...jsonShape && !v1?.shape ? { shape: jsonShape } : {}
|
|
647
694
|
});
|
|
648
695
|
}
|
|
649
696
|
const name = this.getSymbol(tbl, "drizzle:Name") || tsName;
|
|
@@ -718,6 +765,9 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
|
|
|
718
765
|
indexes: [...pkCols.length ? [{ columns: pkCols }] : [], ...indexes],
|
|
719
766
|
checks,
|
|
720
767
|
foreignKeys,
|
|
768
|
+
// A materialized view refuses every write, so the generators skip its insert and update
|
|
769
|
+
// schemas rather than describe an operation the database will always reject.
|
|
770
|
+
...isReadOnlyRelation(tbl) ? { readOnly: true } : {},
|
|
721
771
|
meta: {}
|
|
722
772
|
};
|
|
723
773
|
}
|
|
@@ -918,6 +968,7 @@ export {
|
|
|
918
968
|
SchemaAnalyzer,
|
|
919
969
|
index_default as default,
|
|
920
970
|
describeV1Column,
|
|
971
|
+
isReadOnlyRelation,
|
|
921
972
|
isRelationsV2,
|
|
922
973
|
readRelationsV2
|
|
923
974
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drzl/analyzer",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -45,6 +45,6 @@
|
|
|
45
45
|
"scripts": {
|
|
46
46
|
"build": "tsup src/index.ts --dts --format esm,cjs",
|
|
47
47
|
"lint": "eslint . --ext .ts",
|
|
48
|
-
"test": "vitest run"
|
|
48
|
+
"test": "vitest run --testTimeout=20000"
|
|
49
49
|
}
|
|
50
50
|
}
|