Skip to content

Commit

Permalink
Merge pull request #891 from samchon/features/ws
Browse files Browse the repository at this point in the history
Finalize WebSocket features with documentation
  • Loading branch information
samchon authored Apr 30, 2024
2 parents 87ae6d3 + 6117fa9 commit 78a9f6b
Show file tree
Hide file tree
Showing 28 changed files with 1,147 additions and 132 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"private": true,
"name": "@nestia/station",
"version": "3.1.0-dev.20240429",
"version": "3.1.1",
"description": "Nestia station",
"scripts": {
"build": "node build/index.js",
Expand Down
6 changes: 3 additions & 3 deletions packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nestia/core",
"version": "3.1.0-dev.20240429",
"version": "3.1.1",
"description": "Super-fast validation decorators of NestJS",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down Expand Up @@ -36,7 +36,7 @@
},
"homepage": "https://nestia.io",
"dependencies": {
"@nestia/fetcher": "^3.1.0-dev.20240429",
"@nestia/fetcher": "^3.1.1",
"@nestjs/common": ">=7.0.1",
"@nestjs/core": ">=7.0.1",
"@samchon/openapi": "^0.1.21",
Expand All @@ -52,7 +52,7 @@
"ws": "^7.5.3"
},
"peerDependencies": {
"@nestia/fetcher": ">=3.1.0-dev.20240429",
"@nestia/fetcher": ">=3.1.1",
"@nestjs/common": ">=7.0.1",
"@nestjs/core": ">=7.0.1",
"reflect-metadata": ">=0.1.12",
Expand Down
16 changes: 13 additions & 3 deletions packages/core/src/adaptors/WebSocketAdaptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export class WebSocketAdaptor {
return;
}
}
await acceptor.reject(1002, `Cannot GET ${path}`);
await acceptor.reject(1002, `WebSocket API not found`);
},
),
);
Expand Down Expand Up @@ -147,7 +147,7 @@ const visitApplication = async (
` methods:`,
...e.methods.map((m) =>
[
` - name: ${m.name}:`,
` - name: ${m.name}`,
` file: ${m.source}:${m.line}:${m.column}`,
` reasons:`,
...m.messages.map(
Expand Down Expand Up @@ -205,7 +205,7 @@ const visitController = async (props: {
: undefined,
modulePrefix: props.modulePrefix,
};
for (const mk of Object.getOwnPropertyNames(controller.prototype).filter(
for (const mk of getOwnPropertyNames(controller.prototype).filter(
(key) =>
key !== "constructor" && typeof controller.prototype[key] === "function",
)) {
Expand Down Expand Up @@ -373,6 +373,16 @@ const visitMethod = (props: {
};

const wrapPaths = (value: string[]) => (value.length === 0 ? [""] : value);
const getOwnPropertyNames = (prototype: any): string[] => {
const result: Set<string> = new Set();
const iterate = (m: any) => {
if (m === null) return;
for (const k of Object.getOwnPropertyNames(m)) result.add(k);
iterate(Object.getPrototypeOf(m));
};
iterate(prototype);
return Array.from(result);
};

interface Entry<T> {
key: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/decorators/WebSocketRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { validate_request_query } from "./internal/validate_request_query";
/**
* WebSocket route decorator.
*
* `@WebSocketRoute` is a route decorator function for WebSocket routes.
* `@WebSocketRoute()` is a route decorator function for WebSocket routes.
* If you want to define a WebSocket route with this `@WebSocketRoute` decorator,
* please don't forget to call the {@link WebSocketAdaptor.upgrade} function
* to the {@link INestApplication} instance.
Expand Down
11 changes: 8 additions & 3 deletions packages/core/src/transformers/WebSocketRouteTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ export namespace WebSocketRouteTransformer {
if (
param.type
?.getText()
.split(".")
.split("<")[0]
?.split(".")
.at(-1)
?.startsWith("WebAcceptor") !== true
)
Expand All @@ -67,8 +68,12 @@ export namespace WebSocketRouteTransformer {
);
} else if (category === "Driver") {
if (
param.type?.getText().split(".").at(-1)?.startsWith("Driver") !==
true
param.type
?.getText()
.split("<")[0]
?.split(".")
.at(-1)
?.startsWith("Driver") !== true
)
report(
param,
Expand Down
2 changes: 1 addition & 1 deletion packages/fetcher/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nestia/fetcher",
"version": "3.1.0-dev.20240429",
"version": "3.1.1",
"description": "Fetcher library of Nestia SDK",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down
8 changes: 4 additions & 4 deletions packages/migrate/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nestia/migrate",
"version": "0.13.9",
"version": "0.13.10",
"description": "Migration program from swagger to NestJS",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down Expand Up @@ -34,9 +34,9 @@
},
"homepage": "https://nestia.io",
"devDependencies": {
"@nestia/core": "^3.0.5",
"@nestia/core": "^3.1.1",
"@nestia/e2e": "^0.4.3",
"@nestia/fetcher": "^3.0.4",
"@nestia/fetcher": "^3.1.1",
"@nestjs/common": "^10.3.5",
"@nestjs/core": "^10.3.5",
"@nestjs/platform-express": "^10.3.5",
Expand All @@ -58,7 +58,7 @@
"typescript-transform-paths": "^3.4.6"
},
"dependencies": {
"@samchon/openapi": "^0.1.19",
"@samchon/openapi": "^0.1.21",
"commander": "10.0.0",
"inquirer": "8.2.5",
"prettier": "^3.2.5",
Expand Down
6 changes: 3 additions & 3 deletions packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nestia/sdk",
"version": "3.1.0-dev.20240429",
"version": "3.1.1",
"description": "Nestia SDK and Swagger generator",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down Expand Up @@ -32,7 +32,7 @@
},
"homepage": "https://nestia.io",
"dependencies": {
"@nestia/fetcher": "^3.1.0-dev.20240429",
"@nestia/fetcher": "^3.1.1",
"@samchon/openapi": "^0.1.21",
"cli": "^1.0.1",
"get-function-location": "^2.0.0",
Expand All @@ -46,7 +46,7 @@
"typia": "^6.0.3"
},
"peerDependencies": {
"@nestia/fetcher": ">=3.1.0-dev.20240429",
"@nestia/fetcher": ">=3.1.1",
"@nestjs/common": ">=7.0.1",
"@nestjs/core": ">=7.0.1",
"reflect-metadata": ">=0.1.12",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export namespace TypedWebSocketOperationAnalyzer {
}`;
})(),
description: CommentFactory.description(props.symbol),
jsDocTags,
};

// CONFIGURE PATHS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ export namespace SdkHttpFunctionProgrammer {
query: ITypedHttpRoute.IParameter | undefined;
input: ITypedHttpRoute.IParameter | undefined;
},
): ts.FunctionDeclaration => {
return ts.factory.createFunctionDeclaration(
): ts.FunctionDeclaration =>
ts.factory.createFunctionDeclaration(
[
ts.factory.createModifier(ts.SyntaxKind.ExportKeyword),
ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword),
Expand Down Expand Up @@ -68,7 +68,6 @@ export namespace SdkHttpFunctionProgrammer {
true,
),
);
};

const write_body =
(config: INestiaConfig) =>
Expand Down
137 changes: 83 additions & 54 deletions packages/sdk/src/generates/internal/SdkWebSocketRouteProgrammer.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import ts from "typescript";
import { IJsDocTagInfo } from "typia";
import { IdentifierFactory } from "typia/lib/factories/IdentifierFactory";

import { INestiaProject } from "../../structures/INestiaProject";
import { ITypedWebSocketRoute } from "../../structures/ITypedWebSocketRoute";
import { FilePrinter } from "./FilePrinter";
import { ImportDictionary } from "./ImportDictionary";
import { SdkImportWizard } from "./SdkImportWizard";
import { SdkTypeProgrammer } from "./SdkTypeProgrammer";
Expand All @@ -13,10 +15,46 @@ export namespace SdkWebSocketRouteProgrammer {
(project: INestiaProject) =>
(importer: ImportDictionary) =>
(route: ITypedWebSocketRoute): ts.Statement[] => [
writeFunction(project)(importer)(route),
FilePrinter.description(
writeFunction(project)(importer)(route),
writeDescription(route),
),
SdkWebSocketNamespaceProgrammer.write(project)(importer)(route),
];

const writeDescription = (route: ITypedWebSocketRoute): string => {
// MAIN DESCRIPTION
const comments: string[] = route.description
? route.description.split("\n")
: [];

// COMMENT TAGS
const tags: IJsDocTagInfo[] = route.jsDocTags.filter(
(tag) =>
tag.name !== "param" ||
route.parameters
.filter((p) => p.category === "param" || p.category === "query")
.some((p) => p.name === tag.text?.[0]?.text),
);
if (tags.length !== 0) {
const content: string[] = tags.map((t) =>
t.text?.length
? `@${t.name} ${t.text.map((e) => e.text).join("")}`
: `@${t.name}`,
);
comments.push("", ...new Set(content));
}

// POSTFIX
if (!!comments.length) comments.push("");
comments.push(
`@controller ${route.controller.name}.${route.name}`,
`@path ${route.path}`,
`@nestia Generated by Nestia - https://github.com/samchon/nestia`,
);
return comments.join("\n");
};

const writeFunction =
(project: INestiaProject) =>
(importer: ImportDictionary) =>
Expand Down Expand Up @@ -178,67 +216,58 @@ const local =
);

const joinPath = (caller: ts.Expression) =>
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createCallExpression(
ts.factory.createTemplateExpression(ts.factory.createTemplateHead("", ""), [
ts.factory.createTemplateSpan(
ts.factory.createConditionalExpression(
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createTemplateExpression(
ts.factory.createTemplateHead("", ""),
[
ts.factory.createTemplateSpan(
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier("connection"),
ts.factory.createIdentifier("host"),
),
ts.factory.createTemplateMiddle("/", "/"),
),
ts.factory.createTemplateSpan(
caller,
ts.factory.createTemplateTail("", ""),
),
],
),
ts.factory.createIdentifier("split"),
ts.factory.createIdentifier("connection"),
ts.factory.createIdentifier("host"),
),
undefined,
[ts.factory.createStringLiteral("/")],
ts.factory.createIdentifier("endsWith"),
),
ts.factory.createIdentifier("filter"),
undefined,
[ts.factory.createStringLiteral("/")],
),
undefined,
[
ts.factory.createArrowFunction(
undefined,
undefined,
[
ts.factory.createParameterDeclaration(
undefined,
undefined,
ts.factory.createIdentifier("str"),
undefined,
undefined,
undefined,
),
],
undefined,
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
ts.factory.createPrefixUnaryExpression(
ts.SyntaxKind.ExclamationToken,
ts.factory.createPrefixUnaryExpression(
ts.SyntaxKind.ExclamationToken,
ts.factory.createIdentifier("str"),
),
ts.factory.createToken(ts.SyntaxKind.QuestionToken),
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier("connection"),
ts.factory.createIdentifier("host"),
),
ts.factory.createIdentifier("substring"),
),
],
undefined,
[
ts.factory.createNumericLiteral("0"),
ts.factory.createBinaryExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier("connection"),
ts.factory.createIdentifier("host"),
),
ts.factory.createIdentifier("length"),
),
ts.factory.createToken(ts.SyntaxKind.MinusToken),
ts.factory.createNumericLiteral("1"),
),
],
),
ts.factory.createToken(ts.SyntaxKind.ColonToken),
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier("connection"),
ts.factory.createIdentifier("host"),
),
),
ts.factory.createIdentifier("join"),
ts.factory.createTemplateMiddle("", ""),
),
ts.factory.createTemplateSpan(
caller,
ts.factory.createTemplateTail("", ""),
),
undefined,
[ts.factory.createStringLiteral("/")],
);
]);
const getPathParameterType =
(project: INestiaProject) =>
(importer: ImportDictionary) =>
Expand Down
1 change: 1 addition & 0 deletions packages/sdk/src/structures/ITypedWebSocketRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface ITypedWebSocketRoute {

location: string;
description?: string;
jsDocTags: ts.JSDocTagInfo[];
}
export namespace ITypedWebSocketRoute {
export type IParameter =
Expand Down
Loading

0 comments on commit 78a9f6b

Please sign in to comment.