@nestia/sdk
Version:
Nestia SDK and Swagger generator
218 lines • 12.5 kB
JavaScript
;
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