@drzl/analyzer 1.7.0 → 1.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 +52 -6
- package/dist/index.d.cts +30 -3
- package/dist/index.d.ts +30 -3
- package/dist/index.js +52 -6
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -44,6 +44,16 @@ function renderSqlLiteral(v) {
|
|
|
44
44
|
if (Array.isArray(v)) return `(${v.map(renderSqlLiteral).join(", ")})`;
|
|
45
45
|
return `'${String(v).replace(/'/g, "''")}'`;
|
|
46
46
|
}
|
|
47
|
+
var MYSQL_TEXT_CAPS = {
|
|
48
|
+
tinytext: 255,
|
|
49
|
+
text: 65535,
|
|
50
|
+
mediumtext: 16777215,
|
|
51
|
+
longtext: 4294967295,
|
|
52
|
+
tinyblob: 255,
|
|
53
|
+
blob: 65535,
|
|
54
|
+
mediumblob: 16777215,
|
|
55
|
+
longblob: 4294967295
|
|
56
|
+
};
|
|
47
57
|
var V1_FLOAT_BOUNDS = {
|
|
48
58
|
float: ["-8388608", "8388607"],
|
|
49
59
|
// real / float4, 2^23
|
|
@@ -53,26 +63,49 @@ var V1_FLOAT_BOUNDS = {
|
|
|
53
63
|
function describeV1Column(column) {
|
|
54
64
|
const codec = column?.codec;
|
|
55
65
|
const dataType = column?.dataType;
|
|
56
|
-
if (typeof
|
|
66
|
+
if (typeof dataType !== "string") return null;
|
|
67
|
+
if (dataType === "custom") {
|
|
68
|
+
const sqlType = typeof column?.getSQLType === "function" ? column.getSQLType() : void 0;
|
|
69
|
+
return {
|
|
70
|
+
tsType: "unknown",
|
|
71
|
+
dbType: typeof sqlType === "string" && sqlType ? sqlType.toUpperCase() : "UNKNOWN",
|
|
72
|
+
shape: { kind: "custom", sqlType: typeof sqlType === "string" ? sqlType : void 0 }
|
|
73
|
+
};
|
|
74
|
+
}
|
|
57
75
|
const [js, semantic = ""] = dataType.split(" ");
|
|
76
|
+
if (typeof codec !== "string" && !semantic) return null;
|
|
58
77
|
const out = {};
|
|
59
78
|
switch (semantic) {
|
|
79
|
+
case "int8":
|
|
60
80
|
case "int16":
|
|
81
|
+
case "int24":
|
|
61
82
|
case "int32":
|
|
62
83
|
case "int53":
|
|
84
|
+
case "uint53":
|
|
63
85
|
case "int64": {
|
|
64
86
|
const range = {
|
|
87
|
+
int8: ["-128", "127"],
|
|
65
88
|
int16: ["-32768", "32767"],
|
|
89
|
+
int24: ["-8388608", "8388607"],
|
|
66
90
|
int32: ["-2147483648", "2147483647"],
|
|
67
91
|
int53: ["-9007199254740991", "9007199254740991"],
|
|
92
|
+
// MySQL `serial` is `bigint unsigned auto_increment`, so it starts at 0 rather than
|
|
93
|
+
// spanning the signed range.
|
|
94
|
+
uint53: ["0", "9007199254740991"],
|
|
68
95
|
int64: ["-9223372036854775808", "9223372036854775807"]
|
|
69
96
|
}[semantic];
|
|
70
97
|
[out.min, out.max] = range;
|
|
71
98
|
out.integer = true;
|
|
72
99
|
out.tsType = js === "bigint" ? "bigint" : "number";
|
|
73
|
-
out.dbType = semantic === "int16" ? "SMALLINT" : semantic === "int32" ? "INTEGER" : "BIGINT";
|
|
100
|
+
out.dbType = semantic === "int8" ? "TINYINT" : semantic === "int16" ? "SMALLINT" : semantic === "int24" ? "MEDIUMINT" : semantic === "int32" ? "INTEGER" : "BIGINT";
|
|
74
101
|
break;
|
|
75
102
|
}
|
|
103
|
+
case "year":
|
|
104
|
+
out.tsType = "number";
|
|
105
|
+
out.dbType = "YEAR";
|
|
106
|
+
out.integer = true;
|
|
107
|
+
[out.min, out.max] = ["1901", "2155"];
|
|
108
|
+
break;
|
|
76
109
|
case "float":
|
|
77
110
|
case "double": {
|
|
78
111
|
[out.min, out.max] = V1_FLOAT_BOUNDS[semantic];
|
|
@@ -89,6 +122,9 @@ function describeV1Column(column) {
|
|
|
89
122
|
case "numeric":
|
|
90
123
|
out.tsType = "string";
|
|
91
124
|
out.dbType = "NUMERIC";
|
|
125
|
+
if (!String(column?.constructor?.[/* @__PURE__ */ Symbol.for("drizzle:entityKind")] ?? "").startsWith("SQLite")) {
|
|
126
|
+
out.format = "numeric";
|
|
127
|
+
}
|
|
92
128
|
break;
|
|
93
129
|
case "json":
|
|
94
130
|
out.tsType = "any";
|
|
@@ -102,7 +138,7 @@ function describeV1Column(column) {
|
|
|
102
138
|
break;
|
|
103
139
|
case "date":
|
|
104
140
|
out.tsType = js === "string" ? "string" : "Date";
|
|
105
|
-
out.dbType = codec
|
|
141
|
+
out.dbType = codec?.startsWith("timestamp") ? "TIMESTAMP" : "DATE";
|
|
106
142
|
break;
|
|
107
143
|
case "timestamp":
|
|
108
144
|
out.tsType = js === "string" ? "string" : "Date";
|
|
@@ -124,8 +160,14 @@ function describeV1Column(column) {
|
|
|
124
160
|
break;
|
|
125
161
|
case "binary":
|
|
126
162
|
out.tsType = "string";
|
|
127
|
-
out.dbType = "BIT";
|
|
128
|
-
out.shape = {
|
|
163
|
+
out.dbType = codec === "bit" ? "BIT" : "BINARY";
|
|
164
|
+
out.shape = {
|
|
165
|
+
kind: "bitstring",
|
|
166
|
+
length: declaredLength(column),
|
|
167
|
+
// A Postgres `bit(3)` holds exactly three digits; a MySQL `binary(4)`/`varbinary(16)`
|
|
168
|
+
// holds at most that many, which is why `''` is valid there and not here.
|
|
169
|
+
exact: codec === "bit"
|
|
170
|
+
};
|
|
129
171
|
break;
|
|
130
172
|
case "point":
|
|
131
173
|
case "geometry":
|
|
@@ -159,6 +201,9 @@ function describeV1Column(column) {
|
|
|
159
201
|
} else if (js === "string") {
|
|
160
202
|
out.tsType = "string";
|
|
161
203
|
out.dbType = codec === "varchar" ? "VARCHAR" : codec === "char" ? "CHAR" : "TEXT";
|
|
204
|
+
const kind = String(column?.constructor?.[/* @__PURE__ */ Symbol.for("drizzle:entityKind")] ?? "");
|
|
205
|
+
const cap = codec && kind.startsWith("MySql") ? MYSQL_TEXT_CAPS[codec] : void 0;
|
|
206
|
+
if (cap) out.maxLength = cap;
|
|
162
207
|
} else {
|
|
163
208
|
return null;
|
|
164
209
|
}
|
|
@@ -563,7 +608,8 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
|
|
|
563
608
|
}
|
|
564
609
|
const ev = col?.enumValues;
|
|
565
610
|
const nullable = !col?.notNull && !col?.config?.notNull;
|
|
566
|
-
const
|
|
611
|
+
const generatedIdentity = col?.generatedIdentity;
|
|
612
|
+
const isGenerated = !!(col?.generated || generatedIdentity?.type === "always" || col?.isGenerated);
|
|
567
613
|
const hasDefault = col?.hasDefault === true || col?.default !== void 0 || col?.config?.default !== void 0 || col?.defaultFn !== void 0 || isGenerated;
|
|
568
614
|
const references = void 0;
|
|
569
615
|
const isUnique = !!(col?.isUnique || col?.config?.isUnique);
|
package/dist/index.d.cts
CHANGED
|
@@ -62,8 +62,16 @@ interface Column {
|
|
|
62
62
|
* generators fall back to the old inference there.
|
|
63
63
|
*/
|
|
64
64
|
integer?: boolean;
|
|
65
|
-
/**
|
|
66
|
-
|
|
65
|
+
/**
|
|
66
|
+
* A string column whose contents have a shape the database enforces.
|
|
67
|
+
*
|
|
68
|
+
* Only formats checked against Postgres itself appear here, and the list is short because most
|
|
69
|
+
* candidates failed: Postgres reads `'today'` and `'January 8, 1999'` as dates, pads
|
|
70
|
+
* `'2020-01-01'` into a macaddr, and accepts `'10.1/16'` as an inet. A check for any of those
|
|
71
|
+
* would reject input the database accepts, and turning away valid data is worse than not
|
|
72
|
+
* checking at all. See `COLUMN_FORMATS` in `@drzl/validation-core`.
|
|
73
|
+
*/
|
|
74
|
+
format?: 'uuid' | 'numeric';
|
|
67
75
|
/**
|
|
68
76
|
* Array depth for a column declared with `.array()`, absent when the column is a scalar.
|
|
69
77
|
*
|
|
@@ -104,10 +112,29 @@ type ColumnShape =
|
|
|
104
112
|
kind: 'numberVector';
|
|
105
113
|
length?: number;
|
|
106
114
|
}
|
|
107
|
-
/**
|
|
115
|
+
/**
|
|
116
|
+
* A `customType` column, whose JavaScript type exists only at compile time.
|
|
117
|
+
*
|
|
118
|
+
* `getSQLType()` gives the declared SQL type, but that is the *database* side: `fromDriver` may
|
|
119
|
+
* map it to anything, so a `numeric(12,2)` custom column can perfectly well hand back a number
|
|
120
|
+
* where a plain numeric hands back a string. Guessing from the SQL type would reject the real
|
|
121
|
+
* value, so the type is taken from Drizzle's own inference or not at all.
|
|
122
|
+
*/
|
|
123
|
+
| {
|
|
124
|
+
kind: 'custom';
|
|
125
|
+
sqlType?: string;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* A string of `0`/`1`: Postgres `bit(n)`, MySQL `binary(n)`/`varbinary(n)`.
|
|
129
|
+
*
|
|
130
|
+
* `exact` separates the two. A Postgres `bit(3)` is always three digits, while a MySQL
|
|
131
|
+
* `varbinary(16)` is at most sixteen, so treating both as exact rejected the empty string on
|
|
132
|
+
* every MySQL binary column.
|
|
133
|
+
*/
|
|
108
134
|
| {
|
|
109
135
|
kind: 'bitstring';
|
|
110
136
|
length?: number;
|
|
137
|
+
exact?: boolean;
|
|
111
138
|
};
|
|
112
139
|
interface Key {
|
|
113
140
|
name?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -62,8 +62,16 @@ interface Column {
|
|
|
62
62
|
* generators fall back to the old inference there.
|
|
63
63
|
*/
|
|
64
64
|
integer?: boolean;
|
|
65
|
-
/**
|
|
66
|
-
|
|
65
|
+
/**
|
|
66
|
+
* A string column whose contents have a shape the database enforces.
|
|
67
|
+
*
|
|
68
|
+
* Only formats checked against Postgres itself appear here, and the list is short because most
|
|
69
|
+
* candidates failed: Postgres reads `'today'` and `'January 8, 1999'` as dates, pads
|
|
70
|
+
* `'2020-01-01'` into a macaddr, and accepts `'10.1/16'` as an inet. A check for any of those
|
|
71
|
+
* would reject input the database accepts, and turning away valid data is worse than not
|
|
72
|
+
* checking at all. See `COLUMN_FORMATS` in `@drzl/validation-core`.
|
|
73
|
+
*/
|
|
74
|
+
format?: 'uuid' | 'numeric';
|
|
67
75
|
/**
|
|
68
76
|
* Array depth for a column declared with `.array()`, absent when the column is a scalar.
|
|
69
77
|
*
|
|
@@ -104,10 +112,29 @@ type ColumnShape =
|
|
|
104
112
|
kind: 'numberVector';
|
|
105
113
|
length?: number;
|
|
106
114
|
}
|
|
107
|
-
/**
|
|
115
|
+
/**
|
|
116
|
+
* A `customType` column, whose JavaScript type exists only at compile time.
|
|
117
|
+
*
|
|
118
|
+
* `getSQLType()` gives the declared SQL type, but that is the *database* side: `fromDriver` may
|
|
119
|
+
* map it to anything, so a `numeric(12,2)` custom column can perfectly well hand back a number
|
|
120
|
+
* where a plain numeric hands back a string. Guessing from the SQL type would reject the real
|
|
121
|
+
* value, so the type is taken from Drizzle's own inference or not at all.
|
|
122
|
+
*/
|
|
123
|
+
| {
|
|
124
|
+
kind: 'custom';
|
|
125
|
+
sqlType?: string;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* A string of `0`/`1`: Postgres `bit(n)`, MySQL `binary(n)`/`varbinary(n)`.
|
|
129
|
+
*
|
|
130
|
+
* `exact` separates the two. A Postgres `bit(3)` is always three digits, while a MySQL
|
|
131
|
+
* `varbinary(16)` is at most sixteen, so treating both as exact rejected the empty string on
|
|
132
|
+
* every MySQL binary column.
|
|
133
|
+
*/
|
|
108
134
|
| {
|
|
109
135
|
kind: 'bitstring';
|
|
110
136
|
length?: number;
|
|
137
|
+
exact?: boolean;
|
|
111
138
|
};
|
|
112
139
|
interface Key {
|
|
113
140
|
name?: string;
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,16 @@ function renderSqlLiteral(v) {
|
|
|
7
7
|
if (Array.isArray(v)) return `(${v.map(renderSqlLiteral).join(", ")})`;
|
|
8
8
|
return `'${String(v).replace(/'/g, "''")}'`;
|
|
9
9
|
}
|
|
10
|
+
var MYSQL_TEXT_CAPS = {
|
|
11
|
+
tinytext: 255,
|
|
12
|
+
text: 65535,
|
|
13
|
+
mediumtext: 16777215,
|
|
14
|
+
longtext: 4294967295,
|
|
15
|
+
tinyblob: 255,
|
|
16
|
+
blob: 65535,
|
|
17
|
+
mediumblob: 16777215,
|
|
18
|
+
longblob: 4294967295
|
|
19
|
+
};
|
|
10
20
|
var V1_FLOAT_BOUNDS = {
|
|
11
21
|
float: ["-8388608", "8388607"],
|
|
12
22
|
// real / float4, 2^23
|
|
@@ -16,26 +26,49 @@ var V1_FLOAT_BOUNDS = {
|
|
|
16
26
|
function describeV1Column(column) {
|
|
17
27
|
const codec = column?.codec;
|
|
18
28
|
const dataType = column?.dataType;
|
|
19
|
-
if (typeof
|
|
29
|
+
if (typeof dataType !== "string") return null;
|
|
30
|
+
if (dataType === "custom") {
|
|
31
|
+
const sqlType = typeof column?.getSQLType === "function" ? column.getSQLType() : void 0;
|
|
32
|
+
return {
|
|
33
|
+
tsType: "unknown",
|
|
34
|
+
dbType: typeof sqlType === "string" && sqlType ? sqlType.toUpperCase() : "UNKNOWN",
|
|
35
|
+
shape: { kind: "custom", sqlType: typeof sqlType === "string" ? sqlType : void 0 }
|
|
36
|
+
};
|
|
37
|
+
}
|
|
20
38
|
const [js, semantic = ""] = dataType.split(" ");
|
|
39
|
+
if (typeof codec !== "string" && !semantic) return null;
|
|
21
40
|
const out = {};
|
|
22
41
|
switch (semantic) {
|
|
42
|
+
case "int8":
|
|
23
43
|
case "int16":
|
|
44
|
+
case "int24":
|
|
24
45
|
case "int32":
|
|
25
46
|
case "int53":
|
|
47
|
+
case "uint53":
|
|
26
48
|
case "int64": {
|
|
27
49
|
const range = {
|
|
50
|
+
int8: ["-128", "127"],
|
|
28
51
|
int16: ["-32768", "32767"],
|
|
52
|
+
int24: ["-8388608", "8388607"],
|
|
29
53
|
int32: ["-2147483648", "2147483647"],
|
|
30
54
|
int53: ["-9007199254740991", "9007199254740991"],
|
|
55
|
+
// MySQL `serial` is `bigint unsigned auto_increment`, so it starts at 0 rather than
|
|
56
|
+
// spanning the signed range.
|
|
57
|
+
uint53: ["0", "9007199254740991"],
|
|
31
58
|
int64: ["-9223372036854775808", "9223372036854775807"]
|
|
32
59
|
}[semantic];
|
|
33
60
|
[out.min, out.max] = range;
|
|
34
61
|
out.integer = true;
|
|
35
62
|
out.tsType = js === "bigint" ? "bigint" : "number";
|
|
36
|
-
out.dbType = semantic === "int16" ? "SMALLINT" : semantic === "int32" ? "INTEGER" : "BIGINT";
|
|
63
|
+
out.dbType = semantic === "int8" ? "TINYINT" : semantic === "int16" ? "SMALLINT" : semantic === "int24" ? "MEDIUMINT" : semantic === "int32" ? "INTEGER" : "BIGINT";
|
|
37
64
|
break;
|
|
38
65
|
}
|
|
66
|
+
case "year":
|
|
67
|
+
out.tsType = "number";
|
|
68
|
+
out.dbType = "YEAR";
|
|
69
|
+
out.integer = true;
|
|
70
|
+
[out.min, out.max] = ["1901", "2155"];
|
|
71
|
+
break;
|
|
39
72
|
case "float":
|
|
40
73
|
case "double": {
|
|
41
74
|
[out.min, out.max] = V1_FLOAT_BOUNDS[semantic];
|
|
@@ -52,6 +85,9 @@ function describeV1Column(column) {
|
|
|
52
85
|
case "numeric":
|
|
53
86
|
out.tsType = "string";
|
|
54
87
|
out.dbType = "NUMERIC";
|
|
88
|
+
if (!String(column?.constructor?.[/* @__PURE__ */ Symbol.for("drizzle:entityKind")] ?? "").startsWith("SQLite")) {
|
|
89
|
+
out.format = "numeric";
|
|
90
|
+
}
|
|
55
91
|
break;
|
|
56
92
|
case "json":
|
|
57
93
|
out.tsType = "any";
|
|
@@ -65,7 +101,7 @@ function describeV1Column(column) {
|
|
|
65
101
|
break;
|
|
66
102
|
case "date":
|
|
67
103
|
out.tsType = js === "string" ? "string" : "Date";
|
|
68
|
-
out.dbType = codec
|
|
104
|
+
out.dbType = codec?.startsWith("timestamp") ? "TIMESTAMP" : "DATE";
|
|
69
105
|
break;
|
|
70
106
|
case "timestamp":
|
|
71
107
|
out.tsType = js === "string" ? "string" : "Date";
|
|
@@ -87,8 +123,14 @@ function describeV1Column(column) {
|
|
|
87
123
|
break;
|
|
88
124
|
case "binary":
|
|
89
125
|
out.tsType = "string";
|
|
90
|
-
out.dbType = "BIT";
|
|
91
|
-
out.shape = {
|
|
126
|
+
out.dbType = codec === "bit" ? "BIT" : "BINARY";
|
|
127
|
+
out.shape = {
|
|
128
|
+
kind: "bitstring",
|
|
129
|
+
length: declaredLength(column),
|
|
130
|
+
// A Postgres `bit(3)` holds exactly three digits; a MySQL `binary(4)`/`varbinary(16)`
|
|
131
|
+
// holds at most that many, which is why `''` is valid there and not here.
|
|
132
|
+
exact: codec === "bit"
|
|
133
|
+
};
|
|
92
134
|
break;
|
|
93
135
|
case "point":
|
|
94
136
|
case "geometry":
|
|
@@ -122,6 +164,9 @@ function describeV1Column(column) {
|
|
|
122
164
|
} else if (js === "string") {
|
|
123
165
|
out.tsType = "string";
|
|
124
166
|
out.dbType = codec === "varchar" ? "VARCHAR" : codec === "char" ? "CHAR" : "TEXT";
|
|
167
|
+
const kind = String(column?.constructor?.[/* @__PURE__ */ Symbol.for("drizzle:entityKind")] ?? "");
|
|
168
|
+
const cap = codec && kind.startsWith("MySql") ? MYSQL_TEXT_CAPS[codec] : void 0;
|
|
169
|
+
if (cap) out.maxLength = cap;
|
|
125
170
|
} else {
|
|
126
171
|
return null;
|
|
127
172
|
}
|
|
@@ -526,7 +571,8 @@ var _SchemaAnalyzer = class _SchemaAnalyzer {
|
|
|
526
571
|
}
|
|
527
572
|
const ev = col?.enumValues;
|
|
528
573
|
const nullable = !col?.notNull && !col?.config?.notNull;
|
|
529
|
-
const
|
|
574
|
+
const generatedIdentity = col?.generatedIdentity;
|
|
575
|
+
const isGenerated = !!(col?.generated || generatedIdentity?.type === "always" || col?.isGenerated);
|
|
530
576
|
const hasDefault = col?.hasDefault === true || col?.default !== void 0 || col?.config?.default !== void 0 || col?.defaultFn !== void 0 || isGenerated;
|
|
531
577
|
const references = void 0;
|
|
532
578
|
const isUnique = !!(col?.isUnique || col?.config?.isUnique);
|