@drzl/analyzer 1.15.0 → 1.16.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
@@ -33,6 +33,7 @@ __export(index_exports, {
33
33
  SchemaAnalyzer: () => SchemaAnalyzer,
34
34
  default: () => index_default,
35
35
  describeV1Column: () => describeV1Column,
36
+ isDrizzleView: () => isDrizzleView,
36
37
  isReadOnlyRelation: () => isReadOnlyRelation,
37
38
  isRelationsV2: () => isRelationsV2,
38
39
  readRelationsV2: () => readRelationsV2
@@ -68,6 +69,7 @@ var TUPLE_CLASS_SHAPES = {
68
69
  PgPointTuple: { kind: "tuple", length: 2 },
69
70
  PgLineTuple: { kind: "tuple", length: 3 }
70
71
  };
72
+ var V1_ONLY_ENTITY_KINDS = /^(?:MsSql|Cockroach)/;
71
73
  function describeV1Column(column) {
72
74
  const codec = column?.codec;
73
75
  const dataType = column?.dataType;
@@ -80,8 +82,9 @@ function describeV1Column(column) {
80
82
  shape: { kind: "custom", sqlType: typeof sqlType === "string" ? sqlType : void 0 }
81
83
  };
82
84
  }
85
+ const entityKind = String(column?.constructor?.[/* @__PURE__ */ Symbol.for("drizzle:entityKind")] ?? "");
83
86
  const [js, semantic = ""] = dataType.split(" ");
84
- if (typeof codec !== "string" && !semantic) return null;
87
+ if (typeof codec !== "string" && !semantic && !V1_ONLY_ENTITY_KINDS.test(entityKind)) return null;
85
88
  const out = {};
86
89
  switch (semantic) {
87
90
  case "int8":
@@ -117,7 +120,7 @@ function describeV1Column(column) {
117
120
  case "float":
118
121
  case "double": {
119
122
  if (semantic === "float")
120
- [out.min, out.max] = codec === "float4" ? PG_FLOAT4_RANGE : MYSQL_FLOAT_RANGE;
123
+ [out.min, out.max] = codec === "float4" || entityKind.startsWith("Cockroach") ? PG_FLOAT4_RANGE : MYSQL_FLOAT_RANGE;
121
124
  out.integer = false;
122
125
  out.tsType = "number";
123
126
  out.dbType = semantic === "float" ? "REAL" : "DOUBLE";
@@ -234,15 +237,33 @@ function declaredLength(column) {
234
237
  const n = column?.length ?? column?.config?.length ?? column?.config?.dimensions;
235
238
  return typeof n === "number" && Number.isFinite(n) && n > 0 ? n : void 0;
236
239
  }
237
- function getSymbolOf(target, key) {
238
- if (!target) return void 0;
240
+ var VIEW_CONFIG_FIELDS = {
241
+ "drizzle:Columns": "selectedFields",
242
+ "drizzle:Name": "name",
243
+ "drizzle:Schema": "schema"
244
+ };
245
+ function ownSymbolOf(target, key) {
239
246
  try {
240
247
  for (const sym of Object.getOwnPropertySymbols(target)) {
241
248
  if (sym.description === key) return target[sym];
242
249
  }
243
250
  } catch {
244
251
  }
245
- return target[Symbol.for(key)];
252
+ return void 0;
253
+ }
254
+ function getSymbolOf(target, key) {
255
+ if (!target) return void 0;
256
+ const own = ownSymbolOf(target, key);
257
+ if (own !== void 0) return own;
258
+ const direct = target[Symbol.for(key)];
259
+ if (direct !== void 0) return direct;
260
+ const field = VIEW_CONFIG_FIELDS[key];
261
+ if (!field) return void 0;
262
+ const cfg = ownSymbolOf(target, "drizzle:ViewBaseConfig");
263
+ return cfg ? cfg[field] : void 0;
264
+ }
265
+ function isDrizzleView(val) {
266
+ return !!val && typeof val === "object" && !!getSymbolOf(val, "drizzle:ViewBaseConfig");
246
267
  }
247
268
  function isReadOnlyRelation(val) {
248
269
  if (!val || typeof val !== "object") return false;
@@ -286,17 +307,7 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
286
307
  this.schemaPath = schemaPath;
287
308
  }
288
309
  getSymbol(table, key) {
289
- if (!table) return void 0;
290
- try {
291
- const syms = Object.getOwnPropertySymbols(table);
292
- for (const s of syms) {
293
- if (s.description === key) {
294
- return table[s];
295
- }
296
- }
297
- } catch {
298
- }
299
- return table[Symbol.for(key)];
310
+ return getSymbolOf(table, key);
300
311
  }
301
312
  /**
302
313
  * Drizzle keys the Columns object by TypeScript property name, but every other piece of
@@ -681,11 +692,10 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
681
692
  if (/Json/i.test(ctor)) return { tsType: "any", dbType: "JSON" };
682
693
  if (/Text/i.test(ctor)) return { tsType: "string", dbType: "TEXT" };
683
694
  if (/Bytes/i.test(ctor)) return { tsType: "Uint8Array", dbType: "BLOB" };
695
+ if (/Bool/i.test(ctor)) return { tsType: "boolean", dbType: "BOOLEAN" };
684
696
  if (/TimestampTz/i.test(ctor)) return { tsType: "Date", dbType: "TIMESTAMPTZ" };
685
- if (/Timestamp/i.test(ctor)) return { tsType: "string", dbType: "TIMESTAMP" };
686
- if (/LocalDateString|LocalTime/i.test(ctor)) return { tsType: "string", dbType: "TEXT" };
687
- if (/DateDuration|RelDuration|Duration/i.test(ctor))
688
- return { tsType: "string", dbType: "TEXT" };
697
+ if (/Timestamp|LocalDateString|LocalTime|DateDuration|RelDuration|Duration/i.test(ctor))
698
+ return { tsType: "unknown", dbType: "UNKNOWN" };
689
699
  }
690
700
  return { tsType: "unknown", dbType: "UNKNOWN" };
691
701
  }
@@ -880,12 +890,14 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
880
890
  const relations = [];
881
891
  const enums = [];
882
892
  const columnEnums = [];
893
+ const viewTables = [];
883
894
  for (const [name, val] of Object.entries(exportsObj)) {
884
895
  try {
885
896
  const cols = this.getSymbol(val, "drizzle:Columns");
886
897
  if (cols && typeof cols === "object") {
887
898
  const table = this.analyzeTable(name, val, issues);
888
899
  tables.push(table);
900
+ if (isDrizzleView(val)) viewTables.push(table);
889
901
  for (const col of table.columns) {
890
902
  const enumVals = cols[col.name]?.enumValues;
891
903
  if (enumVals && enumVals.length) {
@@ -936,7 +948,7 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
936
948
  let dialect = "unknown";
937
949
  const marks = /* @__PURE__ */ new Set();
938
950
  for (const [_, val] of Object.entries(exportsObj)) {
939
- const cols = val?.[/* @__PURE__ */ Symbol.for("drizzle:Columns")];
951
+ const cols = this.getSymbol(val, "drizzle:Columns");
940
952
  if (!cols) continue;
941
953
  for (const c of Object.values(cols)) {
942
954
  const kind = c?.constructor?.[/* @__PURE__ */ Symbol.for("drizzle:entityKind")];
@@ -953,6 +965,9 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
953
965
  else if (/MySql|Mysql/i.test(names)) dialect = "mysql";
954
966
  else if (/Pg|Postgres/i.test(names)) dialect = "postgres";
955
967
  else if (/Gel/i.test(names)) dialect = "gel";
968
+ if (dialect === "sqlite") {
969
+ for (const view of viewTables) view.readOnly = true;
970
+ }
956
971
  if (dialect === "unknown" && tables.length) {
957
972
  issues.push({
958
973
  code: "DRZL_ANL_DIALECT",
@@ -1098,6 +1113,7 @@ var index_default = SchemaAnalyzer;
1098
1113
  0 && (module.exports = {
1099
1114
  SchemaAnalyzer,
1100
1115
  describeV1Column,
1116
+ isDrizzleView,
1101
1117
  isReadOnlyRelation,
1102
1118
  isRelationsV2,
1103
1119
  readRelationsV2
package/dist/index.d.cts CHANGED
@@ -231,6 +231,17 @@ interface AnalyzeOptions {
231
231
  * path below untouched.
232
232
  */
233
233
  declare function describeV1Column(column: any): Partial<Column> | null;
234
+ /**
235
+ * Whether an export is a Drizzle view, of any dialect and on either major.
236
+ *
237
+ * Asked of `drizzle:ViewBaseConfig` rather than of `drizzle:IsDrizzleView`, which reads like the
238
+ * obvious question and is not there to be asked: the marker was introduced in 0.39.0, and a view
239
+ * built on 0.29.5, 0.33.0 or 0.36.4 answers undefined to it. The config is an own symbol on all
240
+ * eleven releases probed and on every view form measured, on both majors: the query-builder and
241
+ * explicit-column-list forms of pg view, pg materialized view, mysql view and sqlite view,
242
+ * `.existing()`, and the schema-qualified pg view and materialized view.
243
+ */
244
+ declare function isDrizzleView(val: any): boolean;
234
245
  /**
235
246
  * Whether an export is a Relations v2 definition, from `defineRelations(schema, (r) => ...)`.
236
247
  *
@@ -402,4 +413,4 @@ declare class SchemaAnalyzer {
402
413
  analyze(opts?: AnalyzeOptions): Promise<Analysis>;
403
414
  }
404
415
 
405
- 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 };
416
+ 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, isDrizzleView, isReadOnlyRelation, isRelationsV2, readRelationsV2 };
package/dist/index.d.ts CHANGED
@@ -231,6 +231,17 @@ interface AnalyzeOptions {
231
231
  * path below untouched.
232
232
  */
233
233
  declare function describeV1Column(column: any): Partial<Column> | null;
234
+ /**
235
+ * Whether an export is a Drizzle view, of any dialect and on either major.
236
+ *
237
+ * Asked of `drizzle:ViewBaseConfig` rather than of `drizzle:IsDrizzleView`, which reads like the
238
+ * obvious question and is not there to be asked: the marker was introduced in 0.39.0, and a view
239
+ * built on 0.29.5, 0.33.0 or 0.36.4 answers undefined to it. The config is an own symbol on all
240
+ * eleven releases probed and on every view form measured, on both majors: the query-builder and
241
+ * explicit-column-list forms of pg view, pg materialized view, mysql view and sqlite view,
242
+ * `.existing()`, and the schema-qualified pg view and materialized view.
243
+ */
244
+ declare function isDrizzleView(val: any): boolean;
234
245
  /**
235
246
  * Whether an export is a Relations v2 definition, from `defineRelations(schema, (r) => ...)`.
236
247
  *
@@ -402,4 +413,4 @@ declare class SchemaAnalyzer {
402
413
  analyze(opts?: AnalyzeOptions): Promise<Analysis>;
403
414
  }
404
415
 
405
- 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 };
416
+ 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, isDrizzleView, isReadOnlyRelation, isRelationsV2, readRelationsV2 };
package/dist/index.js CHANGED
@@ -28,6 +28,7 @@ var TUPLE_CLASS_SHAPES = {
28
28
  PgPointTuple: { kind: "tuple", length: 2 },
29
29
  PgLineTuple: { kind: "tuple", length: 3 }
30
30
  };
31
+ var V1_ONLY_ENTITY_KINDS = /^(?:MsSql|Cockroach)/;
31
32
  function describeV1Column(column) {
32
33
  const codec = column?.codec;
33
34
  const dataType = column?.dataType;
@@ -40,8 +41,9 @@ function describeV1Column(column) {
40
41
  shape: { kind: "custom", sqlType: typeof sqlType === "string" ? sqlType : void 0 }
41
42
  };
42
43
  }
44
+ const entityKind = String(column?.constructor?.[/* @__PURE__ */ Symbol.for("drizzle:entityKind")] ?? "");
43
45
  const [js, semantic = ""] = dataType.split(" ");
44
- if (typeof codec !== "string" && !semantic) return null;
46
+ if (typeof codec !== "string" && !semantic && !V1_ONLY_ENTITY_KINDS.test(entityKind)) return null;
45
47
  const out = {};
46
48
  switch (semantic) {
47
49
  case "int8":
@@ -77,7 +79,7 @@ function describeV1Column(column) {
77
79
  case "float":
78
80
  case "double": {
79
81
  if (semantic === "float")
80
- [out.min, out.max] = codec === "float4" ? PG_FLOAT4_RANGE : MYSQL_FLOAT_RANGE;
82
+ [out.min, out.max] = codec === "float4" || entityKind.startsWith("Cockroach") ? PG_FLOAT4_RANGE : MYSQL_FLOAT_RANGE;
81
83
  out.integer = false;
82
84
  out.tsType = "number";
83
85
  out.dbType = semantic === "float" ? "REAL" : "DOUBLE";
@@ -194,15 +196,33 @@ function declaredLength(column) {
194
196
  const n = column?.length ?? column?.config?.length ?? column?.config?.dimensions;
195
197
  return typeof n === "number" && Number.isFinite(n) && n > 0 ? n : void 0;
196
198
  }
197
- function getSymbolOf(target, key) {
198
- if (!target) return void 0;
199
+ var VIEW_CONFIG_FIELDS = {
200
+ "drizzle:Columns": "selectedFields",
201
+ "drizzle:Name": "name",
202
+ "drizzle:Schema": "schema"
203
+ };
204
+ function ownSymbolOf(target, key) {
199
205
  try {
200
206
  for (const sym of Object.getOwnPropertySymbols(target)) {
201
207
  if (sym.description === key) return target[sym];
202
208
  }
203
209
  } catch {
204
210
  }
205
- return target[Symbol.for(key)];
211
+ return void 0;
212
+ }
213
+ function getSymbolOf(target, key) {
214
+ if (!target) return void 0;
215
+ const own = ownSymbolOf(target, key);
216
+ if (own !== void 0) return own;
217
+ const direct = target[Symbol.for(key)];
218
+ if (direct !== void 0) return direct;
219
+ const field = VIEW_CONFIG_FIELDS[key];
220
+ if (!field) return void 0;
221
+ const cfg = ownSymbolOf(target, "drizzle:ViewBaseConfig");
222
+ return cfg ? cfg[field] : void 0;
223
+ }
224
+ function isDrizzleView(val) {
225
+ return !!val && typeof val === "object" && !!getSymbolOf(val, "drizzle:ViewBaseConfig");
206
226
  }
207
227
  function isReadOnlyRelation(val) {
208
228
  if (!val || typeof val !== "object") return false;
@@ -246,17 +266,7 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
246
266
  this.schemaPath = schemaPath;
247
267
  }
248
268
  getSymbol(table, key) {
249
- if (!table) return void 0;
250
- try {
251
- const syms = Object.getOwnPropertySymbols(table);
252
- for (const s of syms) {
253
- if (s.description === key) {
254
- return table[s];
255
- }
256
- }
257
- } catch {
258
- }
259
- return table[Symbol.for(key)];
269
+ return getSymbolOf(table, key);
260
270
  }
261
271
  /**
262
272
  * Drizzle keys the Columns object by TypeScript property name, but every other piece of
@@ -641,11 +651,10 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
641
651
  if (/Json/i.test(ctor)) return { tsType: "any", dbType: "JSON" };
642
652
  if (/Text/i.test(ctor)) return { tsType: "string", dbType: "TEXT" };
643
653
  if (/Bytes/i.test(ctor)) return { tsType: "Uint8Array", dbType: "BLOB" };
654
+ if (/Bool/i.test(ctor)) return { tsType: "boolean", dbType: "BOOLEAN" };
644
655
  if (/TimestampTz/i.test(ctor)) return { tsType: "Date", dbType: "TIMESTAMPTZ" };
645
- if (/Timestamp/i.test(ctor)) return { tsType: "string", dbType: "TIMESTAMP" };
646
- if (/LocalDateString|LocalTime/i.test(ctor)) return { tsType: "string", dbType: "TEXT" };
647
- if (/DateDuration|RelDuration|Duration/i.test(ctor))
648
- return { tsType: "string", dbType: "TEXT" };
656
+ if (/Timestamp|LocalDateString|LocalTime|DateDuration|RelDuration|Duration/i.test(ctor))
657
+ return { tsType: "unknown", dbType: "UNKNOWN" };
649
658
  }
650
659
  return { tsType: "unknown", dbType: "UNKNOWN" };
651
660
  }
@@ -840,12 +849,14 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
840
849
  const relations = [];
841
850
  const enums = [];
842
851
  const columnEnums = [];
852
+ const viewTables = [];
843
853
  for (const [name, val] of Object.entries(exportsObj)) {
844
854
  try {
845
855
  const cols = this.getSymbol(val, "drizzle:Columns");
846
856
  if (cols && typeof cols === "object") {
847
857
  const table = this.analyzeTable(name, val, issues);
848
858
  tables.push(table);
859
+ if (isDrizzleView(val)) viewTables.push(table);
849
860
  for (const col of table.columns) {
850
861
  const enumVals = cols[col.name]?.enumValues;
851
862
  if (enumVals && enumVals.length) {
@@ -896,7 +907,7 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
896
907
  let dialect = "unknown";
897
908
  const marks = /* @__PURE__ */ new Set();
898
909
  for (const [_, val] of Object.entries(exportsObj)) {
899
- const cols = val?.[/* @__PURE__ */ Symbol.for("drizzle:Columns")];
910
+ const cols = this.getSymbol(val, "drizzle:Columns");
900
911
  if (!cols) continue;
901
912
  for (const c of Object.values(cols)) {
902
913
  const kind = c?.constructor?.[/* @__PURE__ */ Symbol.for("drizzle:entityKind")];
@@ -913,6 +924,9 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
913
924
  else if (/MySql|Mysql/i.test(names)) dialect = "mysql";
914
925
  else if (/Pg|Postgres/i.test(names)) dialect = "postgres";
915
926
  else if (/Gel/i.test(names)) dialect = "gel";
927
+ if (dialect === "sqlite") {
928
+ for (const view of viewTables) view.readOnly = true;
929
+ }
916
930
  if (dialect === "unknown" && tables.length) {
917
931
  issues.push({
918
932
  code: "DRZL_ANL_DIALECT",
@@ -1058,6 +1072,7 @@ export {
1058
1072
  SchemaAnalyzer,
1059
1073
  index_default as default,
1060
1074
  describeV1Column,
1075
+ isDrizzleView,
1061
1076
  isReadOnlyRelation,
1062
1077
  isRelationsV2,
1063
1078
  readRelationsV2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drzl/analyzer",
3
- "version": "1.15.0",
3
+ "version": "1.16.0",
4
4
  "private": false,
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",