typia
Version:
Superfast runtime validators with only one line
106 lines (95 loc) • 3.48 kB
text/typescript
import ts from "typescript";
import { IdentifierFactory } from "../../factories/IdentifierFactory";
import { TemplateFactory } from "../../factories/TemplateFactory";
import { stringify_dynamic_properties } from "../internal/stringify_dynamic_properties";
import { stringify_regular_properties } from "../internal/stringify_regular_properties";
import { FunctionImporter } from "./FunctionImporter";
import { IExpressionEntry } from "./IExpressionEntry";
export namespace StringifyJoiner {
export const object =
(importer: FunctionImporter) =>
(
_input: ts.Expression,
entries: IExpressionEntry<ts.Expression>[],
): ts.Expression => {
// CHECK AND SORT ENTRIES
if (entries.length === 0) return ts.factory.createStringLiteral("{}");
// PROPERTIES
const regular: IExpressionEntry<ts.Expression>[] = entries.filter(
(entry) => entry.key.isSoleLiteral(),
);
const dynamic: IExpressionEntry<ts.Expression>[] = entries.filter(
(entry) => !entry.key.isSoleLiteral(),
);
const expressions: ts.Expression[] = [
...stringify_regular_properties(regular, dynamic),
...(dynamic.length
? [
stringify_dynamic_properties(
dynamic,
regular.map((r) => r.key.getSoleLiteral()!),
),
]
: []),
];
// POP LAST COMMA, IF REQUIRED
const filtered: ts.Expression[] =
(regular.length &&
regular[regular.length - 1]!.meta.isRequired() &&
dynamic.length === 0) ||
(regular.length === 0 && dynamic.length)
? expressions
: [
ts.factory.createCallExpression(importer.use("tail"), undefined, [
TemplateFactory.generate(expressions),
]),
];
// RETURNS WITH OBJECT BRACKET
return TemplateFactory.generate([
ts.factory.createStringLiteral(`{`),
...filtered,
ts.factory.createStringLiteral(`}`),
]);
};
export const array = (
input: ts.Expression,
arrow: ts.ArrowFunction,
): ts.Expression =>
TemplateFactory.generate([
ts.factory.createStringLiteral(`[`),
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createCallExpression(
IdentifierFactory.access(input)("map"),
undefined,
[arrow],
),
ts.factory.createIdentifier("join"),
),
undefined,
[ts.factory.createStringLiteral(`,`)],
),
ts.factory.createStringLiteral(`]`),
]);
export const tuple = (
children: ts.Expression[],
rest: ts.Expression | null,
): ts.Expression => {
if (children.length === 0) return ts.factory.createStringLiteral("[]");
if (rest === null && children.every((child) => ts.isStringLiteral(child)))
return ts.factory.createStringLiteral(
"[" +
children.map((child) => (child as ts.StringLiteral).text).join(",") +
"]",
);
const elements: ts.Expression[] = [ts.factory.createStringLiteral(`[`)];
children.forEach((child, i) => {
elements.push(child);
if (i !== children.length - 1)
elements.push(ts.factory.createStringLiteral(`,`));
});
if (rest !== null) elements.push(rest);
elements.push(ts.factory.createStringLiteral(`]`));
return TemplateFactory.generate(elements);
};
}