@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,15 @@
1
+ import type { SqlGrammar } from './grammar.js';
2
+ import type { Row, RowValue } from './types.js';
3
+ export interface QueryResult {
4
+ rows: Row[];
5
+ changes: number;
6
+ lastInsertId?: number | bigint;
7
+ }
8
+ export interface DatabaseConnection {
9
+ readonly grammar: SqlGrammar;
10
+ query(sql: string, bindings?: RowValue[]): Promise<QueryResult>;
11
+ exec(sql: string): Promise<void>;
12
+ transaction<T>(callback: (connection: DatabaseConnection) => Promise<T>): Promise<T>;
13
+ close?(): Promise<void>;
14
+ }
15
+ //# sourceMappingURL=connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAChE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,kBAAkB,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACrF,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import type { DatabaseConnection } from './connection.js';
2
+ import type { DatabaseConfig } from './types.js';
3
+ export declare class DatabaseManager {
4
+ private readonly config;
5
+ private readonly basePath;
6
+ private readonly connections;
7
+ constructor(config: DatabaseConfig, basePath?: string);
8
+ connection(name?: string): DatabaseConnection;
9
+ close(name?: string): Promise<void>;
10
+ private createConnection;
11
+ }
12
+ //# sourceMappingURL=database-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-manager.d.ts","sourceRoot":"","sources":["../src/database-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAI1D,OAAO,KAAK,EAAoB,cAAc,EAAE,MAAM,YAAY,CAAC;AAEnE,qBAAa,eAAe;IAIxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAJ3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyC;gBAGlD,MAAM,EAAE,cAAc,EACtB,QAAQ,SAAgB;IAG3C,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,kBAAkB;IAiBvC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAczC,OAAO,CAAC,gBAAgB;CAYzB"}
@@ -0,0 +1,49 @@
1
+ import { MysqlConnection } from './mysql-connection.js';
2
+ import { PostgresConnection } from './postgres-connection.js';
3
+ import { SqliteConnection } from './sqlite-connection.js';
4
+ export class DatabaseManager {
5
+ config;
6
+ basePath;
7
+ connections = new Map();
8
+ constructor(config, basePath = process.cwd()) {
9
+ this.config = config;
10
+ this.basePath = basePath;
11
+ }
12
+ connection(name) {
13
+ const connectionName = name ?? this.config.default;
14
+ const existing = this.connections.get(connectionName);
15
+ if (existing) {
16
+ return existing;
17
+ }
18
+ const connectionConfig = this.config.connections[connectionName];
19
+ if (!connectionConfig) {
20
+ throw new Error(`Database connection not configured: ${connectionName}`);
21
+ }
22
+ const connection = this.createConnection(connectionConfig);
23
+ this.connections.set(connectionName, connection);
24
+ return connection;
25
+ }
26
+ async close(name) {
27
+ if (name) {
28
+ const connection = this.connections.get(name);
29
+ await connection?.close?.();
30
+ this.connections.delete(name);
31
+ return;
32
+ }
33
+ await Promise.all([...this.connections.values()].map((connection) => connection.close?.()));
34
+ this.connections.clear();
35
+ }
36
+ createConnection(config) {
37
+ switch (config.driver) {
38
+ case 'sqlite':
39
+ return new SqliteConnection(config.database, this.basePath);
40
+ case 'postgres':
41
+ return new PostgresConnection(config);
42
+ case 'mysql':
43
+ return new MysqlConnection(config);
44
+ default:
45
+ throw new Error(`Unsupported database driver: ${config.driver}`);
46
+ }
47
+ }
48
+ }
49
+ //# sourceMappingURL=database-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-manager.js","sourceRoot":"","sources":["../src/database-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,MAAM,OAAO,eAAe;IAIP;IACA;IAJF,WAAW,GAAG,IAAI,GAAG,EAA8B,CAAC;IAErE,YACmB,MAAsB,EACtB,WAAW,OAAO,CAAC,GAAG,EAAE;QADxB,WAAM,GAAN,MAAM,CAAgB;QACtB,aAAQ,GAAR,QAAQ,CAAgB;IACxC,CAAC;IAEJ,UAAU,CAAC,IAAa;QACtB,MAAM,cAAc,GAAG,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;QACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACtD,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;QACjE,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,uCAAuC,cAAc,EAAE,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;QAC3D,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;QACjD,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAa;QACvB,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC9C,MAAM,UAAU,EAAE,KAAK,EAAE,EAAE,CAAC;YAC5B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,MAAM,OAAO,CAAC,GAAG,CACf,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC,CACzE,CAAC;QACF,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;IAEO,gBAAgB,CAAC,MAAwB;QAC/C,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;YACtB,KAAK,QAAQ;gBACX,OAAO,IAAI,gBAAgB,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9D,KAAK,UAAU;gBACb,OAAO,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;YACxC,KAAK,OAAO;gBACV,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;YACrC;gBACE,MAAM,IAAI,KAAK,CAAC,gCAAiC,MAA2B,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3F,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,26 @@
1
+ export type DriverName = 'sqlite' | 'postgres' | 'mysql';
2
+ export interface SqlGrammar {
3
+ readonly driver: DriverName;
4
+ wrapIdentifier(identifier: string): string;
5
+ parameter(index: number): string;
6
+ readonly supportsReturning: boolean;
7
+ }
8
+ export declare class SqliteGrammar implements SqlGrammar {
9
+ readonly driver: "sqlite";
10
+ readonly supportsReturning = false;
11
+ wrapIdentifier(identifier: string): string;
12
+ parameter(): string;
13
+ }
14
+ export declare class PostgresGrammar implements SqlGrammar {
15
+ readonly driver: "postgres";
16
+ readonly supportsReturning = true;
17
+ wrapIdentifier(identifier: string): string;
18
+ parameter(index: number): string;
19
+ }
20
+ export declare class MysqlGrammar implements SqlGrammar {
21
+ readonly driver: "mysql";
22
+ readonly supportsReturning = false;
23
+ wrapIdentifier(identifier: string): string;
24
+ parameter(): string;
25
+ }
26
+ //# sourceMappingURL=grammar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grammar.d.ts","sourceRoot":"","sources":["../src/grammar.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAEzD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3C,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;CACrC;AAED,qBAAa,aAAc,YAAW,UAAU;IAC9C,QAAQ,CAAC,MAAM,EAAG,QAAQ,CAAU;IACpC,QAAQ,CAAC,iBAAiB,SAAS;IAEnC,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAI1C,SAAS,IAAI,MAAM;CAGpB;AAED,qBAAa,eAAgB,YAAW,UAAU;IAChD,QAAQ,CAAC,MAAM,EAAG,UAAU,CAAU;IACtC,QAAQ,CAAC,iBAAiB,QAAQ;IAElC,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAI1C,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;CAGjC;AAED,qBAAa,YAAa,YAAW,UAAU;IAC7C,QAAQ,CAAC,MAAM,EAAG,OAAO,CAAU;IACnC,QAAQ,CAAC,iBAAiB,SAAS;IAEnC,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAI1C,SAAS,IAAI,MAAM;CAGpB"}
@@ -0,0 +1,31 @@
1
+ export class SqliteGrammar {
2
+ driver = 'sqlite';
3
+ supportsReturning = false;
4
+ wrapIdentifier(identifier) {
5
+ return `"${identifier.replaceAll('"', '""')}"`;
6
+ }
7
+ parameter() {
8
+ return '?';
9
+ }
10
+ }
11
+ export class PostgresGrammar {
12
+ driver = 'postgres';
13
+ supportsReturning = true;
14
+ wrapIdentifier(identifier) {
15
+ return `"${identifier.replaceAll('"', '""')}"`;
16
+ }
17
+ parameter(index) {
18
+ return `$${index}`;
19
+ }
20
+ }
21
+ export class MysqlGrammar {
22
+ driver = 'mysql';
23
+ supportsReturning = false;
24
+ wrapIdentifier(identifier) {
25
+ return `\`${identifier.replaceAll('`', '``')}\``;
26
+ }
27
+ parameter() {
28
+ return '?';
29
+ }
30
+ }
31
+ //# sourceMappingURL=grammar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grammar.js","sourceRoot":"","sources":["../src/grammar.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,aAAa;IACf,MAAM,GAAG,QAAiB,CAAC;IAC3B,iBAAiB,GAAG,KAAK,CAAC;IAEnC,cAAc,CAAC,UAAkB;QAC/B,OAAO,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;IACjD,CAAC;IAED,SAAS;QACP,OAAO,GAAG,CAAC;IACb,CAAC;CACF;AAED,MAAM,OAAO,eAAe;IACjB,MAAM,GAAG,UAAmB,CAAC;IAC7B,iBAAiB,GAAG,IAAI,CAAC;IAElC,cAAc,CAAC,UAAkB;QAC/B,OAAO,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;IACjD,CAAC;IAED,SAAS,CAAC,KAAa;QACrB,OAAO,IAAI,KAAK,EAAE,CAAC;IACrB,CAAC;CACF;AAED,MAAM,OAAO,YAAY;IACd,MAAM,GAAG,OAAgB,CAAC;IAC1B,iBAAiB,GAAG,KAAK,CAAC;IAEnC,cAAc,CAAC,UAAkB;QAC/B,OAAO,KAAK,UAAU,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC;IACnD,CAAC;IAED,SAAS;QACP,OAAO,GAAG,CAAC;IACb,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=grammar.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grammar.test.d.ts","sourceRoot":"","sources":["../src/grammar.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,48 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { MysqlGrammar, PostgresGrammar, SqliteGrammar } from './grammar.js';
3
+ import { QueryBuilder } from './query-builder.js';
4
+ function mockConnection(grammar) {
5
+ return {
6
+ grammar,
7
+ async query() {
8
+ return { rows: [], changes: 0 };
9
+ },
10
+ async exec() { },
11
+ async transaction(callback) {
12
+ return callback(mockConnection(grammar));
13
+ },
14
+ };
15
+ }
16
+ describe('SqlGrammar', () => {
17
+ it('uses dialect-specific placeholders and identifier quoting', () => {
18
+ const cases = [
19
+ {
20
+ grammar: new SqliteGrammar(),
21
+ sql: 'SELECT * FROM "users" WHERE "id" = ? LIMIT ?',
22
+ },
23
+ {
24
+ grammar: new PostgresGrammar(),
25
+ sql: 'SELECT * FROM "users" WHERE "id" = $1 LIMIT $2',
26
+ },
27
+ {
28
+ grammar: new MysqlGrammar(),
29
+ sql: 'SELECT * FROM `users` WHERE `id` = ? LIMIT ?',
30
+ },
31
+ ];
32
+ for (const { grammar, sql } of cases) {
33
+ const builder = new QueryBuilder(mockConnection(grammar), 'users')
34
+ .where('id', 1)
35
+ .limit(10);
36
+ expect(builder.toSql()).toEqual({
37
+ sql,
38
+ bindings: [1, 10],
39
+ });
40
+ }
41
+ });
42
+ it('flags postgres as supporting RETURNING', () => {
43
+ expect(new PostgresGrammar().supportsReturning).toBe(true);
44
+ expect(new SqliteGrammar().supportsReturning).toBe(false);
45
+ expect(new MysqlGrammar().supportsReturning).toBe(false);
46
+ });
47
+ });
48
+ //# sourceMappingURL=grammar.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grammar.test.js","sourceRoot":"","sources":["../src/grammar.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAMlD,SAAS,cAAc,CAAC,OAAmB;IACzC,OAAO;QACL,OAAO;QACP,KAAK,CAAC,KAAK;YACT,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;QAClC,CAAC;QACD,KAAK,CAAC,IAAI,KAAmB,CAAC;QAC9B,KAAK,CAAC,WAAW,CAAI,QAAwD;YAC3E,OAAO,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3C,CAAC;KACF,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,KAAK,GAAG;YACZ;gBACE,OAAO,EAAE,IAAI,aAAa,EAAE;gBAC5B,GAAG,EAAE,8CAA8C;aACpD;YACD;gBACE,OAAO,EAAE,IAAI,eAAe,EAAE;gBAC9B,GAAG,EAAE,gDAAgD;aACtD;YACD;gBACE,OAAO,EAAE,IAAI,YAAY,EAAE;gBAC3B,GAAG,EAAE,8CAA8C;aACpD;SACF,CAAC;QAEF,KAAK,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,KAAK,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;iBAC/D,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;iBACd,KAAK,CAAC,EAAE,CAAC,CAAC;YAEb,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;gBAC9B,GAAG;gBACH,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;aAClB,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,CAAC,IAAI,eAAe,EAAE,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3D,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1D,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,22 @@
1
+ export type { DatabaseConnection, QueryResult } from './connection.js';
2
+ export { DatabaseManager } from './database-manager.js';
3
+ export { MysqlGrammar, PostgresGrammar, SqliteGrammar, } from './grammar.js';
4
+ export type { DriverName, SqlGrammar } from './grammar.js';
5
+ export { Migration } from './migration.js';
6
+ export { Migrator } from './migrator.js';
7
+ export { Model } from './model.js';
8
+ export { ModelQueryBuilder } from './model-query-builder.js';
9
+ export { QueryBuilder } from './query-builder.js';
10
+ export { BelongsToManyRelation } from './relations/belongs-to-many.js';
11
+ export { BelongsToRelation } from './relations/belongs-to.js';
12
+ export { HasManyRelation } from './relations/has-many.js';
13
+ export { HasOneRelation } from './relations/has-one.js';
14
+ export { Relation } from './relations/relation.js';
15
+ export { Blueprint } from './schema/blueprint.js';
16
+ export { SchemaBuilder } from './schema/schema-builder.js';
17
+ export type { GlobalScope, LocalScope } from './scopes.js';
18
+ export { MysqlConnection } from './mysql-connection.js';
19
+ export { PostgresConnection } from './postgres-connection.js';
20
+ export { SqliteConnection } from './sqlite-connection.js';
21
+ export type { ConnectionConfig, DatabaseConfig, MysqlConnectionConfig, PostgresConnectionConfig, Row, RowValue, SqliteConnectionConfig, WhereClause, WhereOperator, } from './types.js';
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EACL,YAAY,EACZ,eAAe,EACf,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EACV,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,wBAAwB,EACxB,GAAG,EACH,QAAQ,EACR,sBAAsB,EACtB,WAAW,EACX,aAAa,GACd,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ export { DatabaseManager } from './database-manager.js';
2
+ export { MysqlGrammar, PostgresGrammar, SqliteGrammar, } from './grammar.js';
3
+ export { Migration } from './migration.js';
4
+ export { Migrator } from './migrator.js';
5
+ export { Model } from './model.js';
6
+ export { ModelQueryBuilder } from './model-query-builder.js';
7
+ export { QueryBuilder } from './query-builder.js';
8
+ export { BelongsToManyRelation } from './relations/belongs-to-many.js';
9
+ export { BelongsToRelation } from './relations/belongs-to.js';
10
+ export { HasManyRelation } from './relations/has-many.js';
11
+ export { HasOneRelation } from './relations/has-one.js';
12
+ export { Relation } from './relations/relation.js';
13
+ export { Blueprint } from './schema/blueprint.js';
14
+ export { SchemaBuilder } from './schema/schema-builder.js';
15
+ export { MysqlConnection } from './mysql-connection.js';
16
+ export { PostgresConnection } from './postgres-connection.js';
17
+ export { SqliteConnection } from './sqlite-connection.js';
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EACL,YAAY,EACZ,eAAe,EACf,aAAa,GACd,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { DatabaseConnection } from './connection.js';
2
+ import { SchemaBuilder } from './schema/schema-builder.js';
3
+ export declare abstract class Migration {
4
+ abstract up(connection: DatabaseConnection, schema: SchemaBuilder): Promise<void>;
5
+ abstract down(connection: DatabaseConnection, schema: SchemaBuilder): Promise<void>;
6
+ }
7
+ export interface MigrationRecord {
8
+ id: number;
9
+ migration: string;
10
+ batch: number;
11
+ executed_at: string;
12
+ }
13
+ //# sourceMappingURL=migration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration.d.ts","sourceRoot":"","sources":["../src/migration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,8BAAsB,SAAS;IAC7B,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,kBAAkB,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IACjF,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,kBAAkB,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;CACpF;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB"}
@@ -0,0 +1,3 @@
1
+ export class Migration {
2
+ }
3
+ //# sourceMappingURL=migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration.js","sourceRoot":"","sources":["../src/migration.ts"],"names":[],"mappings":"AAGA,MAAM,OAAgB,SAAS;CAG9B"}
@@ -0,0 +1,15 @@
1
+ import type { DatabaseConnection } from './connection.js';
2
+ export declare class Migrator {
3
+ private readonly connection;
4
+ private readonly migrationsPath;
5
+ constructor(connection: DatabaseConnection, migrationsPath: string);
6
+ ensureMigrationsTable(): Promise<void>;
7
+ pending(): Promise<string[]>;
8
+ run(): Promise<string[]>;
9
+ private executed;
10
+ private latestBatch;
11
+ private files;
12
+ private load;
13
+ private record;
14
+ }
15
+ //# sourceMappingURL=migrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrator.d.ts","sourceRoot":"","sources":["../src/migrator.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAI1D,qBAAa,QAAQ;IAEjB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,cAAc;gBADd,UAAU,EAAE,kBAAkB,EAC9B,cAAc,EAAE,MAAM;IAGnC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAWtC,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAM5B,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YAsBhB,QAAQ;YAOR,WAAW;IAQzB,OAAO,CAAC,KAAK;YAUC,IAAI;YAcJ,MAAM;CAMrB"}
@@ -0,0 +1,77 @@
1
+ import { readdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { pathToFileURL } from 'node:url';
4
+ import { SchemaBuilder } from './schema/schema-builder.js';
5
+ export class Migrator {
6
+ connection;
7
+ migrationsPath;
8
+ constructor(connection, migrationsPath) {
9
+ this.connection = connection;
10
+ this.migrationsPath = migrationsPath;
11
+ }
12
+ async ensureMigrationsTable() {
13
+ await this.connection.exec(`
14
+ CREATE TABLE IF NOT EXISTS "migrations" (
15
+ "id" INTEGER PRIMARY KEY AUTOINCREMENT,
16
+ "migration" TEXT NOT NULL,
17
+ "batch" INTEGER NOT NULL,
18
+ "executed_at" TEXT NOT NULL
19
+ )
20
+ `);
21
+ }
22
+ async pending() {
23
+ await this.ensureMigrationsTable();
24
+ const executed = await this.executed();
25
+ return this.files().filter((file) => !executed.includes(file));
26
+ }
27
+ async run() {
28
+ await this.ensureMigrationsTable();
29
+ const pending = await this.pending();
30
+ if (pending.length === 0) {
31
+ return [];
32
+ }
33
+ const batch = (await this.latestBatch()) + 1;
34
+ const schema = new SchemaBuilder(this.connection);
35
+ const ran = [];
36
+ for (const file of pending) {
37
+ const MigrationClass = await this.load(file);
38
+ const migration = new MigrationClass();
39
+ await migration.up(this.connection, schema);
40
+ await this.record(file, batch);
41
+ ran.push(file);
42
+ }
43
+ return ran;
44
+ }
45
+ async executed() {
46
+ const result = await this.connection.query(`SELECT "migration" FROM "migrations" ORDER BY "id" ASC`);
47
+ return result.rows.map((row) => String(row.migration));
48
+ }
49
+ async latestBatch() {
50
+ const result = await this.connection.query(`SELECT MAX("batch") as "batch" FROM "migrations"`);
51
+ const batch = result.rows[0]?.batch;
52
+ return typeof batch === 'number' ? batch : 0;
53
+ }
54
+ files() {
55
+ try {
56
+ return readdirSync(this.migrationsPath)
57
+ .filter((file) => file.endsWith('.ts') || file.endsWith('.js'))
58
+ .sort();
59
+ }
60
+ catch {
61
+ return [];
62
+ }
63
+ }
64
+ async load(file) {
65
+ const moduleUrl = pathToFileURL(join(this.migrationsPath, file)).href;
66
+ const loaded = await import(moduleUrl);
67
+ const MigrationClass = loaded.default ?? Object.values(loaded).find((value) => typeof value === 'function');
68
+ if (typeof MigrationClass !== 'function') {
69
+ throw new Error(`Migration class not found in ${file}`);
70
+ }
71
+ return MigrationClass;
72
+ }
73
+ async record(migration, batch) {
74
+ await this.connection.query(`INSERT INTO "migrations" ("migration", "batch", "executed_at") VALUES (?, ?, ?)`, [migration, batch, new Date().toISOString()]);
75
+ }
76
+ }
77
+ //# sourceMappingURL=migrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrator.js","sourceRoot":"","sources":["../src/migrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=migrator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrator.test.d.ts","sourceRoot":"","sources":["../src/migrator.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,37 @@
1
+ import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { afterEach, describe, expect, it } from 'vitest';
5
+ import { Migrator } from './migrator.js';
6
+ import { SqliteConnection } from './sqlite-connection.js';
7
+ import { SchemaBuilder } from './schema/schema-builder.js';
8
+ describe('Migrator', () => {
9
+ let tempDir = '';
10
+ afterEach(() => {
11
+ if (tempDir) {
12
+ rmSync(tempDir, { recursive: true, force: true });
13
+ tempDir = '';
14
+ }
15
+ });
16
+ it('runs pending migration files', async () => {
17
+ tempDir = mkdtempSync(join(tmpdir(), 'tyravel-migrations-'));
18
+ writeFileSync(join(tempDir, '2026_06_20_000000_create_users_table.js'), `export default class CreateUsersTable {
19
+ async up(_connection, schema) {
20
+ await schema.create('users', (table) => {
21
+ table.id();
22
+ table.string('email');
23
+ });
24
+ }
25
+ async down(_connection, schema) {
26
+ await schema.drop('users');
27
+ }
28
+ }`);
29
+ const connection = new SqliteConnection(':memory:');
30
+ const migrator = new Migrator(connection, tempDir);
31
+ const ran = await migrator.run();
32
+ expect(ran).toEqual(['2026_06_20_000000_create_users_table.js']);
33
+ const schema = new SchemaBuilder(connection);
34
+ expect(await schema.hasTable('users')).toBe(true);
35
+ });
36
+ });
37
+ //# sourceMappingURL=migrator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrator.test.js","sourceRoot":"","sources":["../src/migrator.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACxB,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAClD,OAAO,GAAG,EAAE,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC,CAAC;QAC7D,aAAa,CACX,IAAI,CAAC,OAAO,EAAE,yCAAyC,CAAC,EACxD;;;;;;;;;;QAUE,CACH,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,UAAU,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,CAAC;QAEjC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,yCAAyC,CAAC,CAAC,CAAC;QAEjE,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,UAAU,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { DatabaseConnection } from './connection.js';
2
+ import { QueryBuilder } from './query-builder.js';
3
+ import type { Model } from './model.js';
4
+ import type { ModelStatic } from './model-types.js';
5
+ import { type GlobalScope } from './scopes.js';
6
+ export declare class ModelQueryBuilder extends QueryBuilder {
7
+ private readonly model;
8
+ constructor(connection: DatabaseConnection, tableName: string, model: ModelStatic);
9
+ clone(): ModelQueryBuilder;
10
+ applyScope(name: string, ...args: unknown[]): this;
11
+ getModels<TModel extends Model>(): Promise<TModel[]>;
12
+ firstModel<TModel extends Model>(): Promise<TModel | null>;
13
+ }
14
+ export declare function applyGlobalScopes(builder: ModelQueryBuilder, scopes: GlobalScope[]): ModelQueryBuilder;
15
+ //# sourceMappingURL=model-query-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-query-builder.d.ts","sourceRoot":"","sources":["../src/model-query-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAmB,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAmB,KAAK,WAAW,EAAmB,MAAM,aAAa,CAAC;AAEjF,qBAAa,iBAAkB,SAAQ,YAAY;IAI/C,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAFtB,UAAU,EAAE,kBAAkB,EAC9B,SAAS,EAAE,MAAM,EACA,KAAK,EAAE,WAAW;IAK5B,KAAK,IAAI,iBAAiB;IAUnC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAc5C,SAAS,CAAC,MAAM,SAAS,KAAK,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;IAQpD,UAAU,CAAC,MAAM,SAAS,KAAK,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAIjE;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,WAAW,EAAE,GACpB,iBAAiB,CASnB"}
@@ -0,0 +1,43 @@
1
+ import { QueryBuilder } from './query-builder.js';
2
+ import { scopeMethodName } from './scopes.js';
3
+ export class ModelQueryBuilder extends QueryBuilder {
4
+ model;
5
+ constructor(connection, tableName, model) {
6
+ super(connection, tableName);
7
+ this.model = model;
8
+ }
9
+ clone() {
10
+ const builder = new ModelQueryBuilder(this.connection, this.getTableName(), this.model);
11
+ this.copyTo(builder);
12
+ return builder;
13
+ }
14
+ applyScope(name, ...args) {
15
+ const scopeName = scopeMethodName(name);
16
+ const scope = this.model[scopeName];
17
+ if (!scope) {
18
+ throw new Error(`Scope [${name}] not defined on model [${this.model.name}].`);
19
+ }
20
+ const result = scope.call(this.model, this, ...args);
21
+ return result ?? this;
22
+ }
23
+ async getModels() {
24
+ const rows = await this.get();
25
+ const ModelClass = this.model;
26
+ return rows.map((row) => new ModelClass(row));
27
+ }
28
+ async firstModel() {
29
+ const rows = await this.clone().limit(1).getModels();
30
+ return rows[0] ?? null;
31
+ }
32
+ }
33
+ export function applyGlobalScopes(builder, scopes) {
34
+ let current = builder;
35
+ for (const scope of scopes) {
36
+ const result = scope(current);
37
+ if (result) {
38
+ current = result;
39
+ }
40
+ }
41
+ return current;
42
+ }
43
+ //# sourceMappingURL=model-query-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-query-builder.js","sourceRoot":"","sources":["../src/model-query-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,OAAO,EAAE,eAAe,EAAqC,MAAM,aAAa,CAAC;AAEjF,MAAM,OAAO,iBAAkB,SAAQ,YAAY;IAI9B;IAHnB,YACE,UAA8B,EAC9B,SAAiB,EACA,KAAkB;QAEnC,KAAK,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAFZ,UAAK,GAAL,KAAK,CAAa;IAGrC,CAAC;IAEQ,KAAK;QACZ,MAAM,OAAO,GAAG,IAAI,iBAAiB,CACnC,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,YAAY,EAAE,EACnB,IAAI,CAAC,KAAK,CACX,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACrB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,UAAU,CAAC,IAAY,EAAE,GAAG,IAAe;QACzC,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,KAAK,GAAI,IAAI,CAAC,KAA2D,CAC7E,SAAS,CACV,CAAC;QAEF,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,UAAU,IAAI,2BAA2B,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;QAChF,CAAC;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;QACrD,OAAQ,MAAe,IAAI,IAAI,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,SAAS;QACb,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,KAEb,CAAC;QACZ,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAU,CAAC;QAC7D,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IACzB,CAAC;CACF;AAED,MAAM,UAAU,iBAAiB,CAC/B,OAA0B,EAC1B,MAAqB;IAErB,IAAI,OAAO,GAAG,OAAO,CAAC;IACtB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,GAAG,MAAM,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { DatabaseConnection } from './connection.js';
2
+ import type { ModelQueryBuilder } from './model-query-builder.js';
3
+ import type { RowValue } from './types.js';
4
+ export type ModelAttributes = Record<string, unknown>;
5
+ export interface ModelStatic {
6
+ new (attributes?: ModelAttributes): unknown;
7
+ name: string;
8
+ table: string;
9
+ primaryKey: string;
10
+ getConnection(): DatabaseConnection;
11
+ query(): ModelQueryBuilder;
12
+ find(id: RowValue): Promise<unknown | null>;
13
+ }
14
+ //# sourceMappingURL=model-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-types.d.ts","sourceRoot":"","sources":["../src/model-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEtD,MAAM,WAAW,WAAW;IAC1B,KAAK,UAAU,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,IAAI,kBAAkB,CAAC;IACpC,KAAK,IAAI,iBAAiB,CAAC;IAC3B,IAAI,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CAC7C"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=model-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-types.js","sourceRoot":"","sources":["../src/model-types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,41 @@
1
+ import { ModelQueryBuilder } from './model-query-builder.js';
2
+ import type { ModelStatic } from './model-types.js';
3
+ import { BelongsToManyRelation } from './relations/belongs-to-many.js';
4
+ import { BelongsToRelation } from './relations/belongs-to.js';
5
+ import { HasManyRelation } from './relations/has-many.js';
6
+ import { HasOneRelation } from './relations/has-one.js';
7
+ import type { DatabaseConnection } from './connection.js';
8
+ import type { GlobalScope } from './scopes.js';
9
+ import type { RowValue } from './types.js';
10
+ type ModelAttributes = Record<string, unknown>;
11
+ export declare class Model<T extends ModelAttributes = ModelAttributes> {
12
+ static table: string;
13
+ static primaryKey: string;
14
+ private static resolver;
15
+ private static globalScopes;
16
+ protected attributes: Partial<T>;
17
+ constructor(attributes?: Partial<T>);
18
+ static setConnectionResolver(resolver: () => DatabaseConnection): void;
19
+ static useConnection(connection: DatabaseConnection): void;
20
+ static addGlobalScope(scope: GlobalScope): void;
21
+ static getConnection(): DatabaseConnection;
22
+ static query(): ModelQueryBuilder;
23
+ static scope(name: string, ...args: unknown[]): ModelQueryBuilder;
24
+ static find<TModel extends Model>(this: new (attributes?: Partial<ModelAttributes>) => TModel, id: RowValue): Promise<TModel | null>;
25
+ static all<TModel extends Model>(this: new (attributes?: Partial<ModelAttributes>) => TModel): Promise<TModel[]>;
26
+ static create<TModel extends Model>(this: new (attributes?: Partial<ModelAttributes>) => TModel, attributes: Partial<ModelAttributes>): Promise<TModel>;
27
+ static where(column: string, operatorOrValue?: RowValue | string, value?: RowValue): ModelQueryBuilder;
28
+ hasMany<Related extends Model>(RelatedModel: ModelStatic, foreignKey?: string, localKey?: string): HasManyRelation<Related>;
29
+ hasOne<Related extends Model>(RelatedModel: ModelStatic, foreignKey?: string, localKey?: string): HasOneRelation<Related>;
30
+ belongsTo<Related extends Model>(RelatedModel: ModelStatic, foreignKey?: string, ownerKey?: string): BelongsToRelation<Related>;
31
+ belongsToMany<Related extends Model>(RelatedModel: ModelStatic, pivotTable?: string, foreignPivotKey?: string, relatedPivotKey?: string, parentKey?: string, relatedKey?: string): BelongsToManyRelation<Related>;
32
+ getAttribute<K extends keyof T>(key: K): T[K] | undefined;
33
+ setAttribute<K extends keyof T>(key: K, value: T[K]): void;
34
+ toJSON(): Partial<T>;
35
+ save(): Promise<this>;
36
+ update(attributes: Partial<ModelAttributes>): Promise<this>;
37
+ delete(): Promise<void>;
38
+ fresh<TModel extends Model>(): Promise<TModel | null>;
39
+ }
40
+ export {};
41
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}