UNPKG

feathers-prisma

Version:

A Feathers service adapter for Prisma ORM.

207 lines (206 loc) 8.37 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildWhereWithOptionalIdObject = exports.checkIdInQuery = exports.buildSelectOrInclude = exports.buildPrismaQueryParams = exports.buildPagination = exports.buildOrderBy = exports.buildSelect = exports.buildWhereAndInclude = exports.mergeFiltersWithSameKey = exports.castEagerQueryToPrismaInclude = exports.castFeathersQueryToPrismaFilters = exports.castToNumberBooleanStringOrNull = void 0; const errors_1 = require("@feathersjs/errors"); const constants_1 = require("./constants"); const castToNumberBooleanStringOrNull = (value) => { const isNumber = typeof value === 'number'; const isBoolean = value === 'true' || value === 'false'; if (isBoolean || typeof value === 'boolean') { return typeof value === 'string' ? value === 'true' : value; } if (isNumber) { return value; } if (value === 'null') { return null; } return value; }; exports.castToNumberBooleanStringOrNull = castToNumberBooleanStringOrNull; const castFeathersQueryToPrismaFilters = (p, whitelist) => { const filters = {}; Object.keys(p).forEach((k) => { const key = k; const prismaKey = constants_1.OPERATORS_MAP[key]; if (prismaKey && key !== '$eager' && whitelist.includes(key)) { const value = p[key]; if (Array.isArray(value)) { filters[prismaKey] = value.map((v) => (0, exports.castToNumberBooleanStringOrNull)(v)); } else if (key === '$rawWhere' && typeof value === 'object' || key === '$prisma' && typeof value === 'object') { Object.keys(value).forEach((rawKey) => { filters[rawKey] = value[rawKey]; }); } else if (value !== undefined && typeof value !== 'object') { filters[prismaKey] = (0, exports.castToNumberBooleanStringOrNull)(value); } } }); return filters; }; exports.castFeathersQueryToPrismaFilters = castFeathersQueryToPrismaFilters; const castEagerQueryToPrismaInclude = (value, whitelist, idField) => { const include = {}; if (Array.isArray(value)) { value.forEach((v) => { if (Array.isArray(v) && typeof v[0] === 'string' && v.length > 1) { const [key, ...includes] = v; const subinclude = (0, exports.castEagerQueryToPrismaInclude)(includes, whitelist, idField); include[key] = { include: subinclude, }; } else if (Array.isArray(v) && typeof v[0] === 'string' && v.length === 1) { const [key] = v; include[key] = true; } else if (typeof v[0] !== 'string') { throw { code: 'FP1001', message: 'First Array Item in a sub-array must be a string!', }; } else if (typeof v === 'string') { include[v] = true; } }); } else { Object.keys(value).forEach((key) => { const val = value[key]; if (typeof val === 'boolean') { include[key] = val; } else if (Array.isArray(val)) { include[key] = { select: Object.assign({ [idField]: true }, (0, exports.buildSelect)(val)), }; } }); } return include; }; exports.castEagerQueryToPrismaInclude = castEagerQueryToPrismaInclude; const mergeFiltersWithSameKey = (where, key, filter) => { const current = where[key]; if (typeof filter === 'object') { const currentIsObj = typeof current === 'object'; return Object.assign(Object.assign(Object.assign({}, (currentIsObj ? current : {})), filter), (!currentIsObj && current ? { equals: current } : {})); } return filter; }; exports.mergeFiltersWithSameKey = mergeFiltersWithSameKey; const buildWhereAndInclude = (query, whitelist, idField) => { const where = {}; let include = {}; Object.keys(query).forEach((k) => { const value = query[k]; if (k === '$or' && Array.isArray(value)) { where.OR = value.map((v) => (0, exports.buildWhereAndInclude)(v, whitelist, idField).where); } else if (k === '$and' && Array.isArray(value)) { value.forEach((v) => { const whereValue = (0, exports.buildWhereAndInclude)(v, whitelist, idField).where; Object.keys(whereValue).map((subKey) => { where[subKey] = (0, exports.mergeFiltersWithSameKey)(where, subKey, whereValue[subKey]); }); }); } else if (k !== '$eager' && typeof value === 'object' && !Array.isArray(value)) { where[k] = (0, exports.mergeFiltersWithSameKey)(where, k, (0, exports.castFeathersQueryToPrismaFilters)(value, whitelist)); } else if (k !== '$eager' && typeof value !== 'object' && !Array.isArray(value)) { where[k] = (0, exports.castToNumberBooleanStringOrNull)(value); } else if (k === '$eager' && whitelist.includes(k)) { const eager = value; include = (0, exports.castEagerQueryToPrismaInclude)(eager, whitelist, idField); } }); return { where, include }; }; exports.buildWhereAndInclude = buildWhereAndInclude; const buildSelect = ($select) => { const select = {}; $select.forEach((f) => { select[f] = true; }); return select; }; exports.buildSelect = buildSelect; const buildOrderBy = ($sort) => { return Object.keys($sort).map((k) => ({ [k]: $sort[k] === 1 ? 'asc' : 'desc' })); }; exports.buildOrderBy = buildOrderBy; const buildPagination = ($skip, $limit) => { return { skip: $skip || 0, take: $limit, }; }; exports.buildPagination = buildPagination; const buildPrismaQueryParams = ({ id, query, filters, whitelist }, idField) => { let select = (0, exports.buildSelect)(filters.$select || []); const selectExists = Object.keys(select).length > 0; const { where, include } = (0, exports.buildWhereAndInclude)(id ? Object.assign({ [idField]: id }, query) : query, whitelist, idField); const includeExists = Object.keys(include).length > 0; const orderBy = (0, exports.buildOrderBy)(filters.$sort || {}); const { skip, take } = (0, exports.buildPagination)(filters.$skip, filters.$limit); const queryWhereExists = Object.keys(where).filter((k) => k !== idField).length > 0; const idQueryIsObject = typeof where.id === 'object'; if (selectExists) { select = Object.assign(Object.assign({ [idField]: true }, select), include); return { skip, take, orderBy, where, select, _helper: { queryWhereExists, idQueryIsObject }, }; } if (!selectExists && includeExists) { return { skip, take, orderBy, where, include, _helper: { queryWhereExists, idQueryIsObject }, }; } return { skip, take, orderBy, where, _helper: { queryWhereExists, idQueryIsObject }, }; }; exports.buildPrismaQueryParams = buildPrismaQueryParams; const buildSelectOrInclude = ({ select, include }) => { return select ? { select } : include ? { include } : {}; }; exports.buildSelectOrInclude = buildSelectOrInclude; const checkIdInQuery = ({ id, query, idField, allowOneOf, }) => { if ((allowOneOf && id && Object.keys(query).length > 0) || (id && query[idField] && id !== query[idField])) { throw new errors_1.NotFound(`No record found for ${idField} '${id}' and query.${idField} '${id}'`); } }; exports.checkIdInQuery = checkIdInQuery; const buildWhereWithOptionalIdObject = (id, where, idField) => { if (typeof where.id === 'object') { return Object.assign(Object.assign({}, where), { [idField]: Object.assign(Object.assign({}, where[idField]), { equals: id }) }); } return where; }; exports.buildWhereWithOptionalIdObject = buildWhereWithOptionalIdObject;