orchid-orm 1.3.16 → 1.4.17

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 (38) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/index.d.ts +39 -32
  3. package/dist/index.esm.js +102 -100
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.js +102 -100
  6. package/dist/index.js.map +1 -1
  7. package/jest-setup.ts +4 -0
  8. package/package.json +8 -4
  9. package/src/appCodeUpdater/appCodeUpdater.ts +19 -0
  10. package/src/appCodeUpdater/fileChanges.ts +41 -0
  11. package/src/appCodeUpdater/testUtils.ts +31 -0
  12. package/src/appCodeUpdater/tsUtils.ts +137 -0
  13. package/src/appCodeUpdater/updateMainFile.test.ts +230 -0
  14. package/src/appCodeUpdater/updateMainFile.ts +163 -0
  15. package/src/appCodeUpdater/updateTableFile.ts +19 -0
  16. package/src/index.ts +5 -1
  17. package/src/orm.test.ts +13 -13
  18. package/src/orm.ts +21 -21
  19. package/src/relations/belongsTo.test.ts +1 -1
  20. package/src/relations/belongsTo.ts +2 -2
  21. package/src/relations/hasAndBelongsToMany.test.ts +1 -1
  22. package/src/relations/hasAndBelongsToMany.ts +9 -9
  23. package/src/relations/hasMany.test.ts +16 -10
  24. package/src/relations/hasMany.ts +6 -6
  25. package/src/relations/hasOne.test.ts +10 -10
  26. package/src/relations/hasOne.ts +6 -6
  27. package/src/relations/relations.ts +73 -71
  28. package/src/relations/utils.ts +3 -3
  29. package/src/repo.test.ts +29 -29
  30. package/src/repo.ts +6 -6
  31. package/src/{model.test.ts → table.test.ts} +15 -15
  32. package/src/{model.ts → table.ts} +17 -17
  33. package/src/test-utils/test-db.ts +15 -15
  34. package/src/test-utils/{test-models.ts → test-tables.ts} +42 -42
  35. package/src/transaction.test.ts +1 -1
  36. package/src/transaction.ts +4 -4
  37. package/src/utils.ts +9 -0
  38. package/tsconfig.json +1 -0
package/src/orm.test.ts CHANGED
@@ -6,21 +6,21 @@ import {
6
6
  useTestDatabase,
7
7
  } from './test-utils/test-utils';
8
8
  import { pgConfig } from './test-utils/test-db';
9
- import { createModel } from './model';
9
+ import { createBaseTable } from './table';
10
10
  import { columnTypes } from 'pqb';
11
11
 
12
12
  describe('orm', () => {
13
13
  useTestDatabase();
14
14
 
15
- const Model = createModel({
15
+ const BaseTable = createBaseTable({
16
16
  columnTypes: {
17
17
  ...columnTypes,
18
18
  text: (min = 0, max = Infinity) => columnTypes.text(min, max),
19
19
  },
20
20
  });
21
21
 
22
- type User = UserModel['columns']['type'];
23
- class UserModel extends Model {
22
+ type User = UserTable['columns']['type'];
23
+ class UserTable extends BaseTable {
24
24
  table = 'user';
25
25
  columns = this.setColumns((t) => ({
26
26
  id: t.serial().primaryKey(),
@@ -29,17 +29,17 @@ describe('orm', () => {
29
29
  }));
30
30
  }
31
31
 
32
- class ProfileModel extends Model {
32
+ class ProfileTable extends BaseTable {
33
33
  table = 'profile';
34
34
  columns = this.setColumns((t) => ({
35
35
  id: t.serial().primaryKey(),
36
36
  }));
37
37
  }
38
38
 
39
- it('should return object with provided adapter, close and transaction method, models', () => {
39
+ it('should return object with provided adapter, close and transaction method, tables', () => {
40
40
  const db = orchidORM(pgConfig, {
41
- user: UserModel,
42
- profile: ProfileModel,
41
+ user: UserTable,
42
+ profile: ProfileTable,
43
43
  });
44
44
 
45
45
  expect('$adapter' in db).toBe(true);
@@ -50,10 +50,10 @@ describe('orm', () => {
50
50
  );
51
51
  });
52
52
 
53
- it('should return model which is a queryable interface', async () => {
53
+ it('should return table which is a queryable interface', async () => {
54
54
  const db = orchidORM(pgConfig, {
55
- user: UserModel,
56
- profile: ProfileModel,
55
+ user: UserTable,
56
+ profile: ProfileTable,
57
57
  });
58
58
 
59
59
  const { id, name } = await db.user.create(userData);
@@ -80,8 +80,8 @@ describe('orm', () => {
80
80
  const db = orchidORM(
81
81
  { ...pgConfig, autoPreparedStatements: true },
82
82
  {
83
- user: UserModel,
84
- profile: ProfileModel,
83
+ user: UserTable,
84
+ profile: ProfileTable,
85
85
  },
86
86
  );
87
87
 
package/src/orm.ts CHANGED
@@ -8,12 +8,12 @@ import {
8
8
  anyShape,
9
9
  DbTableOptions,
10
10
  } from 'pqb';
11
- import { DbModel, Model, ModelClasses } from './model';
11
+ import { DbTable, Table, TableClasses } from './table';
12
12
  import { applyRelations } from './relations/relations';
13
13
  import { transaction } from './transaction';
14
14
 
15
- export type OrchidORM<T extends ModelClasses> = {
16
- [K in keyof T]: DbModel<T[K]>;
15
+ export type OrchidORM<T extends TableClasses> = {
16
+ [K in keyof T]: DbTable<T[K]>;
17
17
  } & {
18
18
  $transaction: typeof transaction;
19
19
  $adapter: Adapter;
@@ -21,7 +21,7 @@ export type OrchidORM<T extends ModelClasses> = {
21
21
  $close(): Promise<void>;
22
22
  };
23
23
 
24
- export const orchidORM = <T extends ModelClasses>(
24
+ export const orchidORM = <T extends TableClasses>(
25
25
  {
26
26
  log,
27
27
  logger,
@@ -33,7 +33,7 @@ export const orchidORM = <T extends ModelClasses>(
33
33
  autoPreparedStatements?: boolean;
34
34
  noPrimaryKey?: NoPrimaryKeyOption;
35
35
  },
36
- models: T,
36
+ tables: T,
37
37
  ): OrchidORM<T> => {
38
38
  const adapter = 'adapter' in options ? options.adapter : new Adapter(options);
39
39
  const commonOptions = {
@@ -57,42 +57,42 @@ export const orchidORM = <T extends ModelClasses>(
57
57
  $adapter: adapter,
58
58
  $queryBuilder: qb,
59
59
  $close: () => adapter.close(),
60
- } as unknown as OrchidORM<ModelClasses>;
60
+ } as unknown as OrchidORM<TableClasses>;
61
61
 
62
- const modelInstances: Record<string, Model> = {};
62
+ const tableInstances: Record<string, Table> = {};
63
63
 
64
- for (const key in models) {
64
+ for (const key in tables) {
65
65
  if (key[0] === '$') {
66
- throw new Error(`Model name must not start with $`);
66
+ throw new Error(`Table class name must not start with $`);
67
67
  }
68
68
 
69
- const model = new models[key]();
70
- modelInstances[key] = model;
69
+ const table = new tables[key]();
70
+ tableInstances[key] = table;
71
71
 
72
72
  const options: DbTableOptions = {
73
73
  ...commonOptions,
74
- schema: model.schema,
74
+ schema: table.schema,
75
75
  };
76
76
 
77
- if (model.noPrimaryKey) options.noPrimaryKey = 'ignore';
77
+ if (table.noPrimaryKey) options.noPrimaryKey = 'ignore';
78
78
 
79
- const dbModel = new Db(
79
+ const dbTable = new Db(
80
80
  adapter,
81
81
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
82
82
  qb as any,
83
- model.table,
84
- model.columns.shape,
85
- model.columnTypes,
83
+ table.table,
84
+ table.columns.shape,
85
+ table.columnTypes,
86
86
  options,
87
87
  );
88
88
 
89
- (dbModel as unknown as { definedAs: string }).definedAs = key;
90
- (dbModel as unknown as { db: unknown }).db = result;
89
+ (dbTable as unknown as { definedAs: string }).definedAs = key;
90
+ (dbTable as unknown as { db: unknown }).db = result;
91
91
 
92
- (result as Record<string, unknown>)[key] = dbModel;
92
+ (result as Record<string, unknown>)[key] = dbTable;
93
93
  }
94
94
 
95
- applyRelations(qb, modelInstances, result);
95
+ applyRelations(qb, tableInstances, result);
96
96
 
97
97
  return result as unknown as OrchidORM<T>;
98
98
  };
@@ -10,7 +10,7 @@ import {
10
10
  useTestDatabase,
11
11
  } from '../test-utils/test-utils';
12
12
  import { RelationQuery } from 'pqb';
13
- import { User } from '../test-utils/test-models';
13
+ import { User } from '../test-utils/test-tables';
14
14
 
15
15
  describe('belongsTo', () => {
16
16
  useTestDatabase();
@@ -1,4 +1,4 @@
1
- import { Model } from '../model';
1
+ import { Table } from '../table';
2
2
  import {
3
3
  addQueryOn,
4
4
  BelongsToRelation,
@@ -23,7 +23,7 @@ export interface BelongsTo extends RelationThunkBase {
23
23
  }
24
24
 
25
25
  export type BelongsToInfo<
26
- T extends Model,
26
+ T extends Table,
27
27
  Relation extends BelongsTo,
28
28
  FK extends string = Relation['options']['foreignKey'],
29
29
  > = {
@@ -9,7 +9,7 @@ import {
9
9
  useRelationCallback,
10
10
  } from '../test-utils/test-utils';
11
11
  import { RelationQuery, Sql, TransactionAdapter } from 'pqb';
12
- import { Chat, User } from '../test-utils/test-models';
12
+ import { Chat, User } from '../test-utils/test-tables';
13
13
 
14
14
  describe('hasAndBelongsToMany', () => {
15
15
  useTestDatabase();
@@ -1,5 +1,5 @@
1
1
  import { RelationData, RelationThunkBase } from './relations';
2
- import { Model } from '../model';
2
+ import { Table } from '../table';
3
3
  import {
4
4
  CreateCtx,
5
5
  getQueryAs,
@@ -25,7 +25,7 @@ export interface HasAndBelongsToMany extends RelationThunkBase {
25
25
  }
26
26
 
27
27
  export type HasAndBelongsToManyInfo<
28
- T extends Model,
28
+ T extends Table,
29
29
  Relation extends HasAndBelongsToMany,
30
30
  > = {
31
31
  params: Record<
@@ -89,7 +89,7 @@ class HasAndBelongsToManyVirtualColumn extends VirtualColumn {
89
89
  }
90
90
 
91
91
  export const makeHasAndBelongsToManyMethod = (
92
- model: Query,
92
+ table: Query,
93
93
  qb: Query,
94
94
  relation: HasAndBelongsToMany,
95
95
  relationName: string,
@@ -107,14 +107,14 @@ export const makeHasAndBelongsToManyMethod = (
107
107
  const associationForeignKeyFull = `${joinTable}.${afk}`;
108
108
  const associationPrimaryKeyFull = `${getQueryAs(query)}.${apk}`;
109
109
 
110
- const __model = Object.create(qb.__model);
111
- __model.__model = __model;
112
- __model.table = joinTable;
113
- __model.shape = {
114
- [fk]: model.shape[pk],
110
+ const __table = Object.create(qb.__table);
111
+ __table.__table = __table;
112
+ __table.table = joinTable;
113
+ __table.shape = {
114
+ [fk]: table.shape[pk],
115
115
  [afk]: query.shape[apk],
116
116
  };
117
- const subQuery = Object.create(__model);
117
+ const subQuery = Object.create(__table);
118
118
  subQuery.query = { ...subQuery.query };
119
119
 
120
120
  const state: State = {
@@ -9,7 +9,13 @@ import {
9
9
  useTestDatabase,
10
10
  } from '../test-utils/test-utils';
11
11
  import { RelationQuery } from 'pqb';
12
- import { Chat, Message, Model, Profile, User } from '../test-utils/test-models';
12
+ import {
13
+ Chat,
14
+ Message,
15
+ BaseTable,
16
+ Profile,
17
+ User,
18
+ } from '../test-utils/test-tables';
13
19
  import { orchidORM } from '../orm';
14
20
 
15
21
  describe('hasMany', () => {
@@ -1653,8 +1659,8 @@ describe('hasMany', () => {
1653
1659
  });
1654
1660
 
1655
1661
  describe('hasMany through', () => {
1656
- it('should resolve recursive situation when both models depends on each other', () => {
1657
- class Post extends Model {
1662
+ it('should resolve recursive situation when both tables depends on each other', () => {
1663
+ class Post extends BaseTable {
1658
1664
  table = 'post';
1659
1665
  columns = this.setColumns((t) => ({
1660
1666
  id: t.serial().primaryKey(),
@@ -1673,7 +1679,7 @@ describe('hasMany through', () => {
1673
1679
  };
1674
1680
  }
1675
1681
 
1676
- class Tag extends Model {
1682
+ class Tag extends BaseTable {
1677
1683
  table = 'tag';
1678
1684
  columns = this.setColumns((t) => ({
1679
1685
  id: t.serial().primaryKey(),
@@ -1692,7 +1698,7 @@ describe('hasMany through', () => {
1692
1698
  };
1693
1699
  }
1694
1700
 
1695
- class PostTag extends Model {
1701
+ class PostTag extends BaseTable {
1696
1702
  table = 'postTag';
1697
1703
  columns = this.setColumns((t) => ({
1698
1704
  postId: t.integer().foreignKey(() => Post, 'id'),
@@ -1730,7 +1736,7 @@ describe('hasMany through', () => {
1730
1736
  });
1731
1737
 
1732
1738
  it('should throw if through relation is not defined', () => {
1733
- class Post extends Model {
1739
+ class Post extends BaseTable {
1734
1740
  table = 'post';
1735
1741
  columns = this.setColumns((t) => ({
1736
1742
  id: t.serial().primaryKey(),
@@ -1744,7 +1750,7 @@ describe('hasMany through', () => {
1744
1750
  };
1745
1751
  }
1746
1752
 
1747
- class Tag extends Model {
1753
+ class Tag extends BaseTable {
1748
1754
  table = 'tag';
1749
1755
  columns = this.setColumns((t) => ({
1750
1756
  id: t.serial().primaryKey(),
@@ -1768,7 +1774,7 @@ describe('hasMany through', () => {
1768
1774
  });
1769
1775
 
1770
1776
  it('should throw if source relation is not defined', () => {
1771
- class Post extends Model {
1777
+ class Post extends BaseTable {
1772
1778
  table = 'post';
1773
1779
  columns = this.setColumns((t) => ({
1774
1780
  id: t.serial().primaryKey(),
@@ -1787,14 +1793,14 @@ describe('hasMany through', () => {
1787
1793
  };
1788
1794
  }
1789
1795
 
1790
- class Tag extends Model {
1796
+ class Tag extends BaseTable {
1791
1797
  table = 'tag';
1792
1798
  columns = this.setColumns((t) => ({
1793
1799
  id: t.serial().primaryKey(),
1794
1800
  }));
1795
1801
  }
1796
1802
 
1797
- class PostTag extends Model {
1803
+ class PostTag extends BaseTable {
1798
1804
  table = 'postTag';
1799
1805
  columns = this.setColumns((t) => ({
1800
1806
  postId: t.integer().foreignKey(() => Post, 'id'),
@@ -4,7 +4,7 @@ import {
4
4
  RelationThunkBase,
5
5
  RelationThunks,
6
6
  } from './relations';
7
- import { Model } from '../model';
7
+ import { Table } from '../table';
8
8
  import {
9
9
  addQueryOn,
10
10
  getQueryAs,
@@ -39,7 +39,7 @@ export interface HasMany extends RelationThunkBase {
39
39
  }
40
40
 
41
41
  export type HasManyInfo<
42
- T extends Model,
42
+ T extends Table,
43
43
  Relations extends RelationThunks,
44
44
  Relation extends HasMany,
45
45
  > = {
@@ -124,7 +124,7 @@ class HasManyVirtualColumn extends VirtualColumn {
124
124
  }
125
125
 
126
126
  export const makeHasManyMethod = (
127
- model: Query,
127
+ table: Query,
128
128
  relation: HasMany,
129
129
  relationName: string,
130
130
  query: Query,
@@ -132,12 +132,12 @@ export const makeHasManyMethod = (
132
132
  if ('through' in relation.options) {
133
133
  const { through, source } = relation.options;
134
134
 
135
- type ModelWithQueryMethod = Record<
135
+ type TableWithQueryMethod = Record<
136
136
  string,
137
137
  (params: Record<string, unknown>) => Query
138
138
  >;
139
139
 
140
- const throughRelation = getThroughRelation(model, through);
140
+ const throughRelation = getThroughRelation(table, through);
141
141
  const sourceRelation = getSourceRelation(throughRelation, source);
142
142
  const sourceRelationQuery = sourceRelation.query.as(relationName);
143
143
  const sourceQuery = sourceRelation.joinQuery(
@@ -150,7 +150,7 @@ export const makeHasManyMethod = (
150
150
  return {
151
151
  returns: 'many',
152
152
  method: (params: Record<string, unknown>) => {
153
- const throughQuery = (model as unknown as ModelWithQueryMethod)[
153
+ const throughQuery = (table as unknown as TableWithQueryMethod)[
154
154
  through
155
155
  ](params);
156
156
 
@@ -8,7 +8,7 @@ import {
8
8
  useRelationCallback,
9
9
  useTestDatabase,
10
10
  } from '../test-utils/test-utils';
11
- import { User, Profile, Model } from '../test-utils/test-models';
11
+ import { User, Profile, BaseTable } from '../test-utils/test-tables';
12
12
  import { RelationQuery } from 'pqb';
13
13
  import { orchidORM } from '../orm';
14
14
 
@@ -1264,8 +1264,8 @@ describe('hasOne', () => {
1264
1264
  });
1265
1265
 
1266
1266
  describe('hasOne through', () => {
1267
- it('should resolve recursive situation when both models depends on each other', () => {
1268
- class Post extends Model {
1267
+ it('should resolve recursive situation when both tables depends on each other', () => {
1268
+ class Post extends BaseTable {
1269
1269
  table = 'post';
1270
1270
  columns = this.setColumns((t) => ({
1271
1271
  id: t.serial().primaryKey(),
@@ -1284,7 +1284,7 @@ describe('hasOne through', () => {
1284
1284
  };
1285
1285
  }
1286
1286
 
1287
- class Tag extends Model {
1287
+ class Tag extends BaseTable {
1288
1288
  table = 'tag';
1289
1289
  columns = this.setColumns((t) => ({
1290
1290
  id: t.serial().primaryKey(),
@@ -1303,7 +1303,7 @@ describe('hasOne through', () => {
1303
1303
  };
1304
1304
  }
1305
1305
 
1306
- class PostTag extends Model {
1306
+ class PostTag extends BaseTable {
1307
1307
  table = 'postTag';
1308
1308
  columns = this.setColumns((t) => ({
1309
1309
  postId: t.integer().foreignKey(() => Post, 'id'),
@@ -1341,7 +1341,7 @@ describe('hasOne through', () => {
1341
1341
  });
1342
1342
 
1343
1343
  it('should throw if through relation is not defined', () => {
1344
- class Post extends Model {
1344
+ class Post extends BaseTable {
1345
1345
  table = 'post';
1346
1346
  columns = this.setColumns((t) => ({
1347
1347
  id: t.serial().primaryKey(),
@@ -1355,7 +1355,7 @@ describe('hasOne through', () => {
1355
1355
  };
1356
1356
  }
1357
1357
 
1358
- class Tag extends Model {
1358
+ class Tag extends BaseTable {
1359
1359
  table = 'tag';
1360
1360
  columns = this.setColumns((t) => ({
1361
1361
  id: t.serial().primaryKey(),
@@ -1379,7 +1379,7 @@ describe('hasOne through', () => {
1379
1379
  });
1380
1380
 
1381
1381
  it('should throw if source relation is not defined', () => {
1382
- class Post extends Model {
1382
+ class Post extends BaseTable {
1383
1383
  table = 'post';
1384
1384
  columns = this.setColumns((t) => ({
1385
1385
  id: t.serial().primaryKey(),
@@ -1398,14 +1398,14 @@ describe('hasOne through', () => {
1398
1398
  };
1399
1399
  }
1400
1400
 
1401
- class Tag extends Model {
1401
+ class Tag extends BaseTable {
1402
1402
  table = 'tag';
1403
1403
  columns = this.setColumns((t) => ({
1404
1404
  id: t.serial().primaryKey(),
1405
1405
  }));
1406
1406
  }
1407
1407
 
1408
- class PostTag extends Model {
1408
+ class PostTag extends BaseTable {
1409
1409
  table = 'postTag';
1410
1410
  columns = this.setColumns((t) => ({
1411
1411
  postId: t.integer().foreignKey(() => Post, 'id'),
@@ -13,7 +13,7 @@ import {
13
13
  WhereArg,
14
14
  WhereResult,
15
15
  } from 'pqb';
16
- import { Model } from '../model';
16
+ import { Table } from '../table';
17
17
  import {
18
18
  RelationData,
19
19
  RelationInfo,
@@ -36,7 +36,7 @@ export interface HasOne extends RelationThunkBase {
36
36
  }
37
37
 
38
38
  export type HasOneInfo<
39
- T extends Model,
39
+ T extends Table,
40
40
  Relations extends RelationThunks,
41
41
  Relation extends HasOne,
42
42
  > = {
@@ -121,7 +121,7 @@ class HasOneVirtualColumn extends VirtualColumn {
121
121
  }
122
122
 
123
123
  export const makeHasOneMethod = (
124
- model: Query,
124
+ table: Query,
125
125
  relation: HasOne,
126
126
  relationName: string,
127
127
  query: Query,
@@ -135,12 +135,12 @@ export const makeHasOneMethod = (
135
135
  if ('through' in relation.options) {
136
136
  const { through, source } = relation.options;
137
137
 
138
- type ModelWithQueryMethod = Record<
138
+ type TableWithQueryMethod = Record<
139
139
  string,
140
140
  (params: Record<string, unknown>) => Query
141
141
  >;
142
142
 
143
- const throughRelation = getThroughRelation(model, through);
143
+ const throughRelation = getThroughRelation(table, through);
144
144
  const sourceRelation = getSourceRelation(throughRelation, source);
145
145
  const sourceQuery = sourceRelation
146
146
  .joinQuery(throughRelation.query, sourceRelation.query)
@@ -151,7 +151,7 @@ export const makeHasOneMethod = (
151
151
  return {
152
152
  returns: 'one',
153
153
  method: (params: Record<string, unknown>) => {
154
- const throughQuery = (model as unknown as ModelWithQueryMethod)[
154
+ const throughQuery = (table as unknown as TableWithQueryMethod)[
155
155
  through
156
156
  ](params);
157
157