@anephenix/objection-relations 0.0.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.
- package/LICENSE +21 -0
- package/README.md +280 -0
- package/dist/index.d.ts +80 -0
- package/dist/index.js +8 -0
- package/dist/objection-relations.cjs.development.js +218 -0
- package/dist/objection-relations.cjs.development.js.map +1 -0
- package/dist/objection-relations.cjs.production.min.js +2 -0
- package/dist/objection-relations.cjs.production.min.js.map +1 -0
- package/dist/objection-relations.esm.js +204 -0
- package/dist/objection-relations.esm.js.map +1 -0
- package/package.json +63 -0
- package/src/index.ts +172 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Anephenix
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
# objection-relations
|
|
2
|
+
|
|
3
|
+
A relations helper for Objection.js. This provides a convenient way to define
|
|
4
|
+
relations in the `relationMappings` function on an Objection.js model.
|
|
5
|
+
|
|
6
|
+
For example, say you have a table called "Persons" with this relation mapping:
|
|
7
|
+
|
|
8
|
+
```javascript
|
|
9
|
+
class Person extends Model {
|
|
10
|
+
static get tableName() {
|
|
11
|
+
return 'persons';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static get relationMappings() {
|
|
15
|
+
return {
|
|
16
|
+
addresses: {
|
|
17
|
+
relation: Model.HasManyRelation,
|
|
18
|
+
modelClass: Address,
|
|
19
|
+
join: {
|
|
20
|
+
from: 'persons.id',
|
|
21
|
+
to: 'addresses.person_id',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
You can use the objection-relations helper module to write the instead:
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
import { relation } from '@anephenix/objection-relations';
|
|
33
|
+
|
|
34
|
+
class Person extends Model {
|
|
35
|
+
static get tableName() {
|
|
36
|
+
return 'persons';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static get relationMappings() {
|
|
40
|
+
return {
|
|
41
|
+
addresses: relation({
|
|
42
|
+
subject: 'Person',
|
|
43
|
+
relType: 'hasMany',
|
|
44
|
+
object: 'Address',
|
|
45
|
+
}),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The helper function will do the following:
|
|
52
|
+
|
|
53
|
+
- Setup the relation type from Objection.js (hasOne, hasMany, hasMnayThrough, belongsTo)
|
|
54
|
+
- Define the join table based on the properties of the subject and object
|
|
55
|
+
models, if they follow a particular pattern (tables for models are named in
|
|
56
|
+
plural format, and foreign keys use a singular format).
|
|
57
|
+
|
|
58
|
+
## Dependencies
|
|
59
|
+
|
|
60
|
+
- Node.js
|
|
61
|
+
|
|
62
|
+
## Install
|
|
63
|
+
|
|
64
|
+
```shell
|
|
65
|
+
npm i @anephenix/objection-relations
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Usage
|
|
69
|
+
|
|
70
|
+
You can setup different kinds of database table relationships like this:
|
|
71
|
+
|
|
72
|
+
### Belongs to
|
|
73
|
+
|
|
74
|
+
```javascript
|
|
75
|
+
relation({ subject: 'Post', relType: 'belongsTo', object: 'User' });
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Is equivalent to writing:
|
|
79
|
+
|
|
80
|
+
```javascript
|
|
81
|
+
{
|
|
82
|
+
relation: Model.BelongsToOneRelation,
|
|
83
|
+
modelClass: User,
|
|
84
|
+
join: {
|
|
85
|
+
from: 'posts.user_id',
|
|
86
|
+
to: 'users.id'
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Has one
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
relation({ subject: 'User', relType: 'hasOne', object: 'Setting' });
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Is equivalent to writing:
|
|
98
|
+
|
|
99
|
+
```javascript
|
|
100
|
+
{
|
|
101
|
+
relation: Model.HasOneRelation,
|
|
102
|
+
modelClass: Setting,
|
|
103
|
+
join: {
|
|
104
|
+
from: 'users.id',
|
|
105
|
+
to: 'settings.user_id'
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Has many
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
relation({ subject: 'User', relType: 'hasMany', object: 'Address' });
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Is equivalent to writing:
|
|
117
|
+
|
|
118
|
+
```javascript
|
|
119
|
+
{
|
|
120
|
+
relation: Model.HasManyRelation,
|
|
121
|
+
modelClass: Address,
|
|
122
|
+
join: {
|
|
123
|
+
from: 'users.id',
|
|
124
|
+
to: 'addresses.user_id'
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Has many through
|
|
130
|
+
|
|
131
|
+
For relationships defined through a join table, you can write this:
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
134
|
+
relation({
|
|
135
|
+
subject: 'User',
|
|
136
|
+
relType: 'hasManyThrough',
|
|
137
|
+
object: 'Company',
|
|
138
|
+
via: 'Employment',
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
This is equivalent to:
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
{
|
|
146
|
+
relation: Model.ManyToManyRelation,
|
|
147
|
+
modelClass: Company,
|
|
148
|
+
join: {
|
|
149
|
+
from: 'users.id',
|
|
150
|
+
through: {
|
|
151
|
+
from: 'employments.user_id',
|
|
152
|
+
to: 'employments.company_id'
|
|
153
|
+
},
|
|
154
|
+
to: 'companies.id'
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Advanced usage
|
|
160
|
+
|
|
161
|
+
There might be cases where the name of the database tables and foreign keys are
|
|
162
|
+
following a different pattern from plural database tables and singular foreign
|
|
163
|
+
keys. In such cases you can define them in the options, like this:
|
|
164
|
+
|
|
165
|
+
### SubjectTable
|
|
166
|
+
|
|
167
|
+
Say a `User` model has many addresses, but the database table is called
|
|
168
|
+
'account_users', you can write this code:
|
|
169
|
+
|
|
170
|
+
```javascript
|
|
171
|
+
relation({
|
|
172
|
+
subject: 'User',
|
|
173
|
+
relType: 'hasMany',
|
|
174
|
+
object: 'Address',
|
|
175
|
+
options: { subjectTable: 'account_users' },
|
|
176
|
+
});
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Which is equivalent to writing:
|
|
180
|
+
|
|
181
|
+
```javascript
|
|
182
|
+
{
|
|
183
|
+
relation: Model.HasManyRelation,
|
|
184
|
+
modelClass: Address,
|
|
185
|
+
join: {
|
|
186
|
+
from: 'account_users.id',
|
|
187
|
+
to: 'addresses.user_id'
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### ObjectTable
|
|
193
|
+
|
|
194
|
+
The same applies for the object table. Say for example the `Address` model has
|
|
195
|
+
the database table 'shipping_addresses', you could write this:
|
|
196
|
+
|
|
197
|
+
```javascript
|
|
198
|
+
relation({
|
|
199
|
+
subject: 'User',
|
|
200
|
+
relType: 'hasMany',
|
|
201
|
+
object: 'Address',
|
|
202
|
+
options: { objectTable: 'shipping_addresses' },
|
|
203
|
+
});
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Which is equivalent to writing:
|
|
207
|
+
|
|
208
|
+
```javascript
|
|
209
|
+
{
|
|
210
|
+
relation: Model.HasManyRelation,
|
|
211
|
+
modelClass: Address,
|
|
212
|
+
join: {
|
|
213
|
+
from: 'users.id',
|
|
214
|
+
to: 'shipping_addresses.user_id'
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### SubjectForeignKey
|
|
220
|
+
|
|
221
|
+
If you find that the foreign key is not a singular form of the related model,
|
|
222
|
+
then you can pass a foreign key for the subject like this:
|
|
223
|
+
|
|
224
|
+
```javascript
|
|
225
|
+
relation({
|
|
226
|
+
subject: 'User',
|
|
227
|
+
relType: 'hasMany',
|
|
228
|
+
object: 'Address',
|
|
229
|
+
options: { subjectForeignKey: 'account_user_id' },
|
|
230
|
+
});
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Which is equivalent to writing:
|
|
234
|
+
|
|
235
|
+
```javascript
|
|
236
|
+
{
|
|
237
|
+
relation: Model.HasManyRelation,
|
|
238
|
+
modelClass: Address,
|
|
239
|
+
join: {
|
|
240
|
+
from: 'users.id',
|
|
241
|
+
to: 'addresses.account_user_id'
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### ObjectForeignKey
|
|
247
|
+
|
|
248
|
+
You can pass a custom foreign key for the object like this:
|
|
249
|
+
|
|
250
|
+
```javascript
|
|
251
|
+
relation({
|
|
252
|
+
subject: 'Post',
|
|
253
|
+
relType: 'belongsTo',
|
|
254
|
+
object: 'User',
|
|
255
|
+
options: { objectForeignKey: 'author_id' },
|
|
256
|
+
});
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Is equivalent to writing:
|
|
260
|
+
|
|
261
|
+
```javascript
|
|
262
|
+
{
|
|
263
|
+
relation: Model.BelongsToOneRelation,
|
|
264
|
+
modelClass: User,
|
|
265
|
+
join: {
|
|
266
|
+
from: 'posts.author_id',
|
|
267
|
+
to: 'users.id'
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Tests
|
|
273
|
+
|
|
274
|
+
```shell
|
|
275
|
+
npm t
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Licence and credits
|
|
279
|
+
|
|
280
|
+
©2022 Anephenix OÜ. Objection-relations is licenced under the MIT Licence.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
declare type CommonRelationOrTableOrForeignKeyProps = {
|
|
2
|
+
options?: {
|
|
3
|
+
subjectTable?: string;
|
|
4
|
+
objectTable?: string;
|
|
5
|
+
subjectForeignKey?: string;
|
|
6
|
+
objectForeignKey?: string;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
declare type RelationProps = CommonRelationOrTableOrForeignKeyProps & {
|
|
10
|
+
subject: string;
|
|
11
|
+
relType: 'hasOne' | 'hasMany' | 'hasManyThrough' | 'belongsTo';
|
|
12
|
+
object: string;
|
|
13
|
+
via?: string;
|
|
14
|
+
};
|
|
15
|
+
declare type RelationTypeProps = {
|
|
16
|
+
modelClass: string;
|
|
17
|
+
from: string;
|
|
18
|
+
to: string;
|
|
19
|
+
};
|
|
20
|
+
declare type AdvancedRelationTypeProps = RelationTypeProps & {
|
|
21
|
+
through: {
|
|
22
|
+
from: string;
|
|
23
|
+
to: string;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
declare type SubjectProps = CommonRelationOrTableOrForeignKeyProps & {
|
|
27
|
+
subject: string;
|
|
28
|
+
};
|
|
29
|
+
declare type ObjectProps = CommonRelationOrTableOrForeignKeyProps & {
|
|
30
|
+
object: string;
|
|
31
|
+
};
|
|
32
|
+
export declare function belongsRelation({ modelClass, from, to }: RelationTypeProps): {
|
|
33
|
+
relation: import("objection").RelationType;
|
|
34
|
+
modelClass: string;
|
|
35
|
+
join: {
|
|
36
|
+
from: string;
|
|
37
|
+
to: string;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
export declare function hasOneRelation({ modelClass, from, to }: RelationTypeProps): {
|
|
41
|
+
relation: import("objection").RelationType;
|
|
42
|
+
modelClass: string;
|
|
43
|
+
join: {
|
|
44
|
+
from: string;
|
|
45
|
+
to: string;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
export declare function hasManyRelation({ modelClass, from, to }: RelationTypeProps): {
|
|
49
|
+
relation: import("objection").RelationType;
|
|
50
|
+
modelClass: string;
|
|
51
|
+
join: {
|
|
52
|
+
from: string;
|
|
53
|
+
to: string;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
export declare function hasManyThroughRelation({ modelClass, from, through, to }: AdvancedRelationTypeProps): {
|
|
57
|
+
relation: import("objection").RelationType;
|
|
58
|
+
modelClass: string;
|
|
59
|
+
join: {
|
|
60
|
+
from: string;
|
|
61
|
+
through: {
|
|
62
|
+
from: string;
|
|
63
|
+
to: string;
|
|
64
|
+
};
|
|
65
|
+
to: string;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
export declare function getSubjectTable({ subject, options }: SubjectProps): string;
|
|
69
|
+
export declare function getObjectTable({ object, options }: ObjectProps): string;
|
|
70
|
+
export declare function getSubjectForeignKey({ subject, options }: SubjectProps): string;
|
|
71
|
+
export declare function getObjectForeignKey({ object, options }: ObjectProps): string;
|
|
72
|
+
export declare function relation({ subject, relType, object, via, options }: RelationProps): {
|
|
73
|
+
relation: import("objection").RelationType;
|
|
74
|
+
modelClass: string;
|
|
75
|
+
join: {
|
|
76
|
+
from: string;
|
|
77
|
+
to: string;
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
|
6
|
+
|
|
7
|
+
var objection = require('objection');
|
|
8
|
+
var snakeCase = _interopDefault(require('lodash.snakecase'));
|
|
9
|
+
var pluralize = _interopDefault(require('pluralize'));
|
|
10
|
+
|
|
11
|
+
// Dependencies
|
|
12
|
+
const {
|
|
13
|
+
HasOneRelation,
|
|
14
|
+
BelongsToOneRelation,
|
|
15
|
+
HasManyRelation,
|
|
16
|
+
ManyToManyRelation
|
|
17
|
+
} = objection.Model;
|
|
18
|
+
/*
|
|
19
|
+
Defines a relationship where a record in one model can belong to a record in
|
|
20
|
+
another model.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
function belongsRelation({
|
|
24
|
+
modelClass,
|
|
25
|
+
from,
|
|
26
|
+
to
|
|
27
|
+
}) {
|
|
28
|
+
return {
|
|
29
|
+
relation: BelongsToOneRelation,
|
|
30
|
+
modelClass,
|
|
31
|
+
join: {
|
|
32
|
+
from,
|
|
33
|
+
to
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/*
|
|
38
|
+
Defines a relationship where a record in one model can own a record in another
|
|
39
|
+
model.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
function hasOneRelation({
|
|
43
|
+
modelClass,
|
|
44
|
+
from,
|
|
45
|
+
to
|
|
46
|
+
}) {
|
|
47
|
+
return {
|
|
48
|
+
relation: HasOneRelation,
|
|
49
|
+
modelClass,
|
|
50
|
+
join: {
|
|
51
|
+
from,
|
|
52
|
+
to
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/*
|
|
57
|
+
Defines a relationship where a record in one model can own many records in
|
|
58
|
+
another model.
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
function hasManyRelation({
|
|
62
|
+
modelClass,
|
|
63
|
+
from,
|
|
64
|
+
to
|
|
65
|
+
}) {
|
|
66
|
+
return {
|
|
67
|
+
relation: HasManyRelation,
|
|
68
|
+
modelClass,
|
|
69
|
+
join: {
|
|
70
|
+
from,
|
|
71
|
+
to
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/*
|
|
76
|
+
Defines a relationship where a record in one model can own many records in
|
|
77
|
+
another model, via a join table
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
function hasManyThroughRelation({
|
|
81
|
+
modelClass,
|
|
82
|
+
from,
|
|
83
|
+
through,
|
|
84
|
+
to
|
|
85
|
+
}) {
|
|
86
|
+
return {
|
|
87
|
+
relation: ManyToManyRelation,
|
|
88
|
+
modelClass,
|
|
89
|
+
join: {
|
|
90
|
+
from,
|
|
91
|
+
through,
|
|
92
|
+
to
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/*
|
|
97
|
+
Gets the SQL table for the subject, either from the options object or the
|
|
98
|
+
plural version of the subject model.
|
|
99
|
+
*/
|
|
100
|
+
|
|
101
|
+
function getSubjectTable({
|
|
102
|
+
subject,
|
|
103
|
+
options
|
|
104
|
+
}) {
|
|
105
|
+
return (options == null ? void 0 : options.subjectTable) || pluralize(snakeCase(subject));
|
|
106
|
+
}
|
|
107
|
+
/*
|
|
108
|
+
Gets the SQL table for the object, either from the options object or the
|
|
109
|
+
plural version of the object model.
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
function getObjectTable({
|
|
113
|
+
object,
|
|
114
|
+
options
|
|
115
|
+
}) {
|
|
116
|
+
return (options == null ? void 0 : options.objectTable) || pluralize(snakeCase(object));
|
|
117
|
+
}
|
|
118
|
+
/*
|
|
119
|
+
Gets the SQL foreign key for the subject, either from the options object
|
|
120
|
+
or the snake case of the subject model.
|
|
121
|
+
*/
|
|
122
|
+
|
|
123
|
+
function getSubjectForeignKey({
|
|
124
|
+
subject,
|
|
125
|
+
options
|
|
126
|
+
}) {
|
|
127
|
+
return (options == null ? void 0 : options.subjectForeignKey) || snakeCase(subject) + '_id';
|
|
128
|
+
}
|
|
129
|
+
/*
|
|
130
|
+
Gets the SQL foreign key for the object, either from the options object
|
|
131
|
+
or the snake case of the object model.
|
|
132
|
+
*/
|
|
133
|
+
|
|
134
|
+
function getObjectForeignKey({
|
|
135
|
+
object,
|
|
136
|
+
options
|
|
137
|
+
}) {
|
|
138
|
+
return (options == null ? void 0 : options.objectForeignKey) || snakeCase(object) + '_id';
|
|
139
|
+
}
|
|
140
|
+
/*
|
|
141
|
+
Defines a relationship by passing the subject, the predicate, and the object,
|
|
142
|
+
along with an optional via model.
|
|
143
|
+
*/
|
|
144
|
+
|
|
145
|
+
function relation({
|
|
146
|
+
subject,
|
|
147
|
+
relType,
|
|
148
|
+
object,
|
|
149
|
+
via,
|
|
150
|
+
options
|
|
151
|
+
}) {
|
|
152
|
+
const subjectTable = getSubjectTable({
|
|
153
|
+
subject,
|
|
154
|
+
options
|
|
155
|
+
});
|
|
156
|
+
const objectTable = getObjectTable({
|
|
157
|
+
object,
|
|
158
|
+
options
|
|
159
|
+
});
|
|
160
|
+
const subjectForeignKey = getSubjectForeignKey({
|
|
161
|
+
subject,
|
|
162
|
+
options
|
|
163
|
+
});
|
|
164
|
+
const objectForeignKey = getObjectForeignKey({
|
|
165
|
+
object,
|
|
166
|
+
options
|
|
167
|
+
});
|
|
168
|
+
let viaTable;
|
|
169
|
+
if (via) viaTable = pluralize(snakeCase(via));
|
|
170
|
+
|
|
171
|
+
switch (relType) {
|
|
172
|
+
case 'hasOne':
|
|
173
|
+
return hasOneRelation({
|
|
174
|
+
modelClass: object,
|
|
175
|
+
from: `${subjectTable}.id`,
|
|
176
|
+
to: `${objectTable}.${subjectForeignKey}`
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
case 'hasMany':
|
|
180
|
+
return hasManyRelation({
|
|
181
|
+
modelClass: object,
|
|
182
|
+
from: `${subjectTable}.id`,
|
|
183
|
+
to: `${objectTable}.${subjectForeignKey}`
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
case 'hasManyThrough':
|
|
187
|
+
return hasManyThroughRelation({
|
|
188
|
+
modelClass: object,
|
|
189
|
+
from: `${subjectTable}.id`,
|
|
190
|
+
through: {
|
|
191
|
+
from: `${viaTable}.${subjectForeignKey}`,
|
|
192
|
+
to: `${viaTable}.${objectForeignKey}`
|
|
193
|
+
},
|
|
194
|
+
to: `${objectTable}.id`
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
case 'belongsTo':
|
|
198
|
+
return belongsRelation({
|
|
199
|
+
modelClass: object,
|
|
200
|
+
from: `${subjectTable}.${objectForeignKey}`,
|
|
201
|
+
to: `${objectTable}.id`
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
default:
|
|
205
|
+
throw new Error('No valid relationship type specified');
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
exports.belongsRelation = belongsRelation;
|
|
210
|
+
exports.getObjectForeignKey = getObjectForeignKey;
|
|
211
|
+
exports.getObjectTable = getObjectTable;
|
|
212
|
+
exports.getSubjectForeignKey = getSubjectForeignKey;
|
|
213
|
+
exports.getSubjectTable = getSubjectTable;
|
|
214
|
+
exports.hasManyRelation = hasManyRelation;
|
|
215
|
+
exports.hasManyThroughRelation = hasManyThroughRelation;
|
|
216
|
+
exports.hasOneRelation = hasOneRelation;
|
|
217
|
+
exports.relation = relation;
|
|
218
|
+
//# sourceMappingURL=objection-relations.cjs.development.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"objection-relations.cjs.development.js","sources":["../src/index.ts"],"sourcesContent":["// Dependencies\nimport { Model } from 'objection';\nconst {\n\tHasOneRelation,\n\tBelongsToOneRelation,\n\tHasManyRelation,\n\tManyToManyRelation,\n} = Model;\nimport snakeCase from 'lodash.snakecase';\nimport pluralize from 'pluralize';\n\ntype CommonRelationOrTableOrForeignKeyProps = {\n options?: {\n subjectTable?: string;\n objectTable?: string;\n subjectForeignKey?: string;\n objectForeignKey?: string;\n }\n}\n\ntype RelationProps = CommonRelationOrTableOrForeignKeyProps & {\n subject: string;\n relType: 'hasOne' | 'hasMany' | 'hasManyThrough' | 'belongsTo';\n object: string;\n via?: string;\n}\n\ntype RelationTypeProps = {\n modelClass: string;\n from: string;\n to: string;\n};\n\ntype AdvancedRelationTypeProps = RelationTypeProps & {\n through: {\n from: string;\n to: string;\n };\n}\n\ntype SubjectProps = CommonRelationOrTableOrForeignKeyProps & {\n subject: string;\n}\n\ntype ObjectProps = CommonRelationOrTableOrForeignKeyProps & {\n object: string;\n}\n\n/*\n Defines a relationship where a record in one model can belong to a record in\n another model.\n*/\nexport function belongsRelation({ modelClass, from, to }:RelationTypeProps) {\n\treturn {\n\t\trelation: BelongsToOneRelation,\n\t\tmodelClass,\n\t\tjoin: { from, to },\n\t};\n};\n\n/*\n\tDefines a relationship where a record in one model can own a record in another\n\tmodel.\n*/\nexport function hasOneRelation({ modelClass, from, to }:RelationTypeProps) {\n\treturn {\n\t\trelation: HasOneRelation,\n\t\tmodelClass,\n\t\tjoin: { from, to },\n\t};\n};\n\n/*\n\tDefines a relationship where a record in one model can own many records in\n\tanother model.\n*/\nexport function hasManyRelation({ modelClass, from, to }:RelationTypeProps) {\n\treturn {\n\t\trelation: HasManyRelation,\n modelClass,\n\t\tjoin: { from, to },\n\t};\n};\n\n/*\n\tDefines a relationship where a record in one model can own many records in\n\tanother model, via a join table\n*/\nexport function hasManyThroughRelation({ modelClass, from, through, to }:AdvancedRelationTypeProps) {\n\treturn {\n\t\trelation: ManyToManyRelation,\n modelClass,\n\t\tjoin: { from, through, to },\n\t};\n};\n\n/*\n Gets the SQL table for the subject, either from the options object or the\n plural version of the subject model.\n*/\nexport function getSubjectTable({ subject, options }:SubjectProps) {\n return options?.subjectTable || pluralize(snakeCase(subject));\n}\n\n/*\n Gets the SQL table for the object, either from the options object or the\n plural version of the object model.\n*/\nexport function getObjectTable({ object, options }:ObjectProps) { \n return options?.objectTable || pluralize(snakeCase(object));\n}\n\n/*\n Gets the SQL foreign key for the subject, either from the options object \n or the snake case of the subject model.\n*/\nexport function getSubjectForeignKey({ subject, options }:SubjectProps) {\n return options?.subjectForeignKey || snakeCase(subject) + '_id';\n}\n\n/*\n Gets the SQL foreign key for the object, either from the options object \n or the snake case of the object model.\n*/\nexport function getObjectForeignKey({ object, options }:ObjectProps) {\n return options?.objectForeignKey || snakeCase(object) + '_id';\n}\n\n/*\n\tDefines a relationship by passing the subject, the predicate, and the object,\n\talong with an optional via model.\n*/\nexport function relation({subject, relType, object, via, options}:RelationProps) {\n\tconst subjectTable = getSubjectTable({subject, options});\n\tconst objectTable = getObjectTable({object, options});\n\tconst subjectForeignKey = getSubjectForeignKey({subject, options});\n\tconst objectForeignKey = getObjectForeignKey({object, options});\n\tlet viaTable;\n\tif (via) viaTable = pluralize(snakeCase(via));\n\tswitch (relType) {\n\t\tcase 'hasOne':\n\t\t\treturn hasOneRelation({\n modelClass: object,\n\t\t\t\tfrom: `${subjectTable}.id`,\n\t\t\t\tto: `${objectTable}.${subjectForeignKey}`\n });\n\t\tcase 'hasMany':\n\t\t\treturn hasManyRelation({\n\t\t\t\tmodelClass: object,\n\t\t\t\tfrom: `${subjectTable}.id`,\n\t\t\t\tto: `${objectTable}.${subjectForeignKey}`\n\t\t\t});\n\t\tcase 'hasManyThrough':\n\t\t\treturn hasManyThroughRelation({\n\t\t\t\tmodelClass: object,\n\t\t\t\tfrom: `${subjectTable}.id`,\n\t\t\t\tthrough: {\n\t\t\t\t\tfrom: `${viaTable}.${subjectForeignKey}`,\n\t\t\t\t\tto: `${viaTable}.${objectForeignKey}`,\n\t\t\t\t},\n\t\t\t\tto: `${objectTable}.id`\n });\n\t\tcase 'belongsTo':\n\t\t\treturn belongsRelation({\n\t\t\t\tmodelClass: object,\n\t\t\t\tfrom: `${subjectTable}.${objectForeignKey}`,\n\t\t\t\tto: `${objectTable}.id`\n });\n\t\tdefault:\n\t\t\tthrow new Error('No valid relationship type specified');\n\t}\n};"],"names":["HasOneRelation","BelongsToOneRelation","HasManyRelation","ManyToManyRelation","Model","belongsRelation","modelClass","from","to","relation","join","hasOneRelation","hasManyRelation","hasManyThroughRelation","through","getSubjectTable","subject","options","subjectTable","pluralize","snakeCase","getObjectTable","object","objectTable","getSubjectForeignKey","subjectForeignKey","getObjectForeignKey","objectForeignKey","relType","via","viaTable","Error"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";function o(o){return o&&"object"==typeof o&&"default"in o?o.default:o}Object.defineProperty(exports,"__esModule",{value:!0});var e=require("objection"),t=o(require("lodash.snakecase")),n=o(require("pluralize"));const{HasOneRelation:r,BelongsToOneRelation:s,HasManyRelation:i,ManyToManyRelation:l}=e.Model;function a({modelClass:o,from:e,to:t}){return{relation:s,modelClass:o,join:{from:e,to:t}}}function u({modelClass:o,from:e,to:t}){return{relation:r,modelClass:o,join:{from:e,to:t}}}function c({modelClass:o,from:e,to:t}){return{relation:i,modelClass:o,join:{from:e,to:t}}}function d({modelClass:o,from:e,through:t,to:n}){return{relation:l,modelClass:o,join:{from:e,through:t,to:n}}}function f({subject:o,options:e}){return(null==e?void 0:e.subjectTable)||n(t(o))}function b({object:o,options:e}){return(null==e?void 0:e.objectTable)||n(t(o))}function p({subject:o,options:e}){return(null==e?void 0:e.subjectForeignKey)||t(o)+"_id"}function j({object:o,options:e}){return(null==e?void 0:e.objectForeignKey)||t(o)+"_id"}exports.belongsRelation=a,exports.getObjectForeignKey=j,exports.getObjectTable=b,exports.getSubjectForeignKey=p,exports.getSubjectTable=f,exports.hasManyRelation=c,exports.hasManyThroughRelation=d,exports.hasOneRelation=u,exports.relation=function({subject:o,relType:e,object:r,via:s,options:i}){const l=f({subject:o,options:i}),m=b({object:r,options:i}),h=p({subject:o,options:i}),g=j({object:r,options:i});let y;switch(s&&(y=n(t(s))),e){case"hasOne":return u({modelClass:r,from:l+".id",to:`${m}.${h}`});case"hasMany":return c({modelClass:r,from:l+".id",to:`${m}.${h}`});case"hasManyThrough":return d({modelClass:r,from:l+".id",through:{from:`${y}.${h}`,to:`${y}.${g}`},to:m+".id"});case"belongsTo":return a({modelClass:r,from:`${l}.${g}`,to:m+".id"});default:throw new Error("No valid relationship type specified")}};
|
|
2
|
+
//# sourceMappingURL=objection-relations.cjs.production.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"objection-relations.cjs.production.min.js","sources":["../src/index.ts"],"sourcesContent":["// Dependencies\nimport { Model } from 'objection';\nconst {\n\tHasOneRelation,\n\tBelongsToOneRelation,\n\tHasManyRelation,\n\tManyToManyRelation,\n} = Model;\nimport snakeCase from 'lodash.snakecase';\nimport pluralize from 'pluralize';\n\ntype CommonRelationOrTableOrForeignKeyProps = {\n options?: {\n subjectTable?: string;\n objectTable?: string;\n subjectForeignKey?: string;\n objectForeignKey?: string;\n }\n}\n\ntype RelationProps = CommonRelationOrTableOrForeignKeyProps & {\n subject: string;\n relType: 'hasOne' | 'hasMany' | 'hasManyThrough' | 'belongsTo';\n object: string;\n via?: string;\n}\n\ntype RelationTypeProps = {\n modelClass: string;\n from: string;\n to: string;\n};\n\ntype AdvancedRelationTypeProps = RelationTypeProps & {\n through: {\n from: string;\n to: string;\n };\n}\n\ntype SubjectProps = CommonRelationOrTableOrForeignKeyProps & {\n subject: string;\n}\n\ntype ObjectProps = CommonRelationOrTableOrForeignKeyProps & {\n object: string;\n}\n\n/*\n Defines a relationship where a record in one model can belong to a record in\n another model.\n*/\nexport function belongsRelation({ modelClass, from, to }:RelationTypeProps) {\n\treturn {\n\t\trelation: BelongsToOneRelation,\n\t\tmodelClass,\n\t\tjoin: { from, to },\n\t};\n};\n\n/*\n\tDefines a relationship where a record in one model can own a record in another\n\tmodel.\n*/\nexport function hasOneRelation({ modelClass, from, to }:RelationTypeProps) {\n\treturn {\n\t\trelation: HasOneRelation,\n\t\tmodelClass,\n\t\tjoin: { from, to },\n\t};\n};\n\n/*\n\tDefines a relationship where a record in one model can own many records in\n\tanother model.\n*/\nexport function hasManyRelation({ modelClass, from, to }:RelationTypeProps) {\n\treturn {\n\t\trelation: HasManyRelation,\n modelClass,\n\t\tjoin: { from, to },\n\t};\n};\n\n/*\n\tDefines a relationship where a record in one model can own many records in\n\tanother model, via a join table\n*/\nexport function hasManyThroughRelation({ modelClass, from, through, to }:AdvancedRelationTypeProps) {\n\treturn {\n\t\trelation: ManyToManyRelation,\n modelClass,\n\t\tjoin: { from, through, to },\n\t};\n};\n\n/*\n Gets the SQL table for the subject, either from the options object or the\n plural version of the subject model.\n*/\nexport function getSubjectTable({ subject, options }:SubjectProps) {\n return options?.subjectTable || pluralize(snakeCase(subject));\n}\n\n/*\n Gets the SQL table for the object, either from the options object or the\n plural version of the object model.\n*/\nexport function getObjectTable({ object, options }:ObjectProps) { \n return options?.objectTable || pluralize(snakeCase(object));\n}\n\n/*\n Gets the SQL foreign key for the subject, either from the options object \n or the snake case of the subject model.\n*/\nexport function getSubjectForeignKey({ subject, options }:SubjectProps) {\n return options?.subjectForeignKey || snakeCase(subject) + '_id';\n}\n\n/*\n Gets the SQL foreign key for the object, either from the options object \n or the snake case of the object model.\n*/\nexport function getObjectForeignKey({ object, options }:ObjectProps) {\n return options?.objectForeignKey || snakeCase(object) + '_id';\n}\n\n/*\n\tDefines a relationship by passing the subject, the predicate, and the object,\n\talong with an optional via model.\n*/\nexport function relation({subject, relType, object, via, options}:RelationProps) {\n\tconst subjectTable = getSubjectTable({subject, options});\n\tconst objectTable = getObjectTable({object, options});\n\tconst subjectForeignKey = getSubjectForeignKey({subject, options});\n\tconst objectForeignKey = getObjectForeignKey({object, options});\n\tlet viaTable;\n\tif (via) viaTable = pluralize(snakeCase(via));\n\tswitch (relType) {\n\t\tcase 'hasOne':\n\t\t\treturn hasOneRelation({\n modelClass: object,\n\t\t\t\tfrom: `${subjectTable}.id`,\n\t\t\t\tto: `${objectTable}.${subjectForeignKey}`\n });\n\t\tcase 'hasMany':\n\t\t\treturn hasManyRelation({\n\t\t\t\tmodelClass: object,\n\t\t\t\tfrom: `${subjectTable}.id`,\n\t\t\t\tto: `${objectTable}.${subjectForeignKey}`\n\t\t\t});\n\t\tcase 'hasManyThrough':\n\t\t\treturn hasManyThroughRelation({\n\t\t\t\tmodelClass: object,\n\t\t\t\tfrom: `${subjectTable}.id`,\n\t\t\t\tthrough: {\n\t\t\t\t\tfrom: `${viaTable}.${subjectForeignKey}`,\n\t\t\t\t\tto: `${viaTable}.${objectForeignKey}`,\n\t\t\t\t},\n\t\t\t\tto: `${objectTable}.id`\n });\n\t\tcase 'belongsTo':\n\t\t\treturn belongsRelation({\n\t\t\t\tmodelClass: object,\n\t\t\t\tfrom: `${subjectTable}.${objectForeignKey}`,\n\t\t\t\tto: `${objectTable}.id`\n });\n\t\tdefault:\n\t\t\tthrow new Error('No valid relationship type specified');\n\t}\n};"],"names":["HasOneRelation","BelongsToOneRelation","HasManyRelation","ManyToManyRelation","Model","belongsRelation","modelClass","from","to","relation","join","hasOneRelation","hasManyRelation","hasManyThroughRelation","through","getSubjectTable","subject","options","subjectTable","pluralize","snakeCase","getObjectTable","object","objectTable","getSubjectForeignKey","subjectForeignKey","getObjectForeignKey","objectForeignKey","relType","via","viaTable","Error"],"mappings":"gOAEA,MAAMA,eACLA,EADKC,qBAELA,EAFKC,gBAGLA,EAHKC,mBAILA,GACGC,iBA6CYC,GAAgBC,WAAEA,EAAFC,KAAcA,EAAdC,GAAoBA,UAC5C,CACNC,SAAUR,EACVK,WAAAA,EACAI,KAAM,CAAEH,KAAAA,EAAMC,GAAAA,aAQAG,GAAeL,WAAEA,EAAFC,KAAcA,EAAdC,GAAoBA,UAC3C,CACNC,SAAUT,EACVM,WAAAA,EACAI,KAAM,CAAEH,KAAAA,EAAMC,GAAAA,aAQAI,GAAgBN,WAAEA,EAAFC,KAAcA,EAAdC,GAAoBA,UAC5C,CACNC,SAAUP,EACJI,WAAAA,EACNI,KAAM,CAAEH,KAAAA,EAAMC,GAAAA,aAQAK,GAAuBP,WAAEA,EAAFC,KAAcA,EAAdO,QAAoBA,EAApBN,GAA6BA,UAC5D,CACNC,SAAUN,EACJG,WAAAA,EACNI,KAAM,CAAEH,KAAAA,EAAMO,QAAAA,EAASN,GAAAA,aAQTO,GAAgBC,QAAEA,EAAFC,QAAWA,iBAChCA,SAAAA,EAASC,eAAgBC,EAAUC,EAAUJ,aAOxCK,GAAeC,OAAEA,EAAFL,QAAUA,iBAC9BA,SAAAA,EAASM,cAAeJ,EAAUC,EAAUE,aAOvCE,GAAqBR,QAAEA,EAAFC,QAAWA,iBACrCA,SAAAA,EAASQ,oBAAqBL,EAAUJ,GAAW,eAO9CU,GAAoBJ,OAAEA,EAAFL,QAAUA,iBACnCA,SAAAA,EAASU,mBAAoBP,EAAUE,GAAU,+PAOnCN,QAACA,EAADY,QAAUA,EAAVN,OAAmBA,EAAnBO,IAA2BA,EAA3BZ,QAAgCA,UAClDC,EAAeH,EAAgB,CAACC,QAAAA,EAASC,QAAAA,IACzCM,EAAcF,EAAe,CAACC,OAAAA,EAAQL,QAAAA,IACtCQ,EAAoBD,EAAqB,CAACR,QAAAA,EAASC,QAAAA,IACnDU,EAAmBD,EAAoB,CAACJ,OAAAA,EAAQL,QAAAA,QAClDa,SACAD,IAAKC,EAAWX,EAAUC,EAAUS,KAChCD,OACF,gBACGjB,EAAe,CACTL,WAAYgB,EACxBf,KAASW,QACTV,MAAOe,KAAeE,UAEnB,iBACGb,EAAgB,CACtBN,WAAYgB,EACZf,KAASW,QACTV,MAAOe,KAAeE,UAEnB,wBACGZ,EAAuB,CAC7BP,WAAYgB,EACZf,KAASW,QACTJ,QAAS,CACRP,QAASuB,KAAYL,IACrBjB,MAAOsB,KAAYH,KAEpBnB,GAAOe,cAEJ,mBACGlB,EAAgB,CACtBC,WAAYgB,EACZf,QAASW,KAAgBS,IACzBnB,GAAOe,wBAGF,IAAIQ,MAAM"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { Model } from 'objection';
|
|
2
|
+
import snakeCase from 'lodash.snakecase';
|
|
3
|
+
import pluralize from 'pluralize';
|
|
4
|
+
|
|
5
|
+
// Dependencies
|
|
6
|
+
const {
|
|
7
|
+
HasOneRelation,
|
|
8
|
+
BelongsToOneRelation,
|
|
9
|
+
HasManyRelation,
|
|
10
|
+
ManyToManyRelation
|
|
11
|
+
} = Model;
|
|
12
|
+
/*
|
|
13
|
+
Defines a relationship where a record in one model can belong to a record in
|
|
14
|
+
another model.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
function belongsRelation({
|
|
18
|
+
modelClass,
|
|
19
|
+
from,
|
|
20
|
+
to
|
|
21
|
+
}) {
|
|
22
|
+
return {
|
|
23
|
+
relation: BelongsToOneRelation,
|
|
24
|
+
modelClass,
|
|
25
|
+
join: {
|
|
26
|
+
from,
|
|
27
|
+
to
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/*
|
|
32
|
+
Defines a relationship where a record in one model can own a record in another
|
|
33
|
+
model.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
function hasOneRelation({
|
|
37
|
+
modelClass,
|
|
38
|
+
from,
|
|
39
|
+
to
|
|
40
|
+
}) {
|
|
41
|
+
return {
|
|
42
|
+
relation: HasOneRelation,
|
|
43
|
+
modelClass,
|
|
44
|
+
join: {
|
|
45
|
+
from,
|
|
46
|
+
to
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/*
|
|
51
|
+
Defines a relationship where a record in one model can own many records in
|
|
52
|
+
another model.
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
function hasManyRelation({
|
|
56
|
+
modelClass,
|
|
57
|
+
from,
|
|
58
|
+
to
|
|
59
|
+
}) {
|
|
60
|
+
return {
|
|
61
|
+
relation: HasManyRelation,
|
|
62
|
+
modelClass,
|
|
63
|
+
join: {
|
|
64
|
+
from,
|
|
65
|
+
to
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/*
|
|
70
|
+
Defines a relationship where a record in one model can own many records in
|
|
71
|
+
another model, via a join table
|
|
72
|
+
*/
|
|
73
|
+
|
|
74
|
+
function hasManyThroughRelation({
|
|
75
|
+
modelClass,
|
|
76
|
+
from,
|
|
77
|
+
through,
|
|
78
|
+
to
|
|
79
|
+
}) {
|
|
80
|
+
return {
|
|
81
|
+
relation: ManyToManyRelation,
|
|
82
|
+
modelClass,
|
|
83
|
+
join: {
|
|
84
|
+
from,
|
|
85
|
+
through,
|
|
86
|
+
to
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/*
|
|
91
|
+
Gets the SQL table for the subject, either from the options object or the
|
|
92
|
+
plural version of the subject model.
|
|
93
|
+
*/
|
|
94
|
+
|
|
95
|
+
function getSubjectTable({
|
|
96
|
+
subject,
|
|
97
|
+
options
|
|
98
|
+
}) {
|
|
99
|
+
return (options == null ? void 0 : options.subjectTable) || pluralize(snakeCase(subject));
|
|
100
|
+
}
|
|
101
|
+
/*
|
|
102
|
+
Gets the SQL table for the object, either from the options object or the
|
|
103
|
+
plural version of the object model.
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
function getObjectTable({
|
|
107
|
+
object,
|
|
108
|
+
options
|
|
109
|
+
}) {
|
|
110
|
+
return (options == null ? void 0 : options.objectTable) || pluralize(snakeCase(object));
|
|
111
|
+
}
|
|
112
|
+
/*
|
|
113
|
+
Gets the SQL foreign key for the subject, either from the options object
|
|
114
|
+
or the snake case of the subject model.
|
|
115
|
+
*/
|
|
116
|
+
|
|
117
|
+
function getSubjectForeignKey({
|
|
118
|
+
subject,
|
|
119
|
+
options
|
|
120
|
+
}) {
|
|
121
|
+
return (options == null ? void 0 : options.subjectForeignKey) || snakeCase(subject) + '_id';
|
|
122
|
+
}
|
|
123
|
+
/*
|
|
124
|
+
Gets the SQL foreign key for the object, either from the options object
|
|
125
|
+
or the snake case of the object model.
|
|
126
|
+
*/
|
|
127
|
+
|
|
128
|
+
function getObjectForeignKey({
|
|
129
|
+
object,
|
|
130
|
+
options
|
|
131
|
+
}) {
|
|
132
|
+
return (options == null ? void 0 : options.objectForeignKey) || snakeCase(object) + '_id';
|
|
133
|
+
}
|
|
134
|
+
/*
|
|
135
|
+
Defines a relationship by passing the subject, the predicate, and the object,
|
|
136
|
+
along with an optional via model.
|
|
137
|
+
*/
|
|
138
|
+
|
|
139
|
+
function relation({
|
|
140
|
+
subject,
|
|
141
|
+
relType,
|
|
142
|
+
object,
|
|
143
|
+
via,
|
|
144
|
+
options
|
|
145
|
+
}) {
|
|
146
|
+
const subjectTable = getSubjectTable({
|
|
147
|
+
subject,
|
|
148
|
+
options
|
|
149
|
+
});
|
|
150
|
+
const objectTable = getObjectTable({
|
|
151
|
+
object,
|
|
152
|
+
options
|
|
153
|
+
});
|
|
154
|
+
const subjectForeignKey = getSubjectForeignKey({
|
|
155
|
+
subject,
|
|
156
|
+
options
|
|
157
|
+
});
|
|
158
|
+
const objectForeignKey = getObjectForeignKey({
|
|
159
|
+
object,
|
|
160
|
+
options
|
|
161
|
+
});
|
|
162
|
+
let viaTable;
|
|
163
|
+
if (via) viaTable = pluralize(snakeCase(via));
|
|
164
|
+
|
|
165
|
+
switch (relType) {
|
|
166
|
+
case 'hasOne':
|
|
167
|
+
return hasOneRelation({
|
|
168
|
+
modelClass: object,
|
|
169
|
+
from: `${subjectTable}.id`,
|
|
170
|
+
to: `${objectTable}.${subjectForeignKey}`
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
case 'hasMany':
|
|
174
|
+
return hasManyRelation({
|
|
175
|
+
modelClass: object,
|
|
176
|
+
from: `${subjectTable}.id`,
|
|
177
|
+
to: `${objectTable}.${subjectForeignKey}`
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
case 'hasManyThrough':
|
|
181
|
+
return hasManyThroughRelation({
|
|
182
|
+
modelClass: object,
|
|
183
|
+
from: `${subjectTable}.id`,
|
|
184
|
+
through: {
|
|
185
|
+
from: `${viaTable}.${subjectForeignKey}`,
|
|
186
|
+
to: `${viaTable}.${objectForeignKey}`
|
|
187
|
+
},
|
|
188
|
+
to: `${objectTable}.id`
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
case 'belongsTo':
|
|
192
|
+
return belongsRelation({
|
|
193
|
+
modelClass: object,
|
|
194
|
+
from: `${subjectTable}.${objectForeignKey}`,
|
|
195
|
+
to: `${objectTable}.id`
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
default:
|
|
199
|
+
throw new Error('No valid relationship type specified');
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export { belongsRelation, getObjectForeignKey, getObjectTable, getSubjectForeignKey, getSubjectTable, hasManyRelation, hasManyThroughRelation, hasOneRelation, relation };
|
|
204
|
+
//# sourceMappingURL=objection-relations.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"objection-relations.esm.js","sources":["../src/index.ts"],"sourcesContent":["// Dependencies\nimport { Model } from 'objection';\nconst {\n\tHasOneRelation,\n\tBelongsToOneRelation,\n\tHasManyRelation,\n\tManyToManyRelation,\n} = Model;\nimport snakeCase from 'lodash.snakecase';\nimport pluralize from 'pluralize';\n\ntype CommonRelationOrTableOrForeignKeyProps = {\n options?: {\n subjectTable?: string;\n objectTable?: string;\n subjectForeignKey?: string;\n objectForeignKey?: string;\n }\n}\n\ntype RelationProps = CommonRelationOrTableOrForeignKeyProps & {\n subject: string;\n relType: 'hasOne' | 'hasMany' | 'hasManyThrough' | 'belongsTo';\n object: string;\n via?: string;\n}\n\ntype RelationTypeProps = {\n modelClass: string;\n from: string;\n to: string;\n};\n\ntype AdvancedRelationTypeProps = RelationTypeProps & {\n through: {\n from: string;\n to: string;\n };\n}\n\ntype SubjectProps = CommonRelationOrTableOrForeignKeyProps & {\n subject: string;\n}\n\ntype ObjectProps = CommonRelationOrTableOrForeignKeyProps & {\n object: string;\n}\n\n/*\n Defines a relationship where a record in one model can belong to a record in\n another model.\n*/\nexport function belongsRelation({ modelClass, from, to }:RelationTypeProps) {\n\treturn {\n\t\trelation: BelongsToOneRelation,\n\t\tmodelClass,\n\t\tjoin: { from, to },\n\t};\n};\n\n/*\n\tDefines a relationship where a record in one model can own a record in another\n\tmodel.\n*/\nexport function hasOneRelation({ modelClass, from, to }:RelationTypeProps) {\n\treturn {\n\t\trelation: HasOneRelation,\n\t\tmodelClass,\n\t\tjoin: { from, to },\n\t};\n};\n\n/*\n\tDefines a relationship where a record in one model can own many records in\n\tanother model.\n*/\nexport function hasManyRelation({ modelClass, from, to }:RelationTypeProps) {\n\treturn {\n\t\trelation: HasManyRelation,\n modelClass,\n\t\tjoin: { from, to },\n\t};\n};\n\n/*\n\tDefines a relationship where a record in one model can own many records in\n\tanother model, via a join table\n*/\nexport function hasManyThroughRelation({ modelClass, from, through, to }:AdvancedRelationTypeProps) {\n\treturn {\n\t\trelation: ManyToManyRelation,\n modelClass,\n\t\tjoin: { from, through, to },\n\t};\n};\n\n/*\n Gets the SQL table for the subject, either from the options object or the\n plural version of the subject model.\n*/\nexport function getSubjectTable({ subject, options }:SubjectProps) {\n return options?.subjectTable || pluralize(snakeCase(subject));\n}\n\n/*\n Gets the SQL table for the object, either from the options object or the\n plural version of the object model.\n*/\nexport function getObjectTable({ object, options }:ObjectProps) { \n return options?.objectTable || pluralize(snakeCase(object));\n}\n\n/*\n Gets the SQL foreign key for the subject, either from the options object \n or the snake case of the subject model.\n*/\nexport function getSubjectForeignKey({ subject, options }:SubjectProps) {\n return options?.subjectForeignKey || snakeCase(subject) + '_id';\n}\n\n/*\n Gets the SQL foreign key for the object, either from the options object \n or the snake case of the object model.\n*/\nexport function getObjectForeignKey({ object, options }:ObjectProps) {\n return options?.objectForeignKey || snakeCase(object) + '_id';\n}\n\n/*\n\tDefines a relationship by passing the subject, the predicate, and the object,\n\talong with an optional via model.\n*/\nexport function relation({subject, relType, object, via, options}:RelationProps) {\n\tconst subjectTable = getSubjectTable({subject, options});\n\tconst objectTable = getObjectTable({object, options});\n\tconst subjectForeignKey = getSubjectForeignKey({subject, options});\n\tconst objectForeignKey = getObjectForeignKey({object, options});\n\tlet viaTable;\n\tif (via) viaTable = pluralize(snakeCase(via));\n\tswitch (relType) {\n\t\tcase 'hasOne':\n\t\t\treturn hasOneRelation({\n modelClass: object,\n\t\t\t\tfrom: `${subjectTable}.id`,\n\t\t\t\tto: `${objectTable}.${subjectForeignKey}`\n });\n\t\tcase 'hasMany':\n\t\t\treturn hasManyRelation({\n\t\t\t\tmodelClass: object,\n\t\t\t\tfrom: `${subjectTable}.id`,\n\t\t\t\tto: `${objectTable}.${subjectForeignKey}`\n\t\t\t});\n\t\tcase 'hasManyThrough':\n\t\t\treturn hasManyThroughRelation({\n\t\t\t\tmodelClass: object,\n\t\t\t\tfrom: `${subjectTable}.id`,\n\t\t\t\tthrough: {\n\t\t\t\t\tfrom: `${viaTable}.${subjectForeignKey}`,\n\t\t\t\t\tto: `${viaTable}.${objectForeignKey}`,\n\t\t\t\t},\n\t\t\t\tto: `${objectTable}.id`\n });\n\t\tcase 'belongsTo':\n\t\t\treturn belongsRelation({\n\t\t\t\tmodelClass: object,\n\t\t\t\tfrom: `${subjectTable}.${objectForeignKey}`,\n\t\t\t\tto: `${objectTable}.id`\n });\n\t\tdefault:\n\t\t\tthrow new Error('No valid relationship type specified');\n\t}\n};"],"names":["HasOneRelation","BelongsToOneRelation","HasManyRelation","ManyToManyRelation","Model","belongsRelation","modelClass","from","to","relation","join","hasOneRelation","hasManyRelation","hasManyThroughRelation","through","getSubjectTable","subject","options","subjectTable","pluralize","snakeCase","getObjectTable","object","objectTable","getSubjectForeignKey","subjectForeignKey","getObjectForeignKey","objectForeignKey","relType","via","viaTable","Error"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.0.1",
|
|
3
|
+
"license": "MIT",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"typings": "dist/index.d.ts",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist",
|
|
8
|
+
"src"
|
|
9
|
+
],
|
|
10
|
+
"engines": {
|
|
11
|
+
"node": ">=10"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"lodash.snakecase": "^4.1.1",
|
|
15
|
+
"objection": "^3.0.1",
|
|
16
|
+
"pluralize": "^8.0.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@size-limit/preset-small-lib": "^7.0.8",
|
|
20
|
+
"@types/jest": "^27.4.0",
|
|
21
|
+
"@types/lodash.snakecase": "^4.1.6",
|
|
22
|
+
"@types/pluralize": "^0.0.29",
|
|
23
|
+
"husky": "^7.0.4",
|
|
24
|
+
"npm-upgrade": "^3.1.0",
|
|
25
|
+
"size-limit": "^7.0.8",
|
|
26
|
+
"tsdx": "^0.14.1",
|
|
27
|
+
"tslib": "^1.14.1",
|
|
28
|
+
"typescript": "^4.5.5"
|
|
29
|
+
},
|
|
30
|
+
"author": "Paul Jensen <paul@anephenix.com>",
|
|
31
|
+
"scripts": {
|
|
32
|
+
"start": "tsdx watch --target node",
|
|
33
|
+
"build": "tsdx build --target node",
|
|
34
|
+
"test": "tsdx test",
|
|
35
|
+
"lint": "tsdx lint",
|
|
36
|
+
"prepare": "tsdx build --target node",
|
|
37
|
+
"size": "size-limit",
|
|
38
|
+
"analyze": "size-limit --why"
|
|
39
|
+
},
|
|
40
|
+
"husky": {
|
|
41
|
+
"hooks": {
|
|
42
|
+
"pre-commit": "tsdx lint && tsdx test"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"name": "@anephenix/objection-relations",
|
|
46
|
+
"module": "dist/objection-relations.esm.js",
|
|
47
|
+
"prettier": {
|
|
48
|
+
"printWidth": 80,
|
|
49
|
+
"semi": true,
|
|
50
|
+
"singleQuote": true,
|
|
51
|
+
"trailingComma": "es5"
|
|
52
|
+
},
|
|
53
|
+
"size-limit": [
|
|
54
|
+
{
|
|
55
|
+
"path": "dist/objection-relations.cjs.production.min.js",
|
|
56
|
+
"limit": "10 KB"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"path": "dist/objection-relations.esm.js",
|
|
60
|
+
"limit": "10 KB"
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
// Dependencies
|
|
2
|
+
import { Model } from 'objection';
|
|
3
|
+
const {
|
|
4
|
+
HasOneRelation,
|
|
5
|
+
BelongsToOneRelation,
|
|
6
|
+
HasManyRelation,
|
|
7
|
+
ManyToManyRelation,
|
|
8
|
+
} = Model;
|
|
9
|
+
import snakeCase from 'lodash.snakecase';
|
|
10
|
+
import pluralize from 'pluralize';
|
|
11
|
+
|
|
12
|
+
type CommonRelationOrTableOrForeignKeyProps = {
|
|
13
|
+
options?: {
|
|
14
|
+
subjectTable?: string;
|
|
15
|
+
objectTable?: string;
|
|
16
|
+
subjectForeignKey?: string;
|
|
17
|
+
objectForeignKey?: string;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type RelationProps = CommonRelationOrTableOrForeignKeyProps & {
|
|
22
|
+
subject: string;
|
|
23
|
+
relType: 'hasOne' | 'hasMany' | 'hasManyThrough' | 'belongsTo';
|
|
24
|
+
object: string;
|
|
25
|
+
via?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type RelationTypeProps = {
|
|
29
|
+
modelClass: string;
|
|
30
|
+
from: string;
|
|
31
|
+
to: string;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
type AdvancedRelationTypeProps = RelationTypeProps & {
|
|
35
|
+
through: {
|
|
36
|
+
from: string;
|
|
37
|
+
to: string;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
type SubjectProps = CommonRelationOrTableOrForeignKeyProps & {
|
|
42
|
+
subject: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
type ObjectProps = CommonRelationOrTableOrForeignKeyProps & {
|
|
46
|
+
object: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/*
|
|
50
|
+
Defines a relationship where a record in one model can belong to a record in
|
|
51
|
+
another model.
|
|
52
|
+
*/
|
|
53
|
+
export function belongsRelation({ modelClass, from, to }:RelationTypeProps) {
|
|
54
|
+
return {
|
|
55
|
+
relation: BelongsToOneRelation,
|
|
56
|
+
modelClass,
|
|
57
|
+
join: { from, to },
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/*
|
|
62
|
+
Defines a relationship where a record in one model can own a record in another
|
|
63
|
+
model.
|
|
64
|
+
*/
|
|
65
|
+
export function hasOneRelation({ modelClass, from, to }:RelationTypeProps) {
|
|
66
|
+
return {
|
|
67
|
+
relation: HasOneRelation,
|
|
68
|
+
modelClass,
|
|
69
|
+
join: { from, to },
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/*
|
|
74
|
+
Defines a relationship where a record in one model can own many records in
|
|
75
|
+
another model.
|
|
76
|
+
*/
|
|
77
|
+
export function hasManyRelation({ modelClass, from, to }:RelationTypeProps) {
|
|
78
|
+
return {
|
|
79
|
+
relation: HasManyRelation,
|
|
80
|
+
modelClass,
|
|
81
|
+
join: { from, to },
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/*
|
|
86
|
+
Defines a relationship where a record in one model can own many records in
|
|
87
|
+
another model, via a join table
|
|
88
|
+
*/
|
|
89
|
+
export function hasManyThroughRelation({ modelClass, from, through, to }:AdvancedRelationTypeProps) {
|
|
90
|
+
return {
|
|
91
|
+
relation: ManyToManyRelation,
|
|
92
|
+
modelClass,
|
|
93
|
+
join: { from, through, to },
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/*
|
|
98
|
+
Gets the SQL table for the subject, either from the options object or the
|
|
99
|
+
plural version of the subject model.
|
|
100
|
+
*/
|
|
101
|
+
export function getSubjectTable({ subject, options }:SubjectProps) {
|
|
102
|
+
return options?.subjectTable || pluralize(snakeCase(subject));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/*
|
|
106
|
+
Gets the SQL table for the object, either from the options object or the
|
|
107
|
+
plural version of the object model.
|
|
108
|
+
*/
|
|
109
|
+
export function getObjectTable({ object, options }:ObjectProps) {
|
|
110
|
+
return options?.objectTable || pluralize(snakeCase(object));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/*
|
|
114
|
+
Gets the SQL foreign key for the subject, either from the options object
|
|
115
|
+
or the snake case of the subject model.
|
|
116
|
+
*/
|
|
117
|
+
export function getSubjectForeignKey({ subject, options }:SubjectProps) {
|
|
118
|
+
return options?.subjectForeignKey || snakeCase(subject) + '_id';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/*
|
|
122
|
+
Gets the SQL foreign key for the object, either from the options object
|
|
123
|
+
or the snake case of the object model.
|
|
124
|
+
*/
|
|
125
|
+
export function getObjectForeignKey({ object, options }:ObjectProps) {
|
|
126
|
+
return options?.objectForeignKey || snakeCase(object) + '_id';
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/*
|
|
130
|
+
Defines a relationship by passing the subject, the predicate, and the object,
|
|
131
|
+
along with an optional via model.
|
|
132
|
+
*/
|
|
133
|
+
export function relation({subject, relType, object, via, options}:RelationProps) {
|
|
134
|
+
const subjectTable = getSubjectTable({subject, options});
|
|
135
|
+
const objectTable = getObjectTable({object, options});
|
|
136
|
+
const subjectForeignKey = getSubjectForeignKey({subject, options});
|
|
137
|
+
const objectForeignKey = getObjectForeignKey({object, options});
|
|
138
|
+
let viaTable;
|
|
139
|
+
if (via) viaTable = pluralize(snakeCase(via));
|
|
140
|
+
switch (relType) {
|
|
141
|
+
case 'hasOne':
|
|
142
|
+
return hasOneRelation({
|
|
143
|
+
modelClass: object,
|
|
144
|
+
from: `${subjectTable}.id`,
|
|
145
|
+
to: `${objectTable}.${subjectForeignKey}`
|
|
146
|
+
});
|
|
147
|
+
case 'hasMany':
|
|
148
|
+
return hasManyRelation({
|
|
149
|
+
modelClass: object,
|
|
150
|
+
from: `${subjectTable}.id`,
|
|
151
|
+
to: `${objectTable}.${subjectForeignKey}`
|
|
152
|
+
});
|
|
153
|
+
case 'hasManyThrough':
|
|
154
|
+
return hasManyThroughRelation({
|
|
155
|
+
modelClass: object,
|
|
156
|
+
from: `${subjectTable}.id`,
|
|
157
|
+
through: {
|
|
158
|
+
from: `${viaTable}.${subjectForeignKey}`,
|
|
159
|
+
to: `${viaTable}.${objectForeignKey}`,
|
|
160
|
+
},
|
|
161
|
+
to: `${objectTable}.id`
|
|
162
|
+
});
|
|
163
|
+
case 'belongsTo':
|
|
164
|
+
return belongsRelation({
|
|
165
|
+
modelClass: object,
|
|
166
|
+
from: `${subjectTable}.${objectForeignKey}`,
|
|
167
|
+
to: `${objectTable}.id`
|
|
168
|
+
});
|
|
169
|
+
default:
|
|
170
|
+
throw new Error('No valid relationship type specified');
|
|
171
|
+
}
|
|
172
|
+
};
|