Skip to content

Commit

Permalink
Merge pull request #860 from samchon/features/plugin
Browse files Browse the repository at this point in the history
Adapt `typia`s `JsonSchemaPlugin` tag in `@nestia/editor` .
  • Loading branch information
samchon authored Apr 2, 2024
2 parents a2a5e56 + 1e9dea4 commit 3007667
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 22 deletions.
4 changes: 3 additions & 1 deletion packages/migrate/assets/input/bbs.json
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,7 @@
"url": {
"type": "string",
"format": "uri",
"contentMediaType": "application/octet-stream",
"title": "URL path of the real file",
"description": "URL path of the real file."
}
Expand All @@ -810,7 +811,8 @@
"type": "string",
"format": "uuid",
"title": "Primary Key",
"description": "Primary Key."
"description": "Primary Key.",
"x-special-description": "Sommetimes made by database automatically."
},
"writer": {
"type": "string",
Expand Down
6 changes: 3 additions & 3 deletions packages/migrate/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nestia/migrate",
"version": "0.12.0",
"version": "0.12.1",
"description": "Migration program from swagger to NestJS",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down Expand Up @@ -63,8 +63,8 @@
"openapi-types": "^12.1.3",
"prettier": "^3.2.5",
"tstl": "^3.0.0",
"typescript": "^5.4.2",
"typia": "^5.5.7"
"typescript": "^5.4.3",
"typia": "^5.5.10"
},
"files": [
"lib",
Expand Down
50 changes: 50 additions & 0 deletions packages/migrate/src/factories/TypeLiteralFactory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import ts from "typescript";
import { Escaper } from "typia/lib/utils/Escaper";

export namespace TypeLiteralFactory {
export const generate = (value: any): ts.TypeNode =>
typeof value === "boolean"
? generateBoolean(value)
: typeof value === "number"
? generateNumber(value)
: typeof value === "string"
? generatestring(value)
: typeof value === "object"
? value === null
? generateNull()
: Array.isArray(value)
? generateTuple(value)
: generateObject(value)
: ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);

const generatestring = (str: string) =>
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(str));

const generateNumber = (num: number) =>
ts.factory.createLiteralTypeNode(ts.factory.createNumericLiteral(num));

const generateBoolean = (bool: boolean) =>
ts.factory.createLiteralTypeNode(
bool ? ts.factory.createTrue() : ts.factory.createFalse(),
);

const generateNull = () =>
ts.factory.createLiteralTypeNode(ts.factory.createNull());

const generateTuple = (items: any[]) =>
ts.factory.createTupleTypeNode(items.map(generate));

const generateObject = (obj: object) =>
ts.factory.createTypeLiteralNode(
Object.entries(obj).map(([key, value]) =>
ts.factory.createPropertySignature(
undefined,
Escaper.variable(key)
? ts.factory.createIdentifier(key)
: ts.factory.createStringLiteral(key),
undefined,
generate(value),
),
),
);
}
10 changes: 3 additions & 7 deletions packages/migrate/src/programmers/MigrateImportProgrammer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ts from "typescript";
import { ExpressionFactory } from "typia/lib/factories/ExpressionFactory";

import { TypeLiteralFactory } from "../factories/TypeLiteralFactory";
import { FilePrinter } from "../utils/FilePrinter";
import { MapUtil } from "../utils/MapUtil";

Expand Down Expand Up @@ -38,18 +38,14 @@ export class MigrateImportProgrammer {
);
}

public tag(type: string, arg: number | string): ts.TypeReferenceNode {
public tag(type: string, arg: any): ts.TypeReferenceNode {
const instance: string = this.external({
type: "instance",
library: "typia",
name: "tags",
});
return ts.factory.createTypeReferenceNode(`${instance}.${type}`, [
ts.factory.createLiteralTypeNode(
typeof arg === "string"
? ts.factory.createStringLiteral(arg)
: ExpressionFactory.number(arg),
),
TypeLiteralFactory.generate(arg),
]);
}

Expand Down
62 changes: 53 additions & 9 deletions packages/migrate/src/programmers/MigrateSchemaProgrammer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import ts from "typescript";
import typia from "typia";
import { ExpressionFactory } from "typia/lib/factories/ExpressionFactory";
import { TypeFactory } from "typia/lib/factories/TypeFactory";
import { FormatCheatSheet } from "typia/lib/tags/internal/FormatCheatSheet";
Expand Down Expand Up @@ -27,7 +28,8 @@ export namespace MigrateSchemaProgrammer {

const type: ts.TypeNode = (() => {
// ATOMIC
if (SwaggerTypeChecker.isBoolean(schema)) return writeBoolean(schema);
if (SwaggerTypeChecker.isBoolean(schema))
return writeBoolean(importer)(schema);
else if (SwaggerTypeChecker.isInteger(schema))
return writeInteger(importer)(schema);
else if (SwaggerTypeChecker.isNumber(schema))
Expand Down Expand Up @@ -58,13 +60,23 @@ export namespace MigrateSchemaProgrammer {
/* -----------------------------------------------------------
ATOMICS
----------------------------------------------------------- */
const writeBoolean = (schema: ISwaggerSchema.IBoolean): ts.TypeNode => {
if (schema.enum?.length)
return ts.factory.createLiteralTypeNode(
schema.enum[0] ? ts.factory.createTrue() : ts.factory.createFalse(),
);
return TypeFactory.keyword("boolean");
};
const writeBoolean =
(importer: MigrateImportProgrammer) =>
(schema: ISwaggerSchema.IBoolean): ts.TypeNode => {
if (schema.enum?.length)
return ts.factory.createLiteralTypeNode(
schema.enum[0] ? ts.factory.createTrue() : ts.factory.createFalse(),
);
const intersection: ts.TypeNode[] = [TypeFactory.keyword("boolean")];
writePlugin({
importer,
regular: typia.misc.literals<keyof ISwaggerSchema.IBoolean>(),
intersection,
})(schema);
return intersection.length === 1
? intersection[0]
: ts.factory.createIntersectionTypeNode(intersection);
};

const writeInteger =
(importer: MigrateImportProgrammer) =>
Expand Down Expand Up @@ -108,7 +120,11 @@ export namespace MigrateSchemaProgrammer {
);
if (schema.multipleOf !== undefined)
intersection.push(importer.tag("MultipleOf", schema.multipleOf));

writePlugin({
importer,
regular: typia.misc.literals<keyof ISwaggerSchema.INumber>(),
intersection,
})(schema);
return intersection.length === 1
? intersection[0]
: ts.factory.createIntersectionTypeNode(intersection);
Expand All @@ -135,6 +151,15 @@ export namespace MigrateSchemaProgrammer {
undefined
)
intersection.push(importer.tag("Format", schema.format));
if (schema.contentMediaType !== undefined)
intersection.push(
importer.tag("ContentMediaType", schema.contentMediaType),
);
writePlugin({
importer,
regular: typia.misc.literals<keyof ISwaggerSchema.IString>(),
intersection,
})(schema);
return intersection.length === 1
? intersection[0]
: ts.factory.createIntersectionTypeNode(intersection);
Expand All @@ -156,6 +181,11 @@ export namespace MigrateSchemaProgrammer {
intersection.push(importer.tag("MinItems", schema.minItems));
if (schema.maxItems !== undefined)
intersection.push(importer.tag("MaxItems", schema.maxItems));
writePlugin({
importer,
regular: typia.misc.literals<keyof ISwaggerSchema.IArray>(),
intersection,
})(schema);
return intersection.length === 1
? intersection[0]
: ts.factory.createIntersectionTypeNode(intersection);
Expand Down Expand Up @@ -261,3 +291,17 @@ const writeComment = (schema: ISwaggerSchema): string =>
...(schema.title !== undefined ? [`@title ${schema.title}`] : []),
...(schema.deprecated === true ? [`@deprecated`] : []),
].join("\n");
const writePlugin =
(props: {
importer: MigrateImportProgrammer;
regular: string[];
intersection: ts.TypeNode[];
}) =>
(schema: any) => {
const extra: any = {};
for (const [key, value] of Object.entries(schema))
if (value !== undefined && false === props.regular.includes(key))
extra[key] = value;
if (Object.keys(extra).length !== 0)
props.intersection.push(props.importer.tag("JsonSchemaPlugin", extra));
};
1 change: 1 addition & 0 deletions packages/migrate/src/structures/ISwaggerSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export namespace ISwaggerSchema {
enum?: string[];
format?: string;
pattern?: string;
contentMediaType?: string;
/** @type uint */ minLength?: number;
/** @type uint */ maxLength?: number;
}
Expand Down
4 changes: 2 additions & 2 deletions website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"@mui/icons-material": "5.15.6",
"@mui/material": "5.15.6",
"@mui/system": "5.15.6",
"@nestia/migrate": "^0.12.0",
"@nestia/migrate": "^0.12.1",
"@stackblitz/sdk": "^1.9.0",
"js-yaml": "^4.1.0",
"next": "14.1.0",
Expand All @@ -33,7 +33,7 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"react-mui-fileuploader": "^0.5.2",
"typia": "^5.5.7"
"typia": "^5.5.10"
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
Expand Down

0 comments on commit 3007667

Please sign in to comment.