@anephenix/objection-relations
Advanced tools
Comparing version 0.0.1 to 0.0.2
@@ -1,80 +0,43 @@ | ||
declare type CommonRelationOrTableOrForeignKeyProps = { | ||
options?: { | ||
subjectTable?: string; | ||
objectTable?: string; | ||
subjectForeignKey?: string; | ||
objectForeignKey?: string; | ||
}; | ||
}; | ||
declare type RelationProps = CommonRelationOrTableOrForeignKeyProps & { | ||
import { OptionsProps } from './global'; | ||
declare type ObjectionRelationProps = { | ||
subject: string; | ||
relType: 'hasOne' | 'hasMany' | 'hasManyThrough' | 'belongsTo'; | ||
object: string; | ||
via?: string; | ||
modelPath: string; | ||
}; | ||
declare type RelationTypeProps = { | ||
modelClass: string; | ||
from: string; | ||
to: string; | ||
}; | ||
declare type AdvancedRelationTypeProps = RelationTypeProps & { | ||
through: { | ||
from: string; | ||
to: string; | ||
}; | ||
}; | ||
declare type SubjectProps = CommonRelationOrTableOrForeignKeyProps & { | ||
export declare class ObjectionRelation { | ||
subject: string; | ||
}; | ||
declare type ObjectProps = CommonRelationOrTableOrForeignKeyProps & { | ||
object: string; | ||
}; | ||
export declare function belongsRelation({ modelClass, from, to }: RelationTypeProps): { | ||
relation: import("objection").RelationType; | ||
modelClass: string; | ||
join: { | ||
from: string; | ||
to: string; | ||
modelPath: string; | ||
constructor({ subject, modelPath }: ObjectionRelationProps); | ||
belongsTo(object: string, options?: OptionsProps): { | ||
relation: import("objection").RelationType; | ||
modelClass: string; | ||
join: { | ||
from: string; | ||
to: string; | ||
}; | ||
}; | ||
}; | ||
export declare function hasOneRelation({ modelClass, from, to }: RelationTypeProps): { | ||
relation: import("objection").RelationType; | ||
modelClass: string; | ||
join: { | ||
from: string; | ||
to: string; | ||
hasOne(object: string, options?: OptionsProps): { | ||
relation: import("objection").RelationType; | ||
modelClass: string; | ||
join: { | ||
from: string; | ||
to: string; | ||
}; | ||
}; | ||
}; | ||
export declare function hasManyRelation({ modelClass, from, to }: RelationTypeProps): { | ||
relation: import("objection").RelationType; | ||
modelClass: string; | ||
join: { | ||
from: string; | ||
to: string; | ||
hasMany(object: string, options?: OptionsProps): { | ||
relation: import("objection").RelationType; | ||
modelClass: string; | ||
join: { | ||
from: string; | ||
to: string; | ||
}; | ||
}; | ||
}; | ||
export declare function hasManyThroughRelation({ modelClass, from, through, to }: AdvancedRelationTypeProps): { | ||
relation: import("objection").RelationType; | ||
modelClass: string; | ||
join: { | ||
from: string; | ||
through: { | ||
hasManyThrough(object: string, via: string, options?: OptionsProps): { | ||
relation: import("objection").RelationType; | ||
modelClass: string; | ||
join: { | ||
from: string; | ||
to: string; | ||
}; | ||
to: string; | ||
}; | ||
}; | ||
export declare function getSubjectTable({ subject, options }: SubjectProps): string; | ||
export declare function getObjectTable({ object, options }: ObjectProps): string; | ||
export declare function getSubjectForeignKey({ subject, options }: SubjectProps): string; | ||
export declare function getObjectForeignKey({ object, options }: ObjectProps): string; | ||
export declare function relation({ subject, relType, object, via, options }: RelationProps): { | ||
relation: import("objection").RelationType; | ||
modelClass: string; | ||
join: { | ||
from: string; | ||
to: string; | ||
}; | ||
}; | ||
} | ||
export {}; |
@@ -10,3 +10,62 @@ 'use strict'; | ||
var pluralize = _interopDefault(require('pluralize')); | ||
var path = require('path'); | ||
/* | ||
Gets the SQL table for the subject, either from the options object or the | ||
plural version of the subject model. | ||
*/ | ||
function getSubjectTable({ | ||
subject, | ||
options | ||
}) { | ||
return (options == null ? void 0 : options.subjectTable) || pluralize(snakeCase(subject)); | ||
} | ||
/* | ||
Gets the SQL table for the object, either from the options object or the | ||
plural version of the object model. | ||
*/ | ||
function getObjectTable({ | ||
object, | ||
options | ||
}) { | ||
return (options == null ? void 0 : options.objectTable) || pluralize(snakeCase(object)); | ||
} | ||
/* | ||
Gets the SQL foreign key for the subject, either from the options object | ||
or the snake case of the subject model. | ||
*/ | ||
function getSubjectForeignKey({ | ||
subject, | ||
options | ||
}) { | ||
return (options == null ? void 0 : options.subjectForeignKey) || snakeCase(subject) + '_id'; | ||
} | ||
/* | ||
Gets the SQL foreign key for the object, either from the options object | ||
or the snake case of the object model. | ||
*/ | ||
function getObjectForeignKey({ | ||
object, | ||
options | ||
}) { | ||
return (options == null ? void 0 : options.objectForeignKey) || snakeCase(object) + '_id'; | ||
} | ||
/* | ||
Allows you to define the model path for a model | ||
*/ | ||
function getModelClass({ | ||
object, | ||
options | ||
}) { | ||
return options != null && options.modelPath ? path.join(options.modelPath, object) : object; | ||
} | ||
function getViaTable(via) { | ||
return via ? pluralize(snakeCase(via)) : null; | ||
} | ||
// Dependencies | ||
@@ -98,46 +157,2 @@ const { | ||
/* | ||
Gets the SQL table for the subject, either from the options object or the | ||
plural version of the subject model. | ||
*/ | ||
function getSubjectTable({ | ||
subject, | ||
options | ||
}) { | ||
return (options == null ? void 0 : options.subjectTable) || pluralize(snakeCase(subject)); | ||
} | ||
/* | ||
Gets the SQL table for the object, either from the options object or the | ||
plural version of the object model. | ||
*/ | ||
function getObjectTable({ | ||
object, | ||
options | ||
}) { | ||
return (options == null ? void 0 : options.objectTable) || pluralize(snakeCase(object)); | ||
} | ||
/* | ||
Gets the SQL foreign key for the subject, either from the options object | ||
or the snake case of the subject model. | ||
*/ | ||
function getSubjectForeignKey({ | ||
subject, | ||
options | ||
}) { | ||
return (options == null ? void 0 : options.subjectForeignKey) || snakeCase(subject) + '_id'; | ||
} | ||
/* | ||
Gets the SQL foreign key for the object, either from the options object | ||
or the snake case of the object model. | ||
*/ | ||
function getObjectForeignKey({ | ||
object, | ||
options | ||
}) { | ||
return (options == null ? void 0 : options.objectForeignKey) || snakeCase(object) + '_id'; | ||
} | ||
/* | ||
Defines a relationship by passing the subject, the predicate, and the object, | ||
@@ -170,4 +185,7 @@ along with an optional via model. | ||
}); | ||
let viaTable; | ||
if (via) viaTable = pluralize(snakeCase(via)); | ||
const modelClass = getModelClass({ | ||
object, | ||
options | ||
}); | ||
const viaTable = getViaTable(via); | ||
@@ -177,3 +195,3 @@ switch (relType) { | ||
return hasOneRelation({ | ||
modelClass: object, | ||
modelClass, | ||
from: `${subjectTable}.id`, | ||
@@ -185,3 +203,3 @@ to: `${objectTable}.${subjectForeignKey}` | ||
return hasManyRelation({ | ||
modelClass: object, | ||
modelClass, | ||
from: `${subjectTable}.id`, | ||
@@ -193,3 +211,3 @@ to: `${objectTable}.${subjectForeignKey}` | ||
return hasManyThroughRelation({ | ||
modelClass: object, | ||
modelClass, | ||
from: `${subjectTable}.id`, | ||
@@ -205,3 +223,3 @@ through: { | ||
return belongsRelation({ | ||
modelClass: object, | ||
modelClass, | ||
from: `${subjectTable}.${objectForeignKey}`, | ||
@@ -216,11 +234,67 @@ to: `${objectTable}.id` | ||
exports.belongsRelation = belongsRelation; | ||
exports.getObjectForeignKey = getObjectForeignKey; | ||
exports.getObjectTable = getObjectTable; | ||
exports.getSubjectForeignKey = getSubjectForeignKey; | ||
exports.getSubjectTable = getSubjectTable; | ||
exports.hasManyRelation = hasManyRelation; | ||
exports.hasManyThroughRelation = hasManyThroughRelation; | ||
exports.hasOneRelation = hasOneRelation; | ||
exports.relation = relation; | ||
class ObjectionRelation { | ||
constructor({ | ||
subject, | ||
modelPath | ||
}) { | ||
this.subject = subject; | ||
this.modelPath = modelPath; | ||
} | ||
belongsTo(object, options) { | ||
if (!options) options = { | ||
modelPath: this.modelPath | ||
}; | ||
if (!options.modelPath) options.modelPath = this.modelPath; | ||
return relation({ | ||
subject: this.subject, | ||
relType: 'belongsTo', | ||
object, | ||
options | ||
}); | ||
} | ||
hasOne(object, options) { | ||
if (!options) options = { | ||
modelPath: this.modelPath | ||
}; | ||
if (!options.modelPath) options.modelPath = this.modelPath; | ||
return relation({ | ||
subject: this.subject, | ||
relType: 'hasOne', | ||
object, | ||
options | ||
}); | ||
} | ||
hasMany(object, options) { | ||
if (!options) options = { | ||
modelPath: this.modelPath | ||
}; | ||
if (!options.modelPath) options.modelPath = this.modelPath; | ||
return relation({ | ||
subject: this.subject, | ||
relType: 'hasMany', | ||
object, | ||
options | ||
}); | ||
} | ||
hasManyThrough(object, via, options) { | ||
if (!options) options = { | ||
modelPath: this.modelPath | ||
}; | ||
if (!options.modelPath) options.modelPath = this.modelPath; | ||
return relation({ | ||
subject: this.subject, | ||
relType: 'hasManyThrough', | ||
object, | ||
via, | ||
options | ||
}); | ||
} | ||
} | ||
exports.ObjectionRelation = ObjectionRelation; | ||
//# sourceMappingURL=objection-relations.cjs.development.js.map |
@@ -1,2 +0,2 @@ | ||
"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")}}; | ||
"use strict";function o(o){return o&&"object"==typeof o&&"default"in o?o.default:o}Object.defineProperty(exports,"__esModule",{value:!0});var t=require("objection"),e=o(require("lodash.snakecase")),n=o(require("pluralize")),s=require("path");const{HasOneRelation:l,BelongsToOneRelation:r,HasManyRelation:a,ManyToManyRelation:i}=t.Model;function u({subject:o,relType:t,object:u,via:h,options:c}){const d=function({subject:o,options:t}){return(null==t?void 0:t.subjectTable)||n(e(o))}({subject:o,options:c}),m=function({object:o,options:t}){return(null==t?void 0:t.objectTable)||n(e(o))}({object:u,options:c}),b=function({subject:o,options:t}){return(null==t?void 0:t.subjectForeignKey)||e(o)+"_id"}({subject:o,options:c}),j=function({object:o,options:t}){return(null==t?void 0:t.objectForeignKey)||e(o)+"_id"}({object:u,options:c}),f=function({object:o,options:t}){return null!=t&&t.modelPath?s.join(t.modelPath,o):o}({object:u,options:c}),p=function(o){return o?n(e(o)):null}(h);switch(t){case"hasOne":return function({modelClass:o,from:t,to:e}){return{relation:l,modelClass:o,join:{from:t,to:e}}}({modelClass:f,from:d+".id",to:`${m}.${b}`});case"hasMany":return function({modelClass:o,from:t,to:e}){return{relation:a,modelClass:o,join:{from:t,to:e}}}({modelClass:f,from:d+".id",to:`${m}.${b}`});case"hasManyThrough":return function({modelClass:o,from:t,through:e,to:n}){return{relation:i,modelClass:o,join:{from:t,through:e,to:n}}}({modelClass:f,from:d+".id",through:{from:`${p}.${b}`,to:`${p}.${j}`},to:m+".id"});case"belongsTo":return function({modelClass:o,from:t,to:e}){return{relation:r,modelClass:o,join:{from:t,to:e}}}({modelClass:f,from:`${d}.${j}`,to:m+".id"});default:throw new Error("No valid relationship type specified")}}exports.ObjectionRelation=class{constructor({subject:o,modelPath:t}){this.subject=o,this.modelPath=t}belongsTo(o,t){return t||(t={modelPath:this.modelPath}),t.modelPath||(t.modelPath=this.modelPath),u({subject:this.subject,relType:"belongsTo",object:o,options:t})}hasOne(o,t){return t||(t={modelPath:this.modelPath}),t.modelPath||(t.modelPath=this.modelPath),u({subject:this.subject,relType:"hasOne",object:o,options:t})}hasMany(o,t){return t||(t={modelPath:this.modelPath}),t.modelPath||(t.modelPath=this.modelPath),u({subject:this.subject,relType:"hasMany",object:o,options:t})}hasManyThrough(o,t,e){return e||(e={modelPath:this.modelPath}),e.modelPath||(e.modelPath=this.modelPath),u({subject:this.subject,relType:"hasManyThrough",object:o,via:t,options:e})}}; | ||
//# sourceMappingURL=objection-relations.cjs.production.min.js.map |
import { Model } from 'objection'; | ||
import snakeCase from 'lodash.snakecase'; | ||
import pluralize from 'pluralize'; | ||
import { join } from 'path'; | ||
/* | ||
Gets the SQL table for the subject, either from the options object or the | ||
plural version of the subject model. | ||
*/ | ||
function getSubjectTable({ | ||
subject, | ||
options | ||
}) { | ||
return (options == null ? void 0 : options.subjectTable) || pluralize(snakeCase(subject)); | ||
} | ||
/* | ||
Gets the SQL table for the object, either from the options object or the | ||
plural version of the object model. | ||
*/ | ||
function getObjectTable({ | ||
object, | ||
options | ||
}) { | ||
return (options == null ? void 0 : options.objectTable) || pluralize(snakeCase(object)); | ||
} | ||
/* | ||
Gets the SQL foreign key for the subject, either from the options object | ||
or the snake case of the subject model. | ||
*/ | ||
function getSubjectForeignKey({ | ||
subject, | ||
options | ||
}) { | ||
return (options == null ? void 0 : options.subjectForeignKey) || snakeCase(subject) + '_id'; | ||
} | ||
/* | ||
Gets the SQL foreign key for the object, either from the options object | ||
or the snake case of the object model. | ||
*/ | ||
function getObjectForeignKey({ | ||
object, | ||
options | ||
}) { | ||
return (options == null ? void 0 : options.objectForeignKey) || snakeCase(object) + '_id'; | ||
} | ||
/* | ||
Allows you to define the model path for a model | ||
*/ | ||
function getModelClass({ | ||
object, | ||
options | ||
}) { | ||
return options != null && options.modelPath ? join(options.modelPath, object) : object; | ||
} | ||
function getViaTable(via) { | ||
return via ? pluralize(snakeCase(via)) : null; | ||
} | ||
// Dependencies | ||
@@ -91,46 +150,2 @@ const { | ||
/* | ||
Gets the SQL table for the subject, either from the options object or the | ||
plural version of the subject model. | ||
*/ | ||
function getSubjectTable({ | ||
subject, | ||
options | ||
}) { | ||
return (options == null ? void 0 : options.subjectTable) || pluralize(snakeCase(subject)); | ||
} | ||
/* | ||
Gets the SQL table for the object, either from the options object or the | ||
plural version of the object model. | ||
*/ | ||
function getObjectTable({ | ||
object, | ||
options | ||
}) { | ||
return (options == null ? void 0 : options.objectTable) || pluralize(snakeCase(object)); | ||
} | ||
/* | ||
Gets the SQL foreign key for the subject, either from the options object | ||
or the snake case of the subject model. | ||
*/ | ||
function getSubjectForeignKey({ | ||
subject, | ||
options | ||
}) { | ||
return (options == null ? void 0 : options.subjectForeignKey) || snakeCase(subject) + '_id'; | ||
} | ||
/* | ||
Gets the SQL foreign key for the object, either from the options object | ||
or the snake case of the object model. | ||
*/ | ||
function getObjectForeignKey({ | ||
object, | ||
options | ||
}) { | ||
return (options == null ? void 0 : options.objectForeignKey) || snakeCase(object) + '_id'; | ||
} | ||
/* | ||
Defines a relationship by passing the subject, the predicate, and the object, | ||
@@ -163,4 +178,7 @@ along with an optional via model. | ||
}); | ||
let viaTable; | ||
if (via) viaTable = pluralize(snakeCase(via)); | ||
const modelClass = getModelClass({ | ||
object, | ||
options | ||
}); | ||
const viaTable = getViaTable(via); | ||
@@ -170,3 +188,3 @@ switch (relType) { | ||
return hasOneRelation({ | ||
modelClass: object, | ||
modelClass, | ||
from: `${subjectTable}.id`, | ||
@@ -178,3 +196,3 @@ to: `${objectTable}.${subjectForeignKey}` | ||
return hasManyRelation({ | ||
modelClass: object, | ||
modelClass, | ||
from: `${subjectTable}.id`, | ||
@@ -186,3 +204,3 @@ to: `${objectTable}.${subjectForeignKey}` | ||
return hasManyThroughRelation({ | ||
modelClass: object, | ||
modelClass, | ||
from: `${subjectTable}.id`, | ||
@@ -198,3 +216,3 @@ through: { | ||
return belongsRelation({ | ||
modelClass: object, | ||
modelClass, | ||
from: `${subjectTable}.${objectForeignKey}`, | ||
@@ -209,3 +227,67 @@ to: `${objectTable}.id` | ||
export { belongsRelation, getObjectForeignKey, getObjectTable, getSubjectForeignKey, getSubjectTable, hasManyRelation, hasManyThroughRelation, hasOneRelation, relation }; | ||
class ObjectionRelation { | ||
constructor({ | ||
subject, | ||
modelPath | ||
}) { | ||
this.subject = subject; | ||
this.modelPath = modelPath; | ||
} | ||
belongsTo(object, options) { | ||
if (!options) options = { | ||
modelPath: this.modelPath | ||
}; | ||
if (!options.modelPath) options.modelPath = this.modelPath; | ||
return relation({ | ||
subject: this.subject, | ||
relType: 'belongsTo', | ||
object, | ||
options | ||
}); | ||
} | ||
hasOne(object, options) { | ||
if (!options) options = { | ||
modelPath: this.modelPath | ||
}; | ||
if (!options.modelPath) options.modelPath = this.modelPath; | ||
return relation({ | ||
subject: this.subject, | ||
relType: 'hasOne', | ||
object, | ||
options | ||
}); | ||
} | ||
hasMany(object, options) { | ||
if (!options) options = { | ||
modelPath: this.modelPath | ||
}; | ||
if (!options.modelPath) options.modelPath = this.modelPath; | ||
return relation({ | ||
subject: this.subject, | ||
relType: 'hasMany', | ||
object, | ||
options | ||
}); | ||
} | ||
hasManyThrough(object, via, options) { | ||
if (!options) options = { | ||
modelPath: this.modelPath | ||
}; | ||
if (!options.modelPath) options.modelPath = this.modelPath; | ||
return relation({ | ||
subject: this.subject, | ||
relType: 'hasManyThrough', | ||
object, | ||
via, | ||
options | ||
}); | ||
} | ||
} | ||
export { ObjectionRelation }; | ||
//# sourceMappingURL=objection-relations.esm.js.map |
{ | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"license": "MIT", | ||
@@ -34,4 +34,4 @@ "main": "dist/index.js", | ||
"build": "tsdx build --target node", | ||
"test": "tsdx test", | ||
"lint": "tsdx lint", | ||
"test": "tsdx test --collectCoverage", | ||
"lint": "tsdx lint --fix", | ||
"prepare": "tsdx build --target node", | ||
@@ -38,0 +38,0 @@ "size": "size-limit", |
@@ -6,8 +6,8 @@ # objection-relations | ||
For example, say you have a table called "Persons" with this relation mapping: | ||
For example, say you have a table called "Users" with this relation mapping: | ||
```javascript | ||
class Person extends Model { | ||
class User extends Model { | ||
static get tableName() { | ||
return 'persons'; | ||
return 'users'; | ||
} | ||
@@ -21,4 +21,4 @@ | ||
join: { | ||
from: 'persons.id', | ||
to: 'addresses.person_id', | ||
from: 'users.id', | ||
to: 'addresses.user_id', | ||
}, | ||
@@ -34,16 +34,16 @@ }, | ||
```javascript | ||
import { relation } from '@anephenix/objection-relations'; | ||
import { ObjectionRelation } from '@anephenix/objection-relations'; | ||
class Person extends Model { | ||
class User extends Model { | ||
static get tableName() { | ||
return 'persons'; | ||
return 'users'; | ||
} | ||
static get relationMappings() { | ||
const or = new ObjectionRelation({ | ||
subject: this.name, | ||
modelPath: __dirname, | ||
}); | ||
return { | ||
addresses: relation({ | ||
subject: 'Person', | ||
relType: 'hasMany', | ||
object: 'Address', | ||
}), | ||
addresses: or.hasMany('Address'), | ||
}; | ||
@@ -59,4 +59,8 @@ } | ||
models, if they follow a particular pattern (tables for models are named in | ||
plural format, and foreign keys use a singular format). | ||
plural format, and foreign keys use a singular format). e.g. | ||
| Model | table name | foreign key | | ||
| ----- | ---------- | ----------- | | ||
| User | users | user_id | | ||
## Dependencies | ||
@@ -79,3 +83,3 @@ | ||
```javascript | ||
relation({ subject: 'Post', relType: 'belongsTo', object: 'User' }); | ||
or.belongsTo('Role'); | ||
``` | ||
@@ -88,6 +92,6 @@ | ||
relation: Model.BelongsToOneRelation, | ||
modelClass: User, | ||
modelClass: 'Role', | ||
join: { | ||
from: 'posts.user_id', | ||
to: 'users.id' | ||
from: 'users.role_id', | ||
to: 'roles.id' | ||
} | ||
@@ -100,3 +104,3 @@ } | ||
```javascript | ||
relation({ subject: 'User', relType: 'hasOne', object: 'Setting' }); | ||
or.hasOne('Setting'); | ||
``` | ||
@@ -109,3 +113,3 @@ | ||
relation: Model.HasOneRelation, | ||
modelClass: Setting, | ||
modelClass: 'Setting', | ||
join: { | ||
@@ -121,3 +125,3 @@ from: 'users.id', | ||
```javascript | ||
relation({ subject: 'User', relType: 'hasMany', object: 'Address' }); | ||
or.hasMany('Address'); | ||
``` | ||
@@ -143,8 +147,3 @@ | ||
```javascript | ||
relation({ | ||
subject: 'User', | ||
relType: 'hasManyThrough', | ||
object: 'Company', | ||
via: 'Employment', | ||
}); | ||
or.hasManyThrough('Company', 'Employment'); | ||
``` | ||
@@ -181,8 +180,3 @@ | ||
```javascript | ||
relation({ | ||
subject: 'User', | ||
relType: 'hasMany', | ||
object: 'Address', | ||
options: { subjectTable: 'account_users' }, | ||
}); | ||
or.hasMany('Address', { subjectTable: 'account_users' }); | ||
``` | ||
@@ -209,8 +203,3 @@ | ||
```javascript | ||
relation({ | ||
subject: 'User', | ||
relType: 'hasMany', | ||
object: 'Address', | ||
options: { objectTable: 'shipping_addresses' }, | ||
}); | ||
or.hasMany('Address', { objectTable: 'shipping_addresses' }); | ||
``` | ||
@@ -237,8 +226,3 @@ | ||
```javascript | ||
relation({ | ||
subject: 'User', | ||
relType: 'hasMany', | ||
object: 'Address', | ||
options: { subjectForeignKey: 'account_user_id' }, | ||
}); | ||
or.hasMany('Address', { subjectForeignKey: 'account_user_id' }); | ||
``` | ||
@@ -261,11 +245,6 @@ | ||
You can pass a custom foreign key for the object like this: | ||
You can pass a custom foreign key for the object (Like a Post model) like this: | ||
```javascript | ||
relation({ | ||
subject: 'Post', | ||
relType: 'belongsTo', | ||
object: 'User', | ||
options: { objectForeignKey: 'author_id' }, | ||
}); | ||
or.belongsTo('User', { objectForeignKey: 'author_id' }); | ||
``` | ||
@@ -272,0 +251,0 @@ |
216
src/index.ts
// Dependencies | ||
import { Model } from 'objection'; | ||
const { | ||
HasOneRelation, | ||
BelongsToOneRelation, | ||
HasManyRelation, | ||
ManyToManyRelation, | ||
} = Model; | ||
import snakeCase from 'lodash.snakecase'; | ||
import pluralize from 'pluralize'; | ||
import { OptionsProps } from './global'; | ||
import { relation } from './relations'; | ||
type CommonRelationOrTableOrForeignKeyProps = { | ||
options?: { | ||
subjectTable?: string; | ||
objectTable?: string; | ||
subjectForeignKey?: string; | ||
objectForeignKey?: string; | ||
} | ||
} | ||
// Types | ||
type RelationProps = CommonRelationOrTableOrForeignKeyProps & { | ||
subject: string; | ||
relType: 'hasOne' | 'hasMany' | 'hasManyThrough' | 'belongsTo'; | ||
object: string; | ||
via?: string; | ||
} | ||
type RelationTypeProps = { | ||
modelClass: string; | ||
from: string; | ||
to: string; | ||
type ObjectionRelationProps = { | ||
subject: string; | ||
modelPath: string; | ||
}; | ||
type AdvancedRelationTypeProps = RelationTypeProps & { | ||
through: { | ||
from: string; | ||
to: string; | ||
}; | ||
} | ||
export class ObjectionRelation { | ||
subject: string; | ||
modelPath: string; | ||
constructor({ subject, modelPath }: ObjectionRelationProps) { | ||
this.subject = subject; | ||
this.modelPath = modelPath; | ||
} | ||
type SubjectProps = CommonRelationOrTableOrForeignKeyProps & { | ||
subject: string; | ||
} | ||
belongsTo(object: string, options?: OptionsProps) { | ||
if (!options) options = { modelPath: this.modelPath }; | ||
if (!options.modelPath) options.modelPath = this.modelPath; | ||
return relation({ | ||
subject: this.subject, | ||
relType: 'belongsTo', | ||
object, | ||
options, | ||
}); | ||
} | ||
type ObjectProps = CommonRelationOrTableOrForeignKeyProps & { | ||
object: string; | ||
} | ||
hasOne(object: string, options?: OptionsProps) { | ||
if (!options) options = { modelPath: this.modelPath }; | ||
if (!options.modelPath) options.modelPath = this.modelPath; | ||
return relation({ | ||
subject: this.subject, | ||
relType: 'hasOne', | ||
object, | ||
options, | ||
}); | ||
} | ||
/* | ||
Defines a relationship where a record in one model can belong to a record in | ||
another model. | ||
*/ | ||
export function belongsRelation({ modelClass, from, to }:RelationTypeProps) { | ||
return { | ||
relation: BelongsToOneRelation, | ||
modelClass, | ||
join: { from, to }, | ||
}; | ||
}; | ||
hasMany(object: string, options?: OptionsProps) { | ||
if (!options) options = { modelPath: this.modelPath }; | ||
if (!options.modelPath) options.modelPath = this.modelPath; | ||
return relation({ | ||
subject: this.subject, | ||
relType: 'hasMany', | ||
object, | ||
options, | ||
}); | ||
} | ||
/* | ||
Defines a relationship where a record in one model can own a record in another | ||
model. | ||
*/ | ||
export function hasOneRelation({ modelClass, from, to }:RelationTypeProps) { | ||
return { | ||
relation: HasOneRelation, | ||
modelClass, | ||
join: { from, to }, | ||
}; | ||
}; | ||
/* | ||
Defines a relationship where a record in one model can own many records in | ||
another model. | ||
*/ | ||
export function hasManyRelation({ modelClass, from, to }:RelationTypeProps) { | ||
return { | ||
relation: HasManyRelation, | ||
modelClass, | ||
join: { from, to }, | ||
}; | ||
}; | ||
/* | ||
Defines a relationship where a record in one model can own many records in | ||
another model, via a join table | ||
*/ | ||
export function hasManyThroughRelation({ modelClass, from, through, to }:AdvancedRelationTypeProps) { | ||
return { | ||
relation: ManyToManyRelation, | ||
modelClass, | ||
join: { from, through, to }, | ||
}; | ||
}; | ||
/* | ||
Gets the SQL table for the subject, either from the options object or the | ||
plural version of the subject model. | ||
*/ | ||
export function getSubjectTable({ subject, options }:SubjectProps) { | ||
return options?.subjectTable || pluralize(snakeCase(subject)); | ||
hasManyThrough(object: string, via: string, options?: OptionsProps) { | ||
if (!options) options = { modelPath: this.modelPath }; | ||
if (!options.modelPath) options.modelPath = this.modelPath; | ||
return relation({ | ||
subject: this.subject, | ||
relType: 'hasManyThrough', | ||
object, | ||
via, | ||
options, | ||
}); | ||
} | ||
} | ||
/* | ||
Gets the SQL table for the object, either from the options object or the | ||
plural version of the object model. | ||
*/ | ||
export function getObjectTable({ object, options }:ObjectProps) { | ||
return options?.objectTable || pluralize(snakeCase(object)); | ||
} | ||
/* | ||
Gets the SQL foreign key for the subject, either from the options object | ||
or the snake case of the subject model. | ||
*/ | ||
export function getSubjectForeignKey({ subject, options }:SubjectProps) { | ||
return options?.subjectForeignKey || snakeCase(subject) + '_id'; | ||
} | ||
/* | ||
Gets the SQL foreign key for the object, either from the options object | ||
or the snake case of the object model. | ||
*/ | ||
export function getObjectForeignKey({ object, options }:ObjectProps) { | ||
return options?.objectForeignKey || snakeCase(object) + '_id'; | ||
} | ||
/* | ||
Defines a relationship by passing the subject, the predicate, and the object, | ||
along with an optional via model. | ||
*/ | ||
export function relation({subject, relType, object, via, options}:RelationProps) { | ||
const subjectTable = getSubjectTable({subject, options}); | ||
const objectTable = getObjectTable({object, options}); | ||
const subjectForeignKey = getSubjectForeignKey({subject, options}); | ||
const objectForeignKey = getObjectForeignKey({object, options}); | ||
let viaTable; | ||
if (via) viaTable = pluralize(snakeCase(via)); | ||
switch (relType) { | ||
case 'hasOne': | ||
return hasOneRelation({ | ||
modelClass: object, | ||
from: `${subjectTable}.id`, | ||
to: `${objectTable}.${subjectForeignKey}` | ||
}); | ||
case 'hasMany': | ||
return hasManyRelation({ | ||
modelClass: object, | ||
from: `${subjectTable}.id`, | ||
to: `${objectTable}.${subjectForeignKey}` | ||
}); | ||
case 'hasManyThrough': | ||
return hasManyThroughRelation({ | ||
modelClass: object, | ||
from: `${subjectTable}.id`, | ||
through: { | ||
from: `${viaTable}.${subjectForeignKey}`, | ||
to: `${viaTable}.${objectForeignKey}`, | ||
}, | ||
to: `${objectTable}.id` | ||
}); | ||
case 'belongsTo': | ||
return belongsRelation({ | ||
modelClass: object, | ||
from: `${subjectTable}.${objectForeignKey}`, | ||
to: `${objectTable}.id` | ||
}); | ||
default: | ||
throw new Error('No valid relationship type specified'); | ||
} | ||
}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
67145
17
913
260
1