Merge pull request #136 from pierissimo/feat-connector-getproperty-definition-nested

Connector.getPropertyDefinition for nested properties
This commit is contained in:
Biniam Admikew 2019-02-19 09:51:24 -05:00 committed by GitHub
commit 9e63fc3448
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 141 additions and 2 deletions

View File

@ -135,8 +135,40 @@ Connector.prototype.getConnectorSpecificSettings = function(modelName) {
* @returns {Object} Property definition
*/
Connector.prototype.getPropertyDefinition = function(modelName, propName) {
var model = this.getModelDefinition(modelName);
return model && model.properties[propName];
const model = this.getModelDefinition(modelName);
return Connector.getNestedPropertyDefinition(
model.model.definition,
propName.split('.')
);
};
/**
* Helper function to get nested property definition
* @param {Object} definition Model name
* @param {Array} propPath
* @returns {Object} Property definition
*/
Connector.getNestedPropertyDefinition = function(definition, propPath) {
const properties = definition.properties || {};
const prop = properties[propPath[0]];
const isPropUndefined = typeof prop === 'undefined';
const isArray = !isPropUndefined && Array.isArray(prop.type);
const isFunction = !isPropUndefined && !isArray && typeof prop.type === 'function';
if (isPropUndefined || (propPath.length > 1 && (isArray && prop.type.length === 0))) {
throw new Error(g.f('Invalid property path'));
}
if (propPath.length === 1) return prop;
const nextDefinition =
(isArray && prop.type[0].definition) ||
(isFunction && prop.type.definition);
return Connector.getNestedPropertyDefinition(
nextDefinition,
propPath.slice(1)
);
};
/**

107
test/connector.test.js Normal file
View File

@ -0,0 +1,107 @@
// Copyright IBM Corp. 2016. All Rights Reserved.
// Node module: loopback-connector
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const expect = require('chai').expect;
const {ModelBuilder} = require('loopback-datasource-juggler');
const Connector = require('../lib/connector');
describe('Connector', () => {
describe('getPropertyDefinition()', () => {
let connector, builder;
beforeEach(() => {
connector = new Connector('MyConnector');
builder = new ModelBuilder();
const MyModel = builder.define('MyModel', {
firstname: String,
phoneList: [
{
number: Number,
label: {
title: String,
},
},
],
address: {
line1: String,
},
someProp: {
innerArray: [
{
date: Date,
},
],
},
});
connector.define({
model: MyModel,
});
});
it('supports retrieving first level properties definitions', () => {
const propDefinition1 = connector.getPropertyDefinition(
'MyModel',
'phoneList'
);
expect(propDefinition1.type).to.be.an('array');
const propDefinition2 = connector.getPropertyDefinition(
'MyModel',
'firstname'
);
expect(propDefinition2.type).to.be.equal(String);
});
it('supports first level nested array property definitions', () => {
const propDefinition = connector.getPropertyDefinition(
'MyModel',
'phoneList.number'
);
expect(propDefinition.type).to.equal(Number);
});
it('supports second level nested array property definitions', () => {
const propDefinition = connector.getPropertyDefinition(
'MyModel',
'phoneList.label.title'
);
expect(propDefinition.type).to.equal(String);
});
it('supports nested property definitions on objects', () => {
const propDefinition = connector.getPropertyDefinition(
'MyModel',
'address.line1'
);
expect(propDefinition.type).to.equal(String);
});
it('supports nested property definitions on array within object', () => {
const propDefinition = connector.getPropertyDefinition(
'MyModel',
'someProp.innerArray.date'
);
expect(propDefinition.type).to.equal(Date);
});
it('should fail for non-existing properties', () => {
expect(() =>
connector.getPropertyDefinition(
'MyModel',
'non.existing.property'
)).to.throw(/Invalid property path/);
});
});
});