Comparing version 0.6.0 to 0.7.0
@@ -0,1 +1,7 @@ | ||
# 0.7.0 | ||
* Fix `isLazyLoad` to just check if the target has been decorated and assume lazy load otherwises | ||
* Add `hasModelOptions` to check whether a class has been decorated as a model | ||
* Have `Model.associate` take an `AssociationTarget` | ||
# 0.6.0 | ||
@@ -2,0 +8,0 @@ |
@@ -67,3 +67,3 @@ import { Model, ModelConstructor } from './model'; | ||
*/ | ||
export declare function isLazyLoad(target: AssociationTarget<any>): boolean; | ||
export declare function isLazyLoad<T extends Model>(target: AssociationTarget<T>): boolean; | ||
/** | ||
@@ -84,2 +84,2 @@ * A decorator for a model association. | ||
*/ | ||
export declare function assoc<T extends Model>(type: AssociationType, target?: AssociationTarget<T>, options?: AssociationOptions): (ctor: Object, key: string | symbol) => void; | ||
export declare function assoc<T extends Model>(type: AssociationType, target?: AssociationTarget<T>, options?: AssociationOptions): (ctor: object, key: string | symbol) => void; |
@@ -21,2 +21,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** Contains the association types. */ | ||
var metadata_1 = require("./metadata"); | ||
@@ -75,3 +76,9 @@ var property_1 = require("./property"); | ||
function isLazyLoad(target) { | ||
return !target.prototype; | ||
// This might seem a bit strange but basically we fall to this as there doesn't | ||
// appear to be a nice way to check if something is a class vs. a function. | ||
// So we return true if there's model options, (i.e. it's a decorated model) | ||
// otherwise we just assume it's lazy loaded. We can do this because | ||
// even if it's some arbitrary value and not a lazy loader, the safe | ||
// will catch that because it requires a model decorator to be associated. | ||
return !metadata_1.hasModelOptions(target); | ||
} | ||
@@ -78,0 +85,0 @@ exports.isLazyLoad = isLazyLoad; |
@@ -55,2 +55,12 @@ "use strict"; | ||
}); | ||
describe('isLazyLoad', function () { | ||
it('should return true for lambdas or functions returning a model', function () { | ||
chai.should().equal(association_1.isLazyLoad(function () { return Entity; }), true); | ||
// tslint:disable-next-line:only-arrow-functions | ||
chai.should().equal(association_1.isLazyLoad(function () { return Entity; }), true); | ||
}); | ||
it('should return false for a regular model', function () { | ||
chai.should().equal(association_1.isLazyLoad(Entity), false); | ||
}); | ||
}); | ||
//# sourceMappingURL=association.spec.js.map |
@@ -164,2 +164,2 @@ import { Property } from './property'; | ||
*/ | ||
export declare function attr(type: AttributeType, options?: AttributeOptions): (target: Object, key: string | symbol) => void; | ||
export declare function attr(type: AttributeType, options?: AttributeOptions): (target: object, key: string | symbol) => void; |
@@ -24,2 +24,12 @@ /** Contains getters/setters for the model metadata. */ | ||
/** | ||
* Checks whether a model constructor has been decorated with the @model | ||
* decorator. This can be used to check whether an object looks like a model, | ||
* although there is no guarantee it's a valid model yet (since technically | ||
* a model isn't valid unless it has a name defined). | ||
* | ||
* @param ctor The model constructor. | ||
* @returns Whether the model constructor is decorated. | ||
*/ | ||
export declare function hasModelOptions(ctor: Function): boolean; | ||
/** | ||
* Define options on a model constructor. | ||
@@ -26,0 +36,0 @@ * |
@@ -11,2 +11,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* tslint:disable:ban-types */ | ||
/** Contains getters/setters for the model metadata. */ | ||
@@ -49,2 +50,15 @@ require("reflect-metadata"); | ||
/** | ||
* Checks whether a model constructor has been decorated with the @model | ||
* decorator. This can be used to check whether an object looks like a model, | ||
* although there is no guarantee it's a valid model yet (since technically | ||
* a model isn't valid unless it has a name defined). | ||
* | ||
* @param ctor The model constructor. | ||
* @returns Whether the model constructor is decorated. | ||
*/ | ||
function hasModelOptions(ctor) { | ||
return Reflect.hasMetadata(exports.MODEL_OPTIONS_META_KEY, ctor.prototype); | ||
} | ||
exports.hasModelOptions = hasModelOptions; | ||
/** | ||
* Define options on a model constructor. | ||
@@ -51,0 +65,0 @@ * |
@@ -74,2 +74,7 @@ "use strict"; | ||
], User); | ||
var NotDecorated = (function () { | ||
function NotDecorated() { | ||
} | ||
return NotDecorated; | ||
}()); | ||
// Add the associaiton target we avoided adding for dependency reasons | ||
@@ -84,2 +89,10 @@ model_1.Model.associate(Comment, function (m) { return [m.user, User]; }); | ||
}); | ||
describe('hasModelOptions', function () { | ||
it('should return true if a class has been decorated', function () { | ||
chai.should().equal(metadata_1.hasModelOptions(User), true); | ||
}); | ||
it('should return false if a class has been decorated', function () { | ||
chai.should().equal(metadata_1.hasModelOptions(NotDecorated), false); | ||
}); | ||
}); | ||
describe('getProperties', function () { | ||
@@ -86,0 +99,0 @@ it('should map properties correctly', function () { |
@@ -1,2 +0,2 @@ | ||
import { AssociationType } from './association'; | ||
import { AssociationType, AssociationTarget } from './association'; | ||
import { Property } from './property'; | ||
@@ -39,3 +39,3 @@ /** | ||
*/ | ||
static associate<T extends Model, U extends Model>(ctor: ModelConstructor<T>, map: (props: ModelProperties<T>) => [Property<T>, ModelConstructor<U>], type?: AssociationType): void; | ||
static associate<T extends Model, U extends Model>(ctor: ModelConstructor<T>, map: (props: ModelProperties<T>) => [Property<any>, AssociationTarget<U>], type?: AssociationType): void; | ||
} | ||
@@ -42,0 +42,0 @@ /** A value that is both a model class value and something that can construct a model. */ |
@@ -60,3 +60,3 @@ "use strict"; | ||
} | ||
metadata_1.defineAssociation(ctor.prototype, key, __assign({}, options, { type: type })); | ||
metadata_1.defineAssociation(ctor.prototype, key, __assign({}, options, { target: target, type: type })); | ||
}; | ||
@@ -75,2 +75,3 @@ return Model; | ||
function model(options) { | ||
// tslint:disable-next-line:ban-types | ||
return function (ctor) { | ||
@@ -77,0 +78,0 @@ metadata_1.defineModelOptions(ctor, __assign({ name: metadata_1.guessModelName(ctor) }, options)); |
@@ -24,2 +24,12 @@ "use strict"; | ||
var model_1 = require("./model"); | ||
var ManualModel = (function (_super) { | ||
__extends(ManualModel, _super); | ||
function ManualModel() { | ||
return _super !== null && _super.apply(this, arguments) || this; | ||
} | ||
return ManualModel; | ||
}(model_1.Model)); | ||
ManualModel = __decorate([ | ||
model_1.model({ name: 'manualModelName' }) | ||
], ManualModel); | ||
var AutomaticModel = (function (_super) { | ||
@@ -41,12 +51,2 @@ __extends(AutomaticModel, _super); | ||
], AutomaticModel); | ||
var ManualModel = (function (_super) { | ||
__extends(ManualModel, _super); | ||
function ManualModel() { | ||
return _super !== null && _super.apply(this, arguments) || this; | ||
} | ||
return ManualModel; | ||
}(model_1.Model)); | ||
ManualModel = __decorate([ | ||
model_1.model({ name: 'manualModelName' }) | ||
], ManualModel); | ||
describe('@model', function () { | ||
@@ -53,0 +53,0 @@ it('should guess names', function () { |
/** Contains the property type. */ | ||
/** A property of a model. This can be either an association or attribute. */ | ||
export declare abstract class Property<T> { | ||
/** The value of the property. This is currently unused. */ | ||
value?: T; | ||
/** | ||
@@ -5,0 +7,0 @@ * Turns the property into its relevant property name. |
@@ -0,3 +1,3 @@ | ||
"use strict"; | ||
/** Contains the property type. */ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -4,0 +4,0 @@ /** A property of a model. This can be either an association or attribute. */ |
@@ -95,6 +95,3 @@ import { Model, ModelConstructor } from './model'; | ||
*/ | ||
export interface ValidationFunction { | ||
/** Validate a value for an attribute. */ | ||
(value: any): boolean; | ||
} | ||
export declare type ValidationFunction = (value: any) => boolean; | ||
/** The options for a validation rule. */ | ||
@@ -114,2 +111,2 @@ export interface ValidationOptions { | ||
*/ | ||
export declare function validate(validation: Validation | ValidationFunction, options?: any): (ctor: Object, key: string | symbol) => void; | ||
export declare function validate(validation: Validation | ValidationFunction, options?: any): (ctor: object, key: string | symbol) => void; |
{ | ||
"name": "modelsafe", | ||
"version": "0.6.0", | ||
"version": "0.7.0", | ||
"main": "dist/index.js", | ||
@@ -20,3 +20,3 @@ "bugs": "https://github.com/creativecuriositystudio/modelsafe/issues", | ||
"prepush": "npm run lint && npm test", | ||
"prepublish": "tsc", | ||
"prepublish": "npm run build", | ||
"build": "tsc", | ||
@@ -37,4 +37,4 @@ "docs": "typedoc --out docs src/index.ts", | ||
"ts-node": "^2.1.0", | ||
"tslint": "^4.3.0", | ||
"tslint-config-ccs": "^0.3.2", | ||
"tslint": "^5.0.0", | ||
"tslint-config-ccs": "^0.5.1", | ||
"typedoc": "^0.5.1" | ||
@@ -47,4 +47,4 @@ }, | ||
"reflect-metadata": "^0.1.8", | ||
"typescript": "^2.1.4" | ||
"typescript": "^2.2.2" | ||
} | ||
} |
/* tslint:disable:completed-docs */ | ||
import * as chai from 'chai'; | ||
import { assoc, HAS_ONE } from './association'; | ||
import { assoc, HAS_ONE, isLazyLoad } from './association'; | ||
import { getAssociations } from './metadata'; | ||
@@ -24,1 +24,14 @@ import { model, Model } from './model'; | ||
}); | ||
describe('isLazyLoad', () => { | ||
it('should return true for lambdas or functions returning a model', () => { | ||
chai.should().equal(isLazyLoad(() => Entity), true); | ||
// tslint:disable-next-line:only-arrow-functions | ||
chai.should().equal(isLazyLoad(function() { return Entity; }), true); | ||
}); | ||
it('should return false for a regular model', () => { | ||
chai.should().equal(isLazyLoad(Entity), false); | ||
}); | ||
}); |
/** Contains the association types. */ | ||
import * as _ from 'lodash'; | ||
import { defineAssociation } from './metadata'; | ||
import { defineAssociation, hasModelOptions } from './metadata'; | ||
import { Model, ModelConstructor } from './model'; | ||
@@ -91,4 +89,10 @@ import { Property } from './property'; | ||
*/ | ||
export function isLazyLoad(target: AssociationTarget<any>): boolean { | ||
return !(target as Function).prototype; | ||
export function isLazyLoad<T extends Model>(target: AssociationTarget<T>): boolean { | ||
// This might seem a bit strange but basically we fall to this as there doesn't | ||
// appear to be a nice way to check if something is a class vs. a function. | ||
// So we return true if there's model options, (i.e. it's a decorated model) | ||
// otherwise we just assume it's lazy loaded. We can do this because | ||
// even if it's some arbitrary value and not a lazy loader, the safe | ||
// will catch that because it requires a model decorator to be associated. | ||
return !hasModelOptions(target); | ||
} | ||
@@ -113,3 +117,3 @@ | ||
options?: AssociationOptions) { | ||
return (ctor: Object, key: string | symbol) => defineAssociation(ctor, key, { | ||
return (ctor: object, key: string | symbol) => defineAssociation(ctor, key, { | ||
readOnly: false, | ||
@@ -116,0 +120,0 @@ |
@@ -229,3 +229,3 @@ /** Contains the attribute types. */ | ||
export function attr(type: AttributeType, options?: AttributeOptions) { | ||
return (target: Object, key: string | symbol) => defineAttribute(target, key, { readOnly: false, ... options, type }); | ||
return (target: object, key: string | symbol) => defineAttribute(target, key, { readOnly: false, ... options, type }); | ||
} |
@@ -6,3 +6,3 @@ /* tslint:disable:completed-docs */ | ||
import { assoc, BELONGS_TO, HAS_MANY } from './association'; | ||
import { guessModelName, getProperties } from './metadata'; | ||
import { guessModelName, hasModelOptions, getProperties } from './metadata'; | ||
import { model, Model, ModelProperties } from './model'; | ||
@@ -34,2 +34,4 @@ | ||
class NotDecorated {} | ||
// Add the associaiton target we avoided adding for dependency reasons | ||
@@ -46,2 +48,12 @@ Model.associate(Comment, m => [m.user, User]); | ||
describe('hasModelOptions', () => { | ||
it('should return true if a class has been decorated', () => { | ||
chai.should().equal(hasModelOptions(User), true); | ||
}); | ||
it('should return false if a class has been decorated', () => { | ||
chai.should().equal(hasModelOptions(NotDecorated), false); | ||
}); | ||
}); | ||
describe('getProperties', () => { | ||
@@ -48,0 +60,0 @@ it('should map properties correctly', () => { |
@@ -0,1 +1,2 @@ | ||
/* tslint:disable:ban-types */ | ||
/** Contains getters/setters for the model metadata. */ | ||
@@ -8,3 +9,3 @@ import 'reflect-metadata'; | ||
import { Model, ModelOptions, ModelProperties } from './model'; | ||
import { Validation, ValidationFunction, ValidationOptions } from './validation'; | ||
import { ValidationOptions } from './validation'; | ||
@@ -51,2 +52,15 @@ /** The meta key for a model's options on a model class. */ | ||
/** | ||
* Checks whether a model constructor has been decorated with the @model | ||
* decorator. This can be used to check whether an object looks like a model, | ||
* although there is no guarantee it's a valid model yet (since technically | ||
* a model isn't valid unless it has a name defined). | ||
* | ||
* @param ctor The model constructor. | ||
* @returns Whether the model constructor is decorated. | ||
*/ | ||
export function hasModelOptions(ctor: Function): boolean { | ||
return Reflect.hasMetadata(MODEL_OPTIONS_META_KEY, ctor.prototype); | ||
} | ||
/** | ||
* Define options on a model constructor. | ||
@@ -53,0 +67,0 @@ * |
@@ -8,15 +8,15 @@ /* tslint:disable:completed-docs */ | ||
@model({ name: 'manualModelName' }) | ||
class ManualModel extends Model { | ||
} | ||
@model() | ||
class AutomaticModel extends Model { | ||
@assoc(BELONGS_TO) | ||
test1: Object; | ||
test1: object; | ||
@assoc(HAS_MANY) | ||
test2: Object; | ||
test2: object; | ||
} | ||
@model({ name: 'manualModelName' }) | ||
class ManualModel extends Model { | ||
} | ||
describe('@model', () => { | ||
@@ -23,0 +23,0 @@ it('should guess names', () => { |
/** Contains the model classes and decorators. */ | ||
import * as _ from 'lodash'; | ||
import { AssociationType } from './association'; | ||
import { Attribute } from './attribute'; | ||
import { AssociationType, AssociationTarget } from './association'; | ||
import { defineModelOptions, defineAssociation, guessModelName, | ||
@@ -51,3 +50,3 @@ getProperties, getAssociations } from './metadata'; | ||
ctor: ModelConstructor<T>, | ||
map: (props: ModelProperties<T>) => [Property<T>, ModelConstructor<U>], | ||
map: (props: ModelProperties<T>) => [Property<any>, AssociationTarget<U>], | ||
type?: AssociationType | ||
@@ -64,3 +63,3 @@ ) { | ||
defineAssociation(ctor.prototype, key, { ... options, type }); | ||
defineAssociation(ctor.prototype, key, { ... options, target, type }); | ||
} | ||
@@ -96,2 +95,3 @@ } | ||
export function model(options?: ModelOptions) { | ||
// tslint:disable-next-line:ban-types | ||
return (ctor: Function): void => { | ||
@@ -98,0 +98,0 @@ defineModelOptions(ctor, { name: guessModelName(ctor), ... options }); |
@@ -5,2 +5,5 @@ /** Contains the property type. */ | ||
export abstract class Property<T> { | ||
/** The value of the property. This is currently unused. */ | ||
value?: T; | ||
/** | ||
@@ -7,0 +10,0 @@ * Turns the property into its relevant property name. |
/** Contains the safe type, which contains the model definitions. */ | ||
import { getModelOptions, getProperties, getAttributes, getAssociations } from './metadata'; | ||
import { getModelOptions, getProperties } from './metadata'; | ||
import { Model, ModelConstructor, ModelProperties } from './model'; | ||
@@ -4,0 +4,0 @@ |
@@ -116,6 +116,3 @@ /** Contains the validation types. */ | ||
*/ | ||
export interface ValidationFunction { | ||
/** Validate a value for an attribute. */ | ||
(value: any): boolean; | ||
} | ||
export type ValidationFunction = (value: any) => boolean; | ||
@@ -138,3 +135,3 @@ /** The options for a validation rule. */ | ||
export function validate(validation: Validation | ValidationFunction, options?: any) { | ||
return (ctor: Object, key: string | symbol) => defineAttributeValidation(ctor, key, { ... options, validation }); | ||
return (ctor: object, key: string | symbol) => defineAttributeValidation(ctor, key, { ... options, validation }); | ||
} |
@@ -11,3 +11,5 @@ { | ||
"suppressImplicitAnyIndexErrors": true, | ||
"declaration": true | ||
"declaration": true, | ||
"noUnusedLocals": true, | ||
"noUnusedParameters": true | ||
}, | ||
@@ -14,0 +16,0 @@ "exclude": [ |
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
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
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
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
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
66
2695
158461
Updatedtypescript@^2.2.2