@3lineas/d1-orm 1.0.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/index.js ADDED
@@ -0,0 +1,474 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ BelongsTo: () => BelongsTo,
24
+ Blueprint: () => Blueprint,
25
+ Connection: () => Connection,
26
+ Database: () => Database,
27
+ HasMany: () => HasMany,
28
+ HasOne: () => HasOne,
29
+ Model: () => Model,
30
+ ModelQueryBuilder: () => ModelQueryBuilder,
31
+ QueryBuilder: () => QueryBuilder,
32
+ Relationship: () => Relationship,
33
+ Schema: () => Schema
34
+ });
35
+ module.exports = __toCommonJS(index_exports);
36
+
37
+ // src/core/connection.ts
38
+ var Connection = class {
39
+ db;
40
+ constructor(database) {
41
+ this.db = database;
42
+ }
43
+ async select(query, bindings = []) {
44
+ const stmt = this.db.prepare(query).bind(...bindings);
45
+ const result = await stmt.all();
46
+ return result.results || [];
47
+ }
48
+ async insert(query, bindings = []) {
49
+ const stmt = this.db.prepare(query).bind(...bindings);
50
+ const result = await stmt.run();
51
+ return result.success;
52
+ }
53
+ async update(query, bindings = []) {
54
+ const stmt = this.db.prepare(query).bind(...bindings);
55
+ const result = await stmt.run();
56
+ return result.success;
57
+ }
58
+ async delete(query, bindings = []) {
59
+ const stmt = this.db.prepare(query).bind(...bindings);
60
+ const result = await stmt.run();
61
+ return result.success;
62
+ }
63
+ async statement(query, bindings = []) {
64
+ const stmt = this.db.prepare(query).bind(...bindings);
65
+ const result = await stmt.run();
66
+ return result.success;
67
+ }
68
+ };
69
+
70
+ // src/core/query-builder.ts
71
+ var QueryBuilder = class {
72
+ connection;
73
+ table;
74
+ columns = ["*"];
75
+ wheres = [];
76
+ bindings = [];
77
+ orders = [];
78
+ limitValue = null;
79
+ offsetValue = null;
80
+ constructor(connection, table) {
81
+ this.connection = connection;
82
+ this.table = table;
83
+ }
84
+ select(...columns) {
85
+ this.columns = columns.length > 0 ? columns : ["*"];
86
+ return this;
87
+ }
88
+ where(column, operator, value) {
89
+ if (value === void 0) {
90
+ value = operator;
91
+ operator = "=";
92
+ }
93
+ this.wheres.push(`${column} ${operator} ?`);
94
+ this.bindings.push(value);
95
+ return this;
96
+ }
97
+ orWhere(column, operator, value) {
98
+ if (value === void 0) {
99
+ value = operator;
100
+ operator = "=";
101
+ }
102
+ this.wheres.push(`OR ${column} ${operator} ?`);
103
+ this.bindings.push(value);
104
+ return this;
105
+ }
106
+ orderBy(column, direction = "asc") {
107
+ this.orders.push(`${column} ${direction.toUpperCase()}`);
108
+ return this;
109
+ }
110
+ limit(limit) {
111
+ this.limitValue = limit;
112
+ return this;
113
+ }
114
+ offset(offset) {
115
+ this.offsetValue = offset;
116
+ return this;
117
+ }
118
+ toSql() {
119
+ let sql = `SELECT ${this.columns.join(", ")} FROM ${this.table}`;
120
+ if (this.wheres.length > 0) {
121
+ const constraints = this.wheres.map((w, i) => {
122
+ if (i === 0) return w.replace(/^OR\s+/, "");
123
+ return w.startsWith("OR") ? w : `AND ${w}`;
124
+ });
125
+ sql += ` WHERE ${constraints.join(" ")}`;
126
+ }
127
+ if (this.orders.length > 0) {
128
+ sql += ` ORDER BY ${this.orders.join(", ")}`;
129
+ }
130
+ if (this.limitValue !== null) {
131
+ sql += ` LIMIT ${this.limitValue}`;
132
+ }
133
+ if (this.offsetValue !== null) {
134
+ sql += ` OFFSET ${this.offsetValue}`;
135
+ }
136
+ return { sql, bindings: this.bindings };
137
+ }
138
+ async get() {
139
+ const { sql, bindings } = this.toSql();
140
+ return this.connection.select(sql, bindings);
141
+ }
142
+ async first() {
143
+ this.limit(1);
144
+ const results = await this.get();
145
+ return results.length > 0 ? results[0] : null;
146
+ }
147
+ async insert(data) {
148
+ const columns = Object.keys(data);
149
+ const values = Object.values(data);
150
+ const placeholders = values.map(() => "?").join(", ");
151
+ const sql = `INSERT INTO ${this.table} (${columns.join(", ")}) VALUES (${placeholders})`;
152
+ return this.connection.insert(sql, values);
153
+ }
154
+ async update(data) {
155
+ const columns = Object.keys(data);
156
+ const values = Object.values(data);
157
+ const sets = columns.map((col) => `${col} = ?`).join(", ");
158
+ let sql = `UPDATE ${this.table} SET ${sets}`;
159
+ if (this.wheres.length > 0) {
160
+ const constraints = this.wheres.map((w, i) => {
161
+ if (i === 0) return w.replace(/^OR\s+/, "");
162
+ return w.startsWith("OR") ? w : `AND ${w}`;
163
+ });
164
+ sql += ` WHERE ${constraints.join(" ")}`;
165
+ } else {
166
+ }
167
+ return this.connection.update(sql, [...values, ...this.bindings]);
168
+ }
169
+ async delete() {
170
+ let sql = `DELETE FROM ${this.table}`;
171
+ if (this.wheres.length > 0) {
172
+ const constraints = this.wheres.map((w, i) => {
173
+ if (i === 0) return w.replace(/^OR\s+/, "");
174
+ return w.startsWith("OR") ? w : `AND ${w}`;
175
+ });
176
+ sql += ` WHERE ${constraints.join(" ")}`;
177
+ }
178
+ return this.connection.delete(sql, this.bindings);
179
+ }
180
+ };
181
+
182
+ // src/core/model-query-builder.ts
183
+ var ModelQueryBuilder = class extends QueryBuilder {
184
+ modelClass;
185
+ constructor(connection, table, modelClass) {
186
+ super(connection, table);
187
+ this.modelClass = modelClass;
188
+ }
189
+ async get() {
190
+ const { sql, bindings } = this.toSql();
191
+ const results = await this.connection.select(sql, bindings);
192
+ return results.map((result) => {
193
+ const instance = new this.modelClass(result);
194
+ instance.exists = true;
195
+ instance.syncOriginal();
196
+ return instance;
197
+ });
198
+ }
199
+ async first() {
200
+ this.limit(1);
201
+ const results = await this.get();
202
+ return results.length > 0 ? results[0] : null;
203
+ }
204
+ getModel() {
205
+ return this.modelClass;
206
+ }
207
+ };
208
+
209
+ // src/core/database.ts
210
+ var Database = class _Database {
211
+ static instance;
212
+ connection;
213
+ constructor(d1) {
214
+ this.connection = new Connection(d1);
215
+ }
216
+ static setup(d1) {
217
+ _Database.instance = new _Database(d1);
218
+ }
219
+ static getInstance() {
220
+ if (!_Database.instance) {
221
+ throw new Error(
222
+ "Database not initialized. Call Database.setup(env.DB) first."
223
+ );
224
+ }
225
+ return _Database.instance;
226
+ }
227
+ };
228
+
229
+ // src/core/relationships/relationship.ts
230
+ var Relationship = class {
231
+ query;
232
+ parent;
233
+ constructor(query, parent) {
234
+ this.query = query;
235
+ this.parent = parent;
236
+ }
237
+ getQuery() {
238
+ return this.query;
239
+ }
240
+ // Common methods proxying to query helper
241
+ async get() {
242
+ return this.query.get();
243
+ }
244
+ async first() {
245
+ return this.query.first();
246
+ }
247
+ };
248
+
249
+ // src/core/relationships/has-one.ts
250
+ var HasOne = class extends Relationship {
251
+ foreignKey;
252
+ localKey;
253
+ constructor(query, parent, foreignKey, localKey) {
254
+ super(query, parent);
255
+ this.foreignKey = foreignKey;
256
+ this.localKey = localKey;
257
+ this.addConstraints();
258
+ }
259
+ addConstraints() {
260
+ const value = this.parent.attributes[this.localKey];
261
+ this.query.where(this.foreignKey, "=", value);
262
+ this.query.limit(1);
263
+ }
264
+ };
265
+
266
+ // src/core/relationships/has-many.ts
267
+ var HasMany = class extends Relationship {
268
+ foreignKey;
269
+ localKey;
270
+ constructor(query, parent, foreignKey, localKey) {
271
+ super(query, parent);
272
+ this.foreignKey = foreignKey;
273
+ this.localKey = localKey;
274
+ this.addConstraints();
275
+ }
276
+ addConstraints() {
277
+ const value = this.parent.attributes[this.localKey];
278
+ this.query.where(this.foreignKey, "=", value);
279
+ }
280
+ };
281
+
282
+ // src/core/relationships/belongs-to.ts
283
+ var BelongsTo = class extends Relationship {
284
+ foreignKey;
285
+ // on parent
286
+ ownerKey;
287
+ // on related
288
+ constructor(query, parent, foreignKey, ownerKey) {
289
+ super(query, parent);
290
+ this.foreignKey = foreignKey;
291
+ this.ownerKey = ownerKey;
292
+ this.addConstraints();
293
+ }
294
+ addConstraints() {
295
+ const value = this.parent.attributes[this.foreignKey];
296
+ this.query.where(this.ownerKey, "=", value);
297
+ this.query.limit(1);
298
+ }
299
+ };
300
+
301
+ // src/models/model.ts
302
+ var Model = class {
303
+ static table;
304
+ static connectionResolver;
305
+ attributes = {};
306
+ fillable = [];
307
+ hidden = [];
308
+ exists = false;
309
+ original = {};
310
+ constructor(attributes = {}) {
311
+ this.fill(attributes);
312
+ }
313
+ // Static Query Builder
314
+ static query() {
315
+ const instance = new this();
316
+ const table = instance.getTable();
317
+ const connection = Database.getInstance().connection;
318
+ return new ModelQueryBuilder(connection, table, this);
319
+ }
320
+ static on(connectionName) {
321
+ return this.query();
322
+ }
323
+ static async all() {
324
+ return this.query().get();
325
+ }
326
+ static async find(id) {
327
+ return this.query().where("id", "=", id).first();
328
+ }
329
+ static async create(attributes) {
330
+ const instance = new this();
331
+ instance.fill(attributes);
332
+ await instance.save();
333
+ return instance;
334
+ }
335
+ // Instance Methods
336
+ fill(attributes) {
337
+ Object.assign(this.attributes, attributes);
338
+ return this;
339
+ }
340
+ async save() {
341
+ const query = this.constructor.query();
342
+ if (this.exists) {
343
+ const dirty = this.getDirty();
344
+ if (Object.keys(dirty).length === 0) return true;
345
+ const id = this.attributes["id"];
346
+ await query.where("id", "=", id).update(dirty);
347
+ this.syncOriginal();
348
+ return true;
349
+ } else {
350
+ const result = await query.insert(this.attributes);
351
+ if (result) {
352
+ this.exists = true;
353
+ this.syncOriginal();
354
+ return true;
355
+ }
356
+ return false;
357
+ }
358
+ }
359
+ async delete() {
360
+ if (!this.exists) return false;
361
+ const query = this.constructor.query();
362
+ const id = this.attributes["id"];
363
+ await query.where("id", "=", id).delete();
364
+ this.exists = false;
365
+ return true;
366
+ }
367
+ getTable() {
368
+ if (this.constructor.table) {
369
+ return this.constructor.table;
370
+ }
371
+ return this.constructor.name.toLowerCase() + "s";
372
+ }
373
+ getDirty() {
374
+ const dirty = {};
375
+ for (const key in this.attributes) {
376
+ if (this.attributes[key] !== this.original[key]) {
377
+ dirty[key] = this.attributes[key];
378
+ }
379
+ }
380
+ return dirty;
381
+ }
382
+ syncOriginal() {
383
+ this.original = { ...this.attributes };
384
+ }
385
+ // Relationships
386
+ hasOne(related, foreignKey, localKey) {
387
+ const instance = new related();
388
+ const fk = foreignKey || this.getForeignKey();
389
+ const lk = localKey || "id";
390
+ return new HasOne(instance.newQuery(), this, fk, lk);
391
+ }
392
+ hasMany(related, foreignKey, localKey) {
393
+ const instance = new related();
394
+ const fk = foreignKey || this.getForeignKey();
395
+ const lk = localKey || "id";
396
+ return new HasMany(instance.newQuery(), this, fk, lk);
397
+ }
398
+ belongsTo(related, foreignKey, ownerKey) {
399
+ const instance = new related();
400
+ const fk = foreignKey || instance.getForeignKey();
401
+ const ok = ownerKey || "id";
402
+ return new BelongsTo(instance.newQuery(), this, fk, ok);
403
+ }
404
+ getForeignKey() {
405
+ return this.getTable().slice(0, -1) + "_id";
406
+ }
407
+ newQuery() {
408
+ return this.constructor.query();
409
+ }
410
+ };
411
+
412
+ // src/database/blueprint.ts
413
+ var Blueprint = class {
414
+ table;
415
+ columns = [];
416
+ commands = [];
417
+ constructor(table) {
418
+ this.table = table;
419
+ }
420
+ id() {
421
+ this.columns.push("id INTEGER PRIMARY KEY AUTOINCREMENT");
422
+ return this;
423
+ }
424
+ string(column, length) {
425
+ this.columns.push(`${column} TEXT`);
426
+ return this;
427
+ }
428
+ integer(column) {
429
+ this.columns.push(`${column} INTEGER`);
430
+ return this;
431
+ }
432
+ boolean(column) {
433
+ this.columns.push(`${column} BOOLEAN`);
434
+ return this;
435
+ }
436
+ timestamps() {
437
+ this.columns.push("created_at DATETIME DEFAULT CURRENT_TIMESTAMP");
438
+ this.columns.push("updated_at DATETIME DEFAULT CURRENT_TIMESTAMP");
439
+ return this;
440
+ }
441
+ toSql() {
442
+ if (this.columns.length > 0) {
443
+ const cols = this.columns.join(", ");
444
+ return [`CREATE TABLE IF NOT EXISTS ${this.table} (${cols})`];
445
+ }
446
+ return this.commands;
447
+ }
448
+ };
449
+
450
+ // src/database/schema.ts
451
+ var Schema = class {
452
+ static create(table, callback) {
453
+ const blueprint = new Blueprint(table);
454
+ callback(blueprint);
455
+ return blueprint.toSql()[0];
456
+ }
457
+ static dropIfExists(table) {
458
+ return `DROP TABLE IF EXISTS ${table}`;
459
+ }
460
+ };
461
+ // Annotate the CommonJS export names for ESM import in node:
462
+ 0 && (module.exports = {
463
+ BelongsTo,
464
+ Blueprint,
465
+ Connection,
466
+ Database,
467
+ HasMany,
468
+ HasOne,
469
+ Model,
470
+ ModelQueryBuilder,
471
+ QueryBuilder,
472
+ Relationship,
473
+ Schema
474
+ });