UNPKG

typia

Version:

Superfast runtime validators with only one line

169 lines 7.57 kB
"use strict"; 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