json-api-nestjs
Version:
JsonApi Plugin for NestJs
286 lines • 9.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.schemaTypeForRelation = exports.errorSchema = void 0;
exports.jsonSchemaResponse = jsonSchemaResponse;
exports.createApiModels = createApiModels;
exports.getEntityMapProps = getEntityMapProps;
const swagger_1 = require("@nestjs/swagger");
const nestjs_shared_1 = require("../../../utils/nestjs-shared");
const types_1 = require("../types");
exports.errorSchema = {
type: 'object',
properties: {
statusCode: {
type: 'number',
},
error: {
type: 'string',
},
message: {
type: 'array',
items: {
type: 'object',
properties: {
code: {
type: 'string',
},
message: {
type: 'string',
},
path: {
type: 'array',
items: {
type: 'string',
},
},
keys: {
type: 'array',
items: {
type: 'string',
},
},
},
required: ['code', 'message', 'path'],
},
},
},
};
function jsonSchemaResponse(entity, mapEntity, array = false) {
const { propsType, relations, relationProperty, primaryColumnName } = getEntityMapProps(mapEntity, entity);
const dataType = {
type: 'object',
properties: {
type: {
type: 'string',
const: (0, nestjs_shared_1.camelToKebab)(entity.name),
},
id: {
type: 'string',
},
attributes: {
type: 'object',
properties: nestjs_shared_1.ObjectTyped.entries(propsType)
.filter(([name]) => name !== primaryColumnName)
.reduce((acum, [name, type]) => {
switch (type) {
case types_1.TypeField.array:
acum[name.toString()] = {
type: 'array',
items: {
type: 'string',
},
};
break;
case types_1.TypeField.date:
acum[name.toString()] = {
format: 'date-time',
type: 'string',
};
break;
case types_1.TypeField.number:
acum[name.toString()] = {
type: 'integer',
};
break;
case types_1.TypeField.boolean:
acum[name.toString()] = {
type: 'boolean',
};
break;
default:
acum[name.toString()] = {
type: 'string',
};
}
return acum;
}, {}),
},
relationships: {
type: 'object',
properties: relations.reduce((acum, name) => {
const dataItem = {
type: 'object',
properties: {
type: {
type: 'string',
const: getEntityMapProps(mapEntity, Reflect.get(relationProperty, name).entityClass).typeName,
},
id: {
type: 'string',
},
},
required: ['type', 'id'],
};
const dataArray = {
type: 'array',
items: dataItem,
};
acum[name.toString()] = {
type: 'object',
properties: {
links: {
type: 'object',
properties: {
self: {
type: 'string',
},
},
required: ['self'],
},
data: Reflect.get(relationProperty, name).isArray
? dataArray
: dataItem,
},
required: ['links'],
};
return acum;
}, {}),
},
links: {
type: 'object',
properties: {
self: {
type: 'string',
},
},
required: ['self'],
},
},
};
const dataTypeArra = {
type: 'array',
items: dataType,
};
return {
type: 'object',
properties: {
meta: {
type: 'object',
},
data: array ? dataTypeArra : dataType,
includes: {
type: 'array',
items: {
type: 'object',
properties: {
type: {
type: 'string',
},
id: {
type: 'string',
},
attributes: {
type: 'object',
},
relationships: {
type: 'object',
properties: {
relationName: {
properties: {
links: {
type: 'object',
properties: {
self: {
type: 'string',
},
},
required: ['self'],
},
},
required: ['links'],
},
},
},
links: {
type: 'object',
properties: {
self: {
type: 'string',
},
},
required: ['self'],
},
},
required: ['type', 'id', 'attributes'],
},
},
},
required: ['meta', 'data'],
};
}
function createApiModels(entity, mapEntity) {
const { propsType, props, relations, propsNullable, relationProperty } = mapEntity;
for (const name of props) {
let currentType;
let required = false;
let isArray = false;
required = !propsNullable.includes(name);
const type = Reflect.get(propsType, name);
isArray = type === 'array';
switch (type) {
case types_1.TypeField.date:
currentType = Date;
break;
case types_1.TypeField.number:
currentType = Number;
break;
case types_1.TypeField.boolean:
currentType = Boolean;
break;
default:
currentType = String;
}
if (relations.includes(name)) {
const propsRel = Reflect.get(relationProperty, name);
currentType = propsRel.entityClass;
isArray = propsRel.isArray;
}
(0, swagger_1.ApiProperty)({
required,
isArray,
type: () => currentType,
})(entity.prototype, name.toString());
}
for (const name of relations) {
const propsRel = Reflect.get(relationProperty, name);
(0, swagger_1.ApiProperty)({
required: !propsRel.nullable,
isArray: propsRel.isArray,
type: propsRel.entityClass,
})(entity.prototype, name.toString());
}
return entity;
}
const dataType = {
type: 'object',
properties: {
type: {
type: 'string',
},
id: {
type: 'string',
},
},
};
exports.schemaTypeForRelation = {
type: 'object',
properties: {
data: {
oneOf: [
dataType,
{ type: 'null' },
{
type: 'array',
items: dataType,
},
],
},
},
};
function getEntityMapProps(mapEntity, entity) {
const entityMap = mapEntity.get(entity);
if (!entityMap)
throw new Error('Entity not found in map');
return entityMap;
}
//# sourceMappingURL=utils.js.map