@rwillians/exto 0.1.1 → 0.2.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/README.md +207 -153
- package/dist/cjs/bun-postgres.js +100 -0
- package/dist/cjs/bun-sqlite.js +100 -0
- package/dist/cjs/index.js +712 -0
- package/dist/cjs/standard-schema.js +249 -0
- package/dist/cjs/utils.js +17 -0
- package/dist/esm/bun-postgres.js +96 -0
- package/dist/esm/bun-sqlite.js +96 -0
- package/dist/esm/index.js +663 -0
- package/dist/esm/standard-schema.js +237 -0
- package/dist/esm/utils.js +10 -0
- package/dist/types/bun-postgres.d.ts +17 -0
- package/dist/types/bun-sqlite.d.ts +17 -0
- package/dist/types/index.d.ts +438 -0
- package/dist/types/standard-schema.d.ts +180 -0
- package/dist/types/utils.d.ts +11 -0
- package/package.json +9 -8
- package/dist/.gitignore +0 -2
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dialect = exports.connect = void 0;
|
|
4
|
+
const bun_sqlite_1 = require("bun:sqlite");
|
|
5
|
+
const TYPES = {
|
|
6
|
+
BIGINT: 'INTEGER',
|
|
7
|
+
BINARY: 'BLOB',
|
|
8
|
+
BOOLEAN: 'INTEGER',
|
|
9
|
+
CITEXT: 'TEXT COLLATE NOCASE',
|
|
10
|
+
DATE: 'TEXT',
|
|
11
|
+
DECIMAL: 'NUMERIC',
|
|
12
|
+
FLOAT: 'REAL',
|
|
13
|
+
INTEGER: 'INTEGER',
|
|
14
|
+
JSON: 'TEXT',
|
|
15
|
+
SEQUENCE: 'INTEGER',
|
|
16
|
+
STRING: 'TEXT',
|
|
17
|
+
TEXT: 'TEXT',
|
|
18
|
+
TIMESTAMP: 'INTEGER',
|
|
19
|
+
UUID: 'TEXT',
|
|
20
|
+
};
|
|
21
|
+
const identity = () => ({
|
|
22
|
+
encode: (value) => value,
|
|
23
|
+
decode: (value) => value,
|
|
24
|
+
});
|
|
25
|
+
// integers are read as bigints (see `execute`), so those that aren't BIGINT
|
|
26
|
+
// columns go back to being numbers
|
|
27
|
+
const numeric = {
|
|
28
|
+
encode: (value) => value,
|
|
29
|
+
decode: (value) => Number(value),
|
|
30
|
+
};
|
|
31
|
+
// sqlite's JSON paths quote each key, so that any key is a valid one
|
|
32
|
+
const jsonPath = (path) => `'$${path.map(key => `."${key.replaceAll('"', '\\"').replaceAll('\'', '\'\'')}"`).join('')}'`;
|
|
33
|
+
const dialect = {
|
|
34
|
+
name: 'sqlite',
|
|
35
|
+
placeholder: () => '?',
|
|
36
|
+
type: (col) => TYPES[col.type],
|
|
37
|
+
generated: (col) => {
|
|
38
|
+
if (col.type === 'SEQUENCE' && col.primaryKey)
|
|
39
|
+
return 'AUTOINCREMENT';
|
|
40
|
+
if (col.type === 'SEQUENCE')
|
|
41
|
+
throw new Error(`SQLite can only generate sequences for primary keys, column "${col.name}" isn't one`);
|
|
42
|
+
return undefined;
|
|
43
|
+
},
|
|
44
|
+
json: (sql, path, type) => `${sql} ${type === 'JSON' ? '->' : '->>'} ${jsonPath(path)}`,
|
|
45
|
+
codecs: {
|
|
46
|
+
BIGINT: { encode: (value) => value, decode: (value) => BigInt(value) },
|
|
47
|
+
BINARY: { encode: (value) => value, decode: (value) => new Uint8Array(value) },
|
|
48
|
+
BOOLEAN: { encode: (value) => (value ? 1 : 0), decode: (value) => Number(value) === 1 },
|
|
49
|
+
CITEXT: identity(),
|
|
50
|
+
DATE: identity(),
|
|
51
|
+
DECIMAL: numeric,
|
|
52
|
+
FLOAT: numeric,
|
|
53
|
+
INTEGER: numeric,
|
|
54
|
+
JSON: { encode: (value) => JSON.stringify(value), decode: (value) => JSON.parse(value) },
|
|
55
|
+
SEQUENCE: numeric,
|
|
56
|
+
STRING: identity(),
|
|
57
|
+
TEXT: identity(),
|
|
58
|
+
TIMESTAMP: { encode: (value) => value.getTime(), decode: (value) => new Date(Number(value)) },
|
|
59
|
+
UUID: identity(),
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
exports.dialect = dialect;
|
|
63
|
+
class BunSQLite {
|
|
64
|
+
conn;
|
|
65
|
+
loggers;
|
|
66
|
+
depth;
|
|
67
|
+
dialect = dialect;
|
|
68
|
+
constructor(conn, loggers = [], depth = 0) {
|
|
69
|
+
this.conn = conn;
|
|
70
|
+
this.loggers = loggers;
|
|
71
|
+
this.depth = depth;
|
|
72
|
+
}
|
|
73
|
+
async execute(sql, params) {
|
|
74
|
+
// without safe integers, bun:sqlite rounds anything beyond 2^53
|
|
75
|
+
return this.conn.prepare(sql).safeIntegers(true).all(...params);
|
|
76
|
+
}
|
|
77
|
+
async close() {
|
|
78
|
+
this.conn.close();
|
|
79
|
+
}
|
|
80
|
+
// bun:sqlite's own `transaction()` is synchronous and would commit before an
|
|
81
|
+
// async callback settles, hence the manual BEGIN/COMMIT (SAVEPOINT if nested)
|
|
82
|
+
async transaction(fn) {
|
|
83
|
+
const savepoint = `"sp_${this.depth}"`;
|
|
84
|
+
const [begin, commit, rollback] = this.depth === 0
|
|
85
|
+
? ['BEGIN', 'COMMIT', 'ROLLBACK']
|
|
86
|
+
: [`SAVEPOINT ${savepoint}`, `RELEASE ${savepoint}`, `ROLLBACK TO ${savepoint}; RELEASE ${savepoint}`];
|
|
87
|
+
this.conn.run(begin);
|
|
88
|
+
try {
|
|
89
|
+
const result = await fn(new BunSQLite(this.conn, this.loggers, this.depth + 1));
|
|
90
|
+
this.conn.run(commit);
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
this.conn.run(rollback);
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const connect = (filename = ':memory:', { loggers = [] } = {}) => new BunSQLite(new bun_sqlite_1.Database(filename), loggers);
|
|
100
|
+
exports.connect = connect;
|