typia
Version:
Superfast runtime validators with only one line
201 lines • 9.27 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MetadataFactory = void 0;
const typescript_1 = __importDefault(require("typescript"));
const Metadata_1 = require("../schemas/metadata/Metadata");
const MetadataConstant_1 = require("../schemas/metadata/MetadataConstant");
const MetadataObject_1 = require("../schemas/metadata/MetadataObject");
const explore_metadata_1 = require("./internal/metadata/explore_metadata");
const iterate_metadata_collection_1 = require("./internal/metadata/iterate_metadata_collection");
const iterate_metadata_sort_1 = require("./internal/metadata/iterate_metadata_sort");
const ExpressionFactory_1 = require("./ExpressionFactory");
var MetadataFactory;
(function (MetadataFactory) {
MetadataFactory.analyze = (props) => {
const errors = [];
const metadata = (0, explore_metadata_1.explore_metadata)(Object.assign(Object.assign({}, props), { errors, explore: {
top: true,
object: null,
property: null,
parameter: null,
nested: null,
aliased: false,
escaped: false,
output: false,
}, intersected: false }));
(0, iterate_metadata_collection_1.iterate_metadata_collection)({
errors,
collection: props.collection,
});
(0, iterate_metadata_sort_1.iterate_metadata_sort)({
collection: props.collection,
metadata: metadata,
});
if (props.options.validate)
errors.push(...MetadataFactory.validate({
transformer: props.transformer,
options: props.options,
functor: props.options.validate,
metadata,
}));
return errors.length
? {
success: false,
errors,
}
: {
success: true,
data: metadata,
};
};
/** @internal */
MetadataFactory.soleLiteral = (value) => {
const meta = Metadata_1.Metadata.initialize();
meta.constants.push(MetadataConstant_1.MetadataConstant.from({
values: [
{
value,
tags: [],
},
],
type: "string",
}));
return meta;
};
MetadataFactory.validate = (props) => {
const visitor = {
functor: props.functor,
errors: [],
objects: new Set(),
arrays: new Set(),
tuples: new Set(),
aliases: new Set(),
functions: new Set(),
};
validateMeta(Object.assign(Object.assign({}, props), { visitor, explore: {
object: null,
property: null,
parameter: null,
nested: null,
top: true,
aliased: false,
escaped: false,
output: false,
} }));
return visitor.errors;
};
const validateMeta = (props) => {
const result = [];
for (const atomic of props.metadata.atomics)
for (const row of atomic.tags)
for (const tag of row.filter((t) => t.validate !== undefined && t.predicate === undefined))
try {
tag.predicate = ExpressionFactory_1.ExpressionFactory.transpile({
script: tag.validate,
});
}
catch (_a) {
result.push(`Unable to transpile type tag script: ${JSON.stringify(tag.validate)}`);
tag.predicate = () => typescript_1.default.factory.createTrue();
}
result.push(...props.visitor.functor(props.metadata, props.explore));
if (result.length)
props.visitor.errors.push({
name: props.metadata.getName(),
explore: Object.assign({}, props.explore),
messages: [...new Set(result)],
});
for (const alias of props.metadata.aliases)
validateAlias(Object.assign(Object.assign({}, props), { alias: alias.type }));
for (const array of props.metadata.arrays)
validateArray(Object.assign(Object.assign({}, props), { array: array.type }));
for (const tuple of props.metadata.tuples)
validateTuple(Object.assign(Object.assign({}, props), { tuple: tuple.type }));
for (const object of props.metadata.objects)
validateObject(Object.assign(Object.assign({}, props), { object: object.type }));
for (const func of props.metadata.functions)
validateFunction(Object.assign(Object.assign({}, props), { function: func }));
for (const set of props.metadata.sets)
validateMeta(Object.assign(Object.assign({}, props), { metadata: set.value }));
for (const map of props.metadata.maps) {
validateMeta(Object.assign(Object.assign({}, props), { metadata: map.key }));
validateMeta(Object.assign(Object.assign({}, props), { metadata: map.value }));
}
if (props.options.escape === true && props.metadata.escaped !== null)
validateMeta(Object.assign(Object.assign({}, props), { metadata: props.metadata.escaped.returns, explore: Object.assign(Object.assign({}, props.explore), { escaped: true }) }));
};
const validateAlias = (props) => {
if (props.visitor.aliases.has(props.alias))
return;
props.visitor.aliases.add(props.alias);
validateMeta(Object.assign(Object.assign({}, props), { metadata: props.alias.value, explore: Object.assign(Object.assign({}, props.explore), { nested: props.alias, aliased: true }) }));
};
const validateArray = (props) => {
if (props.visitor.arrays.has(props.array))
return;
props.visitor.arrays.add(props.array);
validateMeta(Object.assign(Object.assign({}, props), { metadata: props.array.value, explore: Object.assign(Object.assign({}, props.explore), { nested: props.array, top: false }) }));
};
const validateTuple = (props) => {
if (props.visitor.tuples.has(props.tuple))
return;
props.visitor.tuples.add(props.tuple);
for (const elem of props.tuple.elements)
validateMeta(Object.assign(Object.assign({}, props), { metadata: elem, explore: Object.assign(Object.assign({}, props.explore), { nested: props.tuple, top: false }) }));
};
const validateObject = (props) => {
if (props.visitor.objects.has(props.object))
return;
props.visitor.objects.add(props.object);
if (props.options.validate) {
const explore = {
object: props.object,
top: false,
property: null,
parameter: null,
nested: null,
aliased: false,
escaped: false,
output: false,
};
const errors = props.options.validate(Metadata_1.Metadata.create(Object.assign(Object.assign({}, Metadata_1.Metadata.initialize()), { objects: [
MetadataObject_1.MetadataObject.create({
type: props.object,
tags: [],
}),
] })), explore);
if (errors.length)
props.visitor.errors.push({
name: props.object.name,
explore,
messages: [...new Set(errors)],
});
}
for (const property of props.object.properties)
validateMeta(Object.assign(Object.assign({}, props), { metadata: property.value, explore: {
object: props.object,
property: property.key.isSoleLiteral()
? property.key.getSoleLiteral()
: {},
parameter: null,
nested: null,
top: false,
aliased: false,
escaped: false,
output: false,
} }));
};
const validateFunction = (props) => {
if (props.visitor.functions.has(props.function))
return;
props.visitor.functions.add(props.function);
for (const param of props.function.parameters)
validateMeta(Object.assign(Object.assign({}, props), { metadata: param.type, explore: Object.assign(Object.assign({}, props.explore), { parameter: param.name, nested: null, top: false, output: false }) }));
if (props.function.output)
validateMeta(Object.assign(Object.assign({}, props), { metadata: props.function.output, explore: Object.assign(Object.assign({}, props.explore), { parameter: null, nested: null, top: false, output: true }) }));
};
})(MetadataFactory || (exports.MetadataFactory = MetadataFactory = {}));
//# sourceMappingURL=MetadataFactory.js.map