@tuyau/core 0.1.4 → 0.2.1
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.
|
@@ -5,8 +5,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
5
5
|
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
6
|
if (decorator = decorators[i])
|
|
7
7
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
-
if (kind && result)
|
|
9
|
-
__defProp(target, key, result);
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
10
9
|
return result;
|
|
11
10
|
};
|
|
12
11
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"commands":[{"commandName":"tuyau:generate","description":"Tuyau generator command","help":"","namespace":"tuyau","aliases":[],"flags":[{"name":"verbose","flagName":"verbose","required":false,"type":"boolean","description":"Verbose logs","default":false,"alias":"v"}],"args":[],"options":{"startApp":true},"filePath":"generate.js"
|
|
1
|
+
{"commands":[{"commandName":"tuyau:generate","description":"Tuyau generator command","help":"","namespace":"tuyau","aliases":[],"flags":[{"name":"verbose","flagName":"verbose","required":false,"type":"boolean","description":"Verbose logs","default":false,"alias":"v"}],"args":[],"options":{"startApp":true},"filePath":"generate.js"}],"version":1}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
__decorateClass
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-ADS4GRIL.js";
|
|
4
4
|
|
|
5
5
|
// commands/generate.ts
|
|
6
6
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
@@ -11,6 +11,7 @@ import { BaseCommand, flags } from "@adonisjs/core/ace";
|
|
|
11
11
|
import { Node } from "ts-morph";
|
|
12
12
|
import matchit from "@poppinss/matchit";
|
|
13
13
|
import { fileURLToPath } from "node:url";
|
|
14
|
+
import { readFile } from "node:fs/promises";
|
|
14
15
|
import { dirname, relative } from "node:path";
|
|
15
16
|
import { existsSync, mkdirSync } from "node:fs";
|
|
16
17
|
import string from "@adonisjs/core/helpers/string";
|
|
@@ -22,6 +23,7 @@ var ApiTypesGenerator = class {
|
|
|
22
23
|
#config;
|
|
23
24
|
#routes;
|
|
24
25
|
#destination;
|
|
26
|
+
#isTuyauInertiaInstalledCached;
|
|
25
27
|
constructor(options) {
|
|
26
28
|
this.#config = options.config;
|
|
27
29
|
this.#routes = options.routes;
|
|
@@ -30,6 +32,24 @@ var ApiTypesGenerator = class {
|
|
|
30
32
|
this.#appRoot = options.appRoot;
|
|
31
33
|
this.#prepareDestination();
|
|
32
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Check if the @tuyau/inertia package is installed.
|
|
37
|
+
*/
|
|
38
|
+
async #isTuyauInertiaInstalled() {
|
|
39
|
+
if (this.#isTuyauInertiaInstalledCached !== void 0)
|
|
40
|
+
return this.#isTuyauInertiaInstalledCached;
|
|
41
|
+
try {
|
|
42
|
+
const pkgJsonText = await readFile(
|
|
43
|
+
fileURLToPath(new URL("./package.json", this.#appRoot)),
|
|
44
|
+
"utf-8"
|
|
45
|
+
);
|
|
46
|
+
const pkgJson = JSON.parse(pkgJsonText);
|
|
47
|
+
this.#isTuyauInertiaInstalledCached = !!pkgJson.dependencies?.["@tuyau/inertia"];
|
|
48
|
+
return this.#isTuyauInertiaInstalledCached;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
throw new Error("Unable to read the package.json file", { cause: error });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
33
53
|
#getDestinationDirectory() {
|
|
34
54
|
return dirname(this.#destination);
|
|
35
55
|
}
|
|
@@ -48,14 +68,11 @@ var ApiTypesGenerator = class {
|
|
|
48
68
|
*/
|
|
49
69
|
#extractClassHandlerData(file, routeHandler) {
|
|
50
70
|
const classDef = file.getClasses().find((c) => c.isDefaultExport());
|
|
51
|
-
if (!classDef)
|
|
52
|
-
return;
|
|
71
|
+
if (!classDef) return;
|
|
53
72
|
const method = classDef.getMethod(routeHandler.method);
|
|
54
|
-
if (!method)
|
|
55
|
-
return;
|
|
73
|
+
if (!method) return;
|
|
56
74
|
const body = method.getBody();
|
|
57
|
-
if (!body)
|
|
58
|
-
return;
|
|
75
|
+
if (!body) return;
|
|
59
76
|
return { method, body, file };
|
|
60
77
|
}
|
|
61
78
|
/**
|
|
@@ -71,17 +88,13 @@ var ApiTypesGenerator = class {
|
|
|
71
88
|
return false;
|
|
72
89
|
});
|
|
73
90
|
const defaultImport = sourceFile.getImportDeclaration((importNode) => {
|
|
74
|
-
if (importNode.getDefaultImport()?.getText() === identifier.getText())
|
|
75
|
-
return true;
|
|
91
|
+
if (importNode.getDefaultImport()?.getText() === identifier.getText()) return true;
|
|
76
92
|
return false;
|
|
77
93
|
});
|
|
78
94
|
const isValidFile = (namedImport || defaultImport)?.getModuleSpecifierSourceFile();
|
|
79
|
-
if (!isValidFile)
|
|
80
|
-
|
|
81
|
-
if (
|
|
82
|
-
return "named";
|
|
83
|
-
if (defaultImport)
|
|
84
|
-
return "default";
|
|
95
|
+
if (!isValidFile) return void 0;
|
|
96
|
+
if (namedImport) return "named";
|
|
97
|
+
if (defaultImport) return "default";
|
|
85
98
|
return void 0;
|
|
86
99
|
}
|
|
87
100
|
/**
|
|
@@ -94,8 +107,7 @@ var ApiTypesGenerator = class {
|
|
|
94
107
|
*/
|
|
95
108
|
#extractRequest(handlerData) {
|
|
96
109
|
const validateUsingCallNode = handlerData.method.forEachDescendant((node) => {
|
|
97
|
-
if (!Node.isCallExpression(node))
|
|
98
|
-
return false;
|
|
110
|
+
if (!Node.isCallExpression(node)) return false;
|
|
99
111
|
if (node.getExpression().getText().includes("validateUsing")) {
|
|
100
112
|
return node;
|
|
101
113
|
}
|
|
@@ -103,11 +115,11 @@ var ApiTypesGenerator = class {
|
|
|
103
115
|
});
|
|
104
116
|
if (validateUsingCallNode) {
|
|
105
117
|
const schema = validateUsingCallNode.getArguments()[0];
|
|
106
|
-
if (!Node.isIdentifier(schema))
|
|
107
|
-
return;
|
|
118
|
+
if (!Node.isIdentifier(schema)) return;
|
|
108
119
|
const definition = schema.getDefinitions().at(0);
|
|
109
120
|
const importType = this.#getIdentifierImportType(schema);
|
|
110
|
-
|
|
121
|
+
const isReExportedFromThisFile = definition ? handlerData.file.getExportedDeclarations().has(definition.getNode().getText()) : false;
|
|
122
|
+
if (!importType && !isReExportedFromThisFile) {
|
|
111
123
|
this.#logger.warning(`Unable to find the schema file for ${schema.getText()}`);
|
|
112
124
|
return;
|
|
113
125
|
}
|
|
@@ -142,28 +154,21 @@ var ApiTypesGenerator = class {
|
|
|
142
154
|
*/
|
|
143
155
|
#filterRoutes(routes, mode) {
|
|
144
156
|
const config = this.#config.codegen?.[mode];
|
|
145
|
-
if (!config || !config.only && !config.except)
|
|
146
|
-
return routes;
|
|
157
|
+
if (!config || !config.only && !config.except) return routes;
|
|
147
158
|
return routes.filter((route) => {
|
|
148
|
-
if (typeof config.only === "function")
|
|
149
|
-
|
|
150
|
-
if (typeof config.except === "function")
|
|
151
|
-
return !config.except(route);
|
|
159
|
+
if (typeof config.only === "function") return config.only(route);
|
|
160
|
+
if (typeof config.except === "function") return !config.except(route);
|
|
152
161
|
if (config.only) {
|
|
153
162
|
for (const pattern of config.only) {
|
|
154
|
-
if (pattern instanceof RegExp && pattern.test(route.pattern))
|
|
155
|
-
|
|
156
|
-
if (route.pattern === pattern)
|
|
157
|
-
return true;
|
|
163
|
+
if (pattern instanceof RegExp && pattern.test(route.pattern)) return true;
|
|
164
|
+
if (route.pattern === pattern) return true;
|
|
158
165
|
}
|
|
159
166
|
return false;
|
|
160
167
|
}
|
|
161
168
|
if (config.except) {
|
|
162
169
|
for (const pattern of config.except) {
|
|
163
|
-
if (pattern instanceof RegExp && pattern.test(route.pattern))
|
|
164
|
-
|
|
165
|
-
if (route.pattern === pattern)
|
|
166
|
-
return false;
|
|
170
|
+
if (pattern instanceof RegExp && pattern.test(route.pattern)) return false;
|
|
171
|
+
if (route.pattern === pattern) return false;
|
|
167
172
|
}
|
|
168
173
|
return true;
|
|
169
174
|
}
|
|
@@ -184,15 +189,14 @@ var ApiTypesGenerator = class {
|
|
|
184
189
|
return routes.map(({ name, pattern, methods }) => {
|
|
185
190
|
const params = matchit.parse(pattern).filter((node) => node.type !== 0).map((node) => node.val);
|
|
186
191
|
let typeName = this.#generateTypeName({ pattern, methods });
|
|
187
|
-
if (!typesByPattern[typeName])
|
|
188
|
-
typeName = "unknown";
|
|
192
|
+
if (!typesByPattern[typeName]) typeName = "unknown";
|
|
189
193
|
return { params, name, path: pattern, method: methods, types: typeName };
|
|
190
194
|
}).filter((route) => !!route.name);
|
|
191
195
|
}
|
|
192
196
|
async #writeApiFile(options) {
|
|
193
197
|
const file = this.#project.createSourceFile(this.#destination, "", { overwrite: true });
|
|
194
|
-
if (!file)
|
|
195
|
-
|
|
198
|
+
if (!file) throw new Error("Unable to create the api.ts file");
|
|
199
|
+
const isTuyauInertiaInstalled = await this.#isTuyauInertiaInstalled();
|
|
196
200
|
file.removeText().insertText(0, (writer) => {
|
|
197
201
|
writer.writeLine(`import type { MakeTuyauRequest, MakeTuyauResponse } from '@tuyau/utils/types'`).writeLine(`import type { InferInput } from '@vinejs/vine/types'`).newLine();
|
|
198
202
|
Object.entries(options.typesByPattern).forEach(([key, value]) => {
|
|
@@ -214,10 +218,12 @@ var ApiTypesGenerator = class {
|
|
|
214
218
|
}
|
|
215
219
|
writer.writeLine(`] as const;`);
|
|
216
220
|
writer.writeLine(`export const api = {`).writeLine(` routes,`).writeLine(` definition: {} as ApiDefinition`).writeLine(`}`);
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
+
if (isTuyauInertiaInstalled) {
|
|
222
|
+
writer.writeLine(`declare module '@tuyau/inertia/types' {`);
|
|
223
|
+
writer.writeLine(` type InertiaApi = typeof api`);
|
|
224
|
+
writer.writeLine(` export interface Api extends InertiaApi {}`);
|
|
225
|
+
writer.writeLine(`}`);
|
|
226
|
+
}
|
|
221
227
|
});
|
|
222
228
|
await file.save();
|
|
223
229
|
}
|
|
@@ -227,8 +233,7 @@ var ApiTypesGenerator = class {
|
|
|
227
233
|
const sourcesFiles = this.#project.getSourceFiles();
|
|
228
234
|
const routes = this.#filterRoutes(this.#routes, "definitions");
|
|
229
235
|
for (const route of routes) {
|
|
230
|
-
if (typeof route.handler === "function")
|
|
231
|
-
continue;
|
|
236
|
+
if (typeof route.handler === "function") continue;
|
|
232
237
|
const routeHandler = await parseBindingReference(route.handler.reference);
|
|
233
238
|
const file = sourcesFiles.find(
|
|
234
239
|
(sf) => sf.getFilePath().endsWith(`${routeHandler.moduleNameOrPath.replace("#", "")}.ts`)
|
|
@@ -249,19 +254,16 @@ var ApiTypesGenerator = class {
|
|
|
249
254
|
let currentLevel = definition;
|
|
250
255
|
const relativePath = slash(relative(this.#getDestinationDirectory(), file.getFilePath()));
|
|
251
256
|
segments.forEach((segment, i) => {
|
|
252
|
-
if (!currentLevel[segment])
|
|
253
|
-
currentLevel[segment] = {};
|
|
257
|
+
if (!currentLevel[segment]) currentLevel[segment] = {};
|
|
254
258
|
currentLevel = currentLevel[segment];
|
|
255
|
-
if (i !== segments.length - 1)
|
|
256
|
-
return;
|
|
259
|
+
if (i !== segments.length - 1) return;
|
|
257
260
|
const typeName = this.#generateTypeName(route);
|
|
258
261
|
typesByPattern[typeName] = {
|
|
259
262
|
request: schemaImport ? `MakeTuyauRequest<${schemaImport}>` : "unknown",
|
|
260
263
|
response: `MakeTuyauResponse<import('${relativePath}').default['${routeHandler.method}']>`
|
|
261
264
|
};
|
|
262
265
|
currentLevel.$url = {};
|
|
263
|
-
for (const method of methods)
|
|
264
|
-
currentLevel[method] = typeName;
|
|
266
|
+
for (const method of methods) currentLevel[method] = typeName;
|
|
265
267
|
});
|
|
266
268
|
}
|
|
267
269
|
const routesNameArray = this.#generateRoutesNameArray(
|
package/build/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "../../chunk-
|
|
1
|
+
import "../../chunk-ADS4GRIL.js";
|
|
2
2
|
|
|
3
3
|
// src/hooks/build_hook.ts
|
|
4
4
|
import util from "node:util";
|
|
@@ -7,8 +7,7 @@ var exec = util.promisify(cpExec);
|
|
|
7
7
|
async function tuyauBuildHook({ logger }) {
|
|
8
8
|
logger.info("generating tuyau codegen file", { suffix: "tuyau" });
|
|
9
9
|
const { stderr } = await exec("node ace tuyau:generate");
|
|
10
|
-
if (stderr)
|
|
11
|
-
throw new Error(stderr);
|
|
10
|
+
if (stderr) throw new Error(stderr);
|
|
12
11
|
}
|
|
13
12
|
export {
|
|
14
13
|
tuyauBuildHook as default
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tuyau/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1
|
|
4
|
+
"version": "0.2.1",
|
|
5
5
|
"description": "",
|
|
6
6
|
"author": "",
|
|
7
7
|
"license": "MIT",
|
|
@@ -23,15 +23,15 @@
|
|
|
23
23
|
"@adonisjs/core": "^6.2.0"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"ts-morph": "^
|
|
26
|
+
"ts-morph": "^23.0.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@adonisjs/assembler": "^7.
|
|
30
|
-
"@adonisjs/core": "^6.
|
|
29
|
+
"@adonisjs/assembler": "^7.8.2",
|
|
30
|
+
"@adonisjs/core": "^6.14.0",
|
|
31
31
|
"@julr/tooling-configs": "^2.2.0",
|
|
32
32
|
"@poppinss/cliui": "^6.4.1",
|
|
33
33
|
"@poppinss/matchit": "^3.1.2",
|
|
34
|
-
"@types/node": "^20.
|
|
34
|
+
"@types/node": "^20.16.5",
|
|
35
35
|
"@tuyau/client": "0.1.2",
|
|
36
36
|
"@tuyau/utils": "0.0.4"
|
|
37
37
|
},
|