@revojs/storage 0.1.58

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.
@@ -0,0 +1,217 @@
1
+ import { CheckConstraint, Column, Database, DeleteStatement, ForeignKeyConstraint, Index, InsertStatement, Migration, PrimaryKeyConstraint, SelectStatement, Table, UniqueConstraint, UniqueIndex, UpdateStatement, combine, sql } from "../index.js";
2
+ //#region src/protocols/sqlite.ts
3
+ var SqliteColumn = class extends Column {
4
+ type() {
5
+ return this;
6
+ }
7
+ };
8
+ var BlobColumn = class extends SqliteColumn {
9
+ toSqlType() {
10
+ return "blob";
11
+ }
12
+ };
13
+ var IntegerColumn = class extends SqliteColumn {
14
+ $options;
15
+ constructor(name, options) {
16
+ super(name);
17
+ this.$options = options;
18
+ }
19
+ toSqlType() {
20
+ return "integer";
21
+ }
22
+ toMeta() {
23
+ return {
24
+ ...super.toMeta(),
25
+ mode: this.$options?.mode
26
+ };
27
+ }
28
+ fromDriverValue(value) {
29
+ if (this.$options?.mode === "timestamp") return typeof value === "string" ? new Date(value.replaceAll("\"", "")) : /* @__PURE__ */ new Date(Number(value) * 1e3);
30
+ if (this.$options?.mode === "timestamp_ms") return typeof value === "string" ? new Date(value.replaceAll("\"", "")) : new Date(Number(value));
31
+ if (this.$options?.mode === "boolean") return Number(value) === 1;
32
+ return Number(value);
33
+ }
34
+ toDriverValue(value) {
35
+ if (this.$options?.mode === "timestamp") return typeof value === "number" ? value : Math.floor(value.getTime() / 1e3);
36
+ if (this.$options?.mode === "timestamp_ms") return typeof value === "number" ? value : value.getTime();
37
+ if (this.$options?.mode === "boolean") return value ? 1 : 0;
38
+ return value;
39
+ }
40
+ };
41
+ var NumericColumn = class extends SqliteColumn {
42
+ toSqlType() {
43
+ return "numeric";
44
+ }
45
+ };
46
+ var RealColumn = class extends SqliteColumn {
47
+ toSqlType() {
48
+ return "real";
49
+ }
50
+ };
51
+ var TextColumn = class extends SqliteColumn {
52
+ $options;
53
+ constructor(name, options) {
54
+ super(name);
55
+ this.$options = options;
56
+ }
57
+ toSqlType() {
58
+ return "text";
59
+ }
60
+ toMeta() {
61
+ return {
62
+ ...super.toMeta(),
63
+ mode: this.$options?.mode
64
+ };
65
+ }
66
+ fromDriverValue(value) {
67
+ if (this.$options?.mode === "json") return JSON.parse(String(value));
68
+ return value;
69
+ }
70
+ toDriverValue(value) {
71
+ if (this.$options?.mode === "json") return JSON.stringify(value);
72
+ return value;
73
+ }
74
+ };
75
+ var SqliteUniqueConstraint = class extends UniqueConstraint {};
76
+ var SqliteCheckConstraint = class extends CheckConstraint {};
77
+ var SqlitePrimaryKeyConstraint = class extends PrimaryKeyConstraint {};
78
+ var SqliteForeignKeyConstraint = class extends ForeignKeyConstraint {};
79
+ var SqliteIndex = class extends Index {
80
+ where() {
81
+ return this;
82
+ }
83
+ };
84
+ var SqliteUniqueIndex = class extends UniqueIndex {
85
+ where() {
86
+ return this;
87
+ }
88
+ };
89
+ var SqliteSelectStatement = class extends SelectStatement {
90
+ fullJoin(table, on) {
91
+ this.push(sql`FULL JOIN ${table} ON ${on}`);
92
+ if (this.$value instanceof Table) {
93
+ this.$selection.push(", ", combine(Object.values(table.$columns), ", "));
94
+ this.$baseNullable = true;
95
+ this.$joins.forEach((join) => join.nullable = true);
96
+ this.$joins.push({
97
+ table,
98
+ nullable: true
99
+ });
100
+ }
101
+ return this;
102
+ }
103
+ };
104
+ var SqliteInsertStatement = class extends InsertStatement {};
105
+ var SqliteUpdateStatement = class extends UpdateStatement {};
106
+ var SqliteDeleteStatement = class extends DeleteStatement {};
107
+ var SqliteTable = class extends Table {};
108
+ var SqliteMigration = class extends Migration {
109
+ $dialect = "sqlite";
110
+ render({ changes, current }) {
111
+ const rebuilds = /* @__PURE__ */ new Map();
112
+ const direct = new Array();
113
+ for (const change of changes) {
114
+ if (change.kind === "updateColumn" && change.before.name === change.after.name && change.before.type === change.after.type && change.before.notNull === change.after.notNull && this.equals(this.columnConstraints(change.before), this.columnConstraints(change.after))) continue;
115
+ if (change.kind === "updateColumn" || change.kind === "deleteColumn" || change.kind === "createConstraint" || change.kind === "deleteConstraint" || change.kind === "createColumn" && this.columnConstraints(change.column).length > 0) {
116
+ const createdColumns = rebuilds.get(change.table) ?? /* @__PURE__ */ new Set();
117
+ if (change.kind === "createColumn") createdColumns.add(change.column.name);
118
+ rebuilds.set(change.table, createdColumns);
119
+ } else direct.push(change);
120
+ }
121
+ const statements = new Array();
122
+ if (rebuilds.size > 0) statements.push("PRAGMA foreign_keys = OFF;");
123
+ for (const change of direct) {
124
+ if (typeof change.table === "string" && rebuilds.has(change.table)) continue;
125
+ statements.push(...this.renderChange(change));
126
+ }
127
+ for (const [name, createdColumns] of rebuilds) {
128
+ const table = current.tables.find((value) => value.name === name);
129
+ if (!table) throw new Error(`Unable to rebuild missing SQLite table "${name}"`);
130
+ const temporaryName = `__revojs_${table.name}_new`;
131
+ const columns = Object.values(table.columns).filter((column) => !createdColumns.has(column.name)).map((column) => column.name);
132
+ statements.push(...this.toCreateTableChange({
133
+ kind: "createTable",
134
+ table
135
+ }, temporaryName));
136
+ if (columns.length > 0) statements.push(`INSERT INTO ${this.quoteIdentifier(temporaryName)} (${this.quoteIdentifiers(columns)}) SELECT ${this.quoteIdentifiers(columns)} FROM ${this.quoteIdentifier(table.name)};`);
137
+ statements.push(`DROP TABLE ${this.quoteIdentifier(table.name)};`, this.alterTable(temporaryName, `RENAME TO ${this.quoteIdentifier(table.name)}`));
138
+ for (const definition of table.definitions) if (definition.kind === "index" || definition.kind === "uniqueIndex") statements.push(...this.toCreateIndexChange({
139
+ kind: "createIndex",
140
+ table: table.name,
141
+ index: definition
142
+ }));
143
+ }
144
+ if (rebuilds.size > 0) statements.push("PRAGMA foreign_keys = ON;");
145
+ return statements;
146
+ }
147
+ toUpdateColumnChange(change) {
148
+ throw new Error(`SQLite column migration for "${change.table}.${change.before.name}" to "${change.after.name}" requires a rebuild`);
149
+ }
150
+ toDeleteConstraintChange(change) {
151
+ throw new Error(`SQLite constraint migration for "${this.constraintName(change.table, change.constraint)}" requires a rebuild`);
152
+ }
153
+ quoteIdentifier(value) {
154
+ return `\`${value.replaceAll("`", "``")}\``;
155
+ }
156
+ serializeLiteral(value) {
157
+ if (typeof value === "boolean") return value ? "1" : "0";
158
+ return super.serializeLiteral(value);
159
+ }
160
+ };
161
+ var SqliteDatabase = class extends Database {
162
+ $migration;
163
+ constructor(session, schema) {
164
+ super(session, schema);
165
+ this.$migration = new SqliteMigration();
166
+ }
167
+ select(value) {
168
+ return new SqliteSelectStatement(this.$session, value);
169
+ }
170
+ insert(table) {
171
+ return new SqliteInsertStatement(this.$session, table);
172
+ }
173
+ update(table) {
174
+ return new SqliteUpdateStatement(this.$session, table);
175
+ }
176
+ delete(table) {
177
+ return new SqliteDeleteStatement(this.$session, table);
178
+ }
179
+ };
180
+ function blob(name) {
181
+ return new BlobColumn(name);
182
+ }
183
+ function integer(name, options) {
184
+ return new IntegerColumn(name, options);
185
+ }
186
+ function numeric(name) {
187
+ return new NumericColumn(name);
188
+ }
189
+ function real(name) {
190
+ return new RealColumn(name);
191
+ }
192
+ function text(name, options) {
193
+ return new TextColumn(name, options);
194
+ }
195
+ function unique(...columns) {
196
+ return new SqliteUniqueConstraint(...columns);
197
+ }
198
+ function check(value) {
199
+ return new SqliteCheckConstraint(value);
200
+ }
201
+ function primaryKey(...columns) {
202
+ return new SqlitePrimaryKeyConstraint(...columns);
203
+ }
204
+ function foreignKey(columns, foreignColumns) {
205
+ return new SqliteForeignKeyConstraint(columns, foreignColumns);
206
+ }
207
+ function index(...columns) {
208
+ return new SqliteIndex(...columns);
209
+ }
210
+ function uniqueIndex(...columns) {
211
+ return new SqliteUniqueIndex(...columns);
212
+ }
213
+ function table(name, columns, definitions) {
214
+ return Object.assign(new SqliteTable(name, columns, definitions?.(columns) ?? []), columns);
215
+ }
216
+ //#endregion
217
+ export { BlobColumn, IntegerColumn, NumericColumn, RealColumn, SqliteCheckConstraint, SqliteColumn, SqliteDatabase, SqliteDeleteStatement, SqliteForeignKeyConstraint, SqliteIndex, SqliteInsertStatement, SqliteMigration, SqlitePrimaryKeyConstraint, SqliteSelectStatement, SqliteTable, SqliteUniqueConstraint, SqliteUniqueIndex, SqliteUpdateStatement, TextColumn, blob, check, foreignKey, index, integer, numeric, primaryKey, real, table, text, unique, uniqueIndex };
@@ -0,0 +1,18 @@
1
+ import type { Database, Statement } from "bun:sqlite";
2
+ import type { Primitive } from "revojs/shared";
3
+ import { PreparedQuery, Session, type Query } from "../index";
4
+ import { SqliteDatabase, type SqliteTable } from "../protocols/sqlite";
5
+ export declare class BunSqlitePreparedQuery extends PreparedQuery {
6
+ protected $statement: Statement;
7
+ constructor(query: Query, statement: Statement);
8
+ run(parameters: Array<Primitive>): import("bun:sqlite").Changes;
9
+ all(parameters: Array<Primitive>): (string | number | bigint | boolean | Uint8Array<ArrayBufferLike>)[][];
10
+ get(parameters: Array<Primitive>): (string | number | bigint | boolean | Uint8Array<ArrayBufferLike>)[];
11
+ values(parameters: Array<Primitive>): (string | number | bigint | boolean | Uint8Array<ArrayBufferLike>)[][];
12
+ }
13
+ export declare class BunSqliteSession extends Session {
14
+ protected $client: Database;
15
+ constructor(client: Database);
16
+ prepareQuery(query: Query): BunSqlitePreparedQuery;
17
+ }
18
+ export declare function bunSqlite<T extends Record<string, SqliteTable>>(client: Database, schema: T): SqliteDatabase<T>;
@@ -0,0 +1,37 @@
1
+ import { PreparedQuery, Session } from "../index.js";
2
+ import { SqliteDatabase } from "../protocols/sqlite.js";
3
+ //#region src/providers/bun-sqlite.ts
4
+ var BunSqlitePreparedQuery = class extends PreparedQuery {
5
+ $statement;
6
+ constructor(query, statement) {
7
+ super(query);
8
+ this.$statement = statement;
9
+ }
10
+ run(parameters) {
11
+ return this.$statement.run(...parameters);
12
+ }
13
+ all(parameters) {
14
+ return this.$statement.values(...parameters);
15
+ }
16
+ get(parameters) {
17
+ return this.$statement.values(...parameters)[0];
18
+ }
19
+ values(parameters) {
20
+ return this.$statement.values(...parameters);
21
+ }
22
+ };
23
+ var BunSqliteSession = class extends Session {
24
+ $client;
25
+ constructor(client) {
26
+ super();
27
+ this.$client = client;
28
+ }
29
+ prepareQuery(query) {
30
+ return new BunSqlitePreparedQuery(query, this.$client.prepare(query.sql));
31
+ }
32
+ };
33
+ function bunSqlite(client, schema) {
34
+ return new SqliteDatabase(new BunSqliteSession(client), schema);
35
+ }
36
+ //#endregion
37
+ export { BunSqlitePreparedQuery, BunSqliteSession, bunSqlite };
@@ -0,0 +1,18 @@
1
+ import type { D1Database, D1DatabaseSession, D1PreparedStatement } from "@cloudflare/workers-types";
2
+ import type { Primitive } from "revojs/shared";
3
+ import { PreparedQuery, Session, type Query } from "../index";
4
+ import { SqliteDatabase, type SqliteTable } from "../protocols/sqlite";
5
+ export declare class D1PreparedQuery extends PreparedQuery {
6
+ protected $statement: D1PreparedStatement;
7
+ constructor(query: Query, statement: D1PreparedStatement);
8
+ run(parameters: Array<Primitive>): Promise<import("@cloudflare/workers-types").D1Result<Record<string, unknown>>>;
9
+ all(parameters: Array<Primitive>): Promise<unknown[][]>;
10
+ get(parameters: Array<Primitive>): Promise<unknown[]>;
11
+ values(parameters: Array<Primitive>): Promise<unknown[][]>;
12
+ }
13
+ export declare class D1Session extends Session {
14
+ protected $client: D1Database | D1DatabaseSession;
15
+ constructor(client: D1Database | D1DatabaseSession);
16
+ prepareQuery(query: Query): D1PreparedQuery;
17
+ }
18
+ export declare function d1<T extends Record<string, SqliteTable>>(client: D1Database | D1DatabaseSession, schema: T): SqliteDatabase<T>;
@@ -0,0 +1,37 @@
1
+ import { PreparedQuery, Session } from "../index.js";
2
+ import { SqliteDatabase } from "../protocols/sqlite.js";
3
+ //#region src/providers/d1.ts
4
+ var D1PreparedQuery = class extends PreparedQuery {
5
+ $statement;
6
+ constructor(query, statement) {
7
+ super(query);
8
+ this.$statement = statement;
9
+ }
10
+ run(parameters) {
11
+ return this.$statement.bind(...parameters).run();
12
+ }
13
+ all(parameters) {
14
+ return this.$statement.bind(...parameters).raw();
15
+ }
16
+ get(parameters) {
17
+ return this.$statement.bind(...parameters).raw().then((rows) => rows[0]);
18
+ }
19
+ values(parameters) {
20
+ return this.$statement.bind(...parameters).raw();
21
+ }
22
+ };
23
+ var D1Session = class extends Session {
24
+ $client;
25
+ constructor(client) {
26
+ super();
27
+ this.$client = client;
28
+ }
29
+ prepareQuery(query) {
30
+ return new D1PreparedQuery(query, this.$client.prepare(query.sql));
31
+ }
32
+ };
33
+ function d1(client, schema) {
34
+ return new SqliteDatabase(new D1Session(client), schema);
35
+ }
36
+ //#endregion
37
+ export { D1PreparedQuery, D1Session, d1 };
@@ -0,0 +1,14 @@
1
+ declare module "#config/storage" {
2
+ import type { StorageConfig } from "@revojs/storage/module";
3
+
4
+ const config: StorageConfig;
5
+ export default config;
6
+ }
7
+
8
+ declare module "#storage" {
9
+ import type { Database } from "../index";
10
+ import type { Scope, Source } from "revojs";
11
+
12
+ const entries: Source<(scope: Scope) => Database>;
13
+ export default entries;
14
+ }
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@revojs/storage",
3
+ "version": "0.1.58",
4
+ "license": "MIT",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/tellua/revojs.git"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "type": "module",
13
+ "main": "./dist/index.js",
14
+ "module": "./dist/index.js",
15
+ "types": "./dist/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.js"
20
+ },
21
+ "./protocols/*": {
22
+ "types": "./dist/protocols/*.d.ts",
23
+ "import": "./dist/protocols/*.js"
24
+ },
25
+ "./providers/*": {
26
+ "types": "./dist/providers/*.d.ts",
27
+ "import": "./dist/providers/*.js"
28
+ },
29
+ "./module": {
30
+ "types": "./dist/module/index.d.ts",
31
+ "import": "./dist/module/index.js"
32
+ }
33
+ },
34
+ "scripts": {
35
+ "build": "vite build",
36
+ "watch": "vite build --watch"
37
+ },
38
+ "dependencies": {
39
+ "revojs": "*"
40
+ },
41
+ "devDependencies": {
42
+ "@revojs/tsconfig": "*"
43
+ },
44
+ "optionalDependencies": {
45
+ "@cloudflare/workers-types": "^5.20260911.1",
46
+ "@types/bun": "^1.4.2"
47
+ }
48
+ }