rado 1.0.8 → 1.0.10

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.
Files changed (44) hide show
  1. package/README.md +18 -8
  2. package/dist/core/Column.js +3 -4
  3. package/dist/core/Database.js +2 -4
  4. package/dist/core/Emitter.js +8 -16
  5. package/dist/core/Query.js +9 -7
  6. package/dist/core/Resolver.js +5 -10
  7. package/dist/core/Selection.js +7 -14
  8. package/dist/core/Sql.js +12 -24
  9. package/dist/core/Table.js +2 -4
  10. package/dist/core/Virtual.js +3 -6
  11. package/dist/core/expr/Conditions.js +7 -14
  12. package/dist/core/expr/Include.js +5 -4
  13. package/dist/core/expr/Input.js +3 -6
  14. package/dist/core/expr/Json.js +4 -4
  15. package/dist/core/query/Delete.js +1 -2
  16. package/dist/core/query/Insert.js +2 -4
  17. package/dist/core/query/Select.js +1 -2
  18. package/dist/core/query/Update.js +1 -2
  19. package/dist/driver/d1.d.ts +25 -0
  20. package/dist/driver/d1.js +60 -0
  21. package/dist/driver/mysql2.d.ts +1 -0
  22. package/dist/driver/mysql2.js +14 -9
  23. package/dist/driver/pg.js +4 -8
  24. package/dist/driver/pglite.d.ts +1 -1
  25. package/dist/driver/pglite.js +2 -3
  26. package/dist/driver/sql.js.js +2 -4
  27. package/dist/driver.d.ts +7 -0
  28. package/dist/driver.js +23 -0
  29. package/dist/mysql/columns.d.ts +2 -1
  30. package/dist/mysql/columns.js +4 -0
  31. package/dist/mysql/dialect.js +1 -2
  32. package/dist/mysql/transactions.js +1 -2
  33. package/dist/postgres/columns.d.ts +2 -2
  34. package/dist/postgres/columns.js +3 -3
  35. package/dist/postgres/dialect.js +5 -10
  36. package/dist/sqlite/dialect.js +3 -6
  37. package/dist/sqlite/diff.js +1 -2
  38. package/dist/sqlite/functions.d.ts +0 -2
  39. package/dist/sqlite/functions.js +0 -2
  40. package/dist/sqlite/transactions.js +2 -4
  41. package/dist/universal/columns.d.ts +6 -0
  42. package/dist/universal/columns.js +45 -6
  43. package/dist/universal/transactions.js +1 -2
  44. package/package.json +20 -20
package/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  [![npm](https://img.shields.io/npm/v/rado.svg)](https://npmjs.org/package/rado)
2
+ [![jsr](https://jsr.io/badges/@rado/rado)](https://jsr.io/@rado/rado)
2
3
 
3
4
  # rado
4
5
 
@@ -149,14 +150,23 @@ const PostTags = table({
149
150
 
150
151
  Currently supported drivers:
151
152
 
152
- | Driver | import |
153
- | ---------------- | ------------------------------ |
154
- | `better-sqlite3` | `'rado/driver/better-sqlite3'` |
155
- | `bun-sqlite` | `'rado/driver/bun-sqlite'` |
156
- | `mysql2` | `'rado/driver/mysql2'` |
157
- | `pg` | `'rado/driver/pg'` |
158
- | `pglite` | `'rado/driver/pglite'` |
159
- | `sql.js` | `'rado/driver/sql.js'` |
153
+ | `PostgreSQL ` | `import ` |
154
+ | -------------------------- | ------------------------------ |
155
+ | `pg` | `'rado/driver/pg'` |
156
+ | `@electric-sql/pglite` | `'rado/driver/pglite'` |
157
+ | `@neondatabase/serverless` | `'rado/driver/pg'` |
158
+ | `@vercel/postgres` | `'rado/driver/pg'` |
159
+
160
+ | `SQLite ` | `import ` |
161
+ | -------------------------- | ------------------------------ |
162
+ | `better-sqlite3` | `'rado/driver/better-sqlite3'` |
163
+ | `bun:sqlite` | `'rado/driver/bun-sqlite'` |
164
+ | `sql.js` | `'rado/driver/sql.js'` |
165
+ | `Cloudflare D1` | `'rado/driver/d1'` |
166
+
167
+ | `MySQL ` | `import ` |
168
+ | -------------------------- | ------------------------------ |
169
+ | `mysql2` | `'rado/driver/mysql2'` |
160
170
 
161
171
  Pass an instance of the database to the `connect` function to get started:
162
172
 
@@ -68,10 +68,9 @@ var column = new Proxy(createColumn, {
68
68
  get(target, method) {
69
69
  return target[method] ??= (...args) => {
70
70
  while (args.length > 0)
71
- if (args.at(-1) === void 0)
72
- args.pop();
73
- if (args.length === 0)
74
- return sql.unsafe(method);
71
+ if (args.at(-1) === void 0) args.pop();
72
+ else break;
73
+ if (args.length === 0) return sql.unsafe(method);
75
74
  return sql`${sql.unsafe(method)}(${sql.join(
76
75
  args.map(sql.inline),
77
76
  sql`, `
@@ -49,8 +49,7 @@ var Database = class extends Builder {
49
49
  txGenerator(function* (tx) {
50
50
  for (const table of tables) {
51
51
  const diff = yield* computeDiff(table);
52
- if (diff.length > 0)
53
- yield* tx.batch(diff.map(sql.unsafe));
52
+ if (diff.length > 0) yield* tx.batch(diff.map(sql.unsafe));
54
53
  }
55
54
  })
56
55
  );
@@ -60,8 +59,7 @@ var Database = class extends Builder {
60
59
  }
61
60
  execute(input) {
62
61
  const emitter = this.dialect.emit(input);
63
- if (emitter.hasParams)
64
- throw new Error("Query has parameters");
62
+ if (emitter.hasParams) throw new Error("Query has parameters");
65
63
  return this.driver.exec(emitter.sql);
66
64
  }
67
65
  transaction(run, options = {}) {
@@ -17,8 +17,7 @@ var Emitter = class {
17
17
  }
18
18
  bind(inputs) {
19
19
  return this.params.map((param) => {
20
- if (param instanceof ValueParam)
21
- return this.processValue(param.value);
20
+ if (param instanceof ValueParam) return this.processValue(param.value);
22
21
  if (inputs && param.name in inputs)
23
22
  return this.processValue(inputs[param.name]);
24
23
  throw new Error(`Missing input for named parameter: ${param.name}`);
@@ -29,8 +28,7 @@ var Emitter = class {
29
28
  }
30
29
  emitIdentifierOrSelf(value) {
31
30
  if (value === Sql.SELF_TARGET) {
32
- if (!this.selfName)
33
- throw new Error("Self target not defined");
31
+ if (!this.selfName) throw new Error("Self target not defined");
34
32
  this.emitIdentifier(this.selfName);
35
33
  } else {
36
34
  this.emitIdentifier(value);
@@ -78,8 +76,7 @@ var Emitter = class {
78
76
  }
79
77
  emitDelete(deleteOp) {
80
78
  const { cte, from, where, returning } = getData(deleteOp);
81
- if (cte)
82
- this.emitWith(cte);
79
+ if (cte) this.emitWith(cte);
83
80
  const table = getTable(from);
84
81
  sql.query({
85
82
  deleteFrom: sql.identifier(table.name),
@@ -89,8 +86,7 @@ var Emitter = class {
89
86
  }
90
87
  emitInsert(insert) {
91
88
  const { cte, into, values, select, onConflict, returning } = getData(insert);
92
- if (cte)
93
- this.emitWith(cte);
89
+ if (cte) this.emitWith(cte);
94
90
  const table = getTable(into);
95
91
  const tableName = sql.identifier(table.name);
96
92
  sql.query({
@@ -113,8 +109,7 @@ var Emitter = class {
113
109
  limit,
114
110
  offset
115
111
  }) {
116
- if (cte)
117
- this.emitWith(cte);
112
+ if (cte) this.emitWith(cte);
118
113
  const prefix = distinctOn ? sql`distinct on (${sql.join(distinctOn, sql`, `)})` : distinct && sql`distinct`;
119
114
  sql.query({
120
115
  select: sql.join([prefix, select]),
@@ -133,8 +128,7 @@ var Emitter = class {
133
128
  emitUpdate(update) {
134
129
  const { cte, table, set, where, returning } = getData(update);
135
130
  const tableApi = getTable(table);
136
- if (cte)
137
- this.emitWith(cte);
131
+ if (cte) this.emitWith(cte);
138
132
  sql.query({
139
133
  update: sql.identifier(tableApi.name),
140
134
  set,
@@ -158,8 +152,7 @@ var Emitter = class {
158
152
  const wrapQuery = Boolean(data.limit || data.offset || data.orderBy);
159
153
  const innerQuery = sql.chunk("emitSelect", data);
160
154
  const inner = wrapQuery ? sql`select * from (${innerQuery})` : innerQuery;
161
- if (!data.select)
162
- throw new Error("No selection defined");
155
+ if (!data.select) throw new Error("No selection defined");
163
156
  const fields = data.select.fieldNames();
164
157
  const subject = jsonArray(
165
158
  ...fields.map((name) => sql`_.${sql.identifier(name)}`)
@@ -168,8 +161,7 @@ var Emitter = class {
168
161
  }
169
162
  emitUniversal(runtimes) {
170
163
  const sql2 = runtimes[this.runtime] ?? runtimes.default;
171
- if (!sql2)
172
- throw new Error("Unsupported runtime");
164
+ if (!sql2) throw new Error("Unsupported runtime");
173
165
  sql2.emitTo(this);
174
166
  }
175
167
  };
@@ -17,8 +17,7 @@ var Executable = class {
17
17
  *[Symbol.iterator]() {
18
18
  const interim = this.#execute();
19
19
  const isAsync = interim instanceof Promise;
20
- if (!isAsync)
21
- return interim;
20
+ if (!isAsync) return interim;
22
21
  let result;
23
22
  yield interim.then((v) => result = v);
24
23
  return result;
@@ -27,9 +26,13 @@ var Executable = class {
27
26
  return this.#execute();
28
27
  }
29
28
  // biome-ignore lint/suspicious/noThenProperty:
30
- then(onfulfilled, onrejected) {
31
- const result = this.#execute();
32
- return Promise.resolve(result).then(onfulfilled, onrejected);
29
+ async then(onfulfilled, onrejected) {
30
+ try {
31
+ const result = await this.#execute();
32
+ return onfulfilled ? onfulfilled(result) : result;
33
+ } catch (error) {
34
+ return onrejected ? onrejected(error) : Promise.reject(error);
35
+ }
33
36
  }
34
37
  catch(onrejected) {
35
38
  return this.then().catch(onrejected);
@@ -82,8 +85,7 @@ var Query = class extends Executable {
82
85
  }
83
86
  toSQL(db) {
84
87
  const resolver = db ? getResolver(db) : getData(this).resolver;
85
- if (!resolver)
86
- throw new Error("Query has no resolver");
88
+ if (!resolver) throw new Error("Query has no resolver");
87
89
  return resolver.toSQL(this);
88
90
  }
89
91
  };
@@ -51,8 +51,7 @@ var Batch = class {
51
51
  };
52
52
  for (let i = 0; i < this.#queries.length; i++) {
53
53
  const { mapRow } = this.#queries[i];
54
- if (!mapRow)
55
- continue;
54
+ if (!mapRow) continue;
56
55
  const rows = results[i];
57
56
  for (let j = 0; j < results[i].length; j++) {
58
57
  ctx.values = rows[i];
@@ -64,8 +63,7 @@ var Batch = class {
64
63
  };
65
64
  execute() {
66
65
  const results = this.#driver.batch(this.#queries);
67
- if (results instanceof Promise)
68
- return results.then(this.#transform);
66
+ if (results instanceof Promise) return results.then(this.#transform);
69
67
  return this.#transform(results);
70
68
  }
71
69
  };
@@ -81,8 +79,7 @@ var PreparedStatement = class {
81
79
  this.#specs = specs;
82
80
  }
83
81
  #transform = (rows) => {
84
- if (!this.#mapRow)
85
- return rows;
82
+ if (!this.#mapRow) return rows;
86
83
  const ctx = {
87
84
  values: void 0,
88
85
  index: 0,
@@ -97,14 +94,12 @@ var PreparedStatement = class {
97
94
  };
98
95
  all(inputs) {
99
96
  const rows = this.#stmt.values(this.#emitter.bind(inputs));
100
- if (rows instanceof Promise)
101
- return rows.then(this.#transform);
97
+ if (rows instanceof Promise) return rows.then(this.#transform);
102
98
  return this.#transform(rows);
103
99
  }
104
100
  get(inputs) {
105
101
  const rows = this.all(inputs);
106
- if (rows instanceof Promise)
107
- return rows.then((rows2) => rows2[0]);
102
+ if (rows instanceof Promise) return rows.then((rows2) => rows2[0]);
108
103
  return rows[0];
109
104
  }
110
105
  run(inputs) {
@@ -15,8 +15,7 @@ var SqlColumn = class {
15
15
  }
16
16
  result(ctx) {
17
17
  const value = ctx.values[ctx.index++];
18
- if (!this.sql.mapFromDriverValue)
19
- return value;
18
+ if (!this.sql.mapFromDriverValue) return value;
20
19
  return this.sql.mapFromDriverValue(value, ctx.specs);
21
20
  }
22
21
  };
@@ -42,8 +41,7 @@ var ObjectColumn = class {
42
41
  }
43
42
  }
44
43
  }
45
- if (isNullable)
46
- return null;
44
+ if (isNullable) return null;
47
45
  return result;
48
46
  }
49
47
  };
@@ -60,8 +58,7 @@ var Selection = class {
60
58
  }
61
59
  #defineColumn(nullable, input) {
62
60
  const expr = getSql(input);
63
- if (expr)
64
- return new SqlColumn(expr, getField(input)?.targetName);
61
+ if (expr) return new SqlColumn(expr, getField(input)?.targetName);
65
62
  return new ObjectColumn(
66
63
  nullable,
67
64
  Object.entries(input).map(([name, value]) => [
@@ -77,10 +74,8 @@ var Selection = class {
77
74
  const expr = getSql(input);
78
75
  if (expr) {
79
76
  let exprName = name ?? expr.alias;
80
- if (!exprName)
81
- throw new Error("Missing field name");
82
- while (names.has(exprName))
83
- exprName = `${exprName}_`;
77
+ if (!exprName) throw new Error("Missing field name");
78
+ while (names.has(exprName)) exprName = `${exprName}_`;
84
79
  return [exprName];
85
80
  }
86
81
  return Object.entries(input).flatMap(
@@ -92,13 +87,11 @@ var Selection = class {
92
87
  if (expr) {
93
88
  let exprName = name ?? expr.alias;
94
89
  if (exprName) {
95
- while (names.has(exprName))
96
- exprName = `${exprName}_`;
90
+ while (names.has(exprName)) exprName = `${exprName}_`;
97
91
  names.add(exprName);
98
92
  if (hasField(input)) {
99
93
  const field = getField(input);
100
- if (field.fieldName === exprName)
101
- return expr;
94
+ if (field.fieldName === exprName) return expr;
102
95
  }
103
96
  return sql`${expr.forSelection()} as ${sql.identifier(exprName)}`;
104
97
  }
package/dist/core/Sql.js CHANGED
@@ -29,8 +29,7 @@ var Sql = class _Sql {
29
29
  return this;
30
30
  }
31
31
  unsafe(sql2) {
32
- if (sql2.length > 0)
33
- this.chunk("emitUnsafe", sql2);
32
+ if (sql2.length > 0) this.chunk("emitUnsafe", sql2);
34
33
  return this;
35
34
  }
36
35
  field(field) {
@@ -38,8 +37,7 @@ var Sql = class _Sql {
38
37
  }
39
38
  add(sql2) {
40
39
  const inner = getSql(sql2);
41
- if (!(inner instanceof _Sql))
42
- throw new Error("Invalid SQL");
40
+ if (!(inner instanceof _Sql)) throw new Error("Invalid SQL");
43
41
  this.#chunks.push(...inner.#chunks);
44
42
  return this;
45
43
  }
@@ -47,19 +45,16 @@ var Sql = class _Sql {
47
45
  return this.chunk("emitValue", value);
48
46
  }
49
47
  getValue() {
50
- if (this.#chunks.length !== 1)
51
- return;
48
+ if (this.#chunks.length !== 1) return;
52
49
  const chunk = this.#chunks[0];
53
- if (chunk?.type === "emitValue")
54
- return chunk.inner;
50
+ if (chunk?.type === "emitValue") return chunk.inner;
55
51
  }
56
52
  inline(value) {
57
53
  return this.chunk("emitInline", value);
58
54
  }
59
55
  jsonPath(path) {
60
56
  const inner = path.target.#chunks[0];
61
- if (inner?.type !== "emitJsonPath")
62
- return this.chunk("emitJsonPath", path);
57
+ if (inner?.type !== "emitJsonPath") return this.chunk("emitJsonPath", path);
63
58
  const innerPath = inner.inner;
64
59
  return this.chunk("emitJsonPath", {
65
60
  ...innerPath,
@@ -83,8 +78,7 @@ var Sql = class _Sql {
83
78
  inlineValues() {
84
79
  return new _Sql(
85
80
  this.#chunks.map((chunk) => {
86
- if (chunk.type !== "emitValue")
87
- return chunk;
81
+ if (chunk.type !== "emitValue") return chunk;
88
82
  return new Chunk("emitInline", chunk.inner);
89
83
  })
90
84
  );
@@ -92,8 +86,7 @@ var Sql = class _Sql {
92
86
  inlineFields(withTableName) {
93
87
  return new _Sql(
94
88
  this.#chunks.flatMap((chunk) => {
95
- if (chunk.type !== "emitField")
96
- return [chunk];
89
+ if (chunk.type !== "emitField") return [chunk];
97
90
  const data = chunk.inner;
98
91
  if (withTableName)
99
92
  return [
@@ -109,8 +102,7 @@ var Sql = class _Sql {
109
102
  return sql.chunk("emitSelf", { name, inner: this });
110
103
  }
111
104
  emitTo(emitter) {
112
- for (const chunk of this.#chunks)
113
- emitter[chunk.type](chunk.inner);
105
+ for (const chunk of this.#chunks) emitter[chunk.type](chunk.inner);
114
106
  }
115
107
  };
116
108
  function sql(strings, ...inner) {
@@ -169,12 +161,9 @@ function sql(strings, ...inner) {
169
161
  return join(
170
162
  Object.entries(ast).map(([key, value2]) => {
171
163
  const statement = key.replace(/([A-Z])/g, " $1").toLocaleLowerCase();
172
- if (value2 === true)
173
- return sql2.unsafe(statement);
174
- if (Array.isArray(value2))
175
- value2 = join(value2);
176
- if (!key)
177
- return value2;
164
+ if (value2 === true) return sql2.unsafe(statement);
165
+ if (Array.isArray(value2)) value2 = join(value2);
166
+ if (!key) return value2;
178
167
  return value2 && sql2`${sql2.unsafe(statement)} ${value2}`;
179
168
  })
180
169
  );
@@ -184,8 +173,7 @@ function sql(strings, ...inner) {
184
173
  const parts = items.filter(Boolean);
185
174
  const sql3 = new Sql();
186
175
  for (let i = 0; i < parts.length; i++) {
187
- if (i > 0)
188
- sql3.add(separator);
176
+ if (i > 0) sql3.add(separator);
189
177
  sql3.add(parts[i]);
190
178
  }
191
179
  return sql3;
@@ -71,8 +71,7 @@ var TableApi = class extends TableData {
71
71
  const columnApi = getData(column);
72
72
  const { name: givenName } = columnApi;
73
73
  const field = new Field(this.aliased, givenName ?? name, columnApi);
74
- if (columnApi.json)
75
- return [name, jsonExpr(field)];
74
+ if (columnApi.json) return [name, jsonExpr(field)];
76
75
  return [name, field];
77
76
  })
78
77
  );
@@ -114,8 +113,7 @@ function table(name, columns, config, schemaName) {
114
113
  [internalTarget]: api.target(),
115
114
  ...api.fields()
116
115
  };
117
- if (config)
118
- api.config = config(table2);
116
+ if (config) api.config = config(table2);
119
117
  return table2;
120
118
  }
121
119
  function alias(table2, alias2) {
@@ -7,17 +7,14 @@ function virtual(alias, source) {
7
7
  if (source && hasSql(source)) {
8
8
  const expr = getSql(source);
9
9
  const name = expr.alias;
10
- if (!name)
11
- throw new Error("Cannot alias a virtual field without a name");
10
+ if (!name) throw new Error("Cannot alias a virtual field without a name");
12
11
  return Object.assign(new Field(alias, name, expr), target);
13
12
  }
14
13
  return new Proxy(target, {
15
14
  get(target2, field) {
16
- if (field in target2)
17
- return target2[field];
15
+ if (field in target2) return target2[field];
18
16
  const from = source?.[field];
19
- if (typeof field !== "string")
20
- return from;
17
+ if (typeof field !== "string") return from;
21
18
  return target2[field] = new Field(
22
19
  alias,
23
20
  field,
@@ -23,18 +23,14 @@ var arrayContained = binop("<@");
23
23
  var arrayOverlaps = binop("&&");
24
24
  function and(...conditions) {
25
25
  const inputs = conditions.filter((v) => v !== void 0).map(input);
26
- if (inputs.length === 0)
27
- return bool(sql`true`);
28
- if (inputs.length === 1)
29
- return bool(inputs[0]);
26
+ if (inputs.length === 0) return bool(sql`true`);
27
+ if (inputs.length === 1) return bool(inputs[0]);
30
28
  return bool(sql`(${sql.join(inputs, sql` and `)})`);
31
29
  }
32
30
  function or(...conditions) {
33
31
  const inputs = conditions.filter((v) => v !== void 0).map(input);
34
- if (inputs.length === 0)
35
- return bool(sql`true`);
36
- if (inputs.length === 1)
37
- return bool(inputs[0]);
32
+ if (inputs.length === 0) return bool(sql`true`);
33
+ if (inputs.length === 1) return bool(inputs[0]);
38
34
  return bool(sql`(${sql.join(inputs, sql` or `)})`);
39
35
  }
40
36
  function not(condition) {
@@ -43,8 +39,7 @@ function not(condition) {
43
39
  function inArray(left, right) {
44
40
  const value = (hasSql(right) ? getSql(right).getValue() : void 0) ?? right;
45
41
  if (Array.isArray(value)) {
46
- if (value.length === 0)
47
- return sql`false`;
42
+ if (value.length === 0) return sql`false`;
48
43
  return bool(sql`${input(left)} in (${sql.join(value.map(input), sql`, `)})`);
49
44
  }
50
45
  return bool(sql`${input(left)} in ${input(right)}`);
@@ -52,8 +47,7 @@ function inArray(left, right) {
52
47
  function notInArray(left, right) {
53
48
  const value = (hasSql(right) ? getSql(right).getValue() : void 0) ?? right;
54
49
  if (Array.isArray(value)) {
55
- if (value.length === 0)
56
- return sql`true`;
50
+ if (value.length === 0) return sql`true`;
57
51
  return bool(
58
52
  sql`${input(left)} not in (${sql.join(value.map(input), sql`, `)})`
59
53
  );
@@ -94,8 +88,7 @@ function when(...cases) {
94
88
  const [condition, result] = pair;
95
89
  return sql`when ${input(condition)} then ${input(result)}`;
96
90
  }
97
- if (index === cases.length - 1)
98
- return sql`else ${input(pair)}`;
91
+ if (index === cases.length - 1) return sql`else ${input(pair)}`;
99
92
  throw new Error("Unexpected else condition");
100
93
  })
101
94
  ),
@@ -13,10 +13,11 @@ var Include = class {
13
13
  #mapFromDriverValue = (value, specs) => {
14
14
  const { select, first } = getData(this);
15
15
  const parsed = specs.parsesJson ? value : JSON.parse(value);
16
- if (first)
17
- return parsed ? select.mapRow({ values: parsed, index: 0, specs }) : null;
18
- if (!parsed)
19
- return [];
16
+ if (first) {
17
+ const result = parsed ? select.mapRow({ values: parsed, index: 0, specs }) : null;
18
+ return result;
19
+ }
20
+ if (!parsed) return [];
20
21
  const rows = parsed;
21
22
  const ctx = {
22
23
  values: void 0,
@@ -2,12 +2,9 @@
2
2
  import { getSql, getTable, hasSql, hasTable } from "../Internal.js";
3
3
  import { sql } from "../Sql.js";
4
4
  function input(value) {
5
- if (typeof value !== "object" || value === null)
6
- return sql.value(value);
7
- if (hasTable(value))
8
- return sql.identifier(getTable(value).name);
9
- if (hasSql(value))
10
- return getSql(value);
5
+ if (typeof value !== "object" || value === null) return sql.value(value);
6
+ if (hasTable(value)) return sql.identifier(getTable(value).name);
7
+ if (hasSql(value)) return getSql(value);
11
8
  return sql.value(value);
12
9
  }
13
10
  export {
@@ -6,8 +6,7 @@ var INDEX_PROPERTY = /^\d+$/;
6
6
  function jsonExpr(e) {
7
7
  return new Proxy(e, {
8
8
  get(target, prop) {
9
- if (typeof prop !== "string")
10
- return Reflect.get(target, prop);
9
+ if (typeof prop !== "string") return Reflect.get(target, prop);
11
10
  const isNumber = INDEX_PROPERTY.test(prop);
12
11
  return jsonExpr(
13
12
  sql.jsonPath({
@@ -26,8 +25,9 @@ function jsonExpr(e) {
26
25
  function jsonAggregateArray(...args) {
27
26
  return callFunction(
28
27
  sql.universal({
28
+ // Once sqlite 3.45+ is more commonplace we can use jsonb_group_array
29
29
  sqlite: sql`json_group_array`,
30
- postgres: sql`json_agg`,
30
+ postgres: sql`jsonb_agg`,
31
31
  mysql: sql`json_arrayagg`
32
32
  }),
33
33
  args
@@ -36,7 +36,7 @@ function jsonAggregateArray(...args) {
36
36
  function jsonArray(...args) {
37
37
  return callFunction(
38
38
  sql.universal({
39
- postgres: sql`json_build_array`,
39
+ postgres: sql`jsonb_build_array`,
40
40
  default: sql`json_array`
41
41
  }),
42
42
  args
@@ -16,8 +16,7 @@ var Delete = class extends Query {
16
16
  constructor(data) {
17
17
  super(data);
18
18
  this[internalData] = data;
19
- if (data.returning)
20
- this[internalSelection] = data.returning;
19
+ if (data.returning) this[internalSelection] = data.returning;
21
20
  }
22
21
  get [internalQuery]() {
23
22
  return sql.chunk("emitDelete", this);
@@ -18,8 +18,7 @@ var Insert = class extends Query {
18
18
  constructor(data) {
19
19
  super(data);
20
20
  this[internalData] = data;
21
- if (data.returning)
22
- this[internalSelection] = data.returning;
21
+ if (data.returning) this[internalSelection] = data.returning;
23
22
  }
24
23
  get [internalQuery]() {
25
24
  return sql.chunk("emitInsert", this);
@@ -87,8 +86,7 @@ var InsertInto = class {
87
86
  const { $default, mapToDriverValue } = getData(column);
88
87
  if (value !== void 0)
89
88
  return input(mapToDriverValue?.(value) ?? value);
90
- if ($default)
91
- return $default();
89
+ if ($default) return $default();
92
90
  return defaultKeyword;
93
91
  }),
94
92
  sql`, `
@@ -102,8 +102,7 @@ var Select = class _Select extends UnionBase {
102
102
  }
103
103
  get [internalSelection]() {
104
104
  const { select } = getData(this);
105
- if (!select)
106
- throw new Error("No selection defined");
105
+ if (!select) throw new Error("No selection defined");
107
106
  return select;
108
107
  }
109
108
  get [internalQuery]() {
@@ -18,8 +18,7 @@ var Update = class extends Query {
18
18
  constructor(data) {
19
19
  super(data);
20
20
  this[internalData] = data;
21
- if (data.returning)
22
- this[internalSelection] = data.returning;
21
+ if (data.returning) this[internalSelection] = data.returning;
23
22
  }
24
23
  get [internalQuery]() {
25
24
  return sql.chunk("emitUpdate", this);
@@ -0,0 +1,25 @@
1
+ import { AsyncDatabase } from '../core/Database.js';
2
+ import type { AsyncDriver, AsyncStatement, BatchQuery, PrepareOptions } from '../core/Driver.js';
3
+ type Client = D1Database;
4
+ declare class PreparedStatement implements AsyncStatement {
5
+ private stmt;
6
+ private isSelection;
7
+ constructor(stmt: D1PreparedStatement, isSelection: boolean);
8
+ all(params: Array<unknown>): Promise<Array<object>>;
9
+ run(params: Array<unknown>): Promise<void>;
10
+ get(params: Array<unknown>): Promise<object | null>;
11
+ values(params: Array<unknown>): Promise<Array<Array<unknown>>>;
12
+ free(): void;
13
+ }
14
+ export declare class D1Driver implements AsyncDriver {
15
+ private client;
16
+ parsesJson: boolean;
17
+ constructor(client: Client);
18
+ exec(query: string): Promise<void>;
19
+ prepare(sql: string, options: PrepareOptions): PreparedStatement;
20
+ close(): Promise<void>;
21
+ batch(queries: Array<BatchQuery>): Promise<Array<Array<unknown>>>;
22
+ transaction<T>(): Promise<T>;
23
+ }
24
+ export declare function connect(client: Client): AsyncDatabase<'sqlite'>;
25
+ export {};
@@ -0,0 +1,60 @@
1
+ // src/driver/d1.ts
2
+ import { AsyncDatabase } from "../core/Database.js";
3
+ import { sqliteDialect } from "../sqlite.js";
4
+ import { sqliteDiff } from "../sqlite/diff.js";
5
+ var PreparedStatement = class {
6
+ constructor(stmt, isSelection) {
7
+ this.stmt = stmt;
8
+ this.isSelection = isSelection;
9
+ }
10
+ async all(params) {
11
+ return this.stmt.bind(...params).all().then(({ results }) => results);
12
+ }
13
+ async run(params) {
14
+ const results = await this.stmt.bind(...params).run();
15
+ }
16
+ async get(params) {
17
+ return this.stmt.bind(...params).first();
18
+ }
19
+ async values(params) {
20
+ if (this.isSelection) {
21
+ const results = await this.stmt.bind(...params).raw();
22
+ console.log(results);
23
+ return results;
24
+ }
25
+ await this.stmt.bind(...params).run();
26
+ return [];
27
+ }
28
+ free() {
29
+ }
30
+ };
31
+ var D1Driver = class {
32
+ constructor(client) {
33
+ this.client = client;
34
+ }
35
+ parsesJson = false;
36
+ async exec(query) {
37
+ await this.client.exec(query);
38
+ }
39
+ prepare(sql, options) {
40
+ return new PreparedStatement(this.client.prepare(sql), options.isSelection);
41
+ }
42
+ async close() {
43
+ }
44
+ async batch(queries) {
45
+ const results = [];
46
+ for (const { sql, params, isSelection } of queries)
47
+ results.push(await this.prepare(sql, { isSelection }).values(params));
48
+ return results;
49
+ }
50
+ async transaction() {
51
+ throw new Error("Transactions are not supported in D1");
52
+ }
53
+ };
54
+ function connect(client) {
55
+ return new AsyncDatabase(new D1Driver(client), sqliteDialect, sqliteDiff);
56
+ }
57
+ export {
58
+ D1Driver,
59
+ connect
60
+ };
@@ -4,6 +4,7 @@ import { AsyncDatabase, type TransactionOptions } from '../core/Database.js';
4
4
  import type { AsyncDriver, AsyncStatement, BatchQuery, PrepareOptions } from '../core/Driver.js';
5
5
  type Queryable = PromiseConnection | Pool | PoolConnection;
6
6
  declare class PreparedStatement implements AsyncStatement {
7
+ #private;
7
8
  private client;
8
9
  private sql;
9
10
  private name?;
@@ -9,17 +9,25 @@ var PreparedStatement = class {
9
9
  this.sql = sql;
10
10
  this.name = name;
11
11
  }
12
+ #transformParam = (param) => {
13
+ if (param instanceof Uint8Array) return Buffer.from(param);
14
+ return param;
15
+ };
12
16
  all(params) {
13
- return this.client.query(this.sql, params).then((res) => res[0]);
17
+ return this.client.query(this.sql, params.map(this.#transformParam)).then((res) => res[0]);
14
18
  }
15
19
  async run(params) {
16
- await this.client.query(this.sql, params);
20
+ await this.client.query(this.sql, params.map(this.#transformParam));
17
21
  }
18
22
  get(params) {
19
23
  return this.all(params).then((rows) => rows[0] ?? null);
20
24
  }
21
25
  values(params) {
22
- return this.client.query({ sql: this.sql, values: params, rowsAsArray: true }).then((res) => res[0]);
26
+ return this.client.query({
27
+ sql: this.sql,
28
+ values: params.map(this.#transformParam),
29
+ rowsAsArray: true
30
+ }).then((res) => res[0]);
23
31
  }
24
32
  free() {
25
33
  }
@@ -37,8 +45,7 @@ var Mysql2Driver = class _Mysql2Driver {
37
45
  return new PreparedStatement(this.client, sql, options?.name);
38
46
  }
39
47
  async close() {
40
- if ("end" in this.client)
41
- return this.client.end();
48
+ if ("end" in this.client) return this.client.end();
42
49
  }
43
50
  async batch(queries) {
44
51
  const transact = async (tx) => {
@@ -47,8 +54,7 @@ var Mysql2Driver = class _Mysql2Driver {
47
54
  results.push(await tx.prepare(sql).values(params));
48
55
  return results;
49
56
  };
50
- if (this.depth > 0)
51
- return transact(this);
57
+ if (this.depth > 0) return transact(this);
52
58
  return this.transaction(transact, {});
53
59
  }
54
60
  async transaction(run, options) {
@@ -60,8 +66,7 @@ var Mysql2Driver = class _Mysql2Driver {
60
66
  );
61
67
  if (this.depth === 0) {
62
68
  const setOptions = setTransaction(options);
63
- if (setOptions)
64
- await client.query(setOptions);
69
+ if (setOptions) await client.query(setOptions);
65
70
  }
66
71
  const result = await run(driver);
67
72
  await client.query(
package/dist/driver/pg.js CHANGED
@@ -53,10 +53,8 @@ var PgDriver = class _PgDriver {
53
53
  return new PreparedStatement(this.client, sql, options?.name);
54
54
  }
55
55
  async close() {
56
- if ("end" in this.client)
57
- return this.client.end();
58
- if ("release" in this.client)
59
- return this.client.release();
56
+ if ("end" in this.client) return this.client.end();
57
+ if ("release" in this.client) return this.client.release();
60
58
  }
61
59
  async batch(queries) {
62
60
  return this.transaction(async (tx) => {
@@ -70,8 +68,7 @@ var PgDriver = class _PgDriver {
70
68
  const client = "totalCount" in this.client ? await this.client.connect() : this.client;
71
69
  try {
72
70
  await client.query(this.depth > 0 ? `savepoint d${this.depth}` : "begin");
73
- if (this.depth === 0)
74
- await client.query(setTransaction(options));
71
+ if (this.depth === 0) await client.query(setTransaction(options));
75
72
  const result = await run(new _PgDriver(client, this.depth + 1));
76
73
  await client.query(
77
74
  this.depth > 0 ? `release savepoint d${this.depth}` : "commit"
@@ -83,8 +80,7 @@ var PgDriver = class _PgDriver {
83
80
  );
84
81
  throw error;
85
82
  } finally {
86
- if ("release" in client)
87
- client.release();
83
+ if ("release" in client) client.release();
88
84
  }
89
85
  }
90
86
  };
@@ -1,6 +1,6 @@
1
1
  import type { PGlite, Transaction } from '@electric-sql/pglite';
2
+ import { AsyncDatabase, type TransactionOptions } from '../core/Database.js';
2
3
  import type { AsyncDriver, AsyncStatement, BatchQuery } from '../core/Driver.js';
3
- import { AsyncDatabase, type TransactionOptions } from '../index.js';
4
4
  type Queryable = PGlite | Transaction;
5
5
  declare class PreparedStatement implements AsyncStatement {
6
6
  private client;
@@ -1,5 +1,5 @@
1
1
  // src/driver/pglite.ts
2
- import { AsyncDatabase } from "../index.js";
2
+ import { AsyncDatabase } from "../core/Database.js";
3
3
  import { postgresDialect } from "../postgres/dialect.js";
4
4
  import { postgresDiff } from "../postgres/diff.js";
5
5
  import { setTransaction } from "../postgres/transactions.js";
@@ -54,8 +54,7 @@ var PGliteDriver = class _PGliteDriver {
54
54
  results.push(await tx.prepare(sql).values(params));
55
55
  return results;
56
56
  };
57
- if (this.depth > 0)
58
- return transact(this);
57
+ if (this.depth > 0) return transact(this);
59
58
  return this.transaction(transact, {});
60
59
  }
61
60
  async transaction(run, options) {
@@ -10,14 +10,12 @@ var PreparedStatement = class {
10
10
  }
11
11
  *iterate(params) {
12
12
  this.stmt.bind(params);
13
- while (this.stmt.step())
14
- yield this.stmt.getAsObject();
13
+ while (this.stmt.step()) yield this.stmt.getAsObject();
15
14
  this.stmt.reset();
16
15
  }
17
16
  *iterateValues(params) {
18
17
  this.stmt.bind(params);
19
- while (this.stmt.step())
20
- yield this.stmt.get();
18
+ while (this.stmt.step()) yield this.stmt.get();
21
19
  this.stmt.reset();
22
20
  }
23
21
  all(params) {
@@ -0,0 +1,7 @@
1
+ export { connect as 'better-sqlite3' } from './driver/better-sqlite3.js';
2
+ export { connect as 'bun:sqlite' } from './driver/bun-sqlite.js';
3
+ export { connect as 'd1' } from './driver/d1.js';
4
+ export { connect as 'mysql2' } from './driver/mysql2.js';
5
+ export { connect as '@neondatabase/serverless', connect as '@vercel/postgres', connect as 'pg' } from './driver/pg.js';
6
+ export { connect as '@electric-sql/pglite' } from './driver/pglite.js';
7
+ export { connect as 'sql.js' } from './driver/sql.js.js';
package/dist/driver.js ADDED
@@ -0,0 +1,23 @@
1
+ // src/driver.ts
2
+ import { connect } from "./driver/better-sqlite3.js";
3
+ import { connect as connect2 } from "./driver/bun-sqlite.js";
4
+ import { connect as connect3 } from "./driver/d1.js";
5
+ import { connect as connect4 } from "./driver/mysql2.js";
6
+ import {
7
+ connect as connect5,
8
+ connect as connect6,
9
+ connect as connect7
10
+ } from "./driver/pg.js";
11
+ import { connect as connect8 } from "./driver/pglite.js";
12
+ import { connect as connect9 } from "./driver/sql.js.js";
13
+ export {
14
+ connect8 as "@electric-sql/pglite",
15
+ connect5 as "@neondatabase/serverless",
16
+ connect6 as "@vercel/postgres",
17
+ connect as "better-sqlite3",
18
+ connect2 as "bun:sqlite",
19
+ connect3 as d1,
20
+ connect4 as mysql2,
21
+ connect7 as pg,
22
+ connect9 as "sql.js"
23
+ };
@@ -1,4 +1,4 @@
1
- import { type Column, JsonColumn } from '../core/Column.js';
1
+ import { JsonColumn, type Column } from '../core/Column.js';
2
2
  type Precision = 0 | 1 | 2 | 3 | 4 | 5 | 6;
3
3
  export declare function bigint(name: string | undefined, options: {
4
4
  mode: 'number';
@@ -11,6 +11,7 @@ export declare function binary(name?: string, options?: {
11
11
  length?: number;
12
12
  }): Column<Uint8Array | null>;
13
13
  export declare function boolean(name?: string): Column<boolean | null>;
14
+ export declare function blob(name?: string): Column<Uint8Array | null>;
14
15
  export declare function char(name?: string, options?: {
15
16
  length: number;
16
17
  }): Column<string | null>;
@@ -13,6 +13,9 @@ function binary(name, options) {
13
13
  function boolean(name) {
14
14
  return column({ name, type: column.boolean() });
15
15
  }
16
+ function blob(name) {
17
+ return column({ name, type: column.blob() });
18
+ }
16
19
  function char(name, options) {
17
20
  return column({ name, type: column.char(options?.length) });
18
21
  }
@@ -125,6 +128,7 @@ function year(name) {
125
128
  export {
126
129
  bigint,
127
130
  binary,
131
+ blob,
128
132
  boolean,
129
133
  char,
130
134
  date,
@@ -24,8 +24,7 @@ var mysqlDialect = new Dialect(
24
24
  );
25
25
  }
26
26
  emitInline(value) {
27
- if (value === null || value === void 0)
28
- return this.sql += "null";
27
+ if (value === null || value === void 0) return this.sql += "null";
29
28
  if (typeof value === "number" || typeof value === "boolean")
30
29
  return this.sql += value;
31
30
  if (typeof value === "string")
@@ -7,8 +7,7 @@ function startTransaction(options) {
7
7
  ].filter(Boolean).join(" ");
8
8
  }
9
9
  function setTransaction(options) {
10
- if (!options.isolationLevel)
11
- return;
10
+ if (!options.isolationLevel) return;
12
11
  return [
13
12
  "set transaction",
14
13
  options.isolationLevel && `isolation level ${options.isolationLevel}`
@@ -1,4 +1,4 @@
1
- import { type Column, JsonColumn } from '../core/Column.js';
1
+ import { JsonColumn, type Column } from '../core/Column.js';
2
2
  type Precision = 0 | 1 | 2 | 3 | 4 | 5 | 6;
3
3
  type IntervalFields = 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second' | 'year to month' | 'day to hour' | 'day to minute' | 'day to second' | 'hour to minute' | 'hour to second' | 'minute to second';
4
4
  export declare function bigint(name: string | undefined, options: {
@@ -30,7 +30,7 @@ export declare function interval(name?: string, options?: {
30
30
  }): Column<string | null>;
31
31
  export declare function serial(name?: string): Column<number>;
32
32
  export declare function boolean(name?: string): Column<boolean | null>;
33
- export declare function blob(name?: string): Column<Uint8Array | null>;
33
+ export declare function bytea(name?: string): Column<Uint8Array | null>;
34
34
  export declare function text(name?: string): Column<string | null>;
35
35
  export declare function json<T>(name?: string): JsonColumn<T | null>;
36
36
  export declare function jsonb<T>(name?: string): JsonColumn<T | null>;
@@ -68,8 +68,8 @@ function serial(name) {
68
68
  function boolean(name) {
69
69
  return column({ name, type: column.boolean() });
70
70
  }
71
- function blob(name) {
72
- return column({ name, type: column.blob() });
71
+ function bytea(name) {
72
+ return column({ name, type: column.bytea() });
73
73
  }
74
74
  function text(name) {
75
75
  return column({ name, type: column.text() });
@@ -157,8 +157,8 @@ function varchar(name, options) {
157
157
  export {
158
158
  bigint,
159
159
  bigserial,
160
- blob,
161
160
  boolean,
161
+ bytea,
162
162
  char,
163
163
  cidr,
164
164
  date,
@@ -20,19 +20,14 @@ var postgresDialect = new Dialect(
20
20
  target.emitTo(this);
21
21
  for (let i = 0; i < segments.length; i++) {
22
22
  const access = segments[i];
23
- if (i <= segments.length - 2)
24
- this.sql += "->";
25
- else if (i === segments.length - 1)
26
- this.sql += asSql ? "->>" : "->";
27
- if (typeof access === "number")
28
- this.sql += access;
29
- else
30
- this.sql += this.quoteString(access);
23
+ if (i <= segments.length - 2) this.sql += "->";
24
+ else if (i === segments.length - 1) this.sql += asSql ? "->>" : "->";
25
+ if (typeof access === "number") this.sql += access;
26
+ else this.sql += this.quoteString(access);
31
27
  }
32
28
  }
33
29
  emitInline(value) {
34
- if (value === null || value === void 0)
35
- return this.sql += "null";
30
+ if (value === null || value === void 0) return this.sql += "null";
36
31
  if (typeof value === "number" || typeof value === "boolean")
37
32
  return this.sql += value;
38
33
  if (typeof value === "string")
@@ -26,14 +26,11 @@ var sqliteDialect = new Dialect(
26
26
  );
27
27
  }
28
28
  emitInline(value) {
29
- if (value === null || value === void 0)
30
- return this.sql += "null";
31
- if (typeof value === "number")
32
- return this.sql += value;
29
+ if (value === null || value === void 0) return this.sql += "null";
30
+ if (typeof value === "number") return this.sql += value;
33
31
  if (typeof value === "string")
34
32
  return this.sql += this.quoteString(value);
35
- if (typeof value === "boolean")
36
- return this.sql += value ? "1" : "0";
33
+ if (typeof value === "boolean") return this.sql += value ? "1" : "0";
37
34
  this.sql += `json(${this.quoteString(JSON.stringify(value))})`;
38
35
  }
39
36
  emitPlaceholder(name) {
@@ -104,8 +104,7 @@ var sqliteDiff = (hasTable) => {
104
104
  sp.rollback(tableInfo);
105
105
  });
106
106
  } catch (err) {
107
- if (!(err instanceof Rollback))
108
- throw err;
107
+ if (!(err instanceof Rollback)) throw err;
109
108
  const localInstruction = err.data;
110
109
  const schemaInstruction = inline(tableApi.createTable());
111
110
  const stripStmt = (q) => q.slice("create table ".length);
@@ -5,8 +5,6 @@ import { type Input } from '../core/expr/Input.js';
5
5
  export declare const count: (x?: HasSql) => Sql<number>;
6
6
  /** The iif(X,Y,Z) function returns the value Y if X is true, and Z otherwise. The iif(X,Y,Z) function is logically equivalent to and generates the same bytecode as the CASE HasSql "CASE WHEN X THEN Y ELSE Z END".*/
7
7
  export declare const iif: <T>(x: Input<boolean>, y: Input<T>, z: Input<T>) => Sql<T>;
8
- /** Use the match operator for the FTS5 module */
9
- export declare const match: (table: HasTable, searchTerm: Input<string>) => Sql<boolean>;
10
8
  /** Returns a real value reflecting the accuracy of the current match */
11
9
  export declare const bm25: (table: HasTable, ...weights: Array<Input<number>>) => Sql<number>;
12
10
  /** The highlight() function returns a copy of the text from a specified column of the current row with extra markup text inserted to mark the start and end of phrase matches. */
@@ -4,7 +4,6 @@ import { Functions } from "../core/expr/Functions.js";
4
4
  import { input } from "../core/expr/Input.js";
5
5
  var count = Functions.count;
6
6
  var iif = Functions.iif;
7
- var match = Functions.match;
8
7
  var bm25 = Functions.bm25;
9
8
  var highlight = Functions.highlight;
10
9
  var snippet = Functions.snippet;
@@ -118,7 +117,6 @@ export {
118
117
  log2,
119
118
  lower,
120
119
  ltrim,
121
- match,
122
120
  max,
123
121
  min,
124
122
  mod,
@@ -3,8 +3,7 @@ var locks = /* @__PURE__ */ new WeakMap();
3
3
  function execTransaction(driver, depth, wrap, run, options) {
4
4
  const needsLock = options.async;
5
5
  const behavior = options.behavior ?? "deferred";
6
- if (!needsLock)
7
- return transact();
6
+ if (!needsLock) return transact();
8
7
  let trigger;
9
8
  const lock = new Promise((resolve) => trigger = resolve);
10
9
  const current = Promise.resolve(locks.get(driver));
@@ -14,8 +13,7 @@ function execTransaction(driver, depth, wrap, run, options) {
14
13
  try {
15
14
  driver.exec(depth > 0 ? `savepoint d${depth}` : `begin ${behavior}`);
16
15
  const result = run(wrap(depth + 1));
17
- if (result instanceof Promise)
18
- return result.then(release, rollback);
16
+ if (result instanceof Promise) return result.then(release, rollback);
19
17
  return release(result);
20
18
  } catch (error) {
21
19
  return rollback(error);
@@ -1,6 +1,12 @@
1
1
  import { type Column, JsonColumn } from '../core/Column.js';
2
2
  export declare function id(name?: string): Column<number>;
3
3
  export declare function text(name?: string): Column<string | null>;
4
+ export declare function varchar(name?: string, options?: {
5
+ length: number;
6
+ }): Column<string | null>;
4
7
  export declare function integer(name?: string): Column<number | null>;
8
+ export declare function number(name?: string): Column<number | null>;
5
9
  export declare function boolean(name?: string): Column<boolean | null>;
6
10
  export declare function json<T>(name?: string): JsonColumn<T>;
11
+ export declare function jsonb<T>(name?: string): JsonColumn<T>;
12
+ export declare function blob(name?: string): Column<Uint8Array | null>;
@@ -6,6 +6,18 @@ var idType = sql.universal({
6
6
  postgres: sql`integer generated always as identity`,
7
7
  mysql: sql`int not null auto_increment`
8
8
  });
9
+ var blobType = sql.universal({
10
+ postgres: sql`bytea`,
11
+ default: sql`blob`
12
+ });
13
+ var numberType = sql.universal({
14
+ mysql: sql`double`,
15
+ default: sql`numeric`
16
+ });
17
+ var jsonbType = sql.universal({
18
+ mysql: sql`json`,
19
+ default: sql`jsonb`
20
+ });
9
21
  function id(name) {
10
22
  return column({
11
23
  name,
@@ -16,18 +28,20 @@ function id(name) {
16
28
  function text(name) {
17
29
  return column({ name, type: column.text() });
18
30
  }
31
+ function varchar(name, options) {
32
+ return column({ name, type: column.varchar(options?.length) });
33
+ }
19
34
  function integer(name) {
20
35
  return column({ name, type: column.integer() });
21
36
  }
37
+ function number(name) {
38
+ return column({ name, type: numberType, mapFromDriverValue: Number });
39
+ }
22
40
  function boolean(name) {
23
41
  return column({
24
42
  name,
25
43
  type: column.boolean(),
26
- mapFromDriverValue(value) {
27
- if (typeof value === "number")
28
- return value === 1;
29
- return Boolean(value);
30
- }
44
+ mapFromDriverValue: Boolean
31
45
  });
32
46
  }
33
47
  function json(name) {
@@ -42,10 +56,35 @@ function json(name) {
42
56
  }
43
57
  });
44
58
  }
59
+ function jsonb(name) {
60
+ return new JsonColumn({
61
+ name,
62
+ type: jsonbType,
63
+ mapToDriverValue(value) {
64
+ return JSON.stringify(value);
65
+ },
66
+ mapFromDriverValue(value, { parsesJson }) {
67
+ return parsesJson ? value : JSON.parse(value);
68
+ }
69
+ });
70
+ }
71
+ function blob(name) {
72
+ return column({
73
+ name,
74
+ type: blobType,
75
+ mapFromDriverValue(value) {
76
+ return new Uint8Array(value);
77
+ }
78
+ });
79
+ }
45
80
  export {
81
+ blob,
46
82
  boolean,
47
83
  id,
48
84
  integer,
49
85
  json,
50
- text
86
+ jsonb,
87
+ number,
88
+ text,
89
+ varchar
51
90
  };
@@ -12,8 +12,7 @@ function txGenerator(create) {
12
12
  }
13
13
  };
14
14
  const handle = ({ done, value }) => {
15
- if (done)
16
- return value;
15
+ if (done) return value;
17
16
  return next(typeof value === "function" ? tx.transaction(value) : value);
18
17
  };
19
18
  return next();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rado",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -11,7 +11,7 @@
11
11
  "cycles": "madge --circular src/index.ts src/sqlite.ts src/mysql.ts src/postgres.ts",
12
12
  "test:bun": "bun test",
13
13
  "test:node": "node --test-force-exit --test-concurrency=1 --import tsx --test \"**/*.test.ts\"",
14
- "test:deno": "deno test --no-check --allow-read"
14
+ "test:deno": "deno test --no-check -A --unstable-ffi"
15
15
  },
16
16
  "sideEffects": false,
17
17
  "exports": {
@@ -26,29 +26,29 @@
26
26
  },
27
27
  "files": ["dist"],
28
28
  "devDependencies": {
29
- "@benmerckx/suite": "^0.3.0",
29
+ "@alinea/suite": "^0.4.0",
30
30
  "@biomejs/biome": "^1.8.3",
31
31
  "@cloudflare/workers-types": "^4.20230628.0",
32
32
  "@electric-sql/pglite": "^0.1.5",
33
+ "@miniflare/d1": "^2.14.2",
34
+ "@miniflare/shared": "^2.14.2",
33
35
  "@sqlite.org/sqlite-wasm": "^3.42.0-build4",
34
- "@types/better-sqlite3": "^5.4.1",
35
- "@types/bun": "^1.1.6",
36
- "@types/glob": "^8.0.0",
37
- "@types/pg": "^8.11.5",
38
- "@types/sql.js": "^1.4.2",
39
- "better-sqlite3": "^11.0.0",
40
- "esbuild": "^0.18.11",
41
- "glob": "^8.0.3",
36
+ "@types/better-sqlite3": "^7.6.11",
37
+ "@types/bun": "^1.1.8",
38
+ "@types/glob": "^8.1.0",
39
+ "@types/pg": "^8.11.8",
40
+ "@types/sql.js": "^1.4.9",
41
+ "@vercel/postgres": "^0.10.0",
42
+ "better-sqlite3": "^11.3.0",
43
+ "esbuild": "^0.23.1",
44
+ "glob": "^11.0.0",
42
45
  "madge": "^8.0.0",
43
- "mysql2": "^3.9.7",
44
- "pg": "^8.11.5",
45
- "rimraf": "^4.1.2",
46
- "sade": "^1.8.1",
46
+ "mysql2": "^3.11.0",
47
+ "pg": "^8.12.0",
47
48
  "speedscope": "^1.15.0",
48
- "sql.js": "^1.8.0",
49
- "sqlite3": "^5.1.6",
50
- "tsx": "^4.7.2",
51
- "typescript": "^5.4.5",
52
- "uvu": "^0.5.6"
49
+ "sql.js": "^1.11.0",
50
+ "sqlite3": "^5.1.7",
51
+ "tsx": "^4.19.0",
52
+ "typescript": "^5.6.2"
53
53
  }
54
54
  }