UNPKG

typia

Version:

Superfast runtime validators with only one line

210 lines (207 loc) • 5.93 kB
import { MetadataNative } from '../../../schemas/metadata/MetadataNative.mjs'; import { ArrayUtil } from '../../../utils/ArrayUtil.mjs'; import { TypeFactory } from '../../TypeFactory.mjs'; const iterate_metadata_native = (props) => { const name = getNativeName(TypeFactory.getFullName({ checker: props.checker, type: props.type, symbol: props.type.getSymbol(), })); const simple = SIMPLES.get(name); if (simple !== undefined && validate({ checker: props.checker, type: props.type, info: simple, })) { ArrayUtil.take(props.metadata.natives, (native) => native.name === name, () => MetadataNative.create({ name, tags: [], })); return true; } for (const generic of GENERICS) if (name.substring(0, generic.name.length) === generic.name && validate({ checker: props.checker, type: props.type, info: generic, })) { ArrayUtil.take(props.metadata.natives, (native) => native.name === name, () => MetadataNative.create({ name: generic.name ?? name, tags: [], })); return true; } return false; }; const validate = (props) => (props.info.methods ?? []).every((method) => { const returnType = TypeFactory.getReturnTypeOfClassMethod({ checker: props.checker, class: props.type, function: method.name, }); return (returnType !== null && props.checker.typeToString(returnType).split("<")?.[0] === method.return); }) && (props.info.properties ?? []).every((property) => { const prop = props.checker.getPropertyOfType(props.type, property.name); const propType = prop?.valueDeclaration ? props.checker.getTypeAtLocation(prop?.valueDeclaration) : undefined; return (propType !== undefined && props.checker.typeToString(propType).split("<")?.[0] === property.type); }); const getBinaryProps = (className) => ({ name: className, methods: [ ...["indexOf", "lastIndexOf"].map((name) => ({ name, return: "number", })), ...["some", "every"].map((name) => ({ name, return: "boolean", })), ...["join", "toLocaleString"].map((name) => ({ name, return: "string", })), ...["reverse", "slice", "subarray"].map((name) => ({ name, return: className, })), ], properties: ["BYTES_PER_ELEMENT", "length", "byteLength", "byteOffset"].map((name) => ({ name, type: "number", })), }); const getNativeName = (name) => { name = name.split("<")?.[0] ?? ""; if (name.startsWith('"') && name.slice(0).includes('".')) name = name.slice(name.indexOf('".', 1) + 2); return name; }; const SIMPLES = new Map([ [ "Date", { methods: ["getTime", "getFullYear", "getMonth", "getMinutes"].map((name) => ({ name, return: "number", })), }, ], [ "Boolean", { methods: [ { name: "valueOf", return: "boolean", }, ], }, ], [ "Number", { methods: [ ...["toFixed", "toExponential", "toPrecision"].map((name) => ({ name, return: "string", })), { name: "valueOf", return: "number" }, ], }, ], [ "String", { methods: [ "charAt", "concat", "valueOf", "trim", "replace", "substring", ].map((name) => ({ name, return: "string" })), }, ], ...[ "Uint8Array", "Uint8ClampedArray", "Uint16Array", "Uint32Array", "BigUint64Array", "Int8Array", "Int16Array", "Int32Array", "BigInt64Array", "Float32Array", "Float64Array", ].map((name) => [name, getBinaryProps(name)]), ...["ArrayBuffer", "SharedArrayBuffer"].map((className) => { const info = { methods: [{ name: "slice", return: className }], properties: [{ name: "byteLength", type: "number" }], }; return [className, info]; }), ...["Blob", "File"].map((className) => [ className, { methods: [ { name: "arrayBuffer", return: "Promise" }, { name: "slice", return: "Blob" }, { name: "text", return: "Promise" }, ], properties: [ { name: "size", type: "number" }, { name: "type", type: "string" }, ], }, ]), [ "DataView", { methods: [ "getFloat32", "getFloat64", "getInt8", "getInt16", "getInt32", "getUint8", "getUint16", "getUint32", ].map((name) => ({ name, return: "number", })), }, ], [ "RegExp", { methods: [ { name: "test", return: "boolean", }, ], }, ], ]); const GENERICS = [ "WeakMap", "WeakSet", ].map((name) => ({ name, methods: ["has", "delete"].map((name) => ({ name, return: "boolean", })), })); export { iterate_metadata_native }; //# sourceMappingURL=iterate_metadata_native.mjs.map