typia
Version:
Superfast runtime validators with only one line
169 lines • 7.57 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.iterate_metadata_intersection = void 0;
const MetadataTypeTagFactory_1 = require("../../MetadataTypeTagFactory");
const explore_metadata_1 = require("./explore_metadata");
const iterate_metadata_1 = require("./iterate_metadata");
const iterate_metadata_intersection = (props) => {
if (props.intersected === true)
return false;
else if (props.type.isIntersection() === false)
return false;
// CONSTRUCT FAKE METADATA LIST
const commit = props.collection.clone();
props.collection["options"] = undefined;
const fakeErrors = [];
const children = props.type.types.map((t) => (0, explore_metadata_1.explore_metadata)(Object.assign(Object.assign({}, props), { options: Object.assign(Object.assign({}, props.options), { absorb: true, functional: false }), collection: props.collection, errors: fakeErrors, type: t, explore: Object.assign(Object.assign({}, props.explore), { aliased: false }), intersected: false })));
// ERROR OR ANY TYPE CASE
const escape = (out) => {
Object.assign(props.collection, commit);
return out;
};
if (fakeErrors.length) {
props.errors.push(...fakeErrors);
return escape(true);
}
else if (children.length === 0)
return escape(false);
else if (children.some((m) => m.any === true || m.size() === 0))
return escape(false);
// PREPARE MEATDATAS AND TAGS
const indexes = [];
const metadatas = [];
const tagObjects = [];
children.forEach((child, i) => {
if (child.size() === 1 &&
child.objects.length === 1 &&
MetadataTypeTagFactory_1.MetadataTypeTagFactory.is(child.objects[0].type))
tagObjects.push(child.objects[0].type);
else {
indexes.push(i);
metadatas.push(child);
}
});
const nonsensible = () => {
props.errors.push({
name: children.map((c) => c.getName()).join(" & "),
explore: Object.assign({}, props.explore),
messages: ["nonsensible intersection"],
});
return escape(true);
};
// NO METADATA CASE
if (metadatas.length === 0)
if (tagObjects.length !== 0) {
props.errors.push({
name: children.map((c) => c.getName()).join(" & "),
explore: Object.assign({}, props.explore),
messages: ["type tag cannot be standalone"],
});
return escape(true);
}
else
return escape(false);
// ONLY OBJECTS CASE
else if (metadatas.every((m) => m.objects.length === 1) &&
tagObjects.length === 0)
return escape(false);
else if (metadatas.length !== 1) {
const indexes = metadatas
.map((m, i) => m.size() === 1 &&
m.objects.length === 1 &&
(m.objects[0].type.properties.length === 0 ||
m.objects[0].type.properties.every((p) => p.value.optional === true))
? i
: null)
.filter((i) => i !== null);
if (indexes.length && metadatas.length !== indexes.length)
for (const i of indexes.reverse())
metadatas.splice(i, 1);
else
return nonsensible();
}
else if (metadatas.some((m) => m.size() !== 1))
return nonsensible();
const candidates = new Map();
const assigners = [];
for (const meta of metadatas) {
for (const a of meta.atomics) {
candidates.set(a.type, a.type);
assigners.push((tags) => {
var _a;
return (_a = props.metadata.atomics
.find((atom) => atom.type === a.type)) === null || _a === void 0 ? void 0 : _a.tags.push(tags);
});
}
for (const c of meta.constants)
for (const v of c.values) {
candidates.set(c.type, c.type);
assigners.push((tags) => {
var _a, _b, _c;
return (_c = (_b = (_a = props.metadata.constants
.find((constant) => constant.type === c.type)) === null || _a === void 0 ? void 0 : _a.values.find((value) => value === v)) === null || _b === void 0 ? void 0 : _b.tags) === null || _c === void 0 ? void 0 : _c.push(tags);
});
}
for (const t of meta.templates) {
candidates.set("string", "string");
assigners.push((tags) => {
var _a;
return (_a = props.metadata.templates
.find((tpl) => tpl.getBaseName() === t.getBaseName())) === null || _a === void 0 ? void 0 : _a.tags.push(tags);
});
}
if (meta.objects.length) {
candidates.set("object", "object");
assigners.push((tags) => { var _a; return (_a = props.metadata.objects.at(-1)) === null || _a === void 0 ? void 0 : _a.tags.push(tags); });
}
if (meta.arrays.length) {
candidates.set("array", "array");
assigners.push((tags) => { var _a; return (_a = props.metadata.arrays.at(-1)) === null || _a === void 0 ? void 0 : _a.tags.push(tags); });
}
if (meta.tuples.length)
candidates.set("invalid", "tuple");
for (const n of meta.natives) {
candidates.set(`native::${n.name}`, "object");
assigners.push((tags) => {
var _a;
return (_a = props.metadata.natives
.find((native) => native.name === n.name)) === null || _a === void 0 ? void 0 : _a.tags.push(tags);
});
}
for (const s of meta.sets) {
candidates.set(`set::${s.value.getName()}`, "object");
assigners.push((tags) => {
var _a;
return (_a = props.metadata.sets
.find((set) => set.value.getName() === s.value.getName())) === null || _a === void 0 ? void 0 : _a.tags.push(tags);
});
}
for (const e of meta.maps) {
candidates.set(`map::${e.key.getName()}::${e.value.getName()}`, "object");
assigners.push((tags) => {
var _a;
return (_a = props.metadata.maps
.find((map) => map.key.getName() === e.key.getName() &&
map.value.getName() === e.value.getName())) === null || _a === void 0 ? void 0 : _a.tags.push(tags);
});
}
}
if (candidates.size !== 1 ||
candidates.has("nonsensible")
// ||
// (candidates.size !== 1 &&
// Array.from(candidates.keys()).some((v) => v !== "object"))
)
return nonsensible();
const tags = MetadataTypeTagFactory_1.MetadataTypeTagFactory.analyze({
errors: props.errors,
type: candidates.values().next().value,
objects: tagObjects,
explore: props.explore,
});
Object.assign(props.collection, commit);
(0, iterate_metadata_1.iterate_metadata)(Object.assign(Object.assign({}, props), { type: props.type.types[indexes[0]], options: Object.assign(Object.assign({}, props.options), { functional: false }), explore: Object.assign(Object.assign({}, props.explore), { aliased: false, escaped: false }), intersected: true }));
if (tags.length)
assigners.forEach((fn) => fn(tags));
return true;
};
exports.iterate_metadata_intersection = iterate_metadata_intersection;
//# sourceMappingURL=iterate_metadata_intersection.js.map