Skip to content

Commit

Permalink
feat(repository): helper function for getting Model metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Delisle committed Dec 20, 2017
1 parent 721e8ee commit 7e19fe1
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 0 deletions.
2 changes: 2 additions & 0 deletions packages/repository/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
},
"dependencies": {
"@loopback/context": "^4.0.0-alpha.23",
"@types/lodash": "^4.14.91",
"lodash": "^4.17.4",
"loopback-datasource-juggler": "^3.9.2"
},
"files": [
Expand Down
41 changes: 41 additions & 0 deletions packages/repository/src/decorators/metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {InspectionOptions, MetadataInspector} from '@loopback/context';
import {MODEL_KEY, MODEL_PROPERTIES_KEY} from '../';
import {ModelDefinition, PropertyDefinition} from '../../index';
import * as _ from 'lodash';

export class ModelMetadataHelper {
/**
* A utility function to simplify retrieving metadata from a target model and
* its properties.
* @param target The class from which to retrieve metadata.
* @param options An options object for the MetadataInspector to customize
* the output of the metadata retrieval functions.
*/
static getModelMetadata(target: Function, options?: InspectionOptions) {
const classDef = MetadataInspector.getClassMetadata(
MODEL_KEY,
target,
options,
);
const meta = new ModelDefinition(
Object.assign(
{
name: target.name,
},
classDef,
),
);
if (_.isEmpty(_.keys(meta.properties))) {
meta.properties = Object.assign(
<PropertyDefinition>{},
MetadataInspector.getAllPropertyMetadata(
MODEL_PROPERTIES_KEY,
target.prototype,
options,
),
);
MetadataInspector.defineMetadata(MODEL_KEY, meta, target);
}
return meta;
}
}
1 change: 1 addition & 0 deletions packages/repository/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export * from './common-types';
export * from './decorators/model';
export * from './decorators/repository';
export * from './decorators/relation';
export * from './decorators/metadata';
export * from './types';
export * from './model';
export * from './query';
Expand Down
77 changes: 77 additions & 0 deletions packages/repository/test/unit/decorator/metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import {ModelMetadataHelper} from '../../../src';
import {property, model, ModelDefinition, MODEL_KEY} from '../../..';
import {expect} from '@loopback/testlab';
import {MetadataInspector} from '@loopback/context';

describe('Repository', () => {
describe('getAllClassMetadata', () => {
@model()
class Colour {
@property({})
rgb: string;
}
@model()
class Widget {
@property() id: number;
@property.array(Colour) colours: Colour[];
}

@model()
class Samoflange {
id: number;
name: string;
canRotate: boolean;
}

@model()
class Phlange {
@property() id: number;
@property() canFlap: boolean;
@property.array(Colour) colours: Colour[];
}

it('retrieves metadata for classes with @model', () => {
const meta = ModelMetadataHelper.getModelMetadata(Samoflange);
expect(meta).to.deepEqual(
new ModelDefinition({
name: 'Samoflange',
properties: {},
settings: new Map(),
}),
);
});

it('retrieves metadata for classes with @model and @property', () => {
const meta = ModelMetadataHelper.getModelMetadata(Widget);
expect(meta).to.deepEqual(
new ModelDefinition({
properties: {
id: {
type: Number,
},
colours: {
array: true,
type: Colour,
},
},
settings: new Map(),
name: 'Widget',
}),
);
});

it('returns existing properties instead of re-assembling them', () => {
const classMeta = MetadataInspector.getClassMetadata(
MODEL_KEY,
Phlange,
) as ModelDefinition;
classMeta.properties = {
foo: {
type: String,
},
};
const meta = ModelMetadataHelper.getModelMetadata(Phlange);
expect(meta.properties).to.eql(classMeta.properties);
});
});
});

0 comments on commit 7e19fe1

Please sign in to comment.