@tyravel/database 0.1.0 → 0.2.1

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 (80) hide show
  1. package/dist/eager-loader.d.ts +6 -0
  2. package/dist/eager-loader.d.ts.map +1 -0
  3. package/dist/eager-loader.js +23 -0
  4. package/dist/eager-loader.js.map +1 -0
  5. package/dist/eager-loading.test.d.ts +2 -0
  6. package/dist/eager-loading.test.d.ts.map +1 -0
  7. package/dist/eager-loading.test.js +150 -0
  8. package/dist/eager-loading.test.js.map +1 -0
  9. package/dist/factory-helpers.d.ts +7 -0
  10. package/dist/factory-helpers.d.ts.map +1 -0
  11. package/dist/factory-helpers.js +23 -0
  12. package/dist/factory-helpers.js.map +1 -0
  13. package/dist/factory.d.ts +12 -0
  14. package/dist/factory.d.ts.map +1 -0
  15. package/dist/factory.js +25 -0
  16. package/dist/factory.js.map +1 -0
  17. package/dist/factory.test.d.ts +2 -0
  18. package/dist/factory.test.d.ts.map +1 -0
  19. package/dist/factory.test.js +53 -0
  20. package/dist/factory.test.js.map +1 -0
  21. package/dist/index.d.ts +5 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +5 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/migrator.d.ts.map +1 -1
  26. package/dist/migrator.js +11 -12
  27. package/dist/migrator.js.map +1 -1
  28. package/dist/model-query-builder.d.ts +3 -0
  29. package/dist/model-query-builder.d.ts.map +1 -1
  30. package/dist/model-query-builder.js +17 -1
  31. package/dist/model-query-builder.js.map +1 -1
  32. package/dist/model.d.ts +5 -0
  33. package/dist/model.d.ts.map +1 -1
  34. package/dist/model.js +14 -0
  35. package/dist/model.js.map +1 -1
  36. package/dist/relations/belongs-to-many.d.ts +8 -0
  37. package/dist/relations/belongs-to-many.d.ts.map +1 -1
  38. package/dist/relations/belongs-to-many.js +49 -0
  39. package/dist/relations/belongs-to-many.js.map +1 -1
  40. package/dist/relations/belongs-to.d.ts +7 -0
  41. package/dist/relations/belongs-to.d.ts.map +1 -1
  42. package/dist/relations/belongs-to.js +33 -2
  43. package/dist/relations/belongs-to.js.map +1 -1
  44. package/dist/relations/has-many.d.ts +5 -0
  45. package/dist/relations/has-many.d.ts.map +1 -1
  46. package/dist/relations/has-many.js +32 -0
  47. package/dist/relations/has-many.js.map +1 -1
  48. package/dist/relations/has-one.d.ts +5 -0
  49. package/dist/relations/has-one.d.ts.map +1 -1
  50. package/dist/relations/has-one.js +28 -0
  51. package/dist/relations/has-one.js.map +1 -1
  52. package/dist/relations/relation.d.ts +6 -0
  53. package/dist/relations/relation.d.ts.map +1 -1
  54. package/dist/relations/relation.js +15 -0
  55. package/dist/relations/relation.js.map +1 -1
  56. package/dist/schema/blueprint.d.ts +6 -1
  57. package/dist/schema/blueprint.d.ts.map +1 -1
  58. package/dist/schema/blueprint.js +88 -13
  59. package/dist/schema/blueprint.js.map +1 -1
  60. package/dist/schema/blueprint.test.d.ts +2 -0
  61. package/dist/schema/blueprint.test.d.ts.map +1 -0
  62. package/dist/schema/blueprint.test.js +36 -0
  63. package/dist/schema/blueprint.test.js.map +1 -0
  64. package/dist/schema/schema-builder.d.ts +2 -0
  65. package/dist/schema/schema-builder.d.ts.map +1 -1
  66. package/dist/schema/schema-builder.js +53 -3
  67. package/dist/schema/schema-builder.js.map +1 -1
  68. package/dist/seeder-runner.d.ts +10 -0
  69. package/dist/seeder-runner.d.ts.map +1 -0
  70. package/dist/seeder-runner.js +52 -0
  71. package/dist/seeder-runner.js.map +1 -0
  72. package/dist/seeder-runner.test.d.ts +2 -0
  73. package/dist/seeder-runner.test.d.ts.map +1 -0
  74. package/dist/seeder-runner.test.js +58 -0
  75. package/dist/seeder-runner.test.js.map +1 -0
  76. package/dist/seeder.d.ts +5 -0
  77. package/dist/seeder.d.ts.map +1 -0
  78. package/dist/seeder.js +6 -0
  79. package/dist/seeder.js.map +1 -0
  80. package/package.json +1 -1
@@ -0,0 +1,6 @@
1
+ import type { Model } from './model.js';
2
+ import type { ModelStatic } from './model-types.js';
3
+ export declare class EagerLoader {
4
+ static load(parents: Model[], relations: string[], ModelClass: ModelStatic): Promise<void>;
5
+ }
6
+ //# sourceMappingURL=eager-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eager-loader.d.ts","sourceRoot":"","sources":["../src/eager-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGpD,qBAAa,WAAW;WACT,IAAI,CACf,OAAO,EAAE,KAAK,EAAE,EAChB,SAAS,EAAE,MAAM,EAAE,EACnB,UAAU,EAAE,WAAW,GACtB,OAAO,CAAC,IAAI,CAAC;CA2BjB"}
@@ -0,0 +1,23 @@
1
+ export class EagerLoader {
2
+ static async load(parents, relations, ModelClass) {
3
+ if (parents.length === 0 || relations.length === 0) {
4
+ return;
5
+ }
6
+ const instance = new ModelClass();
7
+ for (const relationName of relations) {
8
+ const relationMethod = instance[relationName];
9
+ if (typeof relationMethod !== 'function') {
10
+ throw new Error(`Relation [${relationName}] not defined on model [${ModelClass.name}].`);
11
+ }
12
+ const relation = relationMethod.call(instance);
13
+ relation.initRelation(parents, relationName);
14
+ const keys = relation.eagerLoadKeys(parents);
15
+ if (keys.length === 0) {
16
+ continue;
17
+ }
18
+ const results = await relation.eagerLoad(keys);
19
+ relation.matchEager(parents, results, relationName);
20
+ }
21
+ }
22
+ }
23
+ //# sourceMappingURL=eager-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eager-loader.js","sourceRoot":"","sources":["../src/eager-loader.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,WAAW;IACtB,MAAM,CAAC,KAAK,CAAC,IAAI,CACf,OAAgB,EAChB,SAAmB,EACnB,UAAuB;QAEvB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnD,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,IAAK,UAA8B,EAAE,CAAC;QAEvD,KAAK,MAAM,YAAY,IAAI,SAAS,EAAE,CAAC;YACrC,MAAM,cAAc,GAAI,QAA+C,CAAC,YAAY,CAAC,CAAC;YACtF,IAAI,OAAO,cAAc,KAAK,UAAU,EAAE,CAAC;gBACzC,MAAM,IAAI,KAAK,CACb,aAAa,YAAY,2BAA2B,UAAU,CAAC,IAAI,IAAI,CACxE,CAAC;YACJ,CAAC;YAED,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAa,CAAC;YAC3D,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAE7C,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YAC7C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtB,SAAS;YACX,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC/C,QAAQ,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=eager-loading.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eager-loading.test.d.ts","sourceRoot":"","sources":["../src/eager-loading.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,150 @@
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
+ posts() {
7
+ return this.hasMany(Post);
8
+ }
9
+ latestPost() {
10
+ return this.hasOne(Post);
11
+ }
12
+ roles() {
13
+ return this.belongsToMany(Role);
14
+ }
15
+ }
16
+ class Post extends Model {
17
+ static table = 'posts';
18
+ user() {
19
+ return this.belongsTo(User);
20
+ }
21
+ }
22
+ class Role extends Model {
23
+ static table = 'roles';
24
+ }
25
+ function trackQueries(connection) {
26
+ let queryCount = 0;
27
+ const originalQuery = connection.query.bind(connection);
28
+ connection.query = async (sql, bindings) => {
29
+ queryCount++;
30
+ return originalQuery(sql, bindings);
31
+ };
32
+ return {
33
+ count: () => queryCount,
34
+ };
35
+ }
36
+ describe('eager loading', () => {
37
+ const connection = new SqliteConnection(':memory:');
38
+ beforeAll(async () => {
39
+ User.useConnection(connection);
40
+ Post.useConnection(connection);
41
+ Role.useConnection(connection);
42
+ await connection.exec(`
43
+ CREATE TABLE "users" (
44
+ "id" INTEGER PRIMARY KEY AUTOINCREMENT,
45
+ "name" TEXT NOT NULL
46
+ );
47
+ CREATE TABLE "posts" (
48
+ "id" INTEGER PRIMARY KEY AUTOINCREMENT,
49
+ "user_id" INTEGER NOT NULL,
50
+ "title" TEXT NOT NULL
51
+ );
52
+ CREATE TABLE "roles" (
53
+ "id" INTEGER PRIMARY KEY AUTOINCREMENT,
54
+ "name" TEXT NOT NULL
55
+ );
56
+ CREATE TABLE "user_role" (
57
+ "user_id" INTEGER NOT NULL,
58
+ "role_id" INTEGER NOT NULL
59
+ );
60
+ `);
61
+ });
62
+ it('eager loads hasMany relations without N+1 queries', async () => {
63
+ const ada = await User.create({ name: 'Ada' });
64
+ const grace = await User.create({ name: 'Grace' });
65
+ await Post.create({ user_id: ada.getAttribute('id'), title: 'Ada 1' });
66
+ await Post.create({ user_id: ada.getAttribute('id'), title: 'Ada 2' });
67
+ await Post.create({ user_id: grace.getAttribute('id'), title: 'Grace 1' });
68
+ const tracker = trackQueries(connection);
69
+ const users = await User.query()
70
+ .whereIn('id', [ada.getAttribute('id'), grace.getAttribute('id')])
71
+ .with('posts')
72
+ .getModels();
73
+ expect(tracker.count()).toBe(2);
74
+ expect(users).toHaveLength(2);
75
+ expect(users.every((user) => user.relationLoaded('posts'))).toBe(true);
76
+ const adaPosts = users
77
+ .find((user) => user.getAttribute('name') === 'Ada')
78
+ ?.getRelation('posts');
79
+ const gracePosts = users
80
+ .find((user) => user.getAttribute('name') === 'Grace')
81
+ ?.getRelation('posts');
82
+ expect(adaPosts).toHaveLength(2);
83
+ expect(gracePosts).toHaveLength(1);
84
+ expect(adaPosts?.map((post) => post.getAttribute('title')).sort()).toEqual([
85
+ 'Ada 1',
86
+ 'Ada 2',
87
+ ]);
88
+ });
89
+ it('eager loads hasOne relations', async () => {
90
+ const user = await User.create({ name: 'Katherine' });
91
+ await Post.create({ user_id: user.getAttribute('id'), title: 'Only' });
92
+ const tracker = trackQueries(connection);
93
+ const loaded = await User.query()
94
+ .where('id', user.getAttribute('id'))
95
+ .with('latestPost')
96
+ .firstModel();
97
+ expect(tracker.count()).toBe(2);
98
+ expect(loaded?.relationLoaded('latestPost')).toBe(true);
99
+ expect(loaded?.getRelation('latestPost')?.getAttribute('title')).toBe('Only');
100
+ });
101
+ it('eager loads belongsTo relations', async () => {
102
+ const ada = await User.create({ name: 'Ada' });
103
+ const grace = await User.create({ name: 'Grace' });
104
+ const adaPost = await Post.create({
105
+ user_id: ada.getAttribute('id'),
106
+ title: 'Ada eager post',
107
+ });
108
+ const gracePost = await Post.create({
109
+ user_id: grace.getAttribute('id'),
110
+ title: 'Grace eager post',
111
+ });
112
+ const tracker = trackQueries(connection);
113
+ const posts = await Post.query()
114
+ .whereIn('id', [adaPost.getAttribute('id'), gracePost.getAttribute('id')])
115
+ .with('user')
116
+ .getModels();
117
+ expect(tracker.count()).toBe(2);
118
+ expect(posts).toHaveLength(2);
119
+ expect(posts.every((post) => post.relationLoaded('user'))).toBe(true);
120
+ expect(posts
121
+ .map((post) => post.getRelation('user')?.getAttribute('name'))
122
+ .sort()).toEqual(['Ada', 'Grace']);
123
+ });
124
+ it('eager loads belongsToMany relations', async () => {
125
+ const user = await User.create({ name: 'Alan' });
126
+ const admin = await Role.create({ name: 'admin' });
127
+ const editor = await Role.create({ name: 'editor' });
128
+ await connection.query('INSERT INTO "user_role" ("user_id", "role_id") VALUES (?, ?), (?, ?)', [
129
+ user.getAttribute('id'),
130
+ admin.getAttribute('id'),
131
+ user.getAttribute('id'),
132
+ editor.getAttribute('id'),
133
+ ]);
134
+ const tracker = trackQueries(connection);
135
+ const users = await User.query()
136
+ .where('id', user.getAttribute('id'))
137
+ .with('roles')
138
+ .getModels();
139
+ expect(tracker.count()).toBe(2);
140
+ expect(users[0]?.relationLoaded('roles')).toBe(true);
141
+ expect(users[0]?.getRelation('roles')?.map((role) => role.getAttribute('name')).sort()).toEqual([
142
+ 'admin',
143
+ 'editor',
144
+ ]);
145
+ });
146
+ it('throws when eager loading an undefined relation', async () => {
147
+ await expect(User.with('missing').getModels()).rejects.toThrow('Relation [missing] not defined on model [User].');
148
+ });
149
+ });
150
+ //# sourceMappingURL=eager-loading.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eager-loading.test.js","sourceRoot":"","sources":["../src/eager-loading.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare function resetFactoryHelpers(): void;
2
+ export declare function fakeSequence(): number;
3
+ export declare function fakeEmail(prefix?: string): string;
4
+ export declare function fakeName(): string;
5
+ export declare function fakeSlug(prefix?: string): string;
6
+ export declare function fakeText(wordCount?: number): string;
7
+ //# sourceMappingURL=factory-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory-helpers.d.ts","sourceRoot":"","sources":["../src/factory-helpers.ts"],"names":[],"mappings":"AAEA,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wBAAgB,YAAY,IAAI,MAAM,CAGrC;AAED,wBAAgB,SAAS,CAAC,MAAM,SAAS,GAAG,MAAM,CAEjD;AAED,wBAAgB,QAAQ,IAAI,MAAM,CAIjC;AAED,wBAAgB,QAAQ,CAAC,MAAM,SAAS,GAAG,MAAM,CAEhD;AAED,wBAAgB,QAAQ,CAAC,SAAS,SAAI,GAAG,MAAM,CAI9C"}
@@ -0,0 +1,23 @@
1
+ let sequence = 0;
2
+ export function resetFactoryHelpers() {
3
+ sequence = 0;
4
+ }
5
+ export function fakeSequence() {
6
+ sequence += 1;
7
+ return sequence;
8
+ }
9
+ export function fakeEmail(prefix = 'user') {
10
+ return `${prefix}.${fakeSequence()}.${Date.now()}@example.com`;
11
+ }
12
+ export function fakeName() {
13
+ const names = ['Ada', 'Grace', 'Alan', 'Katherine', 'Linus', 'Margaret'];
14
+ const index = (fakeSequence() - 1) % names.length;
15
+ return names[index] ?? `User ${fakeSequence()}`;
16
+ }
17
+ export function fakeSlug(prefix = 'item') {
18
+ return `${prefix}-${fakeSequence()}`;
19
+ }
20
+ export function fakeText(wordCount = 3) {
21
+ return Array.from({ length: wordCount }, (_, index) => `word${fakeSequence() + index}`).join(' ');
22
+ }
23
+ //# sourceMappingURL=factory-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory-helpers.js","sourceRoot":"","sources":["../src/factory-helpers.ts"],"names":[],"mappings":"AAAA,IAAI,QAAQ,GAAG,CAAC,CAAC;AAEjB,MAAM,UAAU,mBAAmB;IACjC,QAAQ,GAAG,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,QAAQ,IAAI,CAAC,CAAC;IACd,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAM,GAAG,MAAM;IACvC,OAAO,GAAG,MAAM,IAAI,YAAY,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IACzE,MAAM,KAAK,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;IAClD,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,QAAQ,YAAY,EAAE,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,MAAM,GAAG,MAAM;IACtC,OAAO,GAAG,MAAM,IAAI,YAAY,EAAE,EAAE,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,SAAS,GAAG,CAAC;IACpC,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,YAAY,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,IAAI,CAC1F,GAAG,CACJ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { Model } from './model.js';
2
+ import type { ModelAttributes } from './model-types.js';
3
+ export declare abstract class Factory<TModel extends Model = Model, TAttributes extends ModelAttributes = ModelAttributes> {
4
+ protected abstract readonly ModelClass: new (attributes?: Partial<TAttributes>) => TModel;
5
+ abstract definition(): Partial<TAttributes>;
6
+ private pendingCount;
7
+ count(amount: number): this;
8
+ make(attributes?: Partial<TAttributes>): TModel;
9
+ makeMany(count: number, attributes?: Partial<TAttributes>): TModel[];
10
+ create(attributes?: Partial<TAttributes>): Promise<TModel | TModel[]>;
11
+ }
12
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,8BAAsB,OAAO,CAC3B,MAAM,SAAS,KAAK,GAAG,KAAK,EAC5B,WAAW,SAAS,eAAe,GAAG,eAAe;IAErD,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,EAAE,KAAK,UAAU,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,MAAM,CAAC;IAE1F,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC;IAE3C,OAAO,CAAC,YAAY,CAAK;IAEzB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK3B,IAAI,CAAC,UAAU,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,MAAM;IAInD,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,MAAM,EAAE;IAIlE,MAAM,CAAC,UAAU,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,OAAO,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;CAahF"}
@@ -0,0 +1,25 @@
1
+ export class Factory {
2
+ pendingCount = 1;
3
+ count(amount) {
4
+ this.pendingCount = amount;
5
+ return this;
6
+ }
7
+ make(attributes = {}) {
8
+ return new this.ModelClass({ ...this.definition(), ...attributes });
9
+ }
10
+ makeMany(count, attributes = {}) {
11
+ return Array.from({ length: count }, () => this.make(attributes));
12
+ }
13
+ async create(attributes = {}) {
14
+ const count = this.pendingCount;
15
+ this.pendingCount = 1;
16
+ const models = [];
17
+ for (let index = 0; index < count; index += 1) {
18
+ const model = this.make(attributes);
19
+ await model.save();
20
+ models.push(model);
21
+ }
22
+ return count === 1 ? models[0] : models;
23
+ }
24
+ }
25
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAGA,MAAM,OAAgB,OAAO;IAQnB,YAAY,GAAG,CAAC,CAAC;IAEzB,KAAK,CAAC,MAAc;QAClB,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,aAAmC,EAAE;QACxC,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,QAAQ,CAAC,KAAa,EAAE,aAAmC,EAAE;QAC3D,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,aAAmC,EAAE;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC;QAChC,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QAEtB,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACpC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QAED,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IAC3C,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=factory.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.test.d.ts","sourceRoot":"","sources":["../src/factory.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,53 @@
1
+ import { afterEach, beforeAll, describe, expect, it } from 'vitest';
2
+ import { fakeEmail, fakeName, resetFactoryHelpers } from './factory-helpers.js';
3
+ import { Factory } from './factory.js';
4
+ import { Model } from './model.js';
5
+ import { SqliteConnection } from './sqlite-connection.js';
6
+ class User extends Model {
7
+ static table = 'users';
8
+ }
9
+ class UserFactory extends Factory {
10
+ ModelClass = User;
11
+ definition() {
12
+ return {
13
+ name: fakeName(),
14
+ email: fakeEmail(),
15
+ };
16
+ }
17
+ }
18
+ describe('Factory', () => {
19
+ const connection = new SqliteConnection(':memory:');
20
+ const userFactory = new UserFactory();
21
+ afterEach(() => {
22
+ resetFactoryHelpers();
23
+ });
24
+ beforeAll(async () => {
25
+ User.useConnection(connection);
26
+ await connection.exec(`
27
+ CREATE TABLE "users" (
28
+ "id" INTEGER PRIMARY KEY AUTOINCREMENT,
29
+ "name" TEXT NOT NULL,
30
+ "email" TEXT NOT NULL
31
+ );
32
+ `);
33
+ });
34
+ it('makes unsaved model instances', () => {
35
+ const user = userFactory.make({ name: 'Ada' });
36
+ expect(user.getAttribute('name')).toBe('Ada');
37
+ expect(user.getAttribute('id')).toBeUndefined();
38
+ });
39
+ it('creates persisted models', async () => {
40
+ const user = (await userFactory.create());
41
+ expect(user.getAttribute('id')).toBeDefined();
42
+ expect(user.getAttribute('email')).toContain('@example.com');
43
+ const found = await User.find(user.getAttribute('id'));
44
+ expect(found?.getAttribute('name')).toBe(user.getAttribute('name'));
45
+ });
46
+ it('creates multiple models with count()', async () => {
47
+ const users = (await userFactory.count(3).create());
48
+ expect(users).toHaveLength(3);
49
+ const emails = users.map((user) => user.getAttribute('email'));
50
+ expect(new Set(emails).size).toBe(3);
51
+ });
52
+ });
53
+ //# sourceMappingURL=factory.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.test.js","sourceRoot":"","sources":["../src/factory.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAS1D,MAAM,IAAK,SAAQ,KAAc;IAC/B,MAAM,CAAU,KAAK,GAAG,OAAO,CAAC;;AAGlC,MAAM,WAAY,SAAQ,OAAsB;IAC3B,UAAU,GAAG,IAAI,CAAC;IAErC,UAAU;QACR,OAAO;YACL,IAAI,EAAE,QAAQ,EAAE;YAChB,KAAK,EAAE,SAAS,EAAE;SACnB,CAAC;IACJ,CAAC;CACF;AAED,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,UAAU,CAAC,CAAC;IACpD,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;IAEtC,SAAS,CAAC,GAAG,EAAE;QACb,mBAAmB,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QAC/B,MAAM,UAAU,CAAC,IAAI,CAAC;;;;;;KAMrB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,IAAI,GAAG,CAAC,MAAM,WAAW,CAAC,MAAM,EAAE,CAAS,CAAC;QAClD,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAE7D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAE,CAAC,CAAC;QACxD,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,KAAK,GAAG,CAAC,MAAM,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAW,CAAC;QAC9D,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAE9B,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;QAC/D,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,9 +1,13 @@
1
1
  export type { DatabaseConnection, QueryResult } from './connection.js';
2
2
  export { DatabaseManager } from './database-manager.js';
3
+ export { Factory } from './factory.js';
4
+ export { fakeEmail, fakeName, fakeSequence, fakeSlug, fakeText, resetFactoryHelpers, } from './factory-helpers.js';
3
5
  export { MysqlGrammar, PostgresGrammar, SqliteGrammar, } from './grammar.js';
4
6
  export type { DriverName, SqlGrammar } from './grammar.js';
5
7
  export { Migration } from './migration.js';
6
8
  export { Migrator } from './migrator.js';
9
+ export { Seeder } from './seeder.js';
10
+ export { SeederRunner } from './seeder-runner.js';
7
11
  export { Model } from './model.js';
8
12
  export { ModelQueryBuilder } from './model-query-builder.js';
9
13
  export { QueryBuilder } from './query-builder.js';
@@ -13,7 +17,7 @@ export { HasManyRelation } from './relations/has-many.js';
13
17
  export { HasOneRelation } from './relations/has-one.js';
14
18
  export { Relation } from './relations/relation.js';
15
19
  export { Blueprint } from './schema/blueprint.js';
16
- export { SchemaBuilder } from './schema/schema-builder.js';
20
+ export { SchemaBuilder, migrationsTableSql } from './schema/schema-builder.js';
17
21
  export type { GlobalScope, LocalScope } from './scopes.js';
18
22
  export { MysqlConnection } from './mysql-connection.js';
19
23
  export { PostgresConnection } from './postgres-connection.js';
@@ -1 +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"}
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,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EACL,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,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,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,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,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAC/E,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 CHANGED
@@ -1,7 +1,11 @@
1
1
  export { DatabaseManager } from './database-manager.js';
2
+ export { Factory } from './factory.js';
3
+ export { fakeEmail, fakeName, fakeSequence, fakeSlug, fakeText, resetFactoryHelpers, } from './factory-helpers.js';
2
4
  export { MysqlGrammar, PostgresGrammar, SqliteGrammar, } from './grammar.js';
3
5
  export { Migration } from './migration.js';
4
6
  export { Migrator } from './migrator.js';
7
+ export { Seeder } from './seeder.js';
8
+ export { SeederRunner } from './seeder-runner.js';
5
9
  export { Model } from './model.js';
6
10
  export { ModelQueryBuilder } from './model-query-builder.js';
7
11
  export { QueryBuilder } from './query-builder.js';
@@ -11,7 +15,7 @@ export { HasManyRelation } from './relations/has-many.js';
11
15
  export { HasOneRelation } from './relations/has-one.js';
12
16
  export { Relation } from './relations/relation.js';
13
17
  export { Blueprint } from './schema/blueprint.js';
14
- export { SchemaBuilder } from './schema/schema-builder.js';
18
+ export { SchemaBuilder, migrationsTableSql } from './schema/schema-builder.js';
15
19
  export { MysqlConnection } from './mysql-connection.js';
16
20
  export { PostgresConnection } from './postgres-connection.js';
17
21
  export { SqliteConnection } from './sqlite-connection.js';
package/dist/index.js.map CHANGED
@@ -1 +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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EACL,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,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,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,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,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAE/E,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -1 +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"}
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;IAItC,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAM5B,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YAsBhB,QAAQ;YAQR,WAAW;IAUzB,OAAO,CAAC,KAAK;YAUC,IAAI;YAcJ,MAAM;CAMrB"}
package/dist/migrator.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { readdirSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import { pathToFileURL } from 'node:url';
4
- import { SchemaBuilder } from './schema/schema-builder.js';
4
+ import { migrationsTableSql, SchemaBuilder } from './schema/schema-builder.js';
5
5
  export class Migrator {
6
6
  connection;
7
7
  migrationsPath;
@@ -10,14 +10,7 @@ export class Migrator {
10
10
  this.migrationsPath = migrationsPath;
11
11
  }
12
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
- `);
13
+ await this.connection.exec(migrationsTableSql(this.connection.grammar));
21
14
  }
22
15
  async pending() {
23
16
  await this.ensureMigrationsTable();
@@ -43,11 +36,14 @@ export class Migrator {
43
36
  return ran;
44
37
  }
45
38
  async executed() {
46
- const result = await this.connection.query(`SELECT "migration" FROM "migrations" ORDER BY "id" ASC`);
39
+ const grammar = this.connection.grammar;
40
+ const result = await this.connection.query(`SELECT ${grammar.wrapIdentifier('migration')} FROM ${grammar.wrapIdentifier('migrations')} ORDER BY ${grammar.wrapIdentifier('id')} ASC`);
47
41
  return result.rows.map((row) => String(row.migration));
48
42
  }
49
43
  async latestBatch() {
50
- const result = await this.connection.query(`SELECT MAX("batch") as "batch" FROM "migrations"`);
44
+ const grammar = this.connection.grammar;
45
+ const batchColumn = grammar.wrapIdentifier('batch');
46
+ const result = await this.connection.query(`SELECT MAX(${batchColumn}) as ${batchColumn} FROM ${grammar.wrapIdentifier('migrations')}`);
51
47
  const batch = result.rows[0]?.batch;
52
48
  return typeof batch === 'number' ? batch : 0;
53
49
  }
@@ -71,7 +67,10 @@ export class Migrator {
71
67
  return MigrationClass;
72
68
  }
73
69
  async record(migration, batch) {
74
- await this.connection.query(`INSERT INTO "migrations" ("migration", "batch", "executed_at") VALUES (?, ?, ?)`, [migration, batch, new Date().toISOString()]);
70
+ const grammar = this.connection.grammar;
71
+ const table = grammar.wrapIdentifier('migrations');
72
+ const sql = `INSERT INTO ${table} (${grammar.wrapIdentifier('migration')}, ${grammar.wrapIdentifier('batch')}, ${grammar.wrapIdentifier('executed_at')}) VALUES (${grammar.parameter(1)}, ${grammar.parameter(2)}, ${grammar.parameter(3)})`;
73
+ await this.connection.query(sql, [migration, batch, new Date().toISOString()]);
75
74
  }
76
75
  }
77
76
  //# sourceMappingURL=migrator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"migrator.js","sourceRoot":"","sources":["../src/migrator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"migrator.js","sourceRoot":"","sources":["../src/migrator.ts"],"names":[],"mappings":"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"}
@@ -5,8 +5,11 @@ import type { ModelStatic } from './model-types.js';
5
5
  import { type GlobalScope } from './scopes.js';
6
6
  export declare class ModelQueryBuilder extends QueryBuilder {
7
7
  private readonly model;
8
+ protected eagerLoad: string[];
8
9
  constructor(connection: DatabaseConnection, tableName: string, model: ModelStatic);
10
+ with(...relations: string[]): this;
9
11
  clone(): ModelQueryBuilder;
12
+ protected copyTo(builder: QueryBuilder): void;
10
13
  applyScope(name: string, ...args: unknown[]): this;
11
14
  getModels<TModel extends Model>(): Promise<TModel[]>;
12
15
  firstModel<TModel extends Model>(): Promise<TModel | null>;
@@ -1 +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"}
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;AAE1D,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;IAM/C,OAAO,CAAC,QAAQ,CAAC,KAAK;IALxB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,CAAM;gBAGjC,UAAU,EAAE,kBAAkB,EAC9B,SAAS,EAAE,MAAM,EACA,KAAK,EAAE,WAAW;IAKrC,IAAI,CAAC,GAAG,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IAKzB,KAAK,IAAI,iBAAiB;cAUhB,MAAM,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAOtD,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;IAcpD,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"}
@@ -1,16 +1,28 @@
1
+ import { EagerLoader } from './eager-loader.js';
1
2
  import { QueryBuilder } from './query-builder.js';
2
3
  import { scopeMethodName } from './scopes.js';
3
4
  export class ModelQueryBuilder extends QueryBuilder {
4
5
  model;
6
+ eagerLoad = [];
5
7
  constructor(connection, tableName, model) {
6
8
  super(connection, tableName);
7
9
  this.model = model;
8
10
  }
11
+ with(...relations) {
12
+ this.eagerLoad.push(...relations);
13
+ return this;
14
+ }
9
15
  clone() {
10
16
  const builder = new ModelQueryBuilder(this.connection, this.getTableName(), this.model);
11
17
  this.copyTo(builder);
12
18
  return builder;
13
19
  }
20
+ copyTo(builder) {
21
+ super.copyTo(builder);
22
+ if (builder instanceof ModelQueryBuilder) {
23
+ builder.eagerLoad = [...this.eagerLoad];
24
+ }
25
+ }
14
26
  applyScope(name, ...args) {
15
27
  const scopeName = scopeMethodName(name);
16
28
  const scope = this.model[scopeName];
@@ -23,7 +35,11 @@ export class ModelQueryBuilder extends QueryBuilder {
23
35
  async getModels() {
24
36
  const rows = await this.get();
25
37
  const ModelClass = this.model;
26
- return rows.map((row) => new ModelClass(row));
38
+ const models = rows.map((row) => new ModelClass(row));
39
+ if (this.eagerLoad.length > 0) {
40
+ await EagerLoader.load(models, this.eagerLoad, this.model);
41
+ }
42
+ return models;
27
43
  }
28
44
  async firstModel() {
29
45
  const rows = await this.clone().limit(1).getModels();
@@ -1 +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"}
1
+ {"version":3,"file":"model-query-builder.js","sourceRoot":"","sources":["../src/model-query-builder.ts"],"names":[],"mappings":"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"}
package/dist/model.d.ts CHANGED
@@ -14,6 +14,7 @@ export declare class Model<T extends ModelAttributes = ModelAttributes> {
14
14
  private static resolver;
15
15
  private static globalScopes;
16
16
  protected attributes: Partial<T>;
17
+ private relations;
17
18
  constructor(attributes?: Partial<T>);
18
19
  static setConnectionResolver(resolver: () => DatabaseConnection): void;
19
20
  static useConnection(connection: DatabaseConnection): void;
@@ -24,11 +25,15 @@ export declare class Model<T extends ModelAttributes = ModelAttributes> {
24
25
  static find<TModel extends Model>(this: new (attributes?: Partial<ModelAttributes>) => TModel, id: RowValue): Promise<TModel | null>;
25
26
  static all<TModel extends Model>(this: new (attributes?: Partial<ModelAttributes>) => TModel): Promise<TModel[]>;
26
27
  static create<TModel extends Model>(this: new (attributes?: Partial<ModelAttributes>) => TModel, attributes: Partial<ModelAttributes>): Promise<TModel>;
28
+ static with(...relations: string[]): ModelQueryBuilder;
27
29
  static where(column: string, operatorOrValue?: RowValue | string, value?: RowValue): ModelQueryBuilder;
28
30
  hasMany<Related extends Model>(RelatedModel: ModelStatic, foreignKey?: string, localKey?: string): HasManyRelation<Related>;
29
31
  hasOne<Related extends Model>(RelatedModel: ModelStatic, foreignKey?: string, localKey?: string): HasOneRelation<Related>;
30
32
  belongsTo<Related extends Model>(RelatedModel: ModelStatic, foreignKey?: string, ownerKey?: string): BelongsToRelation<Related>;
31
33
  belongsToMany<Related extends Model>(RelatedModel: ModelStatic, pivotTable?: string, foreignPivotKey?: string, relatedPivotKey?: string, parentKey?: string, relatedKey?: string): BelongsToManyRelation<Related>;
34
+ setRelation(name: string, value: unknown): void;
35
+ getRelation<TRelation>(name: string): TRelation | undefined;
36
+ relationLoaded(name: string): boolean;
32
37
  getAttribute<K extends keyof T>(key: K): T[K] | undefined;
33
38
  setAttribute<K extends keyof T>(key: K, value: T[K]): void;
34
39
  toJSON(): Partial<T>;