UNPKG

@nestia/sdk

Version:

Nestia SDK and Swagger generator

218 lines 12.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SdkTypeProgrammer = void 0; const factory_1 = require("@ttsc/factory"); const utils_1 = require("@typia/utils"); const ExpressionFactory_1 = require("../../factories/ExpressionFactory"); const TypeFactory_1 = require("../../factories/TypeFactory"); const legacy_1 = require("../../internal/legacy"); const FilePrinter_1 = require("./FilePrinter"); const SdkTypeTagProgrammer_1 = require("./SdkTypeTagProgrammer"); var SdkTypeProgrammer; (function (SdkTypeProgrammer) { /* ----------------------------------------------------------- FACADE ----------------------------------------------------------- */ SdkTypeProgrammer.write = (project) => (importer) => (meta, parentEscaped = false) => { var _a; const union = []; // COALESCES if (meta.any) union.push(TypeFactory_1.TypeFactory.keyword("any")); if (meta.nullable) union.push(writeNode("null")); if (meta.required === false) union.push(writeNode("undefined")); if (parentEscaped === false && meta.escaped) union.push(write_escaped(project)(importer)(meta.escaped)); // ATOMIC TYPES for (const c of meta.constants) for (const value of c.values) union.push(write_constant(value)); for (const tpl of meta.templates) union.push(write_template(project)(importer)((_a = tpl.row) !== null && _a !== void 0 ? _a : tpl)); for (const atom of meta.atomics) union.push(write_atomic(importer)(atom)); // OBJECT TYPES for (const tuple of meta.tuples) union.push(write_tuple(project)(importer)(tuple)); for (const array of meta.arrays) union.push(write_array(project)(importer)(array)); for (const object of meta.objects) { const target = object.type; if (target.name === "object" || target.name === "__type" || target.name.startsWith("__type.") || target.name === "__object" || target.name.startsWith("__object.")) union.push(SdkTypeProgrammer.write_object(project)(importer)(target)); else union.push(writeAlias(project)(importer)(target)); } for (const alias of meta.aliases) union.push(writeAlias(project)(importer)(alias.type)); for (const native of meta.natives) if (native.name === "Blob" || native.name === "File") union.push(write_native(native.name)); return union.length === 1 ? union[0] : factory_1.factory.createUnionTypeNode(union); }; SdkTypeProgrammer.write_object = (project) => (importer) => (object) => { const regular = object.properties.filter((p) => (0, legacy_1.isSoleLiteralOf)(p.key)); const dynamic = object.properties.filter((p) => !(0, legacy_1.isSoleLiteralOf)(p.key)); return regular.length && dynamic.length ? factory_1.factory.createIntersectionTypeNode([ write_regular_property(project)(importer)(regular), ...dynamic.map(write_dynamic_property(project)(importer)), ]) : dynamic.length ? factory_1.factory.createIntersectionTypeNode(dynamic.map(write_dynamic_property(project)(importer))) : write_regular_property(project)(importer)(regular); }; const write_escaped = (project) => (importer) => (meta) => { if ((0, legacy_1.sizeOf)(meta.original) === 1 && meta.original.natives.length === 1 && meta.original.natives[0].name === "Date") return factory_1.factory.createIntersectionTypeNode([ TypeFactory_1.TypeFactory.keyword("string"), SdkTypeTagProgrammer_1.SdkTypeTagProgrammer.write(importer, "string", { name: "Format", value: "date-time", }), ]); return SdkTypeProgrammer.write(project)(importer)(meta.returns, true); }; /* ----------------------------------------------------------- ATOMICS ----------------------------------------------------------- */ const write_constant = (value) => { if (typeof value.value === "boolean") return factory_1.factory.createLiteralTypeNode(value.value ? factory_1.factory.createTrue() : factory_1.factory.createFalse()); else if (typeof value.value === "bigint") return factory_1.factory.createLiteralTypeNode(value.value < BigInt(0) ? factory_1.factory.createPrefixUnaryExpression(factory_1.SyntaxKind.MinusToken, factory_1.factory.createBigIntLiteral((-value.value).toString())) : factory_1.factory.createBigIntLiteral(value.value.toString())); else if (typeof value.value === "number") return factory_1.factory.createLiteralTypeNode(ExpressionFactory_1.ExpressionFactory.number(value.value)); return factory_1.factory.createLiteralTypeNode(factory_1.factory.createStringLiteral(value.value)); }; const write_template = (project) => (importer) => (meta) => { var _a; const head = (0, legacy_1.isSoleLiteralOf)(meta[0]); const spans = []; for (const elem of meta.slice(head ? 1 : 0)) { const last = (_a = spans.at(-1)) !== null && _a !== void 0 ? _a : (() => { const tuple = [null, null]; spans.push(tuple); return tuple; })(); if ((0, legacy_1.isSoleLiteralOf)(elem)) if (last[1] === null) last[1] = String(elem.constants[0].values[0].value); else spans.push([ factory_1.factory.createLiteralTypeNode(factory_1.factory.createStringLiteral(String(elem.constants[0].values[0].value))), null, ]); else if (last[0] === null) last[0] = SdkTypeProgrammer.write(project)(importer)(elem); else spans.push([SdkTypeProgrammer.write(project)(importer)(elem), null]); } return factory_1.factory.createTemplateLiteralType(factory_1.factory.createTemplateHead(head ? meta[0].constants[0].values[0].value : ""), spans .filter(([node]) => node !== null) .map(([node, str], i, array) => factory_1.factory.createTemplateLiteralTypeSpan(node, (i !== array.length - 1 ? factory_1.factory.createTemplateMiddle : factory_1.factory.createTemplateTail)(str !== null && str !== void 0 ? str : "")))); }; const write_atomic = (importer) => (meta) => write_type_tag_matrix(importer)(meta.type, factory_1.factory.createKeywordTypeNode(meta.type === "boolean" ? factory_1.SyntaxKind.BooleanKeyword : meta.type === "bigint" ? factory_1.SyntaxKind.BigIntKeyword : meta.type === "number" ? factory_1.SyntaxKind.NumberKeyword : factory_1.SyntaxKind.StringKeyword), meta.tags); /* ----------------------------------------------------------- INSTANCES ----------------------------------------------------------- */ const write_array = (project) => (importer) => (meta) => write_type_tag_matrix(importer)("array", factory_1.factory.createArrayTypeNode(SdkTypeProgrammer.write(project)(importer)(meta.type.value)), meta.tags); const write_tuple = (project) => (importer) => (meta) => factory_1.factory.createTupleTypeNode(meta.type.elements.map((elem) => elem.rest ? factory_1.factory.createRestTypeNode(factory_1.factory.createArrayTypeNode(SdkTypeProgrammer.write(project)(importer)(elem.rest))) : elem.optional ? factory_1.factory.createOptionalTypeNode(SdkTypeProgrammer.write(project)(importer)(elem)) : SdkTypeProgrammer.write(project)(importer)(elem))); const write_regular_property = (project) => (importer) => (properties) => factory_1.factory.createTypeLiteralNode(properties .map((p) => { const description = writeComment(p.value.atomics)(p.description, p.jsDocTags); const signature = factory_1.factory.createPropertySignature(undefined, utils_1.NamingConvention.variable(String(p.key.constants[0].values[0].value)) ? factory_1.factory.createIdentifier(String(p.key.constants[0].values[0].value)) : factory_1.factory.createStringLiteral(String(p.key.constants[0].values[0].value)), p.value.required === false ? factory_1.factory.createToken(factory_1.SyntaxKind.QuestionToken) : undefined, SdkTypeProgrammer.write(project)(importer)(p.value)); return !!description.length ? [ factory_1.factory.createIdentifier("\n"), FilePrinter_1.FilePrinter.description(signature, description), ] : signature; }) .flat()); const write_dynamic_property = (project) => (importer) => (property) => factory_1.factory.createTypeLiteralNode([ FilePrinter_1.FilePrinter.description(factory_1.factory.createIndexSignature(undefined, [ factory_1.factory.createParameterDeclaration(undefined, undefined, factory_1.factory.createIdentifier("key"), undefined, SdkTypeProgrammer.write(project)(importer)(property.key)), ], SdkTypeProgrammer.write(project)(importer)(property.value)), writeComment(property.value.atomics)(property.description, property.jsDocTags)), ]); const writeAlias = (project) => (importer) => (meta) => { importInternalFile(project)(importer)(meta.name); return factory_1.factory.createTypeReferenceNode(meta.name); }; const write_native = (name) => factory_1.factory.createTypeReferenceNode(name); /* ----------------------------------------------------------- MISCELLANEOUS ----------------------------------------------------------- */ const write_type_tag_matrix = (importer) => (from, base, matrix) => { matrix = matrix.filter((row) => row.length !== 0); if (matrix.length === 0) return base; else if (matrix.length === 1) return factory_1.factory.createIntersectionTypeNode([ base, ...matrix[0].map((tag) => SdkTypeTagProgrammer_1.SdkTypeTagProgrammer.write(importer, from, tag)), ]); return factory_1.factory.createIntersectionTypeNode([ base, factory_1.factory.createUnionTypeNode(matrix.map((row) => row.length === 1 ? SdkTypeTagProgrammer_1.SdkTypeTagProgrammer.write(importer, from, row[0]) : factory_1.factory.createIntersectionTypeNode(row.map((tag) => SdkTypeTagProgrammer_1.SdkTypeTagProgrammer.write(importer, from, tag))))), ]); }; })(SdkTypeProgrammer || (exports.SdkTypeProgrammer = SdkTypeProgrammer = {})); const writeNode = (text) => factory_1.factory.createTypeReferenceNode(text); const writeComment = (atomics) => (description, jsDocTags) => { const lines = []; if (description === null || description === void 0 ? void 0 : description.length) lines.push(...description.split("\n").map((s) => `${s}`)); const filtered = !!atomics.length && !!(jsDocTags === null || jsDocTags === void 0 ? void 0 : jsDocTags.length) ? jsDocTags.filter((tag) => !atomics.some((a) => a.tags.some((r) => r.some((t) => t.kind === tag.name)))) : (jsDocTags !== null && jsDocTags !== void 0 ? jsDocTags : []); if ((description === null || description === void 0 ? void 0 : description.length) && filtered.length) lines.push(""); if (filtered.length) lines.push(...filtered.map((t) => { var _a; return ((_a = t.text) === null || _a === void 0 ? void 0 : _a.length) ? `@${t.name} ${t.text.map((e) => e.text).join("")}` : `@${t.name}`; })); return lines.join("\n"); }; const importInternalFile = (project) => (importer) => (name) => { const top = name.split(".")[0]; if (importer.file === `${project.config.output}/structures/${top}.ts`) return; importer.internal({ declaration: true, file: `${project.config.output}/structures/${name.split(".")[0]}`, type: "element", name: top, }); }; //# sourceMappingURL=SdkTypeProgrammer.js.map