@feathersjs/typebox
Version:
TypeBox integration for @feathersjs/schema
147 lines • 6.46 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ObjectIdSchema = exports.querySyntax = exports.queryProperties = exports.queryProperty = exports.getDataValidator = exports.getValidator = void 0;
exports.StringEnum = StringEnum;
exports.sortDefinition = sortDefinition;
const typebox_1 = require("@sinclair/typebox");
const schema_1 = require("@feathersjs/schema");
__exportStar(require("@sinclair/typebox"), exports);
__exportStar(require("./default-schemas"), exports);
/**
* Returns a compiled validation function for a TypeBox object and AJV validator instance.
*
* @param schema The JSON schema definition
* @param validator The AJV validation instance
* @returns A compiled validation function
*/
const getValidator = (schema, validator) => schema_1.jsonSchema.getValidator(schema, validator);
exports.getValidator = getValidator;
/**
* Returns compiled validation functions to validate data for the `create`, `update` and `patch`
* service methods. If not passed explicitly, the `update` validator will be the same as the `create`
* and `patch` will be the `create` validator with no required fields.
*
* @param def Either general TypeBox object definition or a mapping of `create`, `update` and `patch`
* to their respective type object
* @param validator The Ajv instance to use as the validator
* @returns A map of validator functions
*/
const getDataValidator = (def, validator) => schema_1.jsonSchema.getDataValidator(def, validator);
exports.getDataValidator = getDataValidator;
/**
* A TypeBox utility that converts an array of provided strings into a string enum.
* @param allowedValues array of strings for the enum
* @returns TypeBox.Type
*/
function StringEnum(allowedValues, options) {
return typebox_1.Type.Unsafe({ type: 'string', enum: allowedValues, ...options });
}
const arrayOfKeys = (type) => {
const keys = Object.keys(type.properties);
return typebox_1.Type.Unsafe({
type: 'array',
maxItems: keys.length,
items: {
type: 'string',
...(keys.length > 0 ? { enum: keys } : {})
}
});
};
/**
* Creates the `$sort` Feathers query syntax schema for an object schema
*
* @param schema The TypeBox object schema
* @returns The `$sort` syntax schema
*/
function sortDefinition(schema) {
const properties = Object.keys(schema.properties).reduce((res, key) => {
const result = res;
result[key] = typebox_1.Type.Optional(typebox_1.Type.Integer({ minimum: -1, maximum: 1 }));
return result;
}, {});
return typebox_1.Type.Object(properties, { additionalProperties: false });
}
/**
* Returns the standard Feathers query syntax for a property schema,
* including operators like `$gt`, `$lt` etc. for a single property
*
* @param def The property definition
* @param extension Additional properties to add to the property query
* @returns The Feathers query syntax schema
*/
const queryProperty = (def, extension = {}) => typebox_1.Type.Optional(typebox_1.Type.Union([
def,
typebox_1.Type.Partial(typebox_1.Type.Intersect([
typebox_1.Type.Object({
$gt: def,
$gte: def,
$lt: def,
$lte: def,
$ne: def,
$in: def.type === 'array' ? def : typebox_1.Type.Array(def),
$nin: def.type === 'array' ? def : typebox_1.Type.Array(def)
}),
typebox_1.Type.Object(extension)
], { additionalProperties: false }))
]));
exports.queryProperty = queryProperty;
/**
* Creates a Feathers query syntax schema for the properties defined in `definition`.
*
* @param definition The properties to create the Feathers query syntax schema for
* @param extensions Additional properties to add to a property query
* @returns The Feathers query syntax schema
*/
const queryProperties = (definition, extensions = {}) => {
const properties = Object.keys(definition.properties).reduce((res, key) => {
const result = res;
const value = definition.properties[key];
result[key] = (0, exports.queryProperty)(value, extensions[key]);
return result;
}, {});
return typebox_1.Type.Optional(typebox_1.Type.Object(properties, { additionalProperties: false }));
};
exports.queryProperties = queryProperties;
/**
* Creates a TypeBox schema for the complete Feathers query syntax including `$limit`, $skip`, `$or`
* and `$sort` and `$select` for the allowed properties.
*
* @param type The properties to create the query syntax for
* @param extensions Additional properties to add to the query syntax
* @param options Options for the TypeBox object schema
* @returns A TypeBox object representing the complete Feathers query syntax for the given properties
*/
const querySyntax = (type, extensions = {}, options = { additionalProperties: false }) => {
const propertySchema = (0, exports.queryProperties)(type, extensions);
const $or = typebox_1.Type.Array(propertySchema);
const $and = typebox_1.Type.Array(typebox_1.Type.Union([propertySchema, typebox_1.Type.Object({ $or })]));
return typebox_1.Type.Intersect([
typebox_1.Type.Partial(typebox_1.Type.Object({
$limit: typebox_1.Type.Number({ minimum: 0 }),
$skip: typebox_1.Type.Number({ minimum: 0 }),
$sort: sortDefinition(type),
$select: arrayOfKeys(type),
$and,
$or
}, { additionalProperties: false })),
propertySchema
], options);
};
exports.querySyntax = querySyntax;
const ObjectIdSchema = () => typebox_1.Type.Union([typebox_1.Type.String({ objectid: true }), typebox_1.Type.Object({}, { additionalProperties: true })]);
exports.ObjectIdSchema = ObjectIdSchema;
//# sourceMappingURL=index.js.map