@drzl/analyzer 1.16.0 → 1.17.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/dist/index.cjs CHANGED
@@ -70,6 +70,12 @@ var TUPLE_CLASS_SHAPES = {
70
70
  PgLineTuple: { kind: "tuple", length: 3 }
71
71
  };
72
72
  var V1_ONLY_ENTITY_KINDS = /^(?:MsSql|Cockroach)/;
73
+ var BYTE_STRING_CLASSES = /* @__PURE__ */ new Set([
74
+ "MySqlBinary",
75
+ "MySqlVarBinary",
76
+ "SingleStoreBinary",
77
+ "SingleStoreVarBinary"
78
+ ]);
73
79
  function describeV1Column(column) {
74
80
  const codec = column?.codec;
75
81
  const dataType = column?.dataType;
@@ -170,17 +176,20 @@ function describeV1Column(column) {
170
176
  out.tsType = "string";
171
177
  out.dbType = semantic.toUpperCase();
172
178
  break;
173
- case "binary":
179
+ case "binary": {
180
+ const entity = String(column?.constructor?.[/* @__PURE__ */ Symbol.for("drizzle:entityKind")] ?? "");
181
+ const bytes = entity.startsWith("MySql") || entity.startsWith("SingleStore");
174
182
  out.tsType = "string";
175
183
  out.dbType = codec === "bit" ? "BIT" : "BINARY";
176
- out.shape = {
184
+ out.shape = bytes ? { kind: "byteString", length: declaredLength(column) } : {
177
185
  kind: "bitstring",
178
186
  length: declaredLength(column),
179
- // A Postgres `bit(3)` holds exactly three digits; a MySQL `binary(4)`/`varbinary(16)`
180
- // holds at most that many, which is why `''` is valid there and not here.
187
+ // A Postgres `bit(3)` holds exactly three digits; a Cockroach `varbit(16)` holds at
188
+ // most that many, which is why `''` is valid there and not here.
181
189
  exact: codec === "bit"
182
190
  };
183
191
  break;
192
+ }
184
193
  case "point":
185
194
  case "geometry":
186
195
  out.tsType = "[number, number]";
@@ -556,12 +565,33 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
556
565
  return { tsType: "bigint", dbType: "BIGINT" };
557
566
  case "SQLiteNumeric":
558
567
  return { tsType: "string", dbType: "NUMERIC" };
568
+ // The other two modes of the same column, which matched no arm here and no dialect regex
569
+ // below either, so both came back UNKNOWN and every generator emitted a schema that
570
+ // accepted anything at all. Read back through better-sqlite3 3.53.4 on a `numeric` column,
571
+ // `db.select()` hands back a number in number mode and a bigint in bigint mode.
572
+ case "SQLiteNumericNumber":
573
+ return { tsType: "number", dbType: "NUMERIC" };
574
+ case "SQLiteNumericBigInt":
575
+ return { tsType: "bigint", dbType: "NUMERIC" };
559
576
  case "SQLiteBoolean":
560
577
  return { tsType: "boolean", dbType: "INTEGER" };
561
578
  // 0.4x gives an enum its own class, which had no arm here at all, so an enum column came
562
579
  // back `unknown` and every generator emitted a schema that accepted anything. The values
563
580
  // were on the column the whole time, in `enumValues`, waiting for a type to attach to.
581
+ //
582
+ // The MySQL and SingleStore classes were added later than the Postgres one, and their
583
+ // absence showed up somewhere unexpected: the emitted validator was already right, because
584
+ // every generator reads `enumValues` before it reads `tsType`, so the only thing wrong was
585
+ // the description. That description reached the user anyway, through the untyped-column
586
+ // warning, which said an enum column "will accept any value" while the emitted schema
587
+ // accepted exactly three. A warning that is wrong about the one thing it names is worse
588
+ // than no warning, because it teaches the reader to skip the true ones.
589
+ //
590
+ // v1 already answered `string` here, so this is also the two majors agreeing again rather
591
+ // than a new opinion; the cross-major diff carried the disagreement as a filed defect.
564
592
  case "PgEnumColumn":
593
+ case "MySqlEnumColumn":
594
+ case "SingleStoreEnumColumn":
565
595
  return { tsType: "string", dbType: "TEXT" };
566
596
  case "PgInteger":
567
597
  case "PgSmallInt":
@@ -600,6 +630,15 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
600
630
  return { tsType: "Date", dbType: "TIMESTAMP" };
601
631
  case "PgNumeric":
602
632
  return { tsType: "string", dbType: "NUMERIC" };
633
+ // The other two modes, each its own class. `PgNumericNumber` reached the coarse
634
+ // `/Numeric|Float|Double|Real/i` arm and got the right answer there; `PgNumericBigInt` got
635
+ // its `bigint` from the `/BigInt/i` arm meant for `bigint` columns, and the SQL label that
636
+ // comes with it, so a `numeric(20,0)` was reported as a BIGINT column. Read back through
637
+ // PGlite, `db.select()` hands back a number in number mode and a bigint in bigint mode.
638
+ case "PgNumericNumber":
639
+ return { tsType: "number", dbType: "NUMERIC" };
640
+ case "PgNumericBigInt":
641
+ return { tsType: "bigint", dbType: "NUMERIC" };
603
642
  case "PgDoublePrecision":
604
643
  return { tsType: "number", dbType: "DOUBLE" };
605
644
  // `real()` builds a `PgReal`, which matched no arm and fell through to the coarse
@@ -622,6 +661,16 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
622
661
  case "PgJson":
623
662
  case "PgJsonb":
624
663
  return { tsType: "any", dbType: ctor === "PgJsonb" ? "JSONB" : "JSON" };
664
+ // The four builders in `BYTE_STRING_CLASSES`, which the coarse `/Blob|Binary|VarBinary/i`
665
+ // arms below would otherwise call a `Uint8Array` on the strength of the word "Binary" in
666
+ // the class name. Asked of MySQL 8.4 through drizzle 0.45.2 instead: the driver hands up a
667
+ // Buffer, `mapFromDriverValue` decodes it, and the caller receives a string. Every one of
668
+ // the four declares `dataType: 'string'` and every one of the four defines that method.
669
+ case "MySqlBinary":
670
+ case "MySqlVarBinary":
671
+ case "SingleStoreBinary":
672
+ case "SingleStoreVarBinary":
673
+ return { tsType: "string", dbType: "BINARY" };
625
674
  default:
626
675
  if (column?.config?.mode === "timestamp" || column?.mode === "timestamp") {
627
676
  return { tsType: "Date", dbType: "INTEGER" };
@@ -649,7 +698,12 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
649
698
  if (/BigInt64/i.test(ctor)) return { tsType: "bigint", dbType: "BIGINT" };
650
699
  if (/BigInt53/i.test(ctor)) return { tsType: "number", dbType: "BIGINT" };
651
700
  if (/\bBigInt\b/i.test(ctor)) return { tsType: "bigint", dbType: "BIGINT" };
652
- if (/Decimal|Numeric|Float|Double|Real/i.test(ctor))
701
+ if (/Decimal/i.test(ctor)) {
702
+ if (/DecimalNumber$/.test(ctor)) return { tsType: "number", dbType: "NUMERIC" };
703
+ if (/DecimalBigInt$/.test(ctor)) return { tsType: "bigint", dbType: "NUMERIC" };
704
+ return { tsType: "string", dbType: "NUMERIC" };
705
+ }
706
+ if (/Numeric|Float|Double|Real/i.test(ctor))
653
707
  return { tsType: "number", dbType: "NUMERIC" };
654
708
  if (/Int|Serial|TinyInt|SmallInt|MediumInt/i.test(ctor))
655
709
  return { tsType: "number", dbType: "INTEGER" };
@@ -668,7 +722,12 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
668
722
  if (/Vector/i.test(ctor)) return { tsType: "any", dbType: "VECTOR" };
669
723
  if (/BigInt64/i.test(ctor)) return { tsType: "bigint", dbType: "BIGINT" };
670
724
  if (/BigInt53/i.test(ctor)) return { tsType: "number", dbType: "BIGINT" };
671
- if (/Decimal|Numeric|Float|Double|Real/i.test(ctor))
725
+ if (/Decimal/i.test(ctor)) {
726
+ if (/DecimalNumber$/.test(ctor)) return { tsType: "number", dbType: "NUMERIC" };
727
+ if (/DecimalBigInt$/.test(ctor)) return { tsType: "bigint", dbType: "NUMERIC" };
728
+ return { tsType: "string", dbType: "NUMERIC" };
729
+ }
730
+ if (/Numeric|Float|Double|Real/i.test(ctor))
672
731
  return { tsType: "number", dbType: "NUMERIC" };
673
732
  if (/Int|Serial|TinyInt|SmallInt|MediumInt/i.test(ctor))
674
733
  return { tsType: "number", dbType: "INTEGER" };
@@ -740,7 +799,9 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
740
799
  const sqlKind = String(outerCol?.constructor?.[/* @__PURE__ */ Symbol.for("drizzle:entityKind")] ?? "");
741
800
  const sqlType = sqlKind.startsWith("MySql") && typeof col?.getSQLType === "function" ? String(col.getSQLType()).toLowerCase() : void 0;
742
801
  const byteCap = sqlType ? MYSQL_TEXT_CAPS[sqlType] : void 0;
743
- const fallbackShape = dbType === "JSON" || dbType === "JSONB" || col?.config?.mode === "json" ? { kind: "json" } : TUPLE_CLASS_SHAPES[String(col?.constructor?.name ?? "")];
802
+ const ctorName = String(col?.constructor?.name ?? "");
803
+ const fallbackShape = dbType === "JSON" || dbType === "JSONB" || col?.config?.mode === "json" ? { kind: "json" } : BYTE_STRING_CLASSES.has(ctorName) ? { kind: "byteString", length: declaredLength(col) } : TUPLE_CLASS_SHAPES[ctorName];
804
+ if (fallbackShape?.kind === "byteString") delete constraints.maxLength;
744
805
  const shape = (v1?.shape ?? fallbackShape)?.kind;
745
806
  const finalTs = v1?.tsType ?? tsType;
746
807
  const wide = (finalTs === "unknown" || finalTs === "any") && (!shape || shape === "custom");
package/dist/index.d.cts CHANGED
@@ -144,16 +144,44 @@ type ColumnShape =
144
144
  sqlType?: string;
145
145
  }
146
146
  /**
147
- * A string of `0`/`1`: Postgres `bit(n)`, MySQL `binary(n)`/`varbinary(n)`.
147
+ * A string of `0`/`1`: Postgres `bit(n)`, Cockroach `bit(n)`/`varbit(n)`.
148
148
  *
149
- * `exact` separates the two. A Postgres `bit(3)` is always three digits, while a MySQL
150
- * `varbinary(16)` is at most sixteen, so treating both as exact rejected the empty string on
151
- * every MySQL binary column.
149
+ * `exact` separates the two. A Postgres `bit(3)` is always three digits, while a Cockroach
150
+ * `varbit(16)` is at most sixteen, so treating both as exact rejects the empty string on every
151
+ * varying column.
152
+ *
153
+ * MySQL `binary(n)`/`varbinary(n)` used to be listed here and is not a bit string at all; see
154
+ * `byteString`.
152
155
  */
153
156
  | {
154
157
  kind: 'bitstring';
155
158
  length?: number;
156
159
  exact?: boolean;
160
+ }
161
+ /**
162
+ * MySQL/SingleStore `binary(n)`/`varbinary(n)`: arbitrary bytes, handed to the caller as a
163
+ * string.
164
+ *
165
+ * Asked of MySQL 8.4 through drizzle on both majors, on the same row of the same table: the
166
+ * driver hands up a Buffer, drizzle decodes it, and what the caller receives is a string on
167
+ * 0.45.2 and on 1.0.0-rc.4 alike. `instanceof Uint8Array` is false for all four column builders
168
+ * on both majors.
169
+ *
170
+ * `length` is the declared width and means two different things depending on direction, which
171
+ * is why it is carried raw here rather than as a `maxLength` or a `maxBytes`:
172
+ *
173
+ * out the decode is lossy, so n bytes become at most n code points. Measured: `<ff ff ff>`
174
+ * in a varbinary(3) comes back as 3 code points that re-encode to 9 UTF-8 bytes, so a
175
+ * byte cap applied to a select schema rejects a row the column itself returned.
176
+ * in the server counts the encoded bytes. Measured on varbinary(8): 8 ascii accepted, 9
177
+ * refused, 2 emoji (8 bytes) accepted, 3 emoji (12 bytes) refused, so a code-point cap
178
+ * applied to an insert schema accepts a write the server refuses.
179
+ *
180
+ * The generators pick which by mode.
181
+ */
182
+ | {
183
+ kind: 'byteString';
184
+ length?: number;
157
185
  };
158
186
  interface Key {
159
187
  name?: string;
package/dist/index.d.ts CHANGED
@@ -144,16 +144,44 @@ type ColumnShape =
144
144
  sqlType?: string;
145
145
  }
146
146
  /**
147
- * A string of `0`/`1`: Postgres `bit(n)`, MySQL `binary(n)`/`varbinary(n)`.
147
+ * A string of `0`/`1`: Postgres `bit(n)`, Cockroach `bit(n)`/`varbit(n)`.
148
148
  *
149
- * `exact` separates the two. A Postgres `bit(3)` is always three digits, while a MySQL
150
- * `varbinary(16)` is at most sixteen, so treating both as exact rejected the empty string on
151
- * every MySQL binary column.
149
+ * `exact` separates the two. A Postgres `bit(3)` is always three digits, while a Cockroach
150
+ * `varbit(16)` is at most sixteen, so treating both as exact rejects the empty string on every
151
+ * varying column.
152
+ *
153
+ * MySQL `binary(n)`/`varbinary(n)` used to be listed here and is not a bit string at all; see
154
+ * `byteString`.
152
155
  */
153
156
  | {
154
157
  kind: 'bitstring';
155
158
  length?: number;
156
159
  exact?: boolean;
160
+ }
161
+ /**
162
+ * MySQL/SingleStore `binary(n)`/`varbinary(n)`: arbitrary bytes, handed to the caller as a
163
+ * string.
164
+ *
165
+ * Asked of MySQL 8.4 through drizzle on both majors, on the same row of the same table: the
166
+ * driver hands up a Buffer, drizzle decodes it, and what the caller receives is a string on
167
+ * 0.45.2 and on 1.0.0-rc.4 alike. `instanceof Uint8Array` is false for all four column builders
168
+ * on both majors.
169
+ *
170
+ * `length` is the declared width and means two different things depending on direction, which
171
+ * is why it is carried raw here rather than as a `maxLength` or a `maxBytes`:
172
+ *
173
+ * out the decode is lossy, so n bytes become at most n code points. Measured: `<ff ff ff>`
174
+ * in a varbinary(3) comes back as 3 code points that re-encode to 9 UTF-8 bytes, so a
175
+ * byte cap applied to a select schema rejects a row the column itself returned.
176
+ * in the server counts the encoded bytes. Measured on varbinary(8): 8 ascii accepted, 9
177
+ * refused, 2 emoji (8 bytes) accepted, 3 emoji (12 bytes) refused, so a code-point cap
178
+ * applied to an insert schema accepts a write the server refuses.
179
+ *
180
+ * The generators pick which by mode.
181
+ */
182
+ | {
183
+ kind: 'byteString';
184
+ length?: number;
157
185
  };
158
186
  interface Key {
159
187
  name?: string;
package/dist/index.js CHANGED
@@ -29,6 +29,12 @@ var TUPLE_CLASS_SHAPES = {
29
29
  PgLineTuple: { kind: "tuple", length: 3 }
30
30
  };
31
31
  var V1_ONLY_ENTITY_KINDS = /^(?:MsSql|Cockroach)/;
32
+ var BYTE_STRING_CLASSES = /* @__PURE__ */ new Set([
33
+ "MySqlBinary",
34
+ "MySqlVarBinary",
35
+ "SingleStoreBinary",
36
+ "SingleStoreVarBinary"
37
+ ]);
32
38
  function describeV1Column(column) {
33
39
  const codec = column?.codec;
34
40
  const dataType = column?.dataType;
@@ -129,17 +135,20 @@ function describeV1Column(column) {
129
135
  out.tsType = "string";
130
136
  out.dbType = semantic.toUpperCase();
131
137
  break;
132
- case "binary":
138
+ case "binary": {
139
+ const entity = String(column?.constructor?.[/* @__PURE__ */ Symbol.for("drizzle:entityKind")] ?? "");
140
+ const bytes = entity.startsWith("MySql") || entity.startsWith("SingleStore");
133
141
  out.tsType = "string";
134
142
  out.dbType = codec === "bit" ? "BIT" : "BINARY";
135
- out.shape = {
143
+ out.shape = bytes ? { kind: "byteString", length: declaredLength(column) } : {
136
144
  kind: "bitstring",
137
145
  length: declaredLength(column),
138
- // A Postgres `bit(3)` holds exactly three digits; a MySQL `binary(4)`/`varbinary(16)`
139
- // holds at most that many, which is why `''` is valid there and not here.
146
+ // A Postgres `bit(3)` holds exactly three digits; a Cockroach `varbit(16)` holds at
147
+ // most that many, which is why `''` is valid there and not here.
140
148
  exact: codec === "bit"
141
149
  };
142
150
  break;
151
+ }
143
152
  case "point":
144
153
  case "geometry":
145
154
  out.tsType = "[number, number]";
@@ -515,12 +524,33 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
515
524
  return { tsType: "bigint", dbType: "BIGINT" };
516
525
  case "SQLiteNumeric":
517
526
  return { tsType: "string", dbType: "NUMERIC" };
527
+ // The other two modes of the same column, which matched no arm here and no dialect regex
528
+ // below either, so both came back UNKNOWN and every generator emitted a schema that
529
+ // accepted anything at all. Read back through better-sqlite3 3.53.4 on a `numeric` column,
530
+ // `db.select()` hands back a number in number mode and a bigint in bigint mode.
531
+ case "SQLiteNumericNumber":
532
+ return { tsType: "number", dbType: "NUMERIC" };
533
+ case "SQLiteNumericBigInt":
534
+ return { tsType: "bigint", dbType: "NUMERIC" };
518
535
  case "SQLiteBoolean":
519
536
  return { tsType: "boolean", dbType: "INTEGER" };
520
537
  // 0.4x gives an enum its own class, which had no arm here at all, so an enum column came
521
538
  // back `unknown` and every generator emitted a schema that accepted anything. The values
522
539
  // were on the column the whole time, in `enumValues`, waiting for a type to attach to.
540
+ //
541
+ // The MySQL and SingleStore classes were added later than the Postgres one, and their
542
+ // absence showed up somewhere unexpected: the emitted validator was already right, because
543
+ // every generator reads `enumValues` before it reads `tsType`, so the only thing wrong was
544
+ // the description. That description reached the user anyway, through the untyped-column
545
+ // warning, which said an enum column "will accept any value" while the emitted schema
546
+ // accepted exactly three. A warning that is wrong about the one thing it names is worse
547
+ // than no warning, because it teaches the reader to skip the true ones.
548
+ //
549
+ // v1 already answered `string` here, so this is also the two majors agreeing again rather
550
+ // than a new opinion; the cross-major diff carried the disagreement as a filed defect.
523
551
  case "PgEnumColumn":
552
+ case "MySqlEnumColumn":
553
+ case "SingleStoreEnumColumn":
524
554
  return { tsType: "string", dbType: "TEXT" };
525
555
  case "PgInteger":
526
556
  case "PgSmallInt":
@@ -559,6 +589,15 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
559
589
  return { tsType: "Date", dbType: "TIMESTAMP" };
560
590
  case "PgNumeric":
561
591
  return { tsType: "string", dbType: "NUMERIC" };
592
+ // The other two modes, each its own class. `PgNumericNumber` reached the coarse
593
+ // `/Numeric|Float|Double|Real/i` arm and got the right answer there; `PgNumericBigInt` got
594
+ // its `bigint` from the `/BigInt/i` arm meant for `bigint` columns, and the SQL label that
595
+ // comes with it, so a `numeric(20,0)` was reported as a BIGINT column. Read back through
596
+ // PGlite, `db.select()` hands back a number in number mode and a bigint in bigint mode.
597
+ case "PgNumericNumber":
598
+ return { tsType: "number", dbType: "NUMERIC" };
599
+ case "PgNumericBigInt":
600
+ return { tsType: "bigint", dbType: "NUMERIC" };
562
601
  case "PgDoublePrecision":
563
602
  return { tsType: "number", dbType: "DOUBLE" };
564
603
  // `real()` builds a `PgReal`, which matched no arm and fell through to the coarse
@@ -581,6 +620,16 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
581
620
  case "PgJson":
582
621
  case "PgJsonb":
583
622
  return { tsType: "any", dbType: ctor === "PgJsonb" ? "JSONB" : "JSON" };
623
+ // The four builders in `BYTE_STRING_CLASSES`, which the coarse `/Blob|Binary|VarBinary/i`
624
+ // arms below would otherwise call a `Uint8Array` on the strength of the word "Binary" in
625
+ // the class name. Asked of MySQL 8.4 through drizzle 0.45.2 instead: the driver hands up a
626
+ // Buffer, `mapFromDriverValue` decodes it, and the caller receives a string. Every one of
627
+ // the four declares `dataType: 'string'` and every one of the four defines that method.
628
+ case "MySqlBinary":
629
+ case "MySqlVarBinary":
630
+ case "SingleStoreBinary":
631
+ case "SingleStoreVarBinary":
632
+ return { tsType: "string", dbType: "BINARY" };
584
633
  default:
585
634
  if (column?.config?.mode === "timestamp" || column?.mode === "timestamp") {
586
635
  return { tsType: "Date", dbType: "INTEGER" };
@@ -608,7 +657,12 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
608
657
  if (/BigInt64/i.test(ctor)) return { tsType: "bigint", dbType: "BIGINT" };
609
658
  if (/BigInt53/i.test(ctor)) return { tsType: "number", dbType: "BIGINT" };
610
659
  if (/\bBigInt\b/i.test(ctor)) return { tsType: "bigint", dbType: "BIGINT" };
611
- if (/Decimal|Numeric|Float|Double|Real/i.test(ctor))
660
+ if (/Decimal/i.test(ctor)) {
661
+ if (/DecimalNumber$/.test(ctor)) return { tsType: "number", dbType: "NUMERIC" };
662
+ if (/DecimalBigInt$/.test(ctor)) return { tsType: "bigint", dbType: "NUMERIC" };
663
+ return { tsType: "string", dbType: "NUMERIC" };
664
+ }
665
+ if (/Numeric|Float|Double|Real/i.test(ctor))
612
666
  return { tsType: "number", dbType: "NUMERIC" };
613
667
  if (/Int|Serial|TinyInt|SmallInt|MediumInt/i.test(ctor))
614
668
  return { tsType: "number", dbType: "INTEGER" };
@@ -627,7 +681,12 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
627
681
  if (/Vector/i.test(ctor)) return { tsType: "any", dbType: "VECTOR" };
628
682
  if (/BigInt64/i.test(ctor)) return { tsType: "bigint", dbType: "BIGINT" };
629
683
  if (/BigInt53/i.test(ctor)) return { tsType: "number", dbType: "BIGINT" };
630
- if (/Decimal|Numeric|Float|Double|Real/i.test(ctor))
684
+ if (/Decimal/i.test(ctor)) {
685
+ if (/DecimalNumber$/.test(ctor)) return { tsType: "number", dbType: "NUMERIC" };
686
+ if (/DecimalBigInt$/.test(ctor)) return { tsType: "bigint", dbType: "NUMERIC" };
687
+ return { tsType: "string", dbType: "NUMERIC" };
688
+ }
689
+ if (/Numeric|Float|Double|Real/i.test(ctor))
631
690
  return { tsType: "number", dbType: "NUMERIC" };
632
691
  if (/Int|Serial|TinyInt|SmallInt|MediumInt/i.test(ctor))
633
692
  return { tsType: "number", dbType: "INTEGER" };
@@ -699,7 +758,9 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
699
758
  const sqlKind = String(outerCol?.constructor?.[/* @__PURE__ */ Symbol.for("drizzle:entityKind")] ?? "");
700
759
  const sqlType = sqlKind.startsWith("MySql") && typeof col?.getSQLType === "function" ? String(col.getSQLType()).toLowerCase() : void 0;
701
760
  const byteCap = sqlType ? MYSQL_TEXT_CAPS[sqlType] : void 0;
702
- const fallbackShape = dbType === "JSON" || dbType === "JSONB" || col?.config?.mode === "json" ? { kind: "json" } : TUPLE_CLASS_SHAPES[String(col?.constructor?.name ?? "")];
761
+ const ctorName = String(col?.constructor?.name ?? "");
762
+ const fallbackShape = dbType === "JSON" || dbType === "JSONB" || col?.config?.mode === "json" ? { kind: "json" } : BYTE_STRING_CLASSES.has(ctorName) ? { kind: "byteString", length: declaredLength(col) } : TUPLE_CLASS_SHAPES[ctorName];
763
+ if (fallbackShape?.kind === "byteString") delete constraints.maxLength;
703
764
  const shape = (v1?.shape ?? fallbackShape)?.kind;
704
765
  const finalTs = v1?.tsType ?? tsType;
705
766
  const wide = (finalTs === "unknown" || finalTs === "any") && (!shape || shape === "custom");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drzl/analyzer",
3
- "version": "1.16.0",
3
+ "version": "1.17.1",
4
4
  "private": false,
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",