@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 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.
@@ -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,8 @@
1
+
2
+ 'use strict'
3
+
4
+ if (process.env.NODE_ENV === 'production') {
5
+ module.exports = require('./objection-relations.cjs.production.min.js')
6
+ } else {
7
+ module.exports = require('./objection-relations.cjs.development.js')
8
+ }
@@ -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
+ };