orchid-orm 1.3.16 → 1.4.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.d.ts +39 -32
- package/dist/index.esm.js +102 -100
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +102 -100
- package/dist/index.js.map +1 -1
- package/jest-setup.ts +4 -0
- package/package.json +8 -4
- package/src/appCodeUpdater/appCodeUpdater.ts +19 -0
- package/src/appCodeUpdater/fileChanges.ts +41 -0
- package/src/appCodeUpdater/testUtils.ts +31 -0
- package/src/appCodeUpdater/tsUtils.ts +137 -0
- package/src/appCodeUpdater/updateMainFile.test.ts +230 -0
- package/src/appCodeUpdater/updateMainFile.ts +163 -0
- package/src/appCodeUpdater/updateTableFile.ts +19 -0
- package/src/index.ts +5 -1
- package/src/orm.test.ts +13 -13
- package/src/orm.ts +21 -21
- package/src/relations/belongsTo.test.ts +1 -1
- package/src/relations/belongsTo.ts +2 -2
- package/src/relations/hasAndBelongsToMany.test.ts +1 -1
- package/src/relations/hasAndBelongsToMany.ts +9 -9
- package/src/relations/hasMany.test.ts +16 -10
- package/src/relations/hasMany.ts +6 -6
- package/src/relations/hasOne.test.ts +10 -10
- package/src/relations/hasOne.ts +6 -6
- package/src/relations/relations.ts +73 -71
- package/src/relations/utils.ts +3 -3
- package/src/repo.test.ts +29 -29
- package/src/repo.ts +6 -6
- package/src/{model.test.ts → table.test.ts} +15 -15
- package/src/{model.ts → table.ts} +17 -17
- package/src/test-utils/test-db.ts +15 -15
- package/src/test-utils/{test-models.ts → test-tables.ts} +42 -42
- package/src/transaction.test.ts +1 -1
- package/src/transaction.ts +4 -4
- package/src/utils.ts +9 -0
- package/tsconfig.json +1 -0
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
import { MapRelations, Relation, RelationThunks } from './relations/relations';
|
|
10
10
|
import { OrchidORM } from './orm';
|
|
11
11
|
|
|
12
|
-
export type
|
|
12
|
+
export type TableClass<T extends Table = Table> = new () => T;
|
|
13
13
|
|
|
14
|
-
export type
|
|
14
|
+
export type TableClasses = Record<string, TableClass>;
|
|
15
15
|
|
|
16
|
-
export type
|
|
16
|
+
export type TableToDb<T extends Table> = Db<
|
|
17
17
|
T['table'],
|
|
18
18
|
T['columns']['shape'],
|
|
19
19
|
'relations' extends keyof T
|
|
@@ -24,34 +24,34 @@ export type ModelToDb<T extends Model> = Db<
|
|
|
24
24
|
: Query['relations']
|
|
25
25
|
: Query['relations'],
|
|
26
26
|
T['columnTypes']
|
|
27
|
-
> & { definedAs: string; db: OrchidORM<
|
|
27
|
+
> & { definedAs: string; db: OrchidORM<TableClasses> };
|
|
28
28
|
|
|
29
|
-
export type
|
|
29
|
+
export type DbTable<T extends TableClass> = TableToDb<InstanceType<T>> &
|
|
30
30
|
Omit<MapRelations<InstanceType<T>>, keyof Query>;
|
|
31
31
|
|
|
32
|
-
type
|
|
32
|
+
type TableConfig = {
|
|
33
33
|
shape: ColumnsShape;
|
|
34
34
|
type: unknown;
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
type ScopeFn<Related extends
|
|
38
|
-
q:
|
|
37
|
+
type ScopeFn<Related extends TableClass, Scope extends Query> = (
|
|
38
|
+
q: DbTable<Related>,
|
|
39
39
|
) => Scope;
|
|
40
40
|
|
|
41
|
-
export type
|
|
41
|
+
export type Table = {
|
|
42
42
|
table: string;
|
|
43
|
-
columns:
|
|
43
|
+
columns: TableConfig;
|
|
44
44
|
schema?: string;
|
|
45
45
|
columnTypes: ColumnTypesBase;
|
|
46
46
|
noPrimaryKey?: boolean;
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
export const
|
|
49
|
+
export const createBaseTable = <CT extends ColumnTypesBase>(options: {
|
|
50
50
|
columnTypes: CT;
|
|
51
51
|
}) => {
|
|
52
|
-
return class
|
|
52
|
+
return class BaseTable {
|
|
53
53
|
table!: string;
|
|
54
|
-
columns!:
|
|
54
|
+
columns!: TableConfig;
|
|
55
55
|
schema?: string;
|
|
56
56
|
columnTypes: CT;
|
|
57
57
|
noPrimaryKey?: boolean;
|
|
@@ -73,7 +73,7 @@ export const createModel = <CT extends ColumnTypesBase>(options: {
|
|
|
73
73
|
|
|
74
74
|
belongsTo<
|
|
75
75
|
Self extends this,
|
|
76
|
-
Related extends
|
|
76
|
+
Related extends TableClass,
|
|
77
77
|
Scope extends Query,
|
|
78
78
|
Options extends {
|
|
79
79
|
primaryKey: keyof InstanceType<Related>['columns']['shape'];
|
|
@@ -92,7 +92,7 @@ export const createModel = <CT extends ColumnTypesBase>(options: {
|
|
|
92
92
|
|
|
93
93
|
hasOne<
|
|
94
94
|
Self extends this,
|
|
95
|
-
Related extends
|
|
95
|
+
Related extends TableClass,
|
|
96
96
|
Scope extends Query,
|
|
97
97
|
Through extends string,
|
|
98
98
|
Source extends string,
|
|
@@ -120,7 +120,7 @@ export const createModel = <CT extends ColumnTypesBase>(options: {
|
|
|
120
120
|
|
|
121
121
|
hasMany<
|
|
122
122
|
Self extends this,
|
|
123
|
-
Related extends
|
|
123
|
+
Related extends TableClass,
|
|
124
124
|
Scope extends Query,
|
|
125
125
|
Through extends string,
|
|
126
126
|
Source extends string,
|
|
@@ -148,7 +148,7 @@ export const createModel = <CT extends ColumnTypesBase>(options: {
|
|
|
148
148
|
|
|
149
149
|
hasAndBelongsToMany<
|
|
150
150
|
Self extends this,
|
|
151
|
-
Related extends
|
|
151
|
+
Related extends TableClass,
|
|
152
152
|
Scope extends Query,
|
|
153
153
|
Options extends {
|
|
154
154
|
primaryKey: keyof Self['columns']['shape'];
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { orchidORM } from '../orm';
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
} from './test-
|
|
3
|
+
ChatTable,
|
|
4
|
+
MessageTable,
|
|
5
|
+
PostTable,
|
|
6
|
+
PostTagTable,
|
|
7
|
+
ProfileTable,
|
|
8
|
+
TagTable,
|
|
9
|
+
UserTable,
|
|
10
|
+
} from './test-tables';
|
|
11
11
|
|
|
12
12
|
export const pgConfig = {
|
|
13
13
|
databaseURL: process.env.DATABASE_URL,
|
|
@@ -19,13 +19,13 @@ export const db = orchidORM(
|
|
|
19
19
|
log: false,
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
|
-
user:
|
|
23
|
-
profile:
|
|
24
|
-
chat:
|
|
25
|
-
message:
|
|
26
|
-
post:
|
|
27
|
-
postTag:
|
|
28
|
-
tag:
|
|
22
|
+
user: UserTable,
|
|
23
|
+
profile: ProfileTable,
|
|
24
|
+
chat: ChatTable,
|
|
25
|
+
message: MessageTable,
|
|
26
|
+
post: PostTable,
|
|
27
|
+
postTag: PostTagTable,
|
|
28
|
+
tag: TagTable,
|
|
29
29
|
},
|
|
30
30
|
);
|
|
31
31
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createBaseTable } from '../table';
|
|
2
2
|
import { columnTypes } from 'pqb';
|
|
3
|
-
import {
|
|
3
|
+
import { tableToZod } from 'orchid-orm-schema-to-zod';
|
|
4
4
|
|
|
5
|
-
export const
|
|
5
|
+
export const BaseTable = createBaseTable({
|
|
6
6
|
columnTypes: {
|
|
7
7
|
...columnTypes,
|
|
8
8
|
text: (min = 0, max = Infinity) => columnTypes.text(min, max),
|
|
@@ -12,8 +12,8 @@ export const Model = createModel({
|
|
|
12
12
|
},
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
export type User =
|
|
16
|
-
export class
|
|
15
|
+
export type User = UserTable['columns']['type'];
|
|
16
|
+
export class UserTable extends BaseTable {
|
|
17
17
|
table = 'user';
|
|
18
18
|
columns = this.setColumns((t) => ({
|
|
19
19
|
id: t.serial().primaryKey(),
|
|
@@ -34,18 +34,18 @@ export class UserModel extends Model {
|
|
|
34
34
|
}));
|
|
35
35
|
|
|
36
36
|
relations = {
|
|
37
|
-
profile: this.hasOne(() =>
|
|
37
|
+
profile: this.hasOne(() => ProfileTable, {
|
|
38
38
|
required: true,
|
|
39
39
|
primaryKey: 'id',
|
|
40
40
|
foreignKey: 'userId',
|
|
41
41
|
}),
|
|
42
42
|
|
|
43
|
-
messages: this.hasMany(() =>
|
|
43
|
+
messages: this.hasMany(() => MessageTable, {
|
|
44
44
|
primaryKey: 'id',
|
|
45
45
|
foreignKey: 'authorId',
|
|
46
46
|
}),
|
|
47
47
|
|
|
48
|
-
chats: this.hasAndBelongsToMany(() =>
|
|
48
|
+
chats: this.hasAndBelongsToMany(() => ChatTable, {
|
|
49
49
|
primaryKey: 'id',
|
|
50
50
|
foreignKey: 'userId',
|
|
51
51
|
associationPrimaryKey: 'id',
|
|
@@ -54,38 +54,38 @@ export class UserModel extends Model {
|
|
|
54
54
|
}),
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
-
export const UserSchema =
|
|
57
|
+
export const UserSchema = tableToZod(UserTable);
|
|
58
58
|
|
|
59
|
-
export type Profile =
|
|
60
|
-
export class
|
|
59
|
+
export type Profile = ProfileTable['columns']['type'];
|
|
60
|
+
export class ProfileTable extends BaseTable {
|
|
61
61
|
table = 'profile';
|
|
62
62
|
columns = this.setColumns((t) => ({
|
|
63
63
|
id: t.serial().primaryKey(),
|
|
64
64
|
userId: t
|
|
65
65
|
.integer()
|
|
66
66
|
.nullable()
|
|
67
|
-
.foreignKey(() =>
|
|
67
|
+
.foreignKey(() => UserTable, 'id'),
|
|
68
68
|
bio: t.text().nullable(),
|
|
69
69
|
...t.timestamps(),
|
|
70
70
|
}));
|
|
71
71
|
|
|
72
72
|
relations = {
|
|
73
|
-
user: this.belongsTo(() =>
|
|
73
|
+
user: this.belongsTo(() => UserTable, {
|
|
74
74
|
required: true,
|
|
75
75
|
primaryKey: 'id',
|
|
76
76
|
foreignKey: 'userId',
|
|
77
77
|
}),
|
|
78
78
|
|
|
79
|
-
chats: this.hasMany(() =>
|
|
79
|
+
chats: this.hasMany(() => ChatTable, {
|
|
80
80
|
through: 'user',
|
|
81
81
|
source: 'chats',
|
|
82
82
|
}),
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
|
-
export const ProfileSchema =
|
|
85
|
+
export const ProfileSchema = tableToZod(ProfileTable);
|
|
86
86
|
|
|
87
|
-
export type Chat =
|
|
88
|
-
export class
|
|
87
|
+
export type Chat = ChatTable['columns']['type'];
|
|
88
|
+
export class ChatTable extends BaseTable {
|
|
89
89
|
table = 'chat';
|
|
90
90
|
columns = this.setColumns((t) => ({
|
|
91
91
|
id: t.serial().primaryKey(),
|
|
@@ -94,7 +94,7 @@ export class ChatModel extends Model {
|
|
|
94
94
|
}));
|
|
95
95
|
|
|
96
96
|
relations = {
|
|
97
|
-
users: this.hasAndBelongsToMany(() =>
|
|
97
|
+
users: this.hasAndBelongsToMany(() => UserTable, {
|
|
98
98
|
primaryKey: 'id',
|
|
99
99
|
foreignKey: 'chatId',
|
|
100
100
|
associationPrimaryKey: 'id',
|
|
@@ -102,92 +102,92 @@ export class ChatModel extends Model {
|
|
|
102
102
|
joinTable: 'chatUser',
|
|
103
103
|
}),
|
|
104
104
|
|
|
105
|
-
profiles: this.hasMany(() =>
|
|
105
|
+
profiles: this.hasMany(() => ProfileTable, {
|
|
106
106
|
through: 'users',
|
|
107
107
|
source: 'profile',
|
|
108
108
|
}),
|
|
109
109
|
|
|
110
|
-
messages: this.hasMany(() =>
|
|
110
|
+
messages: this.hasMany(() => MessageTable, {
|
|
111
111
|
primaryKey: 'id',
|
|
112
112
|
foreignKey: 'chatId',
|
|
113
113
|
}),
|
|
114
114
|
};
|
|
115
115
|
}
|
|
116
|
-
export const ChatSchema =
|
|
116
|
+
export const ChatSchema = tableToZod(ChatTable);
|
|
117
117
|
|
|
118
|
-
export type Message =
|
|
119
|
-
export class
|
|
118
|
+
export type Message = MessageTable['columns']['type'];
|
|
119
|
+
export class MessageTable extends BaseTable {
|
|
120
120
|
table = 'message';
|
|
121
121
|
columns = this.setColumns((t) => ({
|
|
122
122
|
id: t.serial().primaryKey(),
|
|
123
|
-
chatId: t.integer().foreignKey(() =>
|
|
123
|
+
chatId: t.integer().foreignKey(() => ChatTable, 'id'),
|
|
124
124
|
authorId: t
|
|
125
125
|
.integer()
|
|
126
126
|
.nullable()
|
|
127
|
-
.foreignKey(() =>
|
|
127
|
+
.foreignKey(() => UserTable, 'id'),
|
|
128
128
|
text: t.text(),
|
|
129
129
|
...t.timestamps(),
|
|
130
130
|
}));
|
|
131
131
|
|
|
132
132
|
relations = {
|
|
133
|
-
user: this.belongsTo(() =>
|
|
133
|
+
user: this.belongsTo(() => UserTable, {
|
|
134
134
|
primaryKey: 'id',
|
|
135
135
|
foreignKey: 'authorId',
|
|
136
136
|
}),
|
|
137
137
|
|
|
138
|
-
chat: this.belongsTo(() =>
|
|
138
|
+
chat: this.belongsTo(() => ChatTable, {
|
|
139
139
|
primaryKey: 'id',
|
|
140
140
|
foreignKey: 'chatId',
|
|
141
141
|
}),
|
|
142
142
|
|
|
143
|
-
profile: this.hasOne(() =>
|
|
143
|
+
profile: this.hasOne(() => ProfileTable, {
|
|
144
144
|
required: true,
|
|
145
145
|
through: 'user',
|
|
146
146
|
source: 'profile',
|
|
147
147
|
}),
|
|
148
148
|
};
|
|
149
149
|
}
|
|
150
|
-
export const MessageSchema =
|
|
150
|
+
export const MessageSchema = tableToZod(MessageTable);
|
|
151
151
|
|
|
152
|
-
export type Post =
|
|
153
|
-
export class
|
|
152
|
+
export type Post = PostTable['columns']['type'];
|
|
153
|
+
export class PostTable extends BaseTable {
|
|
154
154
|
table = 'post';
|
|
155
155
|
columns = this.setColumns((t) => ({
|
|
156
156
|
id: t.serial().primaryKey(),
|
|
157
|
-
userId: t.integer().foreignKey(() =>
|
|
157
|
+
userId: t.integer().foreignKey(() => UserTable, 'id'),
|
|
158
158
|
title: t.text(),
|
|
159
159
|
...t.timestamps(),
|
|
160
160
|
}));
|
|
161
161
|
|
|
162
162
|
relations = {
|
|
163
|
-
postTags: this.hasMany(() =>
|
|
163
|
+
postTags: this.hasMany(() => PostTagTable, {
|
|
164
164
|
primaryKey: 'id',
|
|
165
165
|
foreignKey: 'postId',
|
|
166
166
|
}),
|
|
167
167
|
};
|
|
168
168
|
}
|
|
169
|
-
export const PostSchema =
|
|
169
|
+
export const PostSchema = tableToZod(PostTable);
|
|
170
170
|
|
|
171
|
-
export type PostTag =
|
|
172
|
-
export class
|
|
171
|
+
export type PostTag = PostTagTable['columns']['type'];
|
|
172
|
+
export class PostTagTable extends BaseTable {
|
|
173
173
|
table = 'postTag';
|
|
174
174
|
columns = this.setColumns((t) => ({
|
|
175
|
-
postId: t.integer().foreignKey(() =>
|
|
176
|
-
tag: t.text().foreignKey(() =>
|
|
175
|
+
postId: t.integer().foreignKey(() => PostTable, 'id'),
|
|
176
|
+
tag: t.text().foreignKey(() => TagTable, 'tag'),
|
|
177
177
|
...t.primaryKey(['postId', 'tag']),
|
|
178
178
|
}));
|
|
179
179
|
|
|
180
180
|
relations = {
|
|
181
|
-
tag: this.belongsTo(() =>
|
|
181
|
+
tag: this.belongsTo(() => TagTable, {
|
|
182
182
|
primaryKey: 'tag',
|
|
183
183
|
foreignKey: 'tag',
|
|
184
184
|
}),
|
|
185
185
|
};
|
|
186
186
|
}
|
|
187
|
-
export const PostTagSchema =
|
|
187
|
+
export const PostTagSchema = tableToZod(PostTagTable);
|
|
188
188
|
|
|
189
|
-
export type Tag =
|
|
190
|
-
export class
|
|
189
|
+
export type Tag = TagTable['columns']['type'];
|
|
190
|
+
export class TagTable extends BaseTable {
|
|
191
191
|
table = 'tag';
|
|
192
192
|
columns = this.setColumns((t) => ({
|
|
193
193
|
tag: t.text().primaryKey(),
|
package/src/transaction.test.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { Client } from 'pg';
|
|
|
4
4
|
import { noop } from 'pqb';
|
|
5
5
|
|
|
6
6
|
describe('transaction', () => {
|
|
7
|
-
it('should have override transaction method which implicitly connects
|
|
7
|
+
it('should have override transaction method which implicitly connects tables with a single transaction', async () => {
|
|
8
8
|
const spy = jest.spyOn(Client.prototype, 'query');
|
|
9
9
|
|
|
10
10
|
await db
|
package/src/transaction.ts
CHANGED
|
@@ -13,10 +13,10 @@ export function transaction<T extends { $queryBuilder: Db }, Result>(
|
|
|
13
13
|
for (const key in this) {
|
|
14
14
|
const value = this[key];
|
|
15
15
|
if (value instanceof Db) {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
(
|
|
19
|
-
orm[key] =
|
|
16
|
+
const table = value.transacting(q);
|
|
17
|
+
table.__table = table;
|
|
18
|
+
(table as unknown as { db: unknown }).db = orm;
|
|
19
|
+
orm[key] = table;
|
|
20
20
|
} else {
|
|
21
21
|
orm[key] = value;
|
|
22
22
|
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const toPascalCase = (s: string) => {
|
|
2
|
+
const words = s.match(/(\w)(\w*)/g) || [];
|
|
3
|
+
return words.map((word) => word[0].toUpperCase() + word.slice(1)).join('');
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export const toCamelCase = (s: string) => {
|
|
7
|
+
const pascal = toPascalCase(s);
|
|
8
|
+
return pascal[0].toLowerCase() + pascal.slice(1);
|
|
9
|
+
};
|