@tyravel/database 0.1.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.
Files changed (117) hide show
  1. package/dist/connection.d.ts +15 -0
  2. package/dist/connection.d.ts.map +1 -0
  3. package/dist/connection.js +2 -0
  4. package/dist/connection.js.map +1 -0
  5. package/dist/database-manager.d.ts +12 -0
  6. package/dist/database-manager.d.ts.map +1 -0
  7. package/dist/database-manager.js +49 -0
  8. package/dist/database-manager.js.map +1 -0
  9. package/dist/grammar.d.ts +26 -0
  10. package/dist/grammar.d.ts.map +1 -0
  11. package/dist/grammar.js +31 -0
  12. package/dist/grammar.js.map +1 -0
  13. package/dist/grammar.test.d.ts +2 -0
  14. package/dist/grammar.test.d.ts.map +1 -0
  15. package/dist/grammar.test.js +48 -0
  16. package/dist/grammar.test.js.map +1 -0
  17. package/dist/index.d.ts +22 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +18 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/migration.d.ts +13 -0
  22. package/dist/migration.d.ts.map +1 -0
  23. package/dist/migration.js +3 -0
  24. package/dist/migration.js.map +1 -0
  25. package/dist/migrator.d.ts +15 -0
  26. package/dist/migrator.d.ts.map +1 -0
  27. package/dist/migrator.js +77 -0
  28. package/dist/migrator.js.map +1 -0
  29. package/dist/migrator.test.d.ts +2 -0
  30. package/dist/migrator.test.d.ts.map +1 -0
  31. package/dist/migrator.test.js +37 -0
  32. package/dist/migrator.test.js.map +1 -0
  33. package/dist/model-query-builder.d.ts +15 -0
  34. package/dist/model-query-builder.d.ts.map +1 -0
  35. package/dist/model-query-builder.js +43 -0
  36. package/dist/model-query-builder.js.map +1 -0
  37. package/dist/model-types.d.ts +14 -0
  38. package/dist/model-types.d.ts.map +1 -0
  39. package/dist/model-types.js +2 -0
  40. package/dist/model-types.js.map +1 -0
  41. package/dist/model.d.ts +41 -0
  42. package/dist/model.d.ts.map +1 -0
  43. package/dist/model.js +135 -0
  44. package/dist/model.js.map +1 -0
  45. package/dist/model.test.d.ts +2 -0
  46. package/dist/model.test.d.ts.map +1 -0
  47. package/dist/model.test.js +32 -0
  48. package/dist/model.test.js.map +1 -0
  49. package/dist/mysql-connection.d.ts +13 -0
  50. package/dist/mysql-connection.d.ts.map +1 -0
  51. package/dist/mysql-connection.js +85 -0
  52. package/dist/mysql-connection.js.map +1 -0
  53. package/dist/postgres-connection.d.ts +13 -0
  54. package/dist/postgres-connection.d.ts.map +1 -0
  55. package/dist/postgres-connection.js +81 -0
  56. package/dist/postgres-connection.js.map +1 -0
  57. package/dist/query-builder.d.ts +45 -0
  58. package/dist/query-builder.d.ts.map +1 -0
  59. package/dist/query-builder.js +167 -0
  60. package/dist/query-builder.js.map +1 -0
  61. package/dist/query-builder.test.d.ts +2 -0
  62. package/dist/query-builder.test.d.ts.map +1 -0
  63. package/dist/query-builder.test.js +37 -0
  64. package/dist/query-builder.test.js.map +1 -0
  65. package/dist/relations/belongs-to-many.d.ts +13 -0
  66. package/dist/relations/belongs-to-many.d.ts.map +1 -0
  67. package/dist/relations/belongs-to-many.js +38 -0
  68. package/dist/relations/belongs-to-many.js.map +1 -0
  69. package/dist/relations/belongs-to.d.ts +10 -0
  70. package/dist/relations/belongs-to.d.ts.map +1 -0
  71. package/dist/relations/belongs-to.js +21 -0
  72. package/dist/relations/belongs-to.js.map +1 -0
  73. package/dist/relations/has-many.d.ts +12 -0
  74. package/dist/relations/has-many.d.ts.map +1 -0
  75. package/dist/relations/has-many.js +18 -0
  76. package/dist/relations/has-many.js.map +1 -0
  77. package/dist/relations/has-one.d.ts +12 -0
  78. package/dist/relations/has-one.d.ts.map +1 -0
  79. package/dist/relations/has-one.js +18 -0
  80. package/dist/relations/has-one.js.map +1 -0
  81. package/dist/relations/relation.d.ts +9 -0
  82. package/dist/relations/relation.d.ts.map +1 -0
  83. package/dist/relations/relation.js +9 -0
  84. package/dist/relations/relation.js.map +1 -0
  85. package/dist/relations.test.d.ts +2 -0
  86. package/dist/relations.test.d.ts.map +1 -0
  87. package/dist/relations.test.js +78 -0
  88. package/dist/relations.test.js.map +1 -0
  89. package/dist/schema/blueprint.d.ts +16 -0
  90. package/dist/schema/blueprint.d.ts.map +1 -0
  91. package/dist/schema/blueprint.js +59 -0
  92. package/dist/schema/blueprint.js.map +1 -0
  93. package/dist/schema/schema-builder.d.ts +10 -0
  94. package/dist/schema/schema-builder.d.ts.map +1 -0
  95. package/dist/schema/schema-builder.js +21 -0
  96. package/dist/schema/schema-builder.js.map +1 -0
  97. package/dist/scopes.d.ts +5 -0
  98. package/dist/scopes.d.ts.map +1 -0
  99. package/dist/scopes.js +4 -0
  100. package/dist/scopes.js.map +1 -0
  101. package/dist/scopes.test.d.ts +2 -0
  102. package/dist/scopes.test.d.ts.map +1 -0
  103. package/dist/scopes.test.js +48 -0
  104. package/dist/scopes.test.js.map +1 -0
  105. package/dist/sqlite-connection.d.ts +12 -0
  106. package/dist/sqlite-connection.d.ts.map +1 -0
  107. package/dist/sqlite-connection.js +60 -0
  108. package/dist/sqlite-connection.js.map +1 -0
  109. package/dist/types.d.ts +37 -0
  110. package/dist/types.d.ts.map +1 -0
  111. package/dist/types.js +2 -0
  112. package/dist/types.js.map +1 -0
  113. package/dist/utils.d.ts +3 -0
  114. package/dist/utils.d.ts.map +1 -0
  115. package/dist/utils.js +15 -0
  116. package/dist/utils.js.map +1 -0
  117. package/package.json +40 -0
@@ -0,0 +1,37 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { SqliteConnection } from './sqlite-connection.js';
3
+ import { QueryBuilder } from './query-builder.js';
4
+ describe('QueryBuilder', () => {
5
+ it('inserts, queries, updates, and deletes rows', async () => {
6
+ const connection = new SqliteConnection(':memory:');
7
+ await connection.exec(`
8
+ CREATE TABLE "users" (
9
+ "id" INTEGER PRIMARY KEY AUTOINCREMENT,
10
+ "name" TEXT NOT NULL,
11
+ "email" TEXT NOT NULL
12
+ )
13
+ `);
14
+ const builder = new QueryBuilder(connection, 'users');
15
+ const id = await builder.insert({ name: 'Ada', email: 'ada@example.com' });
16
+ const found = await new QueryBuilder(connection, 'users')
17
+ .where('id', Number(id))
18
+ .first();
19
+ expect(found).toEqual({
20
+ id: Number(id),
21
+ name: 'Ada',
22
+ email: 'ada@example.com',
23
+ });
24
+ await new QueryBuilder(connection, 'users')
25
+ .where('id', Number(id))
26
+ .update({ name: 'Grace' });
27
+ const updated = await new QueryBuilder(connection, 'users')
28
+ .where('email', 'ada@example.com')
29
+ .first();
30
+ expect(updated?.name).toBe('Grace');
31
+ const deleted = await new QueryBuilder(connection, 'users')
32
+ .where('id', Number(id))
33
+ .delete();
34
+ expect(deleted).toBe(1);
35
+ });
36
+ });
37
+ //# sourceMappingURL=query-builder.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-builder.test.js","sourceRoot":"","sources":["../src/query-builder.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,UAAU,CAAC,CAAC;QACpD,MAAM,UAAU,CAAC,IAAI,CAAC;;;;;;KAMrB,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACtD,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAE3E,MAAM,KAAK,GAAG,MAAM,IAAI,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC;aACtD,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;aACvB,KAAK,EAAE,CAAC;QAEX,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC;YACpB,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC;YACd,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,iBAAiB;SACzB,CAAC,CAAC;QAEH,MAAM,IAAI,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC;aACxC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;aACvB,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAE7B,MAAM,OAAO,GAAG,MAAM,IAAI,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC;aACxD,KAAK,CAAC,OAAO,EAAE,iBAAiB,CAAC;aACjC,KAAK,EAAE,CAAC;QAEX,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEpC,MAAM,OAAO,GAAG,MAAM,IAAI,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC;aACxD,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;aACvB,MAAM,EAAE,CAAC;QAEZ,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { Model } from '../model.js';
2
+ import type { ModelStatic } from '../model-types.js';
3
+ import { Relation } from './relation.js';
4
+ export declare class BelongsToManyRelation<Related extends Model = Model> extends Relation<Related> {
5
+ private readonly pivotTable;
6
+ private readonly foreignPivotKey;
7
+ private readonly relatedPivotKey;
8
+ private readonly parentKey;
9
+ private readonly relatedKey;
10
+ constructor(parent: Model, relatedModel: ModelStatic, pivotTable: string, foreignPivotKey: string, relatedPivotKey: string, parentKey: string, relatedKey: string);
11
+ get(): Promise<Related[]>;
12
+ }
13
+ //# sourceMappingURL=belongs-to-many.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"belongs-to-many.d.ts","sourceRoot":"","sources":["../../src/relations/belongs-to-many.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,qBAAa,qBAAqB,CAAC,OAAO,SAAS,KAAK,GAAG,KAAK,CAAE,SAAQ,QAAQ,CAAC,OAAO,CAAC;IAIvF,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAN3B,MAAM,EAAE,KAAK,EACb,YAAY,EAAE,WAAW,EACR,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM;IAK/B,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;CA2BhC"}
@@ -0,0 +1,38 @@
1
+ import { Relation } from './relation.js';
2
+ export class BelongsToManyRelation extends Relation {
3
+ pivotTable;
4
+ foreignPivotKey;
5
+ relatedPivotKey;
6
+ parentKey;
7
+ relatedKey;
8
+ constructor(parent, relatedModel, pivotTable, foreignPivotKey, relatedPivotKey, parentKey, relatedKey) {
9
+ super(parent, relatedModel);
10
+ this.pivotTable = pivotTable;
11
+ this.foreignPivotKey = foreignPivotKey;
12
+ this.relatedPivotKey = relatedPivotKey;
13
+ this.parentKey = parentKey;
14
+ this.relatedKey = relatedKey;
15
+ }
16
+ async get() {
17
+ const parentId = this.parent.getAttribute(this.parentKey);
18
+ if (parentId === undefined || parentId === null) {
19
+ return [];
20
+ }
21
+ const grammar = this.relatedModel.getConnection().grammar;
22
+ const relatedTable = this.relatedModel.table;
23
+ const pivot = grammar.wrapIdentifier(this.pivotTable);
24
+ const related = grammar.wrapIdentifier(relatedTable);
25
+ const sql = `
26
+ SELECT ${related}.*
27
+ FROM ${related}
28
+ INNER JOIN ${pivot}
29
+ ON ${related}.${grammar.wrapIdentifier(this.relatedKey)}
30
+ = ${pivot}.${grammar.wrapIdentifier(this.relatedPivotKey)}
31
+ WHERE ${pivot}.${grammar.wrapIdentifier(this.foreignPivotKey)} = ${grammar.parameter(1)}
32
+ `;
33
+ const result = await this.relatedModel.getConnection().query(sql, [parentId]);
34
+ const ModelClass = this.relatedModel;
35
+ return result.rows.map((row) => new ModelClass(row));
36
+ }
37
+ }
38
+ //# sourceMappingURL=belongs-to-many.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"belongs-to-many.js","sourceRoot":"","sources":["../../src/relations/belongs-to-many.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,MAAM,OAAO,qBAAqD,SAAQ,QAAiB;IAItE;IACA;IACA;IACA;IACA;IAPnB,YACE,MAAa,EACb,YAAyB,EACR,UAAkB,EAClB,eAAuB,EACvB,eAAuB,EACvB,SAAiB,EACjB,UAAkB;QAEnC,KAAK,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QANX,eAAU,GAAV,UAAU,CAAQ;QAClB,oBAAe,GAAf,eAAe,CAAQ;QACvB,oBAAe,GAAf,eAAe,CAAQ;QACvB,cAAS,GAAT,SAAS,CAAQ;QACjB,eAAU,GAAV,UAAU,CAAQ;IAGrC,CAAC;IAED,KAAK,CAAC,GAAG;QACP,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,SAAkB,CAAa,CAAC;QAC/E,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YAChD,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC;QAC1D,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;QAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtD,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QAErD,MAAM,GAAG,GAAG;eACD,OAAO;aACT,OAAO;mBACD,KAAK;aACX,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC;aAClD,KAAK,IAAI,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,eAAe,CAAC;cACpD,KAAK,IAAI,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;KACxF,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9E,MAAM,UAAU,GAAG,IAAI,CAAC,YAEZ,CAAC;QAEb,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IACvD,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ import type { Model } from '../model.js';
2
+ import type { ModelStatic } from '../model-types.js';
3
+ import { Relation } from './relation.js';
4
+ export declare class BelongsToRelation<Related extends Model = Model> extends Relation<Related> {
5
+ private readonly foreignKey;
6
+ private readonly ownerKey;
7
+ constructor(parent: Model, relatedModel: ModelStatic, foreignKey: string, ownerKey: string);
8
+ get(): Promise<Related | null>;
9
+ }
10
+ //# sourceMappingURL=belongs-to.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"belongs-to.d.ts","sourceRoot":"","sources":["../../src/relations/belongs-to.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,qBAAa,iBAAiB,CAAC,OAAO,SAAS,KAAK,GAAG,KAAK,CAAE,SAAQ,QAAQ,CAAC,OAAO,CAAC;IAInF,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAHzB,MAAM,EAAE,KAAK,EACb,YAAY,EAAE,WAAW,EACR,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM;IAK7B,GAAG,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;CAWrC"}
@@ -0,0 +1,21 @@
1
+ import { Relation } from './relation.js';
2
+ export class BelongsToRelation extends Relation {
3
+ foreignKey;
4
+ ownerKey;
5
+ constructor(parent, relatedModel, foreignKey, ownerKey) {
6
+ super(parent, relatedModel);
7
+ this.foreignKey = foreignKey;
8
+ this.ownerKey = ownerKey;
9
+ }
10
+ async get() {
11
+ const foreignValue = this.parent.getAttribute(this.foreignKey);
12
+ if (foreignValue === undefined || foreignValue === null) {
13
+ return null;
14
+ }
15
+ return this.relatedModel
16
+ .query()
17
+ .where(this.ownerKey, foreignValue)
18
+ .firstModel();
19
+ }
20
+ }
21
+ //# sourceMappingURL=belongs-to.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"belongs-to.js","sourceRoot":"","sources":["../../src/relations/belongs-to.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,MAAM,OAAO,iBAAiD,SAAQ,QAAiB;IAIlE;IACA;IAJnB,YACE,MAAa,EACb,YAAyB,EACR,UAAkB,EAClB,QAAgB;QAEjC,KAAK,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QAHX,eAAU,GAAV,UAAU,CAAQ;QAClB,aAAQ,GAAR,QAAQ,CAAQ;IAGnC,CAAC;IAED,KAAK,CAAC,GAAG;QACP,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,UAAmB,CAAa,CAAC;QACpF,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YACxD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,IAAI,CAAC,YAAY;aACrB,KAAK,EAAE;aACP,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC;aAClC,UAAU,EAAW,CAAC;IAC3B,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import type { Model } from '../model.js';
2
+ import type { ModelStatic } from '../model-types.js';
3
+ import type { ModelQueryBuilder } from '../model-query-builder.js';
4
+ import { Relation } from './relation.js';
5
+ export declare class HasManyRelation<Related extends Model = Model> extends Relation<Related> {
6
+ private readonly foreignKey;
7
+ private readonly localKey;
8
+ constructor(parent: Model, relatedModel: ModelStatic, foreignKey: string, localKey: string);
9
+ query(): ModelQueryBuilder;
10
+ get(): Promise<Related[]>;
11
+ }
12
+ //# sourceMappingURL=has-many.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"has-many.d.ts","sourceRoot":"","sources":["../../src/relations/has-many.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,qBAAa,eAAe,CAAC,OAAO,SAAS,KAAK,GAAG,KAAK,CAAE,SAAQ,QAAQ,CAAC,OAAO,CAAC;IAIjF,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAHzB,MAAM,EAAE,KAAK,EACb,YAAY,EAAE,WAAW,EACR,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM;IAKnC,KAAK,IAAI,iBAAiB;IAKpB,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;CAGhC"}
@@ -0,0 +1,18 @@
1
+ import { Relation } from './relation.js';
2
+ export class HasManyRelation extends Relation {
3
+ foreignKey;
4
+ localKey;
5
+ constructor(parent, relatedModel, foreignKey, localKey) {
6
+ super(parent, relatedModel);
7
+ this.foreignKey = foreignKey;
8
+ this.localKey = localKey;
9
+ }
10
+ query() {
11
+ const localValue = this.parent.getAttribute(this.localKey);
12
+ return this.relatedModel.query().where(this.foreignKey, localValue);
13
+ }
14
+ async get() {
15
+ return this.query().getModels();
16
+ }
17
+ }
18
+ //# sourceMappingURL=has-many.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"has-many.js","sourceRoot":"","sources":["../../src/relations/has-many.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,MAAM,OAAO,eAA+C,SAAQ,QAAiB;IAIhE;IACA;IAJnB,YACE,MAAa,EACb,YAAyB,EACR,UAAkB,EAClB,QAAgB;QAEjC,KAAK,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QAHX,eAAU,GAAV,UAAU,CAAQ;QAClB,aAAQ,GAAR,QAAQ,CAAQ;IAGnC,CAAC;IAED,KAAK;QACH,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,QAAiB,CAAa,CAAC;QAChF,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,GAAG;QACP,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,SAAS,EAAW,CAAC;IAC3C,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import type { Model } from '../model.js';
2
+ import type { ModelStatic } from '../model-types.js';
3
+ import type { ModelQueryBuilder } from '../model-query-builder.js';
4
+ import { Relation } from './relation.js';
5
+ export declare class HasOneRelation<Related extends Model = Model> extends Relation<Related> {
6
+ private readonly foreignKey;
7
+ private readonly localKey;
8
+ constructor(parent: Model, relatedModel: ModelStatic, foreignKey: string, localKey: string);
9
+ query(): ModelQueryBuilder;
10
+ get(): Promise<Related | null>;
11
+ }
12
+ //# sourceMappingURL=has-one.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"has-one.d.ts","sourceRoot":"","sources":["../../src/relations/has-one.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,qBAAa,cAAc,CAAC,OAAO,SAAS,KAAK,GAAG,KAAK,CAAE,SAAQ,QAAQ,CAAC,OAAO,CAAC;IAIhF,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAHzB,MAAM,EAAE,KAAK,EACb,YAAY,EAAE,WAAW,EACR,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM;IAKnC,KAAK,IAAI,iBAAiB;IAKpB,GAAG,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;CAGrC"}
@@ -0,0 +1,18 @@
1
+ import { Relation } from './relation.js';
2
+ export class HasOneRelation extends Relation {
3
+ foreignKey;
4
+ localKey;
5
+ constructor(parent, relatedModel, foreignKey, localKey) {
6
+ super(parent, relatedModel);
7
+ this.foreignKey = foreignKey;
8
+ this.localKey = localKey;
9
+ }
10
+ query() {
11
+ const localValue = this.parent.getAttribute(this.localKey);
12
+ return this.relatedModel.query().where(this.foreignKey, localValue);
13
+ }
14
+ async get() {
15
+ return this.query().firstModel();
16
+ }
17
+ }
18
+ //# sourceMappingURL=has-one.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"has-one.js","sourceRoot":"","sources":["../../src/relations/has-one.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,MAAM,OAAO,cAA8C,SAAQ,QAAiB;IAI/D;IACA;IAJnB,YACE,MAAa,EACb,YAAyB,EACR,UAAkB,EAClB,QAAgB;QAEjC,KAAK,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QAHX,eAAU,GAAV,UAAU,CAAQ;QAClB,aAAQ,GAAR,QAAQ,CAAQ;IAGnC,CAAC;IAED,KAAK;QACH,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,QAAiB,CAAa,CAAC;QAChF,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,GAAG;QACP,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,UAAU,EAAW,CAAC;IAC5C,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ import type { Model } from '../model.js';
2
+ import type { ModelStatic } from '../model-types.js';
3
+ export declare abstract class Relation<Related extends Model = Model> {
4
+ protected readonly parent: Model;
5
+ protected readonly relatedModel: ModelStatic;
6
+ constructor(parent: Model, relatedModel: ModelStatic);
7
+ abstract get(): Promise<Related | Related[] | null>;
8
+ }
9
+ //# sourceMappingURL=relation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation.d.ts","sourceRoot":"","sources":["../../src/relations/relation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,8BAAsB,QAAQ,CAAC,OAAO,SAAS,KAAK,GAAG,KAAK;IAExD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK;IAChC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,WAAW;gBADzB,MAAM,EAAE,KAAK,EACb,YAAY,EAAE,WAAW;IAG9C,QAAQ,CAAC,GAAG,IAAI,OAAO,CAAC,OAAO,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC;CACpD"}
@@ -0,0 +1,9 @@
1
+ export class Relation {
2
+ parent;
3
+ relatedModel;
4
+ constructor(parent, relatedModel) {
5
+ this.parent = parent;
6
+ this.relatedModel = relatedModel;
7
+ }
8
+ }
9
+ //# sourceMappingURL=relation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation.js","sourceRoot":"","sources":["../../src/relations/relation.ts"],"names":[],"mappings":"AAGA,MAAM,OAAgB,QAAQ;IAEP;IACA;IAFrB,YACqB,MAAa,EACb,YAAyB;QADzB,WAAM,GAAN,MAAM,CAAO;QACb,iBAAY,GAAZ,YAAY,CAAa;IAC3C,CAAC;CAGL"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=relations.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relations.test.d.ts","sourceRoot":"","sources":["../src/relations.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,78 @@
1
+ import { beforeAll, describe, expect, it } from 'vitest';
2
+ import { Model } from './model.js';
3
+ import { SqliteConnection } from './sqlite-connection.js';
4
+ class User extends Model {
5
+ static table = 'users';
6
+ }
7
+ class Post extends Model {
8
+ static table = 'posts';
9
+ }
10
+ class Role extends Model {
11
+ static table = 'roles';
12
+ }
13
+ describe('relationships', () => {
14
+ const connection = new SqliteConnection(':memory:');
15
+ beforeAll(async () => {
16
+ User.useConnection(connection);
17
+ Post.useConnection(connection);
18
+ Role.useConnection(connection);
19
+ await connection.exec(`
20
+ CREATE TABLE "users" (
21
+ "id" INTEGER PRIMARY KEY AUTOINCREMENT,
22
+ "name" TEXT NOT NULL
23
+ );
24
+ CREATE TABLE "posts" (
25
+ "id" INTEGER PRIMARY KEY AUTOINCREMENT,
26
+ "user_id" INTEGER NOT NULL,
27
+ "title" TEXT NOT NULL
28
+ );
29
+ CREATE TABLE "roles" (
30
+ "id" INTEGER PRIMARY KEY AUTOINCREMENT,
31
+ "name" TEXT NOT NULL
32
+ );
33
+ CREATE TABLE "user_role" (
34
+ "user_id" INTEGER NOT NULL,
35
+ "role_id" INTEGER NOT NULL
36
+ );
37
+ `);
38
+ });
39
+ it('loads hasMany related models', async () => {
40
+ const user = await User.create({ name: 'Ada' });
41
+ await Post.create({ user_id: user.getAttribute('id'), title: 'First' });
42
+ await Post.create({ user_id: user.getAttribute('id'), title: 'Second' });
43
+ const posts = await user.hasMany(Post).get();
44
+ expect(posts).toHaveLength(2);
45
+ expect(posts.map((post) => post.getAttribute('title'))).toEqual([
46
+ 'First',
47
+ 'Second',
48
+ ]);
49
+ });
50
+ it('loads hasOne related model', async () => {
51
+ const user = await User.create({ name: 'Grace' });
52
+ await Post.create({ user_id: user.getAttribute('id'), title: 'Only' });
53
+ const post = await user.hasOne(Post).get();
54
+ expect(post?.getAttribute('title')).toBe('Only');
55
+ });
56
+ it('loads belongsTo parent model', async () => {
57
+ const user = await User.create({ name: 'Katherine' });
58
+ const post = await Post.create({
59
+ user_id: user.getAttribute('id'),
60
+ title: 'Hello',
61
+ });
62
+ const owner = await post.belongsTo(User).get();
63
+ expect(owner?.getAttribute('name')).toBe('Katherine');
64
+ });
65
+ it('loads belongsToMany related models through pivot table', async () => {
66
+ const user = await User.create({ name: 'Alan' });
67
+ const admin = await Role.create({ name: 'admin' });
68
+ const editor = await Role.create({ name: 'editor' });
69
+ await connection.query('INSERT INTO "user_role" ("user_id", "role_id") VALUES (?, ?), (?, ?)', [user.getAttribute('id'), admin.getAttribute('id'), user.getAttribute('id'), editor.getAttribute('id')]);
70
+ const roles = await user.belongsToMany(Role).get();
71
+ expect(roles).toHaveLength(2);
72
+ expect(roles.map((role) => role.getAttribute('name')).sort()).toEqual([
73
+ 'admin',
74
+ 'editor',
75
+ ]);
76
+ });
77
+ });
78
+ //# sourceMappingURL=relations.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relations.test.js","sourceRoot":"","sources":["../src/relations.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export declare class Blueprint {
2
+ private readonly tableName;
3
+ private readonly statements;
4
+ constructor(tableName: string);
5
+ id(name?: string): this;
6
+ string(name: string, length?: number): this;
7
+ text(name: string): this;
8
+ integer(name: string): this;
9
+ boolean(name: string): this;
10
+ timestamps(): this;
11
+ nullable(): this;
12
+ unique(columns?: string | string[]): this;
13
+ toCreateSql(): string;
14
+ toDropSql(): string;
15
+ }
16
+ //# sourceMappingURL=blueprint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blueprint.d.ts","sourceRoot":"","sources":["../../src/schema/blueprint.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAS;IAGR,OAAO,CAAC,QAAQ,CAAC,SAAS;IAFtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;gBAEd,SAAS,EAAE,MAAM;IAE9C,EAAE,CAAC,IAAI,SAAO,GAAG,IAAI;IAKrB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAM,GAAG,IAAI;IAKxC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKxB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK3B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK3B,UAAU,IAAI,IAAI;IAMlB,QAAQ,IAAI,IAAI;IAShB,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;IAgBzC,WAAW,IAAI,MAAM;IAIrB,SAAS,IAAI,MAAM;CAGpB"}
@@ -0,0 +1,59 @@
1
+ export class Blueprint {
2
+ tableName;
3
+ statements = [];
4
+ constructor(tableName) {
5
+ this.tableName = tableName;
6
+ }
7
+ id(name = 'id') {
8
+ this.statements.push(`"${name}" INTEGER PRIMARY KEY AUTOINCREMENT`);
9
+ return this;
10
+ }
11
+ string(name, length = 255) {
12
+ this.statements.push(`"${name}" VARCHAR(${length}) NOT NULL`);
13
+ return this;
14
+ }
15
+ text(name) {
16
+ this.statements.push(`"${name}" TEXT NOT NULL`);
17
+ return this;
18
+ }
19
+ integer(name) {
20
+ this.statements.push(`"${name}" INTEGER NOT NULL`);
21
+ return this;
22
+ }
23
+ boolean(name) {
24
+ this.statements.push(`"${name}" INTEGER NOT NULL DEFAULT 0`);
25
+ return this;
26
+ }
27
+ timestamps() {
28
+ this.string('created_at', 64);
29
+ this.string('updated_at', 64);
30
+ return this;
31
+ }
32
+ nullable() {
33
+ const last = this.statements.at(-1);
34
+ if (!last) {
35
+ return this;
36
+ }
37
+ this.statements[this.statements.length - 1] = last.replace(' NOT NULL', '');
38
+ return this;
39
+ }
40
+ unique(columns) {
41
+ if (columns === undefined) {
42
+ const last = this.statements.at(-1);
43
+ if (last) {
44
+ this.statements[this.statements.length - 1] = `${last} UNIQUE`;
45
+ }
46
+ return this;
47
+ }
48
+ const names = Array.isArray(columns) ? columns : [columns];
49
+ this.statements.push(`UNIQUE (${names.map((name) => `"${name}"`).join(', ')})`);
50
+ return this;
51
+ }
52
+ toCreateSql() {
53
+ return `CREATE TABLE "${this.tableName}" (${this.statements.join(', ')})`;
54
+ }
55
+ toDropSql() {
56
+ return `DROP TABLE IF EXISTS "${this.tableName}"`;
57
+ }
58
+ }
59
+ //# sourceMappingURL=blueprint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blueprint.js","sourceRoot":"","sources":["../../src/schema/blueprint.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,SAAS;IAGS;IAFZ,UAAU,GAAa,EAAE,CAAC;IAE3C,YAA6B,SAAiB;QAAjB,cAAS,GAAT,SAAS,CAAQ;IAAG,CAAC;IAElD,EAAE,CAAC,IAAI,GAAG,IAAI;QACZ,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,qCAAqC,CAAC,CAAC;QACpE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,MAAM,GAAG,GAAG;QAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,aAAa,MAAM,YAAY,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,IAAY;QACf,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,iBAAiB,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CAAC,IAAY;QAClB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,oBAAoB,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CAAC,IAAY;QAClB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,8BAA8B,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,UAAU;QACR,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,QAAQ;QACN,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,OAA2B;QAChC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACpC,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,GAAG,IAAI,SAAS,CAAC;YACjE,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC3D,IAAI,CAAC,UAAU,CAAC,IAAI,CAClB,WAAW,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC1D,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,WAAW;QACT,OAAO,iBAAiB,IAAI,CAAC,SAAS,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IAC5E,CAAC;IAED,SAAS;QACP,OAAO,yBAAyB,IAAI,CAAC,SAAS,GAAG,CAAC;IACpD,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ import type { DatabaseConnection } from '../connection.js';
2
+ import { Blueprint } from './blueprint.js';
3
+ export declare class SchemaBuilder {
4
+ private readonly connection;
5
+ constructor(connection: DatabaseConnection);
6
+ create(tableName: string, callback: (table: Blueprint) => void): Promise<void>;
7
+ drop(tableName: string): Promise<void>;
8
+ hasTable(tableName: string): Promise<boolean>;
9
+ }
10
+ //# sourceMappingURL=schema-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-builder.d.ts","sourceRoot":"","sources":["../../src/schema/schema-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,kBAAkB;IAErD,MAAM,CACV,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,GACnC,OAAO,CAAC,IAAI,CAAC;IAMV,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKtC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAOpD"}
@@ -0,0 +1,21 @@
1
+ import { Blueprint } from './blueprint.js';
2
+ export class SchemaBuilder {
3
+ connection;
4
+ constructor(connection) {
5
+ this.connection = connection;
6
+ }
7
+ async create(tableName, callback) {
8
+ const blueprint = new Blueprint(tableName);
9
+ callback(blueprint);
10
+ await this.connection.exec(blueprint.toCreateSql());
11
+ }
12
+ async drop(tableName) {
13
+ const blueprint = new Blueprint(tableName);
14
+ await this.connection.exec(blueprint.toDropSql());
15
+ }
16
+ async hasTable(tableName) {
17
+ const result = await this.connection.query(`SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?`, [tableName]);
18
+ return result.rows.length > 0;
19
+ }
20
+ }
21
+ //# sourceMappingURL=schema-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-builder.js","sourceRoot":"","sources":["../../src/schema/schema-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,OAAO,aAAa;IACK;IAA7B,YAA6B,UAA8B;QAA9B,eAAU,GAAV,UAAU,CAAoB;IAAG,CAAC;IAE/D,KAAK,CAAC,MAAM,CACV,SAAiB,EACjB,QAAoC;QAEpC,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,SAAS,CAAC,CAAC;QAC3C,QAAQ,CAAC,SAAS,CAAC,CAAC;QACpB,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAiB;QAC1B,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,SAAS,CAAC,CAAC;QAC3C,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,SAAiB;QAC9B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CACxC,kEAAkE,EAClE,CAAC,SAAS,CAAC,CACZ,CAAC;QACF,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAChC,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ import type { ModelQueryBuilder } from './model-query-builder.js';
2
+ export type LocalScope = (builder: ModelQueryBuilder, ...args: unknown[]) => ModelQueryBuilder | void;
3
+ export type GlobalScope = (builder: ModelQueryBuilder) => ModelQueryBuilder | void;
4
+ export declare function scopeMethodName(name: string): string;
5
+ //# sourceMappingURL=scopes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,MAAM,MAAM,UAAU,GAAG,CACvB,OAAO,EAAE,iBAAiB,EAC1B,GAAG,IAAI,EAAE,OAAO,EAAE,KACf,iBAAiB,GAAG,IAAI,CAAC;AAE9B,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,iBAAiB,KAAK,iBAAiB,GAAG,IAAI,CAAC;AAEnF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD"}
package/dist/scopes.js ADDED
@@ -0,0 +1,4 @@
1
+ export function scopeMethodName(name) {
2
+ return `scope${name.charAt(0).toUpperCase()}${name.slice(1)}`;
3
+ }
4
+ //# sourceMappingURL=scopes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scopes.js","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,QAAQ,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAChE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=scopes.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scopes.test.d.ts","sourceRoot":"","sources":["../src/scopes.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,48 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { Model } from './model.js';
3
+ import { SqliteConnection } from './sqlite-connection.js';
4
+ describe('query scopes', () => {
5
+ it('applies local scopes via Model.scope()', async () => {
6
+ class Post extends Model {
7
+ static table = 'posts';
8
+ static scopePublished(builder) {
9
+ return builder.where('published', 1);
10
+ }
11
+ }
12
+ const connection = new SqliteConnection(':memory:');
13
+ Post.useConnection(connection);
14
+ await connection.exec(`
15
+ CREATE TABLE "posts" (
16
+ "id" INTEGER PRIMARY KEY AUTOINCREMENT,
17
+ "title" TEXT NOT NULL,
18
+ "published" INTEGER NOT NULL DEFAULT 0
19
+ )
20
+ `);
21
+ await Post.create({ title: 'Draft', published: 0 });
22
+ await Post.create({ title: 'Live', published: 1 });
23
+ const published = await Post.scope('published').getModels();
24
+ expect(published).toHaveLength(1);
25
+ expect(published[0]?.getAttribute('title')).toBe('Live');
26
+ });
27
+ it('applies global scopes on every query', async () => {
28
+ class Post extends Model {
29
+ static table = 'posts';
30
+ }
31
+ const connection = new SqliteConnection(':memory:');
32
+ Post.useConnection(connection);
33
+ Post.addGlobalScope((builder) => builder.where('published', 1));
34
+ await connection.exec(`
35
+ CREATE TABLE "posts" (
36
+ "id" INTEGER PRIMARY KEY AUTOINCREMENT,
37
+ "title" TEXT NOT NULL,
38
+ "published" INTEGER NOT NULL DEFAULT 0
39
+ )
40
+ `);
41
+ await Post.create({ title: 'Draft', published: 0 });
42
+ await Post.create({ title: 'Live', published: 1 });
43
+ const posts = await Post.all();
44
+ expect(posts).toHaveLength(1);
45
+ expect(posts[0]?.getAttribute('title')).toBe('Live');
46
+ });
47
+ });
48
+ //# sourceMappingURL=scopes.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scopes.test.js","sourceRoot":"","sources":["../src/scopes.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAS1D,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,IAAK,SAAQ,KAAc;YAC/B,MAAM,CAAU,KAAK,GAAG,OAAO,CAAC;YAEhC,MAAM,CAAC,cAAc,CAAC,OAA0B;gBAC9C,OAAO,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;YACvC,CAAC;;QAGH,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,UAAU,CAAC,CAAC;QACpD,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QAE/B,MAAM,UAAU,CAAC,IAAI,CAAC;;;;;;KAMrB,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;QACpD,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;QAEnD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,SAAS,EAAQ,CAAC;QAClE,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,IAAK,SAAQ,KAAc;YAC/B,MAAM,CAAU,KAAK,GAAG,OAAO,CAAC;;QAGlC,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,UAAU,CAAC,CAAC;QACpD,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QAC/B,IAAI,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;QAEhE,MAAM,UAAU,CAAC,IAAI,CAAC;;;;;;KAMrB,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;QACpD,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;QAEnD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,EAAQ,CAAC;QACrC,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { DatabaseConnection, QueryResult } from './connection.js';
2
+ import { type SqlGrammar } from './grammar.js';
3
+ import type { RowValue } from './types.js';
4
+ export declare class SqliteConnection implements DatabaseConnection {
5
+ readonly grammar: SqlGrammar;
6
+ private readonly database;
7
+ constructor(databasePath: string, basePath?: string);
8
+ query(sql: string, bindings?: RowValue[]): Promise<QueryResult>;
9
+ exec(sql: string): Promise<void>;
10
+ transaction<T>(callback: (connection: DatabaseConnection) => Promise<T>): Promise<T>;
11
+ }
12
+ //# sourceMappingURL=sqlite-connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-connection.d.ts","sourceRoot":"","sources":["../src/sqlite-connection.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAiB3C,qBAAa,gBAAiB,YAAW,kBAAkB;IACzD,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAuB;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;gBAE9B,YAAY,EAAE,MAAM,EAAE,QAAQ,SAAgB;IAapD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,QAAQ,EAAO,GAAG,OAAO,CAAC,WAAW,CAAC;IAiBnE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhC,WAAW,CAAC,CAAC,EACjB,QAAQ,EAAE,CAAC,UAAU,EAAE,kBAAkB,KAAK,OAAO,CAAC,CAAC,CAAC,GACvD,OAAO,CAAC,CAAC,CAAC;CAWd"}