Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions packages/cli/generators/model/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ module.exports = class ModelGenerator extends ArtifactGenerator {
choices: this.typeChoices,
},
{
name: 'arrayType',
name: 'itemType',
message: 'Type of array items:',
type: 'list',
choices: this.typeChoices.filter(choice => {
Expand Down Expand Up @@ -204,18 +204,18 @@ module.exports = class ModelGenerator extends ArtifactGenerator {
// Set up types for Templating
const TS_TYPES = ['string', 'number', 'object', 'boolean', 'any'];
const NON_TS_TYPES = ['geopoint', 'date'];
Object.entries(this.artifactInfo.properties).forEach(([key, val]) => {
Object.values(this.artifactInfo.properties).forEach(val => {
// Default tsType is the type property
val.tsType = val.type;

// Override tsType based on certain type values
if (val.type === 'array') {
if (TS_TYPES.includes(val.arrayType)) {
val.tsType = `${val.arrayType}[]`;
if (TS_TYPES.includes(val.itemType)) {
val.tsType = `${val.itemType}[]`;
} else if (val.type === 'buffer') {
val.tsType = `Buffer[]`;
val.tsType = 'Buffer[]';
} else {
val.tsType = `string[]`;
val.tsType = 'string[]';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'string[]' ---> 'String[]' ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know string[] works but does String[] work as well?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry never mind :( I mixed it with the array type in juggler. string[] is correct.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think they both work 🤷‍♂️

}
} else if (val.type === 'buffer') {
val.tsType = 'Buffer';
Expand All @@ -234,8 +234,8 @@ module.exports = class ModelGenerator extends ArtifactGenerator {

// Convert Type to include '' for template
val.type = `'${val.type}'`;
if (val.arrayType) {
val.arrayType = `'${val.arrayType}'`;
if (val.itemType) {
val.itemType = `'${val.itemType}'`;
}

// If required is false, we can delete it as that's the default assumption
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/generators/model/templates/model.ts.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export class <%= className %> extends Entity {
<% Object.entries(properties).forEach(([key, val]) => { -%>
@property({
<%_ Object.entries(val).forEach(([propKey, propVal]) => { -%>
<%_ if (propKey !== 'tsType') { -%>
<%_ if (!['tsType'].includes(propKey)) { -%>
<%= propKey %>: <%- propVal %>,
<%_ } -%>
<%_ }) -%>
Expand Down
92 changes: 65 additions & 27 deletions packages/repository-json-schema/src/build-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ export function getJsonSchema(ctor: Function): JSONSchema {
* Gets the wrapper function of primitives string, number, and boolean
* @param type Name of type
*/
export function stringTypeToWrapper(type: string): Function {
export function stringTypeToWrapper(type: string | Function): Function {
if (typeof type === 'function') {
return type;
}
type = type.toLowerCase();
let wrapper;
switch (type) {
Expand All @@ -52,6 +55,22 @@ export function stringTypeToWrapper(type: string): Function {
wrapper = Boolean;
break;
}
case 'array': {
wrapper = Array;
break;
}
case 'object': {
wrapper = Object;
break;
}
case 'date': {
wrapper = Date;
break;
}
case 'buffer': {
wrapper = Buffer;
break;
}
default: {
throw new Error('Unsupported type: ' + type);
}
Expand All @@ -64,40 +83,55 @@ export function stringTypeToWrapper(type: string): Function {
* @param ctor Constructor
*/
export function isComplexType(ctor: Function) {
return !([String, Number, Boolean, Object, Function] as Function[]).includes(
ctor,
);
return !([
String,
Number,
Boolean,
Object,
Function,
Array,
] as Function[]).includes(ctor);
}

/**
* Determines whether a given string or constructor is array type or not
* @param type Type as string or wrapper
*/
export function isArrayType(type: string | Function) {
return type === Array || type === 'array';
}

/**
* Converts property metadata into a JSON property definition
* @param meta
*/
export function metaToJsonProperty(meta: PropertyDefinition): JSONSchema {
let ctor = meta.type as string | Function;
let def: JSONSchema = {};

// errors out if @property.array() is not used on a property of array
if (ctor === Array) {
throw new Error('type is defined as an array');
}

if (typeof ctor === 'string') {
ctor = stringTypeToWrapper(ctor);
// tslint:disable-next-line:no-any
const propDef: JSONSchema = {};
let result: JSONSchema;
let propertyType = meta.type as string | Function;

if (isArrayType(propertyType) && meta.itemType) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm...any reason why using two different ways to assert the array type?
isArrayType vs Array.isArray

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isArrayType essentially asserts whether given data corresponds to the Wrapper Array or the string 'array'

if (Array.isArray(meta.itemType)) {
throw new Error('itemType as an array is not supported');
}
result = {type: 'array', items: propDef};
propertyType = meta.itemType as string | Function;
} else {
result = propDef;
}

const propDef = isComplexType(ctor)
? {$ref: `#/definitions/${ctor.name}`}
: {type: <JSONSchemaTypeName>ctor.name.toLowerCase()};
propertyType = stringTypeToWrapper(propertyType);

if (meta.array) {
def.type = 'array';
def.items = propDef;
if (isComplexType(propertyType)) {
Object.assign(propDef, {$ref: `#/definitions/${propertyType.name}`});
} else {
Object.assign(def, propDef);
Object.assign(propDef, {
type: <JSONSchemaTypeName>propertyType.name.toLowerCase(),
});
}

return def;
return result;
}

// NOTE(shimks) no metadata for: union, optional, nested array, any, enum,
Expand Down Expand Up @@ -131,15 +165,19 @@ export function modelToJsonSchema(ctor: Function): JSONSchema {
result.properties = result.properties || {};
result.properties[p] = result.properties[p] || {};

const metaProperty = meta.properties[p];
const metaType = metaProperty.type;
const metaProperty = Object.assign({}, meta.properties[p]);

// populating "properties" key
result.properties[p] = metaToJsonProperty(metaProperty);

// populating JSON Schema 'definitions'
if (typeof metaType === 'function' && isComplexType(metaType)) {
const propSchema = getJsonSchema(metaType);
const referenceType = isArrayType(metaProperty.type as string | Function)
? // shimks: ugly type casting; this should be replaced by logic to throw
// error if itemType/type is not a string or a function
(metaProperty.itemType as string | Function)
: (metaProperty.type as string | Function);
if (typeof referenceType === 'function' && isComplexType(referenceType)) {
const propSchema = getJsonSchema(referenceType);

if (propSchema && Object.keys(propSchema).length > 0) {
result.definitions = result.definitions || {};
Expand All @@ -152,7 +190,7 @@ export function modelToJsonSchema(ctor: Function): JSONSchema {
delete propSchema.definitions;
}

result.definitions[metaType.name] = propSchema;
result.definitions[referenceType.name] = propSchema;
}
}

Expand Down
Loading