Skip to content

Commit

Permalink
Renames schema to result for readability
Browse files Browse the repository at this point in the history
  • Loading branch information
bravo-kernel committed Aug 18, 2019
1 parent 32123dc commit b91172d
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 41 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -26,7 +26,7 @@ schema = SchemaManager.generate(sequelizeModel, strategy);

## TODO/Notes:

- [ ] support sequelize 4, 5 (and 6?)
- [ ] add ci test for sequelize 4, 5
- [ ] use http or https schema pointers

#### Development tools
Expand Down
84 changes: 44 additions & 40 deletions lib/type-mapper.js
@@ -1,4 +1,4 @@
const _ = require('lodash'); // limit later to `merge`, `capitalize`, etc.
const _ = require('lodash');

// Common types. These should never be exposed directly but, rather, get cloned
// before being returned. This avoids cross-contamination if a user modifies
Expand All @@ -17,22 +17,26 @@ const STRING_LENGTHS = {
};

/**
* TypeMapper
* Class responsible for converting Sequelize DataTypes to strategy-compatible `type` properties.
*
* @see {@link https://sequelize.org/master/manual/data-types.html}
* @license MIT
*/
class TypeMapper {
/**
* Translates the `type` properties of a Sequelize attribute `type` property to the correlating JSON schema supported type.
* Returns the strategy-specific `type` property for the given Sequelize DataType
*
* @param {string} attributeName Name of the Sequelize attribute
* @param {object} properties Properties of the Sequelize attribute
* @param {StrategyInterface} strategy Strategy instance
* @returns {object} property schema
* @returns {object} Object holding the `type` property
* @throws {TypeError} Throws an exception if the resolved DataType is unkown to the Mapper
*/
map(attributeName, properties, strategy) {
let schema;

let result;
let attributeType = properties && properties.type && properties.type.key;

// w
// NOTE: All known sequelize types should be mentioned in the switch blocks
// below, either under aliases or transforms (but may be commented out if not
// supported yet)
Expand Down Expand Up @@ -60,7 +64,7 @@ class TypeMapper {
// ABSTRACT - not supported

case 'ARRAY': {
schema = {
result = {
...ARRAY,
// Sequelize requires attribute.type to be defined for ARRAYs
items: this.map({ type: properties.type.type, allowNull: false }),
Expand All @@ -69,50 +73,50 @@ class TypeMapper {
}

case 'BIGINT': {
schema = { ...INTEGER, format: 'int64' };
result = { ...INTEGER, format: 'int64' };
break;
}
case 'BLOB': {
schema = { ...STRING, contentEncoding: 'base64' };
result = { ...STRING, contentEncoding: 'base64' };
break;
}
case 'BOOLEAN': {
schema = { ...BOOLEAN };
result = { ...BOOLEAN };
break;
}
case 'CHAR': {
schema = { ...STRING };
result = { ...STRING };
break;
}
case 'CIDR': {
schema = { ...STRING };
result = { ...STRING };
break;
}

case 'DATE': {
schema = { ...STRING, format: 'date-time' };
result = { ...STRING, format: 'date-time' };
break;
}
case 'DATEONLY': {
schema = { ...STRING, format: 'date' };
result = { ...STRING, format: 'date' };
break;
}
case 'DECIMAL': {
schema = { ...NUMBER };
result = { ...NUMBER };
break;
}

// This is the `key` for DOUBLE datatypes... ¯\_(ツ)_/¯
case 'DOUBLE PRECISION': {
schema = { ...NUMBER, format: 'double' };
result = { ...NUMBER, format: 'double' };
break;
}
case 'ENUM': {
schema = { ...STRING, enum: [...properties.values] };
result = { ...STRING, enum: [...properties.values] };
break;
}
case 'FLOAT': {
schema = { ...NUMBER, format: 'float' };
result = { ...NUMBER, format: 'float' };
break;
}
// GEOGRAPHY - needs definition
Expand All @@ -122,88 +126,88 @@ class TypeMapper {
// @todo: fix this one, does not validate against version 7 schema
// @see https://github.com/Julian/jsonschema/issues/171
case 'INET': {
schema = { type: [{ ...STRING, format: 'ipv4' }, { ...STRING, format: 'ipv6' }] };
result = { type: [{ ...STRING, format: 'ipv4' }, { ...STRING, format: 'ipv6' }] };
break;
}

case 'INTEGER': {
schema = { ...INTEGER, format: 'int32' };
result = { ...INTEGER, format: 'int32' };
break;
}
case 'JSON': {
schema = { ...ANY, type: [...ANY.type] };
result = { ...ANY, type: [...ANY.type] };
break;
}
case 'JSONB': {
schema = { ...ANY, type: [...ANY.type] };
result = { ...ANY, type: [...ANY.type] };
break;
}
case 'MACADDR': {
schema = { ...STRING };
result = { ...STRING };
break;
}
case 'MEDIUMINT': {
schema = { ...INTEGER };
result = { ...INTEGER };
break;
}
// NOW: null,
case 'NUMBER': {
schema = { ...NUMBER };
result = { ...NUMBER };
break;
}
// RANGE: null,
case 'REAL': {
schema = { ...NUMBER };
result = { ...NUMBER };
break;
}
case 'SMALLINT': {
schema = { ...INTEGER };
result = { ...INTEGER };
break;
}

case 'STRING': {
schema = { ...STRING };
result = { ...STRING };
let length = properties.type.options && properties.type.options.length;

// use available length aliases if length property matches
// @todo make more readable, drop the const ??
length = STRING_LENGTHS[length] || length;
if (length) schema.maxLength = length;
if (length) result.maxLength = length;

//
const binary = properties.type.options && properties.type.options.binary;

if (binary) {
schema.format = 'binary';
result.format = 'binary';
}

break;
}

case 'TIME': {
schema = { ...STRING, format: 'time' };
result = { ...STRING, format: 'time' };
break;
}
case 'TINYINT': {
schema = { ...NUMBER };
result = { ...NUMBER };
break;
}
case 'UUID': {
schema = { ...STRING, format: 'uuid' };
result = { ...STRING, format: 'uuid' };
break;
}
case 'UUIDV1': {
schema = { ...STRING, format: 'uuid' };
result = { ...STRING, format: 'uuid' };
break;
}
case 'UUIDV4': {
schema = { ...STRING, format: 'uuid' };
result = { ...STRING, format: 'uuid' };
break;
}

case 'VIRTUAL': {
// Use schema for the return type (if defined)
schema = this.map({ ...properties, type: properties.type && properties.type.returnType });
// Use result for the return type (if defined)
result = this.map({ ...properties, type: properties.type && properties.type.returnType });
break;
}

Expand All @@ -212,17 +216,17 @@ class TypeMapper {
}

// throw an exception if we receive unknown (non) Sequelize types.
if (!schema)
if (!result)
throw new TypeError(
`Your Sequelize attribute '${attributeName}' contains unkown datatype '${attributeName}'`,
);

// convert type property if sequelize option `allowNUll` is true
if (properties.allowNull === true) {
_.merge(schema, this.constructor._getNullableType(schema.type, strategy));
_.merge(result, this.constructor._getNullableType(result.type, strategy));
}

return schema;
return result;
}

/**
Expand Down

0 comments on commit b91172d

Please sign in to comment.