@rindle/sql-client 0.7.2 → 0.7.3
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/drizzle.d.ts +41 -1
- package/dist/drizzle.d.ts.map +1 -1
- package/dist/drizzle.js +53 -6
- package/dist/drizzle.js.map +1 -1
- package/package.json +1 -1
- package/src/drizzle.ts +62 -7
package/dist/drizzle.d.ts
CHANGED
|
@@ -1,4 +1,44 @@
|
|
|
1
1
|
import type { ClientOptions, SqlClient, SqlValue, StatementResult } from "./types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* The exact-i64 column for Drizzle schemas (design 226 §7.2). Three promises,
|
|
4
|
+
* lined up with the column contract: generated DDL says `BIGINT` (the opt-in
|
|
5
|
+
* exact int64 declaration), bind/predicate values are JS `bigint`, and selected
|
|
6
|
+
* values infer as JS `bigint`. Drizzle's own `integer()` remains the
|
|
7
|
+
* number/date/boolean surface and still emits `INTEGER` (the safe-range f64
|
|
8
|
+
* plane).
|
|
9
|
+
*
|
|
10
|
+
* Caveat (§7.2): decltype dispatch fires only for **direct column references**.
|
|
11
|
+
* SQLite reports no decltype for expression results, so `max(big_id)` or
|
|
12
|
+
* `big_id + 1` falls into the safe-number arm and is a typed
|
|
13
|
+
* `VALUE_UNSUPPORTED` past the round-trip bound — never a rounded number. For
|
|
14
|
+
* exact expression results, use the native client with `intMode: "bigint"`.
|
|
15
|
+
*/
|
|
16
|
+
export declare const rindleBigint: {
|
|
17
|
+
(): import("drizzle-orm/sqlite-core").SQLiteCustomColumnBuilder<{
|
|
18
|
+
name: "";
|
|
19
|
+
dataType: "custom";
|
|
20
|
+
columnType: "SQLiteCustomColumn";
|
|
21
|
+
data: bigint;
|
|
22
|
+
driverParam: bigint;
|
|
23
|
+
enumValues: undefined;
|
|
24
|
+
}>;
|
|
25
|
+
<TConfig extends Record<string, any>>(fieldConfig?: TConfig | undefined): import("drizzle-orm/sqlite-core").SQLiteCustomColumnBuilder<{
|
|
26
|
+
name: "";
|
|
27
|
+
dataType: "custom";
|
|
28
|
+
columnType: "SQLiteCustomColumn";
|
|
29
|
+
data: bigint;
|
|
30
|
+
driverParam: bigint;
|
|
31
|
+
enumValues: undefined;
|
|
32
|
+
}>;
|
|
33
|
+
<TName extends string>(dbName: TName, fieldConfig?: unknown): import("drizzle-orm/sqlite-core").SQLiteCustomColumnBuilder<{
|
|
34
|
+
name: TName;
|
|
35
|
+
dataType: "custom";
|
|
36
|
+
columnType: "SQLiteCustomColumn";
|
|
37
|
+
data: bigint;
|
|
38
|
+
driverParam: bigint;
|
|
39
|
+
enumValues: undefined;
|
|
40
|
+
}>;
|
|
41
|
+
};
|
|
2
42
|
/** The small, structural statement shape consumed by drizzle-orm/libsql. */
|
|
3
43
|
export interface DrizzleStatement {
|
|
4
44
|
sql: string;
|
|
@@ -7,7 +47,7 @@ export interface DrizzleStatement {
|
|
|
7
47
|
export type DrizzleArgs = readonly unknown[] | Readonly<Record<string, unknown>>;
|
|
8
48
|
export type DrizzleInputStatement = string | DrizzleStatement | readonly [sql: string, args?: DrizzleArgs];
|
|
9
49
|
export type DrizzleTransactionMode = "write" | "read" | "deferred";
|
|
10
|
-
export type DrizzleValue = Exclude<SqlValue, boolean
|
|
50
|
+
export type DrizzleValue = Exclude<SqlValue, boolean>;
|
|
11
51
|
export type DrizzleRow = DrizzleValue[] & Record<string, DrizzleValue>;
|
|
12
52
|
export interface DrizzleResultSet {
|
|
13
53
|
columns: string[];
|
package/dist/drizzle.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drizzle.d.ts","sourceRoot":"","sources":["../src/drizzle.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"drizzle.d.ts","sourceRoot":"","sources":["../src/drizzle.ts"],"names":[],"mappings":"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"}
|
package/dist/drizzle.js
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
|
+
import { customType } from "drizzle-orm/sqlite-core";
|
|
1
2
|
import { createSqlClient } from "./client.js";
|
|
2
3
|
import { RindleSqlError, valueUnsupported } from "./errors.js";
|
|
4
|
+
/**
|
|
5
|
+
* The exact-i64 column for Drizzle schemas (design 226 §7.2). Three promises,
|
|
6
|
+
* lined up with the column contract: generated DDL says `BIGINT` (the opt-in
|
|
7
|
+
* exact int64 declaration), bind/predicate values are JS `bigint`, and selected
|
|
8
|
+
* values infer as JS `bigint`. Drizzle's own `integer()` remains the
|
|
9
|
+
* number/date/boolean surface and still emits `INTEGER` (the safe-range f64
|
|
10
|
+
* plane).
|
|
11
|
+
*
|
|
12
|
+
* Caveat (§7.2): decltype dispatch fires only for **direct column references**.
|
|
13
|
+
* SQLite reports no decltype for expression results, so `max(big_id)` or
|
|
14
|
+
* `big_id + 1` falls into the safe-number arm and is a typed
|
|
15
|
+
* `VALUE_UNSUPPORTED` past the round-trip bound — never a rounded number. For
|
|
16
|
+
* exact expression results, use the native client with `intMode: "bigint"`.
|
|
17
|
+
*/
|
|
18
|
+
export const rindleBigint = customType({
|
|
19
|
+
dataType: () => "BIGINT",
|
|
20
|
+
});
|
|
3
21
|
function toNativeStatement(input, args) {
|
|
4
22
|
if (typeof input === "string")
|
|
5
23
|
return args === undefined ? input : { sql: input, args: args };
|
|
@@ -25,14 +43,37 @@ function defineNamedCell(row, name, value) {
|
|
|
25
43
|
// An exotic/non-configurable property name cannot be represented in the hybrid row.
|
|
26
44
|
}
|
|
27
45
|
}
|
|
28
|
-
|
|
46
|
+
/** The exact whole-declaration match (design 226 §4.1): `BIGINT`/`INT8` and nothing
|
|
47
|
+
* else — `UNSIGNED BIGINT` and every decorated spelling keeps its safe-number
|
|
48
|
+
* INTEGER-affinity meaning, mirroring the daemon's `value_type_of`. */
|
|
49
|
+
function isInt64Decltype(decltype) {
|
|
50
|
+
if (!decltype)
|
|
51
|
+
return false;
|
|
52
|
+
const t = decltype.trim().toUpperCase();
|
|
53
|
+
return t === "BIGINT" || t === "INT8";
|
|
54
|
+
}
|
|
55
|
+
function toDrizzleValue(value, int64Column) {
|
|
29
56
|
if (typeof value === "bigint") {
|
|
57
|
+
// A BIGINT/INT8-declared result column preserves the exact value as JS bigint
|
|
58
|
+
// (the `rindleBigint` lane, design 226 §7.2). This dispatch must be per-column:
|
|
59
|
+
// globally returning bigint would break Drizzle's integer/timestamp mappers,
|
|
60
|
+
// globally returning number would defeat `rindleBigint`.
|
|
61
|
+
if (int64Column)
|
|
62
|
+
return value;
|
|
30
63
|
const number = Number(value);
|
|
31
64
|
if (!Number.isSafeInteger(number)) {
|
|
32
65
|
throw valueUnsupported(`integer ${value.toString()} is outside Number's safe integer range required by Drizzle`);
|
|
33
66
|
}
|
|
34
67
|
return number;
|
|
35
68
|
}
|
|
69
|
+
if (int64Column && value !== null) {
|
|
70
|
+
// Under the facade's lossless-bigint contract every non-NULL INTEGER cell arrives
|
|
71
|
+
// as bigint, so a number or string here is a REAL/TEXT physical cell — SQLite
|
|
72
|
+
// affinity permits them and schema admission never scans rows. Passing it through
|
|
73
|
+
// would hand a `rindleBigint` field (statically `bigint`) the wrong runtime type;
|
|
74
|
+
// §7.2's contract is a typed error, never a mistyped value.
|
|
75
|
+
throw valueUnsupported(`BIGINT/INT8-declared column holds a ${typeof value} cell; exact int64 columns require INTEGER storage`);
|
|
76
|
+
}
|
|
36
77
|
// The native decoder never produces booleans, but normalize a structurally supplied result too.
|
|
37
78
|
if (typeof value === "boolean")
|
|
38
79
|
return value ? 1 : 0;
|
|
@@ -42,8 +83,9 @@ function toDrizzleValue(value) {
|
|
|
42
83
|
export function toDrizzleResultSet(result) {
|
|
43
84
|
const columns = result.columns.map((column) => column.name);
|
|
44
85
|
const columnTypes = result.columns.map((column) => column.decltype ?? "");
|
|
86
|
+
const int64Columns = result.columns.map((column) => isInt64Decltype(column.decltype));
|
|
45
87
|
const rows = result.rows.map((cells) => {
|
|
46
|
-
const row = cells.map(toDrizzleValue);
|
|
88
|
+
const row = cells.map((cell, index) => toDrizzleValue(cell, int64Columns[index] === true));
|
|
47
89
|
for (let index = 0; index < columns.length; index += 1) {
|
|
48
90
|
defineNamedCell(row, columns[index], row[index]);
|
|
49
91
|
}
|
|
@@ -167,10 +209,15 @@ class ClientFacade {
|
|
|
167
209
|
}
|
|
168
210
|
/** Create the structural libSQL-client facade used by drizzle-orm/libsql. */
|
|
169
211
|
export function createDrizzleClient(options) {
|
|
170
|
-
//
|
|
171
|
-
//
|
|
172
|
-
//
|
|
173
|
-
|
|
212
|
+
// The internal client is LOSSLESS (`intMode: "bigint"`) so precision is not
|
|
213
|
+
// discarded before result metadata is considered (design 226 §7.2):
|
|
214
|
+
// toDrizzleResultSet then dispatches per column decltype — BIGINT/INT8 keeps
|
|
215
|
+
// the exact bigint (the `rindleBigint` lane); every other column converts to
|
|
216
|
+
// the safe number Drizzle's integer/timestamp mappers consume, with an unsafe
|
|
217
|
+
// integer a typed VALUE_UNSUPPORTED, never a rounded number. An INJECTED
|
|
218
|
+
// structural client used with `rindleBigint` must likewise expose lossless
|
|
219
|
+
// bigint results, or exact values are lost before this facade sees them.
|
|
220
|
+
const client = isSqlClient(options) ? options : createSqlClient({ ...options, intMode: "bigint" });
|
|
174
221
|
return new ClientFacade(client);
|
|
175
222
|
}
|
|
176
223
|
function isSqlClient(value) {
|
package/dist/drizzle.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drizzle.js","sourceRoot":"","sources":["../src/drizzle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"drizzle.js","sourceRoot":"","sources":["../src/drizzle.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/drizzle.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { customType } from "drizzle-orm/sqlite-core";
|
|
2
|
+
|
|
1
3
|
import { createSqlClient } from "./client.ts";
|
|
2
4
|
import { RindleSqlError, valueUnsupported } from "./errors.ts";
|
|
3
5
|
import type {
|
|
@@ -9,6 +11,27 @@ import type {
|
|
|
9
11
|
StatementResult,
|
|
10
12
|
} from "./types.ts";
|
|
11
13
|
|
|
14
|
+
/**
|
|
15
|
+
* The exact-i64 column for Drizzle schemas (design 226 §7.2). Three promises,
|
|
16
|
+
* lined up with the column contract: generated DDL says `BIGINT` (the opt-in
|
|
17
|
+
* exact int64 declaration), bind/predicate values are JS `bigint`, and selected
|
|
18
|
+
* values infer as JS `bigint`. Drizzle's own `integer()` remains the
|
|
19
|
+
* number/date/boolean surface and still emits `INTEGER` (the safe-range f64
|
|
20
|
+
* plane).
|
|
21
|
+
*
|
|
22
|
+
* Caveat (§7.2): decltype dispatch fires only for **direct column references**.
|
|
23
|
+
* SQLite reports no decltype for expression results, so `max(big_id)` or
|
|
24
|
+
* `big_id + 1` falls into the safe-number arm and is a typed
|
|
25
|
+
* `VALUE_UNSUPPORTED` past the round-trip bound — never a rounded number. For
|
|
26
|
+
* exact expression results, use the native client with `intMode: "bigint"`.
|
|
27
|
+
*/
|
|
28
|
+
export const rindleBigint = customType<{
|
|
29
|
+
data: bigint;
|
|
30
|
+
driverData: bigint;
|
|
31
|
+
}>({
|
|
32
|
+
dataType: () => "BIGINT",
|
|
33
|
+
});
|
|
34
|
+
|
|
12
35
|
/** The small, structural statement shape consumed by drizzle-orm/libsql. */
|
|
13
36
|
export interface DrizzleStatement {
|
|
14
37
|
sql: string;
|
|
@@ -20,7 +43,9 @@ export type DrizzleInputStatement = string | DrizzleStatement | readonly [sql: s
|
|
|
20
43
|
export type DrizzleTransactionMode = "write" | "read" | "deferred";
|
|
21
44
|
|
|
22
45
|
// Booleans are a bind convenience only; SQLite result storage classes never decode to boolean.
|
|
23
|
-
|
|
46
|
+
// `bigint` appears ONLY in cells of a column whose decltype is exactly BIGINT/INT8 (the
|
|
47
|
+
// `rindleBigint` opt-in, design 226 §7.2); every other integer cell stays a safe number.
|
|
48
|
+
export type DrizzleValue = Exclude<SqlValue, boolean>;
|
|
24
49
|
export type DrizzleRow = DrizzleValue[] & Record<string, DrizzleValue>;
|
|
25
50
|
|
|
26
51
|
export interface DrizzleResultSet {
|
|
@@ -85,14 +110,38 @@ function defineNamedCell(row: DrizzleRow, name: string, value: DrizzleValue): vo
|
|
|
85
110
|
}
|
|
86
111
|
}
|
|
87
112
|
|
|
88
|
-
|
|
113
|
+
/** The exact whole-declaration match (design 226 §4.1): `BIGINT`/`INT8` and nothing
|
|
114
|
+
* else — `UNSIGNED BIGINT` and every decorated spelling keeps its safe-number
|
|
115
|
+
* INTEGER-affinity meaning, mirroring the daemon's `value_type_of`. */
|
|
116
|
+
function isInt64Decltype(decltype: string | null | undefined): boolean {
|
|
117
|
+
if (!decltype) return false;
|
|
118
|
+
const t = decltype.trim().toUpperCase();
|
|
119
|
+
return t === "BIGINT" || t === "INT8";
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function toDrizzleValue(value: SqlValue, int64Column: boolean): DrizzleValue {
|
|
89
123
|
if (typeof value === "bigint") {
|
|
124
|
+
// A BIGINT/INT8-declared result column preserves the exact value as JS bigint
|
|
125
|
+
// (the `rindleBigint` lane, design 226 §7.2). This dispatch must be per-column:
|
|
126
|
+
// globally returning bigint would break Drizzle's integer/timestamp mappers,
|
|
127
|
+
// globally returning number would defeat `rindleBigint`.
|
|
128
|
+
if (int64Column) return value;
|
|
90
129
|
const number = Number(value);
|
|
91
130
|
if (!Number.isSafeInteger(number)) {
|
|
92
131
|
throw valueUnsupported(`integer ${value.toString()} is outside Number's safe integer range required by Drizzle`);
|
|
93
132
|
}
|
|
94
133
|
return number;
|
|
95
134
|
}
|
|
135
|
+
if (int64Column && value !== null) {
|
|
136
|
+
// Under the facade's lossless-bigint contract every non-NULL INTEGER cell arrives
|
|
137
|
+
// as bigint, so a number or string here is a REAL/TEXT physical cell — SQLite
|
|
138
|
+
// affinity permits them and schema admission never scans rows. Passing it through
|
|
139
|
+
// would hand a `rindleBigint` field (statically `bigint`) the wrong runtime type;
|
|
140
|
+
// §7.2's contract is a typed error, never a mistyped value.
|
|
141
|
+
throw valueUnsupported(
|
|
142
|
+
`BIGINT/INT8-declared column holds a ${typeof value} cell; exact int64 columns require INTEGER storage`,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
96
145
|
// The native decoder never produces booleans, but normalize a structurally supplied result too.
|
|
97
146
|
if (typeof value === "boolean") return value ? 1 : 0;
|
|
98
147
|
return value;
|
|
@@ -102,8 +151,9 @@ function toDrizzleValue(value: SqlValue): DrizzleValue {
|
|
|
102
151
|
export function toDrizzleResultSet(result: StatementResult): DrizzleResultSet {
|
|
103
152
|
const columns = result.columns.map((column) => column.name);
|
|
104
153
|
const columnTypes = result.columns.map((column) => column.decltype ?? "");
|
|
154
|
+
const int64Columns = result.columns.map((column) => isInt64Decltype(column.decltype));
|
|
105
155
|
const rows = result.rows.map((cells) => {
|
|
106
|
-
const row = cells.map(toDrizzleValue) as DrizzleRow;
|
|
156
|
+
const row = cells.map((cell, index) => toDrizzleValue(cell, int64Columns[index] === true)) as DrizzleRow;
|
|
107
157
|
for (let index = 0; index < columns.length; index += 1) {
|
|
108
158
|
defineNamedCell(row, columns[index]!, row[index]!);
|
|
109
159
|
}
|
|
@@ -244,10 +294,15 @@ class ClientFacade implements DrizzleClient {
|
|
|
244
294
|
|
|
245
295
|
/** Create the structural libSQL-client facade used by drizzle-orm/libsql. */
|
|
246
296
|
export function createDrizzleClient(options: ClientOptions | SqlClient): DrizzleClient {
|
|
247
|
-
//
|
|
248
|
-
//
|
|
249
|
-
//
|
|
250
|
-
|
|
297
|
+
// The internal client is LOSSLESS (`intMode: "bigint"`) so precision is not
|
|
298
|
+
// discarded before result metadata is considered (design 226 §7.2):
|
|
299
|
+
// toDrizzleResultSet then dispatches per column decltype — BIGINT/INT8 keeps
|
|
300
|
+
// the exact bigint (the `rindleBigint` lane); every other column converts to
|
|
301
|
+
// the safe number Drizzle's integer/timestamp mappers consume, with an unsafe
|
|
302
|
+
// integer a typed VALUE_UNSUPPORTED, never a rounded number. An INJECTED
|
|
303
|
+
// structural client used with `rindleBigint` must likewise expose lossless
|
|
304
|
+
// bigint results, or exact values are lost before this facade sees them.
|
|
305
|
+
const client = isSqlClient(options) ? options : createSqlClient({ ...options, intMode: "bigint" });
|
|
251
306
|
return new ClientFacade(client);
|
|
252
307
|
}
|
|
253
308
|
|