wexts 4.0.0 → 4.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -49
- package/bin/wexts.cjs +2 -2
- package/package.json +153 -148
- package/templates/.dockerignore +43 -43
- package/templates/.env.example +17 -17
- package/templates/Dockerfile +60 -60
- package/templates/Procfile +1 -1
- package/templates/README.md +67 -67
- package/templates/api-sdk.ts +115 -115
- package/templates/docker-compose.yml +34 -34
- package/templates/nestjs-api/.env.example +3 -3
- package/templates/nestjs-api/README.md +87 -87
- package/templates/nestjs-api/nest-cli.json +6 -6
- package/templates/nestjs-api/package.json +40 -40
- package/templates/nestjs-api/prisma/migrations/20251123205437_init/migration.sql +24 -24
- package/templates/nestjs-api/prisma/migrations/migration_lock.toml +3 -3
- package/templates/nestjs-api/prisma/schema.prisma +29 -29
- package/templates/nestjs-api/src/app.module.ts +17 -17
- package/templates/nestjs-api/src/auth/auth.controller.ts +27 -27
- package/templates/nestjs-api/src/auth/auth.module.ts +37 -37
- package/templates/nestjs-api/src/auth/auth.service.ts +86 -86
- package/templates/nestjs-api/src/auth/dto/auth.dto.ts +22 -22
- package/templates/nestjs-api/src/auth/guards/jwt-auth.guard.ts +5 -5
- package/templates/nestjs-api/src/auth/strategies/jwt.strategy.ts +27 -27
- package/templates/nestjs-api/src/main.ts +32 -32
- package/templates/nestjs-api/src/prisma/prisma.module.ts +9 -9
- package/templates/nestjs-api/src/prisma/prisma.service.ts +14 -14
- package/templates/nestjs-api/src/todos/dto/todo.dto.ts +24 -24
- package/templates/nestjs-api/src/todos/todos.controller.ts +39 -39
- package/templates/nestjs-api/src/todos/todos.module.ts +11 -11
- package/templates/nestjs-api/src/todos/todos.service.ts +53 -53
- package/templates/nestjs-api/src/users/users.controller.ts +14 -14
- package/templates/nestjs-api/src/users/users.module.ts +12 -12
- package/templates/nestjs-api/src/users/users.service.ts +19 -19
- package/templates/nestjs-api/tsconfig.json +39 -39
- package/templates/nextjs-web/README.md +76 -76
- package/templates/nextjs-web/app/actions/auth.ts +108 -108
- package/templates/nextjs-web/app/dashboard/error.tsx +39 -39
- package/templates/nextjs-web/app/dashboard/loading.tsx +14 -14
- package/templates/nextjs-web/app/dashboard/page.tsx +5 -5
- package/templates/nextjs-web/app/globals.css +93 -93
- package/templates/nextjs-web/app/layout.tsx +29 -29
- package/templates/nextjs-web/app/login/page.tsx +5 -5
- package/templates/nextjs-web/app/page.tsx +28 -28
- package/templates/nextjs-web/app/register/page.tsx +5 -5
- package/templates/nextjs-web/components/ui/button.tsx +56 -56
- package/templates/nextjs-web/components/ui/card.tsx +79 -79
- package/templates/nextjs-web/components/ui/input.tsx +25 -25
- package/templates/nextjs-web/components/ui/label.tsx +24 -24
- package/templates/nextjs-web/features/auth/LoginForm.tsx +140 -140
- package/templates/nextjs-web/features/auth/RegisterForm.tsx +159 -159
- package/templates/nextjs-web/features/auth/api.ts +35 -35
- package/templates/nextjs-web/features/auth/index.ts +3 -3
- package/templates/nextjs-web/features/dashboard/DashboardView.tsx +204 -204
- package/templates/nextjs-web/features/dashboard/api.ts +9 -9
- package/templates/nextjs-web/features/dashboard/components.tsx +74 -74
- package/templates/nextjs-web/features/dashboard/index.ts +3 -3
- package/templates/nextjs-web/hooks/index.ts +4 -4
- package/templates/nextjs-web/lib/api-client.ts +89 -89
- package/templates/nextjs-web/lib/api.ts +115 -115
- package/templates/nextjs-web/lib/axios-global-config.ts +17 -17
- package/templates/nextjs-web/lib/utils.ts +6 -6
- package/templates/nextjs-web/lib/wexts-client.ts +4 -4
- package/templates/nextjs-web/next-env.d.ts +6 -6
- package/templates/nextjs-web/next.config.ts +20 -20
- package/templates/nextjs-web/package.json +37 -37
- package/templates/nextjs-web/postcss.config.js +6 -6
- package/templates/nextjs-web/tailwind.config.ts +69 -69
- package/templates/nextjs-web/tsconfig.json +41 -41
- package/templates/nixpacks.toml +11 -11
- package/templates/root-package.json +31 -31
- package/templates/server.ts +66 -66
- package/templates/tsconfig.json +30 -30
- package/dist/chunk-2KAQYLVN.js +0 -1
- package/dist/chunk-2KAQYLVN.js.map +0 -1
- package/dist/chunk-2LJVUMXW.js +0 -228
- package/dist/chunk-2LJVUMXW.js.map +0 -1
- package/dist/chunk-7QKLIVRF.js +0 -94
- package/dist/chunk-7QKLIVRF.js.map +0 -1
- package/dist/chunk-7WULUGLH.mjs +0 -22
- package/dist/chunk-7WULUGLH.mjs.map +0 -1
- package/dist/chunk-BG56B4DE.js +0 -106
- package/dist/chunk-BG56B4DE.js.map +0 -1
- package/dist/chunk-CLM5PNSG.mjs +0 -496
- package/dist/chunk-CLM5PNSG.mjs.map +0 -1
- package/dist/chunk-DNLGCKTT.js +0 -31
- package/dist/chunk-DNLGCKTT.js.map +0 -1
- package/dist/chunk-JHOVXH3X.mjs +0 -65
- package/dist/chunk-JHOVXH3X.mjs.map +0 -1
- package/dist/chunk-MXINIFPC.js +0 -105
- package/dist/chunk-MXINIFPC.js.map +0 -1
- package/dist/chunk-SE32ZPOZ.js +0 -496
- package/dist/chunk-SE32ZPOZ.js.map +0 -1
- package/dist/chunk-UAL54DVV.mjs +0 -106
- package/dist/chunk-UAL54DVV.mjs.map +0 -1
- package/dist/chunk-WCKSKU3C.js +0 -65
- package/dist/chunk-WCKSKU3C.js.map +0 -1
- package/dist/chunk-WU6FW77M.mjs +0 -105
- package/dist/chunk-WU6FW77M.mjs.map +0 -1
- package/dist/chunk-XE4OXN2W.js +0 -12
- package/dist/chunk-XE4OXN2W.js.map +0 -1
- package/dist/chunk-YBM3IJEA.mjs +0 -94
- package/dist/chunk-YBM3IJEA.mjs.map +0 -1
- package/dist/chunk-YN6WIWNQ.mjs +0 -228
- package/dist/chunk-YN6WIWNQ.mjs.map +0 -1
- package/dist/chunk-YSLEF5C5.mjs +0 -1
- package/dist/chunk-YSLEF5C5.mjs.map +0 -1
- package/dist/chunk-ZX7QIN24.mjs +0 -31
- package/dist/chunk-ZX7QIN24.mjs.map +0 -1
- package/dist/cli/index.d.mts +0 -11
- package/dist/cli/index.d.ts +0 -11
- package/dist/cli/index.js +0 -332
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/index.mjs +0 -334
- package/dist/cli/index.mjs.map +0 -1
- package/dist/client/index.d.mts +0 -21
- package/dist/client/index.d.ts +0 -21
- package/dist/client/index.js +0 -12
- package/dist/client/index.js.map +0 -1
- package/dist/client/index.mjs +0 -12
- package/dist/client/index.mjs.map +0 -1
- package/dist/codegen/index.d.mts +0 -2
- package/dist/codegen/index.d.ts +0 -2
- package/dist/codegen/index.js +0 -15
- package/dist/codegen/index.js.map +0 -1
- package/dist/codegen/index.mjs +0 -15
- package/dist/codegen/index.mjs.map +0 -1
- package/dist/decorators-BT1FFqN0.d.mts +0 -29
- package/dist/decorators-DvS58PqC.d.ts +0 -29
- package/dist/dev-server/index.d.mts +0 -1
- package/dist/dev-server/index.d.ts +0 -1
- package/dist/dev-server/index.js +0 -13
- package/dist/dev-server/index.js.map +0 -1
- package/dist/dev-server/index.mjs +0 -13
- package/dist/dev-server/index.mjs.map +0 -1
- package/dist/index-7QeQEf37.d.ts +0 -92
- package/dist/index-7RvU-jGE.d.mts +0 -66
- package/dist/index-7RvU-jGE.d.ts +0 -66
- package/dist/index-8nzxy0NN.d.mts +0 -92
- package/dist/index-Co5ZsLqq.d.ts +0 -58
- package/dist/index-D94W1__r.d.mts +0 -58
- package/dist/index-DQmyVp6F.d.mts +0 -27
- package/dist/index-KL_1BrQb.d.ts +0 -27
- package/dist/index.d.mts +0 -258
- package/dist/index.d.ts +0 -258
- package/dist/index.js +0 -410
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -410
- package/dist/index.mjs.map +0 -1
- package/dist/nest/index.d.mts +0 -3
- package/dist/nest/index.d.ts +0 -3
- package/dist/nest/index.js +0 -38
- package/dist/nest/index.js.map +0 -1
- package/dist/nest/index.mjs +0 -38
- package/dist/nest/index.mjs.map +0 -1
- package/dist/next/index.d.mts +0 -66
- package/dist/next/index.d.ts +0 -66
- package/dist/next/index.js +0 -226
- package/dist/next/index.js.map +0 -1
- package/dist/next/index.mjs +0 -188
- package/dist/next/index.mjs.map +0 -1
- package/dist/rpc/index.d.mts +0 -2
- package/dist/rpc/index.d.ts +0 -2
- package/dist/rpc/index.js +0 -23
- package/dist/rpc/index.js.map +0 -1
- package/dist/rpc/index.mjs +0 -23
- package/dist/rpc/index.mjs.map +0 -1
- package/dist/runtime/index.d.mts +0 -55
- package/dist/runtime/index.d.ts +0 -55
- package/dist/runtime/index.js +0 -213
- package/dist/runtime/index.js.map +0 -1
- package/dist/runtime/index.mjs +0 -213
- package/dist/runtime/index.mjs.map +0 -1
- package/dist/types/index.d.mts +0 -12
- package/dist/types/index.d.ts +0 -12
- package/dist/types/index.js +0 -2
- package/dist/types/index.js.map +0 -1
- package/dist/types/index.mjs +0 -3
- package/dist/types/index.mjs.map +0 -1
- package/dist/types-7d_fC-C3.d.mts +0 -32
- package/dist/types-7d_fC-C3.d.ts +0 -32
- package/dist/vercel-builder/index.d.mts +0 -58
- package/dist/vercel-builder/index.d.ts +0 -58
- package/dist/vercel-builder/index.js +0 -330
- package/dist/vercel-builder/index.js.map +0 -1
- package/dist/vercel-builder/index.mjs +0 -330
- package/dist/vercel-builder/index.mjs.map +0 -1
- package/templates/nestjs-api/package-lock.json +0 -5623
- package/templates/nextjs-web/package-lock.json +0 -3254
package/dist/chunk-CLM5PNSG.mjs
DELETED
|
@@ -1,496 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
logger
|
|
3
|
-
} from "./chunk-JHOVXH3X.mjs";
|
|
4
|
-
import {
|
|
5
|
-
__export,
|
|
6
|
-
__name
|
|
7
|
-
} from "./chunk-7WULUGLH.mjs";
|
|
8
|
-
|
|
9
|
-
// src/codegen/index.ts
|
|
10
|
-
var codegen_exports = {};
|
|
11
|
-
__export(codegen_exports, {
|
|
12
|
-
ClientGenerator: () => ClientGenerator,
|
|
13
|
-
CodegenWatcher: () => CodegenWatcher,
|
|
14
|
-
NestJSParser: () => NestJSParser,
|
|
15
|
-
generateRpcClient: () => generateRpcClient
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
// src/codegen/parser.ts
|
|
19
|
-
import * as path from "path";
|
|
20
|
-
import * as ts from "typescript";
|
|
21
|
-
var RPC_SERVICE_DECORATORS = /* @__PURE__ */ new Set([
|
|
22
|
-
"RpcService",
|
|
23
|
-
"WextsRpcService"
|
|
24
|
-
]);
|
|
25
|
-
var RPC_METHOD_DECORATORS = /* @__PURE__ */ new Set([
|
|
26
|
-
"RpcMethod",
|
|
27
|
-
"WextsRpc"
|
|
28
|
-
]);
|
|
29
|
-
var REQUIRE_AUTH_DECORATORS = /* @__PURE__ */ new Set([
|
|
30
|
-
"RequireAuth"
|
|
31
|
-
]);
|
|
32
|
-
var NestJSParser = class {
|
|
33
|
-
static {
|
|
34
|
-
__name(this, "NestJSParser");
|
|
35
|
-
}
|
|
36
|
-
projectPath;
|
|
37
|
-
program;
|
|
38
|
-
constructor(projectPath) {
|
|
39
|
-
this.projectPath = projectPath;
|
|
40
|
-
const configPath = ts.findConfigFile(projectPath, ts.sys.fileExists, "tsconfig.json");
|
|
41
|
-
if (!configPath) {
|
|
42
|
-
throw new Error("tsconfig.json not found");
|
|
43
|
-
}
|
|
44
|
-
const config = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
45
|
-
const parsedConfig = ts.parseJsonConfigFileContent(config.config, ts.sys, path.dirname(configPath));
|
|
46
|
-
this.program = ts.createProgram(parsedConfig.fileNames, parsedConfig.options);
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Find all controllers with @FusionController decorator
|
|
50
|
-
*/
|
|
51
|
-
findFusionControllers() {
|
|
52
|
-
const controllers = [];
|
|
53
|
-
const sourceFiles = this.program.getSourceFiles();
|
|
54
|
-
for (const sourceFile of sourceFiles) {
|
|
55
|
-
if (sourceFile.fileName.includes("node_modules")) continue;
|
|
56
|
-
if (!sourceFile.fileName.includes(".controller.ts")) continue;
|
|
57
|
-
const fileControllers = this.parseSourceFile(sourceFile);
|
|
58
|
-
controllers.push(...fileControllers);
|
|
59
|
-
}
|
|
60
|
-
return controllers;
|
|
61
|
-
}
|
|
62
|
-
findRpcManifest() {
|
|
63
|
-
const services = [];
|
|
64
|
-
for (const sourceFile of this.program.getSourceFiles()) {
|
|
65
|
-
if (sourceFile.fileName.includes("node_modules")) continue;
|
|
66
|
-
if (!sourceFile.fileName.endsWith(".ts")) continue;
|
|
67
|
-
if (sourceFile.fileName.endsWith(".d.ts")) continue;
|
|
68
|
-
services.push(...this.parseRpcServices(sourceFile));
|
|
69
|
-
}
|
|
70
|
-
services.sort((a, b) => a.name.localeCompare(b.name));
|
|
71
|
-
for (const service of services) {
|
|
72
|
-
service.methods.sort((a, b) => a.name.localeCompare(b.name));
|
|
73
|
-
}
|
|
74
|
-
if (services.length === 0) {
|
|
75
|
-
return {
|
|
76
|
-
schemaVersion: 1,
|
|
77
|
-
services
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
return {
|
|
81
|
-
schemaVersion: 1,
|
|
82
|
-
services
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
parseSourceFile(sourceFile) {
|
|
86
|
-
const controllers = [];
|
|
87
|
-
ts.forEachChild(sourceFile, (node) => {
|
|
88
|
-
if (ts.isClassDeclaration(node) && node.name) {
|
|
89
|
-
const controllerInfo = this.parseController(node);
|
|
90
|
-
if (controllerInfo) {
|
|
91
|
-
controllers.push(controllerInfo);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
return controllers;
|
|
96
|
-
}
|
|
97
|
-
parseController(classNode) {
|
|
98
|
-
const decorators = ts.getDecorators(classNode);
|
|
99
|
-
if (!decorators) return null;
|
|
100
|
-
let controllerPrefix = "";
|
|
101
|
-
let isFusionController = false;
|
|
102
|
-
for (const decorator of decorators) {
|
|
103
|
-
const expr = decorator.expression;
|
|
104
|
-
if (ts.isCallExpression(expr) && ts.isIdentifier(expr.expression)) {
|
|
105
|
-
const decoratorName = expr.expression.text;
|
|
106
|
-
if (decoratorName === "FusionController") {
|
|
107
|
-
isFusionController = true;
|
|
108
|
-
if (expr.arguments.length > 0) {
|
|
109
|
-
const arg = expr.arguments[0];
|
|
110
|
-
if (ts.isStringLiteral(arg)) {
|
|
111
|
-
controllerPrefix = arg.text;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
if (!isFusionController) return null;
|
|
118
|
-
const routes = this.parseRoutes(classNode);
|
|
119
|
-
const className = classNode.name?.text || "Unknown";
|
|
120
|
-
return {
|
|
121
|
-
name: className,
|
|
122
|
-
prefix: controllerPrefix,
|
|
123
|
-
routes: routes.map((r) => ({
|
|
124
|
-
...r,
|
|
125
|
-
controllerName: className
|
|
126
|
-
}))
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
parseRoutes(classNode) {
|
|
130
|
-
const routes = [];
|
|
131
|
-
classNode.members.forEach((member) => {
|
|
132
|
-
if (ts.isMethodDeclaration(member)) {
|
|
133
|
-
const decorators = ts.getDecorators(member);
|
|
134
|
-
if (!decorators) return;
|
|
135
|
-
for (const decorator of decorators) {
|
|
136
|
-
const expr = decorator.expression;
|
|
137
|
-
if (ts.isCallExpression(expr) && ts.isIdentifier(expr.expression)) {
|
|
138
|
-
const decoratorName = expr.expression.text;
|
|
139
|
-
let method = null;
|
|
140
|
-
let routePath = "";
|
|
141
|
-
if (decoratorName === "FusionGet") method = "GET";
|
|
142
|
-
else if (decoratorName === "FusionPost") method = "POST";
|
|
143
|
-
else if (decoratorName === "FusionPut") method = "PUT";
|
|
144
|
-
else if (decoratorName === "FusionDelete") method = "DELETE";
|
|
145
|
-
if (method) {
|
|
146
|
-
if (expr.arguments.length > 0) {
|
|
147
|
-
const arg = expr.arguments[0];
|
|
148
|
-
if (ts.isStringLiteral(arg)) {
|
|
149
|
-
routePath = arg.text;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
const handlerName = member.name.text;
|
|
153
|
-
routes.push({
|
|
154
|
-
method,
|
|
155
|
-
path: routePath,
|
|
156
|
-
handler: handlerName,
|
|
157
|
-
controllerName: ""
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
return routes;
|
|
165
|
-
}
|
|
166
|
-
parseRpcServices(sourceFile) {
|
|
167
|
-
const services = [];
|
|
168
|
-
const rootDir = path.resolve(this.projectPath);
|
|
169
|
-
ts.forEachChild(sourceFile, (node) => {
|
|
170
|
-
if (!ts.isClassDeclaration(node) || !node.name) return;
|
|
171
|
-
const serviceDecorator = this.findDecorator(node, RPC_SERVICE_DECORATORS);
|
|
172
|
-
if (!serviceDecorator) return;
|
|
173
|
-
const className = node.name.text;
|
|
174
|
-
const serviceOptions = this.readDecoratorOptions(serviceDecorator);
|
|
175
|
-
const classRequiresAuth = serviceOptions.requireAuth || this.hasDecorator(node, REQUIRE_AUTH_DECORATORS);
|
|
176
|
-
const serviceName = serviceOptions.name || toStableServiceName(className);
|
|
177
|
-
const methods = this.parseRpcMethods(node, classRequiresAuth, sourceFile);
|
|
178
|
-
if (methods.length === 0) return;
|
|
179
|
-
services.push({
|
|
180
|
-
name: serviceName,
|
|
181
|
-
className,
|
|
182
|
-
importPath: toPosixPath(path.relative(rootDir, sourceFile.fileName).replace(/\.ts$/, "")),
|
|
183
|
-
requireAuth: classRequiresAuth,
|
|
184
|
-
methods
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
return services;
|
|
188
|
-
}
|
|
189
|
-
parseRpcMethods(classNode, classRequiresAuth, sourceFile) {
|
|
190
|
-
const methods = [];
|
|
191
|
-
for (const member of classNode.members) {
|
|
192
|
-
if (!ts.isMethodDeclaration(member)) continue;
|
|
193
|
-
if (!ts.isIdentifier(member.name)) continue;
|
|
194
|
-
const methodDecorator = this.findDecorator(member, RPC_METHOD_DECORATORS);
|
|
195
|
-
if (!methodDecorator) continue;
|
|
196
|
-
const handlerName = member.name.text;
|
|
197
|
-
const methodOptions = this.readDecoratorOptions(methodDecorator);
|
|
198
|
-
const requireAuth = classRequiresAuth || methodOptions.requireAuth || this.hasDecorator(member, REQUIRE_AUTH_DECORATORS);
|
|
199
|
-
methods.push({
|
|
200
|
-
name: methodOptions.name || handlerName,
|
|
201
|
-
handlerName,
|
|
202
|
-
requireAuth,
|
|
203
|
-
parameters: member.parameters.map((parameter) => this.parseParameter(parameter, sourceFile)),
|
|
204
|
-
returnType: member.type ? getNodeText(member.type, sourceFile) : "unknown"
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
return methods;
|
|
208
|
-
}
|
|
209
|
-
parseParameter(parameter, sourceFile) {
|
|
210
|
-
return {
|
|
211
|
-
name: ts.isIdentifier(parameter.name) ? parameter.name.text : parameter.name.getText(),
|
|
212
|
-
type: parameter.type ? getNodeText(parameter.type, sourceFile) : "unknown",
|
|
213
|
-
optional: Boolean(parameter.questionToken || parameter.initializer)
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
findDecorator(node, names) {
|
|
217
|
-
const decorators = ts.getDecorators(node);
|
|
218
|
-
if (!decorators) return void 0;
|
|
219
|
-
return decorators.find((decorator) => {
|
|
220
|
-
const name = getDecoratorName(decorator);
|
|
221
|
-
return Boolean(name && names.has(name));
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
hasDecorator(node, names) {
|
|
225
|
-
return Boolean(this.findDecorator(node, names));
|
|
226
|
-
}
|
|
227
|
-
readDecoratorOptions(decorator) {
|
|
228
|
-
const expression = decorator.expression;
|
|
229
|
-
if (!ts.isCallExpression(expression)) return {};
|
|
230
|
-
const firstArg = expression.arguments[0];
|
|
231
|
-
if (!firstArg) return {};
|
|
232
|
-
if (ts.isStringLiteral(firstArg)) {
|
|
233
|
-
return {
|
|
234
|
-
name: firstArg.text
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
if (!ts.isObjectLiteralExpression(firstArg)) return {};
|
|
238
|
-
const result = {};
|
|
239
|
-
for (const property of firstArg.properties) {
|
|
240
|
-
if (!ts.isPropertyAssignment(property) || !ts.isIdentifier(property.name)) continue;
|
|
241
|
-
if (property.name.text === "name" && ts.isStringLiteral(property.initializer)) {
|
|
242
|
-
result.name = property.initializer.text;
|
|
243
|
-
}
|
|
244
|
-
if (property.name.text === "requireAuth") {
|
|
245
|
-
if (property.initializer.kind === ts.SyntaxKind.TrueKeyword) {
|
|
246
|
-
result.requireAuth = true;
|
|
247
|
-
} else if (property.initializer.kind === ts.SyntaxKind.FalseKeyword) {
|
|
248
|
-
result.requireAuth = false;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
return result;
|
|
253
|
-
}
|
|
254
|
-
};
|
|
255
|
-
function getDecoratorName(decorator) {
|
|
256
|
-
const expression = decorator.expression;
|
|
257
|
-
if (ts.isIdentifier(expression)) return expression.text;
|
|
258
|
-
if (ts.isCallExpression(expression) && ts.isIdentifier(expression.expression)) {
|
|
259
|
-
return expression.expression.text;
|
|
260
|
-
}
|
|
261
|
-
return void 0;
|
|
262
|
-
}
|
|
263
|
-
__name(getDecoratorName, "getDecoratorName");
|
|
264
|
-
function toStableServiceName(className) {
|
|
265
|
-
const withoutSuffix = className.replace(/(Service|Controller)$/, "");
|
|
266
|
-
return withoutSuffix.charAt(0).toLowerCase() + withoutSuffix.slice(1);
|
|
267
|
-
}
|
|
268
|
-
__name(toStableServiceName, "toStableServiceName");
|
|
269
|
-
function toPosixPath(filePath) {
|
|
270
|
-
return filePath.split(path.sep).join(path.posix.sep);
|
|
271
|
-
}
|
|
272
|
-
__name(toPosixPath, "toPosixPath");
|
|
273
|
-
function getNodeText(node, sourceFile) {
|
|
274
|
-
return sourceFile.text.slice(node.getStart(sourceFile), node.getEnd());
|
|
275
|
-
}
|
|
276
|
-
__name(getNodeText, "getNodeText");
|
|
277
|
-
|
|
278
|
-
// src/core/filesystem.ts
|
|
279
|
-
import * as fs from "fs";
|
|
280
|
-
import * as path2 from "path";
|
|
281
|
-
import { promisify } from "util";
|
|
282
|
-
var readFile2 = promisify(fs.readFile);
|
|
283
|
-
var writeFile2 = promisify(fs.writeFile);
|
|
284
|
-
var mkdir2 = promisify(fs.mkdir);
|
|
285
|
-
var access2 = promisify(fs.access);
|
|
286
|
-
var FileSystem = class {
|
|
287
|
-
static {
|
|
288
|
-
__name(this, "FileSystem");
|
|
289
|
-
}
|
|
290
|
-
/**
|
|
291
|
-
* Read file as string
|
|
292
|
-
*/
|
|
293
|
-
async readFile(filePath, encoding = "utf-8") {
|
|
294
|
-
return readFile2(filePath, encoding);
|
|
295
|
-
}
|
|
296
|
-
/**
|
|
297
|
-
* Write file
|
|
298
|
-
*/
|
|
299
|
-
async writeFile(filePath, content) {
|
|
300
|
-
await this.ensureDir(path2.dirname(filePath));
|
|
301
|
-
return writeFile2(filePath, content, "utf-8");
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Read JSON file
|
|
305
|
-
*/
|
|
306
|
-
async readJSON(filePath) {
|
|
307
|
-
const content = await this.readFile(filePath);
|
|
308
|
-
return JSON.parse(content);
|
|
309
|
-
}
|
|
310
|
-
/**
|
|
311
|
-
* Write JSON file
|
|
312
|
-
*/
|
|
313
|
-
async writeJSON(filePath, data, pretty = true) {
|
|
314
|
-
const content = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
|
|
315
|
-
return this.writeFile(filePath, content);
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Check if file/directory exists
|
|
319
|
-
*/
|
|
320
|
-
async exists(filePath) {
|
|
321
|
-
try {
|
|
322
|
-
await access2(filePath, fs.constants.F_OK);
|
|
323
|
-
return true;
|
|
324
|
-
} catch {
|
|
325
|
-
return false;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
/**
|
|
329
|
-
* Ensure directory exists (create if not)
|
|
330
|
-
*/
|
|
331
|
-
async ensureDir(dirPath) {
|
|
332
|
-
if (!await this.exists(dirPath)) {
|
|
333
|
-
await mkdir2(dirPath, {
|
|
334
|
-
recursive: true
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Copy file
|
|
340
|
-
*/
|
|
341
|
-
async copyFile(src, dest) {
|
|
342
|
-
const content = await this.readFile(src);
|
|
343
|
-
await this.writeFile(dest, content);
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* Read directory
|
|
347
|
-
*/
|
|
348
|
-
readDir(dirPath) {
|
|
349
|
-
return promisify(fs.readdir)(dirPath);
|
|
350
|
-
}
|
|
351
|
-
};
|
|
352
|
-
var filesystem = new FileSystem();
|
|
353
|
-
|
|
354
|
-
// src/codegen/generator.ts
|
|
355
|
-
import * as path3 from "path";
|
|
356
|
-
var ClientGenerator = class {
|
|
357
|
-
static {
|
|
358
|
-
__name(this, "ClientGenerator");
|
|
359
|
-
}
|
|
360
|
-
async generate(options) {
|
|
361
|
-
const { manifest, outputPath, manifestFileName = "wexts.rpc.manifest.json", clientFileName = "client.ts" } = options;
|
|
362
|
-
if (manifest.services.length === 0) {
|
|
363
|
-
throw new Error("No Wexts RPC services found. Add @RpcService() to a Nest provider and @RpcMethod() to at least one method.");
|
|
364
|
-
}
|
|
365
|
-
const sortedManifest = sortManifest(manifest);
|
|
366
|
-
const clientCode = this.generateRpcClientCode(sortedManifest);
|
|
367
|
-
await filesystem.writeJSON(path3.join(outputPath, manifestFileName), sortedManifest, true);
|
|
368
|
-
await filesystem.writeFile(path3.join(outputPath, clientFileName), clientCode);
|
|
369
|
-
const indexCode = `export * from './client';
|
|
370
|
-
`;
|
|
371
|
-
await filesystem.writeFile(path3.join(outputPath, "index.ts"), indexCode);
|
|
372
|
-
}
|
|
373
|
-
generateRpcClientCode(manifest) {
|
|
374
|
-
const manifestJson = JSON.stringify(manifest, null, 2);
|
|
375
|
-
return `import { createWextsRpcClient, type WextsRpcClientOptions } from 'wexts/client';
|
|
376
|
-
import type { RpcManifest } from 'wexts/rpc';
|
|
377
|
-
|
|
378
|
-
const manifest = ${manifestJson} satisfies RpcManifest;
|
|
379
|
-
|
|
380
|
-
${this.generateClientInterface(manifest)}
|
|
381
|
-
|
|
382
|
-
export function createWextsClient(options?: WextsRpcClientOptions): WextsClient {
|
|
383
|
-
return createWextsRpcClient(manifest, options) as unknown as WextsClient;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
export const wexts = createWextsClient();
|
|
387
|
-
`;
|
|
388
|
-
}
|
|
389
|
-
generateClientInterface(manifest) {
|
|
390
|
-
const services = manifest.services.map((service) => this.generateServiceInterface(service)).join("\n");
|
|
391
|
-
return `export interface WextsClient {
|
|
392
|
-
${services}}
|
|
393
|
-
`;
|
|
394
|
-
}
|
|
395
|
-
generateServiceInterface(service) {
|
|
396
|
-
const methods = service.methods.map((method) => ` ${method.name}: (${this.parametersToSignature(method)}) => Promise<${normalizeReturnType(method.returnType)}>;`).join("\n");
|
|
397
|
-
return ` ${service.name}: {
|
|
398
|
-
${methods}
|
|
399
|
-
};
|
|
400
|
-
`;
|
|
401
|
-
}
|
|
402
|
-
parametersToSignature(method) {
|
|
403
|
-
return method.parameters.map((parameter) => `${parameter.name}${parameter.optional ? "?" : ""}: ${parameter.type}`).join(", ");
|
|
404
|
-
}
|
|
405
|
-
};
|
|
406
|
-
async function generateRpcClient(options) {
|
|
407
|
-
const parser = new NestJSParser(options.projectPath);
|
|
408
|
-
const manifest = parser.findRpcManifest();
|
|
409
|
-
const generator = new ClientGenerator();
|
|
410
|
-
await generator.generate({
|
|
411
|
-
manifest,
|
|
412
|
-
outputPath: options.outputPath,
|
|
413
|
-
manifestFileName: options.manifestFileName,
|
|
414
|
-
clientFileName: options.clientFileName
|
|
415
|
-
});
|
|
416
|
-
return sortManifest(manifest);
|
|
417
|
-
}
|
|
418
|
-
__name(generateRpcClient, "generateRpcClient");
|
|
419
|
-
function sortManifest(manifest) {
|
|
420
|
-
return {
|
|
421
|
-
schemaVersion: 1,
|
|
422
|
-
services: [
|
|
423
|
-
...manifest.services
|
|
424
|
-
].sort((a, b) => a.name.localeCompare(b.name)).map((service) => ({
|
|
425
|
-
...service,
|
|
426
|
-
methods: [
|
|
427
|
-
...service.methods
|
|
428
|
-
].sort((a, b) => a.name.localeCompare(b.name))
|
|
429
|
-
}))
|
|
430
|
-
};
|
|
431
|
-
}
|
|
432
|
-
__name(sortManifest, "sortManifest");
|
|
433
|
-
function normalizeReturnType(returnType) {
|
|
434
|
-
const match = returnType.match(/^Promise<(.+)>$/);
|
|
435
|
-
return match?.[1] ?? returnType;
|
|
436
|
-
}
|
|
437
|
-
__name(normalizeReturnType, "normalizeReturnType");
|
|
438
|
-
|
|
439
|
-
// src/codegen/watcher.ts
|
|
440
|
-
import * as chokidar from "chokidar";
|
|
441
|
-
var CodegenWatcher = class {
|
|
442
|
-
static {
|
|
443
|
-
__name(this, "CodegenWatcher");
|
|
444
|
-
}
|
|
445
|
-
watcher = null;
|
|
446
|
-
async watch(options) {
|
|
447
|
-
const { projectPath, outputPath, pattern = "**/*.controller.ts" } = options;
|
|
448
|
-
logger.info("\u{1F440} Watching for controller changes...");
|
|
449
|
-
await this.generateClient(projectPath, outputPath);
|
|
450
|
-
this.watcher = chokidar.watch(pattern, {
|
|
451
|
-
cwd: projectPath,
|
|
452
|
-
ignored: /node_modules/,
|
|
453
|
-
persistent: true
|
|
454
|
-
});
|
|
455
|
-
this.watcher.on("change", async (path4) => {
|
|
456
|
-
logger.info(`\u{1F4DD} Controller changed: ${path4}`);
|
|
457
|
-
await this.generateClient(projectPath, outputPath);
|
|
458
|
-
});
|
|
459
|
-
this.watcher.on("add", async (path4) => {
|
|
460
|
-
logger.info(`\u2795 New controller: ${path4}`);
|
|
461
|
-
await this.generateClient(projectPath, outputPath);
|
|
462
|
-
});
|
|
463
|
-
this.watcher.on("unlink", async (path4) => {
|
|
464
|
-
logger.info(`\u2796 Controller removed: ${path4}`);
|
|
465
|
-
await this.generateClient(projectPath, outputPath);
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
async stop() {
|
|
469
|
-
if (this.watcher) {
|
|
470
|
-
await this.watcher.close();
|
|
471
|
-
this.watcher = null;
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
async generateClient(projectPath, outputPath) {
|
|
475
|
-
try {
|
|
476
|
-
const manifest = await generateRpcClient({
|
|
477
|
-
projectPath,
|
|
478
|
-
outputPath
|
|
479
|
-
});
|
|
480
|
-
logger.success(`Generated client for ${manifest.services.length} RPC service(s)`);
|
|
481
|
-
} catch (error) {
|
|
482
|
-
logger.error("Failed to generate client:", error.message);
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
};
|
|
486
|
-
|
|
487
|
-
export {
|
|
488
|
-
FileSystem,
|
|
489
|
-
filesystem,
|
|
490
|
-
NestJSParser,
|
|
491
|
-
ClientGenerator,
|
|
492
|
-
generateRpcClient,
|
|
493
|
-
CodegenWatcher,
|
|
494
|
-
codegen_exports
|
|
495
|
-
};
|
|
496
|
-
//# sourceMappingURL=chunk-CLM5PNSG.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/codegen/index.ts","../src/codegen/parser.ts","../src/core/filesystem.ts","../src/codegen/generator.ts","../src/codegen/watcher.ts"],"sourcesContent":["export * from './parser';\nexport * from './generator';\nexport * from './watcher';\n","import * as path from 'path';\nimport * as ts from 'typescript';\nimport type {\n RpcManifest,\n RpcMethodManifest,\n RpcParameterManifest,\n RpcServiceManifest,\n} from '../rpc/types';\n\nexport interface RouteInfo {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n path: string;\n handler: string;\n controllerName: string;\n}\n\nexport interface ControllerInfo {\n name: string;\n prefix: string;\n routes: RouteInfo[];\n}\n\nconst RPC_SERVICE_DECORATORS = new Set(['RpcService', 'WextsRpcService']);\nconst RPC_METHOD_DECORATORS = new Set(['RpcMethod', 'WextsRpc']);\nconst REQUIRE_AUTH_DECORATORS = new Set(['RequireAuth']);\n\n/**\n * Parse NestJS controllers to extract Fusion metadata\n */\nexport class NestJSParser {\n private program: ts.Program;\n\n constructor(private projectPath: string) {\n const configPath = ts.findConfigFile(projectPath, ts.sys.fileExists, 'tsconfig.json');\n if (!configPath) {\n throw new Error('tsconfig.json not found');\n }\n\n const config = ts.readConfigFile(configPath, ts.sys.readFile);\n const parsedConfig = ts.parseJsonConfigFileContent(\n config.config,\n ts.sys,\n path.dirname(configPath)\n );\n\n this.program = ts.createProgram(parsedConfig.fileNames, parsedConfig.options);\n }\n\n /**\n * Find all controllers with @FusionController decorator\n */\n findFusionControllers(): ControllerInfo[] {\n const controllers: ControllerInfo[] = [];\n const sourceFiles = this.program.getSourceFiles();\n\n for (const sourceFile of sourceFiles) {\n if (sourceFile.fileName.includes('node_modules')) continue;\n if (!sourceFile.fileName.includes('.controller.ts')) continue;\n\n const fileControllers = this.parseSourceFile(sourceFile);\n controllers.push(...fileControllers);\n }\n\n return controllers;\n }\n\n findRpcManifest(): RpcManifest {\n const services: RpcServiceManifest[] = [];\n\n for (const sourceFile of this.program.getSourceFiles()) {\n if (sourceFile.fileName.includes('node_modules')) continue;\n if (!sourceFile.fileName.endsWith('.ts')) continue;\n if (sourceFile.fileName.endsWith('.d.ts')) continue;\n\n services.push(...this.parseRpcServices(sourceFile));\n }\n\n services.sort((a, b) => a.name.localeCompare(b.name));\n for (const service of services) {\n service.methods.sort((a, b) => a.name.localeCompare(b.name));\n }\n\n if (services.length === 0) {\n return {\n schemaVersion: 1,\n services,\n };\n }\n\n return {\n schemaVersion: 1,\n services,\n };\n }\n\n private parseSourceFile(sourceFile: ts.SourceFile): ControllerInfo[] {\n const controllers: ControllerInfo[] = [];\n\n ts.forEachChild(sourceFile, (node) => {\n if (ts.isClassDeclaration(node) && node.name) {\n const controllerInfo = this.parseController(node);\n if (controllerInfo) {\n controllers.push(controllerInfo);\n }\n }\n });\n\n return controllers;\n }\n\n private parseController(classNode: ts.ClassDeclaration): ControllerInfo | null {\n const decorators = ts.getDecorators(classNode);\n if (!decorators) return null;\n\n let controllerPrefix = '';\n let isFusionController = false;\n\n // Check for @FusionController decorator\n for (const decorator of decorators) {\n const expr = decorator.expression;\n if (ts.isCallExpression(expr) && ts.isIdentifier(expr.expression)) {\n const decoratorName = expr.expression.text;\n\n if (decoratorName === 'FusionController') {\n isFusionController = true;\n if (expr.arguments.length > 0) {\n const arg = expr.arguments[0];\n if (ts.isStringLiteral(arg)) {\n controllerPrefix = arg.text;\n }\n }\n }\n }\n }\n\n if (!isFusionController) return null;\n\n const routes = this.parseRoutes(classNode);\n const className = classNode.name?.text || 'Unknown';\n\n return {\n name: className,\n prefix: controllerPrefix,\n routes: routes.map(r => ({ ...r, controllerName: className })),\n };\n }\n\n private parseRoutes(classNode: ts.ClassDeclaration): RouteInfo[] {\n const routes: RouteInfo[] = [];\n\n classNode.members.forEach((member) => {\n if (ts.isMethodDeclaration(member)) {\n const decorators = ts.getDecorators(member);\n if (!decorators) return;\n\n for (const decorator of decorators) {\n const expr = decorator.expression;\n if (ts.isCallExpression(expr) && ts.isIdentifier(expr.expression)) {\n const decoratorName = expr.expression.text;\n\n let method: RouteInfo['method'] | null = null;\n let routePath = '';\n\n // Map decorator to HTTP method\n if (decoratorName === 'FusionGet') method = 'GET';\n else if (decoratorName === 'FusionPost') method = 'POST';\n else if (decoratorName === 'FusionPut') method = 'PUT';\n else if (decoratorName === 'FusionDelete') method = 'DELETE';\n\n if (method) {\n // Get route path from decorator argument\n if (expr.arguments.length > 0) {\n const arg = expr.arguments[0];\n if (ts.isStringLiteral(arg)) {\n routePath = arg.text;\n }\n }\n\n const handlerName = (member.name as ts.Identifier).text;\n\n routes.push({\n method,\n path: routePath,\n handler: handlerName,\n controllerName: '', // Will be set by caller\n });\n }\n }\n }\n }\n });\n\n return routes;\n }\n\n private parseRpcServices(sourceFile: ts.SourceFile): RpcServiceManifest[] {\n const services: RpcServiceManifest[] = [];\n const rootDir = path.resolve(this.projectPath);\n\n ts.forEachChild(sourceFile, (node) => {\n if (!ts.isClassDeclaration(node) || !node.name) return;\n\n const serviceDecorator = this.findDecorator(node, RPC_SERVICE_DECORATORS);\n if (!serviceDecorator) return;\n\n const className = node.name.text;\n const serviceOptions = this.readDecoratorOptions(serviceDecorator);\n const classRequiresAuth = serviceOptions.requireAuth || this.hasDecorator(node, REQUIRE_AUTH_DECORATORS);\n const serviceName = serviceOptions.name || toStableServiceName(className);\n const methods = this.parseRpcMethods(node, classRequiresAuth, sourceFile);\n\n if (methods.length === 0) return;\n\n services.push({\n name: serviceName,\n className,\n importPath: toPosixPath(path.relative(rootDir, sourceFile.fileName).replace(/\\.ts$/, '')),\n requireAuth: classRequiresAuth,\n methods,\n });\n });\n\n return services;\n }\n\n private parseRpcMethods(classNode: ts.ClassDeclaration, classRequiresAuth: boolean, sourceFile: ts.SourceFile): RpcMethodManifest[] {\n const methods: RpcMethodManifest[] = [];\n\n for (const member of classNode.members) {\n if (!ts.isMethodDeclaration(member)) continue;\n if (!ts.isIdentifier(member.name)) continue;\n\n const methodDecorator = this.findDecorator(member, RPC_METHOD_DECORATORS);\n if (!methodDecorator) continue;\n\n const handlerName = member.name.text;\n const methodOptions = this.readDecoratorOptions(methodDecorator);\n const requireAuth = classRequiresAuth || methodOptions.requireAuth || this.hasDecorator(member, REQUIRE_AUTH_DECORATORS);\n\n methods.push({\n name: methodOptions.name || handlerName,\n handlerName,\n requireAuth,\n parameters: member.parameters.map((parameter) => this.parseParameter(parameter, sourceFile)),\n returnType: member.type ? getNodeText(member.type, sourceFile) : 'unknown',\n });\n }\n\n return methods;\n }\n\n private parseParameter(parameter: ts.ParameterDeclaration, sourceFile: ts.SourceFile): RpcParameterManifest {\n return {\n name: ts.isIdentifier(parameter.name) ? parameter.name.text : parameter.name.getText(),\n type: parameter.type ? getNodeText(parameter.type, sourceFile) : 'unknown',\n optional: Boolean(parameter.questionToken || parameter.initializer),\n };\n }\n\n private findDecorator(\n node: ts.ClassDeclaration | ts.MethodDeclaration,\n names: Set<string>\n ): ts.Decorator | undefined {\n const decorators = ts.getDecorators(node);\n if (!decorators) return undefined;\n\n return decorators.find((decorator) => {\n const name = getDecoratorName(decorator);\n return Boolean(name && names.has(name));\n });\n }\n\n private hasDecorator(\n node: ts.ClassDeclaration | ts.MethodDeclaration,\n names: Set<string>\n ): boolean {\n return Boolean(this.findDecorator(node, names));\n }\n\n private readDecoratorOptions(decorator: ts.Decorator): { name?: string; requireAuth?: boolean } {\n const expression = decorator.expression;\n if (!ts.isCallExpression(expression)) return {};\n\n const firstArg = expression.arguments[0];\n if (!firstArg) return {};\n\n if (ts.isStringLiteral(firstArg)) {\n return { name: firstArg.text };\n }\n\n if (!ts.isObjectLiteralExpression(firstArg)) return {};\n\n const result: { name?: string; requireAuth?: boolean } = {};\n\n for (const property of firstArg.properties) {\n if (!ts.isPropertyAssignment(property) || !ts.isIdentifier(property.name)) continue;\n\n if (property.name.text === 'name' && ts.isStringLiteral(property.initializer)) {\n result.name = property.initializer.text;\n }\n\n if (property.name.text === 'requireAuth') {\n if (property.initializer.kind === ts.SyntaxKind.TrueKeyword) {\n result.requireAuth = true;\n } else if (property.initializer.kind === ts.SyntaxKind.FalseKeyword) {\n result.requireAuth = false;\n }\n }\n }\n\n return result;\n }\n}\n\nfunction getDecoratorName(decorator: ts.Decorator): string | undefined {\n const expression = decorator.expression;\n if (ts.isIdentifier(expression)) return expression.text;\n if (ts.isCallExpression(expression) && ts.isIdentifier(expression.expression)) {\n return expression.expression.text;\n }\n\n return undefined;\n}\n\nfunction toStableServiceName(className: string): string {\n const withoutSuffix = className.replace(/(Service|Controller)$/, '');\n return withoutSuffix.charAt(0).toLowerCase() + withoutSuffix.slice(1);\n}\n\nfunction toPosixPath(filePath: string): string {\n return filePath.split(path.sep).join(path.posix.sep);\n}\n\nfunction getNodeText(node: ts.Node, sourceFile: ts.SourceFile): string {\n return sourceFile.text.slice(node.getStart(sourceFile), node.getEnd());\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { promisify } from 'util';\n\nconst readFile = promisify(fs.readFile);\nconst writeFile = promisify(fs.writeFile);\nconst mkdir = promisify(fs.mkdir);\nconst access = promisify(fs.access);\n\nexport class FileSystem {\n /**\n * Read file as string\n */\n async readFile(filePath: string, encoding: BufferEncoding = 'utf-8'): Promise<string> {\n return readFile(filePath, encoding);\n }\n\n /**\n * Write file\n */\n async writeFile(filePath: string, content: string): Promise<void> {\n // Ensure directory exists\n await this.ensureDir(path.dirname(filePath));\n return writeFile(filePath, content, 'utf-8');\n }\n\n /**\n * Read JSON file\n */\n async readJSON<T = any>(filePath: string): Promise<T> {\n const content = await this.readFile(filePath);\n return JSON.parse(content);\n }\n\n /**\n * Write JSON file\n */\n async writeJSON(filePath: string, data: any, pretty: boolean = true): Promise<void> {\n const content = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);\n return this.writeFile(filePath, content);\n }\n\n /**\n * Check if file/directory exists\n */\n async exists(filePath: string): Promise<boolean> {\n try {\n await access(filePath, fs.constants.F_OK);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Ensure directory exists (create if not)\n */\n async ensureDir(dirPath: string): Promise<void> {\n if (!(await this.exists(dirPath))) {\n await mkdir(dirPath, { recursive: true });\n }\n }\n\n /**\n * Copy file\n */\n async copyFile(src: string, dest: string): Promise<void> {\n const content = await this.readFile(src);\n await this.writeFile(dest, content);\n }\n\n /**\n * Read directory\n */\n readDir(dirPath: string): Promise<string[]> {\n return promisify(fs.readdir)(dirPath);\n }\n}\n\n// Export singleton\nexport const filesystem = new FileSystem();\n","import { filesystem } from '../core/filesystem';\nimport * as path from 'path';\nimport type { RpcManifest, RpcMethodManifest, RpcServiceManifest } from '../rpc/types';\nimport { NestJSParser } from './parser';\n\nexport interface GenerateOptions {\n outputPath: string;\n manifest: RpcManifest;\n manifestFileName?: string;\n clientFileName?: string;\n}\n\nexport interface GenerateRpcOptions {\n projectPath: string;\n outputPath: string;\n manifestFileName?: string;\n clientFileName?: string;\n}\n\n/**\n * Generate TypeScript API client from controller metadata\n */\nexport class ClientGenerator {\n async generate(options: GenerateOptions): Promise<void> {\n const {\n manifest,\n outputPath,\n manifestFileName = 'wexts.rpc.manifest.json',\n clientFileName = 'client.ts',\n } = options;\n\n if (manifest.services.length === 0) {\n throw new Error('No Wexts RPC services found. Add @RpcService() to a Nest provider and @RpcMethod() to at least one method.');\n }\n\n const sortedManifest = sortManifest(manifest);\n const clientCode = this.generateRpcClientCode(sortedManifest);\n await filesystem.writeJSON(path.join(outputPath, manifestFileName), sortedManifest, true);\n await filesystem.writeFile(path.join(outputPath, clientFileName), clientCode);\n\n const indexCode = `export * from './client';\\n`;\n await filesystem.writeFile(path.join(outputPath, 'index.ts'), indexCode);\n }\n\n private generateRpcClientCode(manifest: RpcManifest): string {\n const manifestJson = JSON.stringify(manifest, null, 2);\n\n return `import { createWextsRpcClient, type WextsRpcClientOptions } from 'wexts/client';\nimport type { RpcManifest } from 'wexts/rpc';\n\nconst manifest = ${manifestJson} satisfies RpcManifest;\n\n${this.generateClientInterface(manifest)}\n\nexport function createWextsClient(options?: WextsRpcClientOptions): WextsClient {\n return createWextsRpcClient(manifest, options) as unknown as WextsClient;\n}\n\nexport const wexts = createWextsClient();\n`;\n }\n\n private generateClientInterface(manifest: RpcManifest): string {\n const services = manifest.services.map((service) => this.generateServiceInterface(service)).join('\\n');\n return `export interface WextsClient {\\n${services}}\\n`;\n }\n\n private generateServiceInterface(service: RpcServiceManifest): string {\n const methods = service.methods.map((method) => ` ${method.name}: (${this.parametersToSignature(method)}) => Promise<${normalizeReturnType(method.returnType)}>;`).join('\\n');\n return ` ${service.name}: {\\n${methods}\\n };\\n`;\n }\n\n private parametersToSignature(method: RpcMethodManifest): string {\n return method.parameters\n .map((parameter) => `${parameter.name}${parameter.optional ? '?' : ''}: ${parameter.type}`)\n .join(', ');\n }\n}\n\nexport async function generateRpcClient(options: GenerateRpcOptions): Promise<RpcManifest> {\n const parser = new NestJSParser(options.projectPath);\n const manifest = parser.findRpcManifest();\n const generator = new ClientGenerator();\n await generator.generate({\n manifest,\n outputPath: options.outputPath,\n manifestFileName: options.manifestFileName,\n clientFileName: options.clientFileName,\n });\n\n return sortManifest(manifest);\n}\n\nfunction sortManifest(manifest: RpcManifest): RpcManifest {\n return {\n schemaVersion: 1,\n services: [...manifest.services]\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((service) => ({\n ...service,\n methods: [...service.methods].sort((a, b) => a.name.localeCompare(b.name)),\n })),\n };\n}\n\nfunction normalizeReturnType(returnType: string): string {\n const match = returnType.match(/^Promise<(.+)>$/);\n return match?.[1] ?? returnType;\n}\n","import * as chokidar from 'chokidar';\nimport { logger } from '../core/logger';\nimport { generateRpcClient } from './generator';\n\nexport interface WatchOptions {\n projectPath: string;\n outputPath: string;\n pattern?: string;\n}\n\n/**\n * Watch NestJS controllers and regenerate client on changes\n */\nexport class CodegenWatcher {\n private watcher: chokidar.FSWatcher | null = null;\n\n async watch(options: WatchOptions): Promise<void> {\n const { projectPath, outputPath, pattern = '**/*.controller.ts' } = options;\n\n logger.info('👀 Watching for controller changes...');\n\n // Initial generation\n await this.generateClient(projectPath, outputPath);\n\n // Watch for changes\n this.watcher = chokidar.watch(pattern, {\n cwd: projectPath,\n ignored: /node_modules/,\n persistent: true,\n });\n\n this.watcher.on('change', async (path) => {\n logger.info(`📝 Controller changed: ${path}`);\n await this.generateClient(projectPath, outputPath);\n });\n\n this.watcher.on('add', async (path) => {\n logger.info(`➕ New controller: ${path}`);\n await this.generateClient(projectPath, outputPath);\n });\n\n this.watcher.on('unlink', async (path) => {\n logger.info(`➖ Controller removed: ${path}`);\n await this.generateClient(projectPath, outputPath);\n });\n }\n\n async stop(): Promise<void> {\n if (this.watcher) {\n await this.watcher.close();\n this.watcher = null;\n }\n }\n\n private async generateClient(projectPath: string, outputPath: string): Promise<void> {\n try {\n const manifest = await generateRpcClient({ projectPath, outputPath });\n logger.success(`Generated client for ${manifest.services.length} RPC service(s)`);\n } catch (error: any) {\n logger.error('Failed to generate client:', error.message);\n }\n }\n}\n"],"mappings":"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","names":["path","ts","RPC_SERVICE_DECORATORS","Set","RPC_METHOD_DECORATORS","REQUIRE_AUTH_DECORATORS","NestJSParser","program","projectPath","configPath","findConfigFile","sys","fileExists","Error","config","readConfigFile","readFile","parsedConfig","parseJsonConfigFileContent","dirname","createProgram","fileNames","options","findFusionControllers","controllers","sourceFiles","getSourceFiles","sourceFile","fileName","includes","fileControllers","parseSourceFile","push","findRpcManifest","services","endsWith","parseRpcServices","sort","a","b","name","localeCompare","service","methods","length","schemaVersion","ts","forEachChild","node","isClassDeclaration","controllerInfo","parseController","classNode","decorators","getDecorators","controllerPrefix","isFusionController","decorator","expr","expression","isCallExpression","isIdentifier","decoratorName","text","arguments","arg","isStringLiteral","routes","parseRoutes","className","prefix","map","r","controllerName","members","forEach","member","isMethodDeclaration","method","routePath","handlerName","path","handler","rootDir","resolve","serviceDecorator","findDecorator","serviceOptions","readDecoratorOptions","classRequiresAuth","requireAuth","hasDecorator","serviceName","toStableServiceName","parseRpcMethods","importPath","toPosixPath","relative","replace","methodDecorator","methodOptions","parameters","parameter","parseParameter","returnType","type","getNodeText","getText","optional","Boolean","questionToken","initializer","names","undefined","find","getDecoratorName","has","firstArg","isObjectLiteralExpression","result","property","properties","isPropertyAssignment","kind","SyntaxKind","TrueKeyword","FalseKeyword","withoutSuffix","charAt","toLowerCase","slice","filePath","split","sep","join","posix","getStart","getEnd","fs","path","promisify","readFile","promisify","writeFile","mkdir","access","FileSystem","filePath","encoding","content","ensureDir","dirname","readJSON","JSON","parse","writeJSON","data","pretty","stringify","exists","constants","F_OK","dirPath","recursive","copyFile","src","dest","readDir","readdir","filesystem","path","ClientGenerator","generate","options","manifest","outputPath","manifestFileName","clientFileName","services","length","Error","sortedManifest","sortManifest","clientCode","generateRpcClientCode","filesystem","writeJSON","join","writeFile","indexCode","manifestJson","JSON","stringify","generateClientInterface","map","service","generateServiceInterface","methods","method","name","parametersToSignature","normalizeReturnType","returnType","parameters","parameter","optional","type","generateRpcClient","parser","NestJSParser","projectPath","findRpcManifest","generator","schemaVersion","sort","a","b","localeCompare","match","chokidar","CodegenWatcher","watcher","watch","options","projectPath","outputPath","pattern","logger","info","generateClient","cwd","ignored","persistent","on","path","stop","close","manifest","generateRpcClient","success","services","length","error","message"]}
|
package/dist/chunk-DNLGCKTT.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
var _chunk7QKLIVRFjs = require('./chunk-7QKLIVRF.js');
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
var _chunkXE4OXN2Wjs = require('./chunk-XE4OXN2W.js');
|
|
14
|
-
|
|
15
|
-
// src/rpc/index.ts
|
|
16
|
-
var rpc_exports = {};
|
|
17
|
-
_chunkXE4OXN2Wjs.__export.call(void 0, rpc_exports, {
|
|
18
|
-
RequireAuth: () => _chunk7QKLIVRFjs.RequireAuth,
|
|
19
|
-
RpcMethod: () => _chunk7QKLIVRFjs.RpcMethod,
|
|
20
|
-
RpcService: () => _chunk7QKLIVRFjs.RpcService,
|
|
21
|
-
WextsRpc: () => _chunk7QKLIVRFjs.WextsRpc,
|
|
22
|
-
WextsRpcService: () => _chunk7QKLIVRFjs.WextsRpcService,
|
|
23
|
-
getRpcAuthPolicy: () => _chunk7QKLIVRFjs.getRpcAuthPolicy,
|
|
24
|
-
getRuntimeRpcMethodsMetadata: () => _chunk7QKLIVRFjs.getRuntimeRpcMethodsMetadata,
|
|
25
|
-
getRuntimeRpcServiceMetadata: () => _chunk7QKLIVRFjs.getRuntimeRpcServiceMetadata
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
exports.rpc_exports = rpc_exports;
|
|
31
|
-
//# sourceMappingURL=chunk-DNLGCKTT.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["/Volumes/Projects/wexts/packages/dist/chunk-DNLGCKTT.js","../src/rpc/index.ts"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,sDAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACA;ACdA,IAAA,YAAA,EAAA,CAAA,CAAA;ADgBA,uCAAQ,WAAY,EAAE;AACtB,EAAE,WAAW,EAAE,CAAC,EAAE,GAAG,4BAAW;AAChC,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,0BAAS;AAC5B,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,2BAAU;AAC9B,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,yBAAQ;AAC1B,EAAE,eAAe,EAAE,CAAC,EAAE,GAAG,gCAAe;AACxC,EAAE,gBAAgB,EAAE,CAAC,EAAE,GAAG,iCAAgB;AAC1C,EAAE,4BAA4B,EAAE,CAAC,EAAE,GAAG,6CAA4B;AAClE,EAAE,4BAA4B,EAAE,CAAC,EAAE,GAAG;AACtC,CAAC,CAAC;AACF;AACA;AACE;AACF,kCAAC","file":"/Volumes/Projects/wexts/packages/dist/chunk-DNLGCKTT.js","sourcesContent":[null,"export * from './decorators';\nexport * from './types';\n"]}
|
package/dist/chunk-JHOVXH3X.mjs
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
__name
|
|
3
|
-
} from "./chunk-7WULUGLH.mjs";
|
|
4
|
-
|
|
5
|
-
// src/core/logger.ts
|
|
6
|
-
var LogLevel = /* @__PURE__ */ (function(LogLevel2) {
|
|
7
|
-
LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
|
|
8
|
-
LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
|
|
9
|
-
LogLevel2[LogLevel2["WARN"] = 2] = "WARN";
|
|
10
|
-
LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
|
|
11
|
-
return LogLevel2;
|
|
12
|
-
})({});
|
|
13
|
-
var Logger = class {
|
|
14
|
-
static {
|
|
15
|
-
__name(this, "Logger");
|
|
16
|
-
}
|
|
17
|
-
level;
|
|
18
|
-
prefix;
|
|
19
|
-
timestamp;
|
|
20
|
-
constructor(options = {}) {
|
|
21
|
-
this.level = options.level ?? 1;
|
|
22
|
-
this.prefix = options.prefix ?? "[Fusion]";
|
|
23
|
-
this.timestamp = options.timestamp ?? true;
|
|
24
|
-
}
|
|
25
|
-
formatMessage(level, ...args) {
|
|
26
|
-
const timestamp = this.timestamp ? `[${(/* @__PURE__ */ new Date()).toISOString()}]` : "";
|
|
27
|
-
return `${timestamp} ${this.prefix} ${level}: ${args.join(" ")}`;
|
|
28
|
-
}
|
|
29
|
-
debug(...args) {
|
|
30
|
-
if (this.level <= 0) {
|
|
31
|
-
console.log(this.formatMessage("DEBUG", ...args));
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
info(...args) {
|
|
35
|
-
if (this.level <= 1) {
|
|
36
|
-
console.log(this.formatMessage("INFO", ...args));
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
warn(...args) {
|
|
40
|
-
if (this.level <= 2) {
|
|
41
|
-
console.warn(this.formatMessage("WARN", ...args));
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
error(...args) {
|
|
45
|
-
if (this.level <= 3) {
|
|
46
|
-
console.error(this.formatMessage("ERROR", ...args));
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
success(...args) {
|
|
50
|
-
console.log(this.formatMessage("\u2713", ...args));
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
var logger = new Logger();
|
|
54
|
-
function createLogger(options) {
|
|
55
|
-
return new Logger(options);
|
|
56
|
-
}
|
|
57
|
-
__name(createLogger, "createLogger");
|
|
58
|
-
|
|
59
|
-
export {
|
|
60
|
-
LogLevel,
|
|
61
|
-
Logger,
|
|
62
|
-
logger,
|
|
63
|
-
createLogger
|
|
64
|
-
};
|
|
65
|
-
//# sourceMappingURL=chunk-JHOVXH3X.mjs.map
|