@tuyau/core 0.4.2 → 1.0.0-beta.0

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.
@@ -1,362 +0,0 @@
1
- import {
2
- __decorateClass
3
- } from "../chunk-ADS4GRIL.js";
4
-
5
- // commands/generate.ts
6
- import { fileURLToPath as fileURLToPath2 } from "url";
7
- import { Project, QuoteKind } from "ts-morph";
8
- import { BaseCommand, flags } from "@adonisjs/core/ace";
9
-
10
- // src/codegen/api_types_generator.ts
11
- import { Node } from "ts-morph";
12
- import matchit from "@poppinss/matchit";
13
- import { fileURLToPath } from "url";
14
- import { readFile } from "fs/promises";
15
- import { dirname, relative } from "path";
16
- import { existsSync, mkdirSync } from "fs";
17
- import string from "@adonisjs/core/helpers/string";
18
- import { assertExists } from "@adonisjs/core/helpers/assert";
19
- import { parseBindingReference, slash } from "@adonisjs/core/helpers";
20
- var ApiTypesGenerator = class {
21
- #appRoot;
22
- #logger;
23
- #project;
24
- #config;
25
- #routes;
26
- #destination;
27
- #cachedPkgJson;
28
- constructor(options) {
29
- this.#config = options.config;
30
- this.#routes = options.routes;
31
- this.#logger = options.logger;
32
- this.#project = options.project;
33
- this.#appRoot = options.appRoot;
34
- this.#prepareDestination();
35
- }
36
- async #loadPkgJson() {
37
- if (this.#cachedPkgJson) return this.#cachedPkgJson;
38
- try {
39
- const pkgJsonText = await readFile(
40
- fileURLToPath(new URL("./package.json", this.#appRoot)),
41
- "utf-8"
42
- );
43
- this.#cachedPkgJson = JSON.parse(pkgJsonText);
44
- return this.#cachedPkgJson;
45
- } catch (error) {
46
- throw new Error("Unable to read the package.json file", { cause: error });
47
- }
48
- }
49
- #isPackageInstalled(name) {
50
- assertExists(
51
- this.#cachedPkgJson,
52
- "package.json should be loaded before checking if a package is installed"
53
- );
54
- return !!this.#cachedPkgJson.dependencies?.[name];
55
- }
56
- #getDestinationDirectory() {
57
- return dirname(this.#destination);
58
- }
59
- /**
60
- * Create the destination directory if it does not exists
61
- */
62
- #prepareDestination() {
63
- this.#destination = fileURLToPath(new URL("./.adonisjs/api.ts", this.#appRoot));
64
- const directory = this.#getDestinationDirectory();
65
- if (!existsSync(directory)) {
66
- mkdirSync(directory, { recursive: true });
67
- }
68
- }
69
- /**
70
- * Extract class and method of the route handler
71
- */
72
- #extractClassHandlerData(file, routeHandler) {
73
- const classDef = file.getClasses().find((c) => c.isDefaultExport());
74
- if (!classDef) return;
75
- const method = classDef.getMethod(routeHandler.method);
76
- if (!method) return;
77
- const body = method.getBody();
78
- if (!body) return;
79
- return { method, body, file };
80
- }
81
- /**
82
- * Get the import type of an identifier
83
- */
84
- #getIdentifierImportType(identifier) {
85
- const sourceFile = identifier.getSourceFile();
86
- const namedImport = sourceFile.getImportDeclaration((importNode) => {
87
- const namedImports = importNode.getNamedImports();
88
- if (namedImports.find((namedImport2) => namedImport2.getName() === identifier.getText())) {
89
- return true;
90
- }
91
- return false;
92
- });
93
- const defaultImport = sourceFile.getImportDeclaration((importNode) => {
94
- if (importNode.getDefaultImport()?.getText() === identifier.getText()) return true;
95
- return false;
96
- });
97
- const isValidFile = (namedImport || defaultImport)?.getModuleSpecifierSourceFile();
98
- if (!isValidFile) return void 0;
99
- if (namedImport) return "named";
100
- if (defaultImport) return "default";
101
- return void 0;
102
- }
103
- /**
104
- * This method will returns the path to the schema file
105
- */
106
- #extractRequest(handlerData) {
107
- const validateUsingCallNode = handlerData.method.forEachDescendant((node) => {
108
- if (!Node.isCallExpression(node)) return false;
109
- if (node.getExpression().getText().includes("validateUsing")) {
110
- return node;
111
- }
112
- return false;
113
- });
114
- if (!validateUsingCallNode) return;
115
- const schema = validateUsingCallNode.getArguments()[0];
116
- if (Node.isIdentifier(schema)) {
117
- const definition = schema.getDefinitions().at(0);
118
- const importType = this.#getIdentifierImportType(schema);
119
- const isReExportedFromThisFile = definition ? handlerData.file.getExportedDeclarations().has(definition.getNode().getText()) : false;
120
- if (!importType && !isReExportedFromThisFile) {
121
- this.#logger.warning(`Unable to find the schema file for ${schema.getText()}`);
122
- return;
123
- }
124
- const importPath = definition.getSourceFile().getFilePath();
125
- const relativeImportPath = slash(relative(this.#getDestinationDirectory(), importPath));
126
- const propName = importType === "default" ? "default" : schema.getText();
127
- return `InferInput<typeof import('${relativeImportPath}')['${propName}']>`;
128
- }
129
- if (Node.isPropertyAccessExpression(schema)) {
130
- const baseExpression = schema.getExpression();
131
- const propertyName = schema.getName();
132
- if (Node.isIdentifier(baseExpression)) {
133
- const className = baseExpression.getText();
134
- const classDeclaration = handlerData.file.getClass(className);
135
- if (!classDeclaration) return;
136
- const staticProperty = classDeclaration.getStaticMember(propertyName);
137
- if (!staticProperty) return;
138
- const importPath = classDeclaration.getSourceFile().getFilePath();
139
- const relativeImportPath = slash(relative(this.#getDestinationDirectory(), importPath));
140
- return `InferInput<typeof import('${relativeImportPath}').default['${propertyName}']>`;
141
- }
142
- }
143
- }
144
- /**
145
- * Generate the final interface containing all routes, request, and response
146
- */
147
- #generateDefinitionInterface(types, indent = " ") {
148
- let interfaceContent = "";
149
- Object.entries(types).forEach(([key, value]) => {
150
- if (typeof value === "object") {
151
- interfaceContent += `${indent}'${key}': {
152
- `;
153
- interfaceContent += this.#generateDefinitionInterface(value, indent + " ");
154
- interfaceContent += `${indent}};
155
- `;
156
- } else {
157
- interfaceContent += `${indent}'${key}': ${value};
158
- `;
159
- }
160
- });
161
- return interfaceContent;
162
- }
163
- /**
164
- * Filter routes to generate based on the config
165
- */
166
- #filterRoutes(routes, mode) {
167
- const config = this.#config.codegen?.[mode];
168
- if (!config || !config.only && !config.except) return routes;
169
- return routes.filter((route) => {
170
- if (typeof config.only === "function") return config.only(route);
171
- if (typeof config.except === "function") return !config.except(route);
172
- if (config.only) {
173
- for (const pattern of config.only) {
174
- if (pattern instanceof RegExp && pattern.test(route.pattern)) return true;
175
- if (route.pattern === pattern) return true;
176
- }
177
- return false;
178
- }
179
- if (config.except) {
180
- for (const pattern of config.except) {
181
- if (pattern instanceof RegExp && pattern.test(route.pattern)) return false;
182
- if (route.pattern === pattern) return false;
183
- }
184
- return true;
185
- }
186
- return true;
187
- });
188
- }
189
- /**
190
- * Generate a type name based on the route pattern and methods
191
- *
192
- * GET /users/:id => UsersIdGet
193
- */
194
- #generateTypeName(route) {
195
- const remappedSegments = route.pattern.split("/").filter(Boolean).map((segment) => segment.startsWith(":") ? "id" : segment).join(" ");
196
- const methods = string.pascalCase(route.methods.join(" "));
197
- return string.pascalCase(remappedSegments) + methods;
198
- }
199
- #generateRoutesNameArray(routes, typesByPattern) {
200
- return routes.map(({ name, pattern, methods }) => {
201
- const params = matchit.parse(pattern).filter((node) => node.type !== 0).map((node) => node.val);
202
- let typeName = this.#generateTypeName({ pattern, methods });
203
- if (!typesByPattern[typeName]) typeName = "unknown";
204
- return { params, name, path: pattern, method: methods, types: typeName };
205
- }).filter((route) => !!route.name);
206
- }
207
- async #writeIndexFile() {
208
- const filePath = this.#getDestinationDirectory() + "/index.ts";
209
- const exist = existsSync(filePath);
210
- if (exist) {
211
- return;
212
- }
213
- const file = this.#project.createSourceFile(filePath, "", {
214
- overwrite: true
215
- });
216
- if (!file) throw new Error("Unable to create the index.ts file");
217
- file.removeText().insertText(0, (writer) => {
218
- writer.writeLine(`/// <reference path="../adonisrc.ts" />`);
219
- writer.newLine();
220
- writer.writeLine(`export * from './api.js'`);
221
- });
222
- await file.save();
223
- }
224
- /**
225
- * If @tuyau/superjson is installed then we must use a special
226
- * type that will not type-serialize the response
227
- */
228
- #getMakeTuyauResponseType() {
229
- const isSuperJsonInstalled = this.#isPackageInstalled("@tuyau/superjson");
230
- return isSuperJsonInstalled ? "MakeNonSerializedTuyauResponse" : "MakeTuyauResponse";
231
- }
232
- async #writeApiFile(options) {
233
- const file = this.#project.createSourceFile(this.#destination, "", { overwrite: true });
234
- if (!file) throw new Error("Unable to create the api.ts file");
235
- const isTuyauInertiaInstalled = this.#isPackageInstalled("@tuyau/inertia");
236
- const makeTuyauResponseType = this.#getMakeTuyauResponseType();
237
- file.removeText().insertText(0, (writer) => {
238
- writer.writeLine(`// @ts-nocheck`).writeLine(`/* eslint-disable */`).writeLine("// --------------------------------------------------").writeLine("// This file is auto-generated by Tuyau. Do not edit manually !").writeLine("// --------------------------------------------------").writeLine("").writeLine(
239
- `import type { MakeTuyauRequest, ${makeTuyauResponseType} } from '@tuyau/utils/types'`
240
- ).writeLine(`import type { InferInput } from '@vinejs/vine/types'`).newLine();
241
- Object.entries(options.typesByPattern).forEach(([key, value]) => {
242
- writer.writeLine(`type ${key} = {`);
243
- writer.writeLine(` request: ${value.request}`);
244
- writer.writeLine(` response: ${value.response}`);
245
- writer.writeLine(`}`);
246
- });
247
- writer.writeLine(`export interface ApiDefinition {`).write(this.#generateDefinitionInterface(options.definition, " ")).writeLine(`}`);
248
- writer.writeLine(`const routes = [`);
249
- for (const route of options.routesNameArray) {
250
- writer.writeLine(` {`);
251
- writer.writeLine(` params: ${JSON.stringify(route.params)},`);
252
- writer.writeLine(` name: '${route.name}',`);
253
- writer.writeLine(` path: '${route.path}',`);
254
- writer.writeLine(` method: ${JSON.stringify(route.method)},`);
255
- writer.writeLine(` types: {} as ${route.types},`);
256
- writer.writeLine(` },`);
257
- }
258
- writer.writeLine(`] as const;`);
259
- writer.writeLine(`export const api = {`).writeLine(` routes,`).writeLine(` definition: {} as ApiDefinition`).writeLine(`}`);
260
- if (isTuyauInertiaInstalled) {
261
- writer.writeLine(`declare module '@tuyau/inertia/types' {`);
262
- writer.writeLine(` type InertiaApi = typeof api`);
263
- writer.writeLine(` export interface Api extends InertiaApi {}`);
264
- writer.writeLine(`}`);
265
- }
266
- });
267
- await file.save();
268
- }
269
- async generate() {
270
- const definition = {};
271
- const typesByPattern = {};
272
- const sourcesFiles = this.#project.getSourceFiles();
273
- const routes = this.#filterRoutes(this.#routes, "definitions");
274
- await this.#loadPkgJson();
275
- for (const route of routes) {
276
- if (typeof route.handler === "function") continue;
277
- const routeHandler = await parseBindingReference(route.handler.reference);
278
- const file = sourcesFiles.find((sf) => {
279
- const filePath = sf.getFilePath();
280
- if (routeHandler.moduleNameOrPath.startsWith("./")) {
281
- return filePath.endsWith(
282
- routeHandler.moduleNameOrPath.replace("./", "").replace(".js", ".ts")
283
- );
284
- }
285
- return filePath.endsWith(`${routeHandler.moduleNameOrPath.replace("#", "")}.ts`);
286
- });
287
- if (!file) {
288
- this.#logger.warning(`Unable to find the controller file for ${route.pattern}`);
289
- continue;
290
- }
291
- this.#logger.info(`Generating types for ${route.pattern}`);
292
- const handlerData = this.#extractClassHandlerData(file, routeHandler);
293
- if (!handlerData) {
294
- this.#logger.warning(`Unable to find the controller method for ${route.pattern}`);
295
- continue;
296
- }
297
- const schemaImport = this.#extractRequest(handlerData);
298
- const methods = route.methods.map((method) => "$" + method.toLowerCase()).filter((method) => method !== "head");
299
- const segments = route.pattern.split("/").filter(Boolean);
300
- let currentLevel = definition;
301
- const relativePath = slash(relative(this.#getDestinationDirectory(), file.getFilePath()));
302
- segments.forEach((segment, i) => {
303
- if (!currentLevel[segment]) currentLevel[segment] = {};
304
- currentLevel = currentLevel[segment];
305
- if (i !== segments.length - 1) return;
306
- const typeName = this.#generateTypeName(route);
307
- const makeTuyauResponseType = this.#getMakeTuyauResponseType();
308
- typesByPattern[typeName] = {
309
- request: schemaImport ? `MakeTuyauRequest<${schemaImport}>` : "unknown",
310
- response: `${makeTuyauResponseType}<import('${relativePath}').default['${routeHandler.method}'], ${!!schemaImport}>`
311
- };
312
- currentLevel.$url = {};
313
- for (const method of methods) currentLevel[method] = typeName;
314
- });
315
- }
316
- const routesNameArray = this.#generateRoutesNameArray(
317
- this.#filterRoutes(routes, "routes"),
318
- typesByPattern
319
- );
320
- await this.#writeApiFile({ definition, typesByPattern, routesNameArray });
321
- await this.#writeIndexFile();
322
- }
323
- };
324
-
325
- // commands/generate.ts
326
- var CodegenTypes = class extends BaseCommand {
327
- static commandName = "tuyau:generate";
328
- static description = "Tuyau generator command";
329
- static options = { startApp: true };
330
- /**
331
- * Get routes from the router instance
332
- */
333
- async #getRoutes() {
334
- const router = await this.app.container.make("router");
335
- router.commit();
336
- return router.toJSON().root;
337
- }
338
- /**
339
- * Execute command
340
- */
341
- async run() {
342
- const project = new Project({
343
- manipulationSettings: { quoteKind: QuoteKind.Single },
344
- tsConfigFilePath: fileURLToPath2(new URL("./tsconfig.json", this.app.appRoot))
345
- });
346
- const apiTypesGenerator = new ApiTypesGenerator({
347
- project,
348
- logger: this.logger,
349
- appRoot: this.app.appRoot,
350
- routes: await this.#getRoutes(),
351
- config: this.app.config.get("tuyau")
352
- });
353
- await apiTypesGenerator.generate();
354
- this.logger.success("Types generated successfully");
355
- }
356
- };
357
- __decorateClass([
358
- flags.boolean({ description: "Verbose logs", default: false, alias: "v" })
359
- ], CodegenTypes.prototype, "verbose", 2);
360
- export {
361
- CodegenTypes as default
362
- };
@@ -1,20 +0,0 @@
1
- {{{
2
- exports({ to: app.configPath('tuyau.ts') })
3
- }}}
4
- import { defineConfig } from '@tuyau/core'
5
-
6
- const tuyauConfig = defineConfig({
7
- codegen: {
8
- /**
9
- * Filters the definitions and named routes to be generated
10
- */
11
- // definitions: {
12
- // only: [],
13
- // }
14
- // routes: {
15
- // only: [],
16
- // }
17
- }
18
- })
19
-
20
- export default tuyauConfig
package/build/index.d.ts DELETED
@@ -1,9 +0,0 @@
1
- import ConfigureCommand from '@adonisjs/core/commands/configure';
2
- import { TuyauConfig } from './src/types.js';
3
- import '@adonisjs/core/types/http';
4
-
5
- declare function configure(command: ConfigureCommand): Promise<void>;
6
-
7
- declare function defineConfig(options: TuyauConfig): TuyauConfig;
8
-
9
- export { configure, defineConfig };
package/build/index.js DELETED
@@ -1,30 +0,0 @@
1
- import "./chunk-ADS4GRIL.js";
2
-
3
- // stubs/main.ts
4
- import { getDirname } from "@adonisjs/core/helpers";
5
- var stubsRoot = getDirname(import.meta.url);
6
-
7
- // configure.ts
8
- async function configure(command) {
9
- const codemods = await command.createCodemods();
10
- await codemods.updateRcFile((rcFile) => {
11
- rcFile.addCommand("@tuyau/core/commands");
12
- rcFile.addProvider("@tuyau/core/tuyau_provider");
13
- });
14
- await codemods.installPackages([
15
- {
16
- isDevDependency: true,
17
- name: "@tuyau/utils"
18
- }
19
- ]);
20
- await codemods.makeUsingStub(stubsRoot, "config/tuyau.stub", {});
21
- }
22
-
23
- // src/define_config.ts
24
- function defineConfig(options) {
25
- return options;
26
- }
27
- export {
28
- configure,
29
- defineConfig
30
- };
@@ -1,190 +0,0 @@
1
- import { ApplicationService } from '@adonisjs/core/types';
2
-
3
- /**
4
- * Extending the HTTP response interface to include status and response
5
- * in the return type.
6
- *
7
- * This is ONLY type information and the properties will not be available
8
- * at runtime. This is needed to infer the correct response type
9
- */
10
- declare module '@adonisjs/core/http' {
11
- interface Response {
12
- continue(): {
13
- __status: 100;
14
- };
15
- switchingProtocols(etag?: boolean): {
16
- __status: 101;
17
- };
18
- ok<T>(body: T, etag?: boolean): {
19
- __response: T;
20
- __status: 200;
21
- };
22
- created<T>(body?: T, etag?: boolean): {
23
- __response: T;
24
- __status: 201;
25
- };
26
- accepted<T>(body: T, etag?: boolean): {
27
- __response: T;
28
- __status: 202;
29
- };
30
- nonAuthoritativeInformation<T>(body?: T, etag?: boolean): {
31
- __response: T;
32
- __status: 203;
33
- };
34
- noContent<T>(body?: T, etag?: boolean): {
35
- __response: T;
36
- __status: 204;
37
- };
38
- resetContent<T>(body?: T, etag?: boolean): {
39
- __response: T;
40
- __status: 205;
41
- };
42
- partialContent<T>(body: T, etag?: boolean): {
43
- __response: T;
44
- __status: 206;
45
- };
46
- multipleChoices<T>(body?: T, etag?: boolean): {
47
- __response: T;
48
- __status: 300;
49
- };
50
- movedPermanently<T>(body?: T, etag?: boolean): {
51
- __response: T;
52
- __status: 301;
53
- };
54
- movedTemporarily<T>(body?: T, etag?: boolean): {
55
- __response: T;
56
- __status: 302;
57
- };
58
- seeOther<T>(body?: T, etag?: boolean): {
59
- __response: T;
60
- __status: 303;
61
- };
62
- notModified<T>(body?: T, etag?: boolean): {
63
- __response: T;
64
- __status: 304;
65
- };
66
- useProxy<T>(body?: T, etag?: boolean): {
67
- __response: T;
68
- __status: 305;
69
- };
70
- temporaryRedirect<T>(body?: T, etag?: boolean): {
71
- __response: T;
72
- __status: 307;
73
- };
74
- badRequest<T>(body?: T, etag?: boolean): {
75
- __response: T;
76
- __status: 400;
77
- };
78
- unauthorized<T>(body?: T, etag?: boolean): {
79
- __response: T;
80
- __status: 401;
81
- };
82
- paymentRequired<T>(body?: T, etag?: boolean): {
83
- __response: T;
84
- __status: 402;
85
- };
86
- forbidden<T>(body?: T, etag?: boolean): {
87
- __response: T;
88
- __status: 403;
89
- };
90
- notFound<T>(body?: T, etag?: boolean): {
91
- __response: T;
92
- __status: 404;
93
- };
94
- methodNotAllowed<T>(body?: T, etag?: boolean): {
95
- __response: T;
96
- __status: 405;
97
- };
98
- notAcceptable<T>(body?: T, etag?: boolean): {
99
- __response: T;
100
- __status: 406;
101
- };
102
- proxyAuthenticationRequired<T>(body?: T, etag?: boolean): {
103
- __response: T;
104
- __status: 407;
105
- };
106
- requestTimeout<T>(body?: T, etag?: boolean): {
107
- __response: T;
108
- __status: 408;
109
- };
110
- conflict<T>(body?: T, etag?: boolean): {
111
- __response: T;
112
- __status: 409;
113
- };
114
- gone<T>(body?: T, etag?: boolean): {
115
- __response: T;
116
- __status: 410;
117
- };
118
- lengthRequired<T>(body?: T, etag?: boolean): {
119
- __response: T;
120
- __status: 411;
121
- };
122
- preconditionFailed<T>(body?: T, etag?: boolean): {
123
- __response: T;
124
- __status: 412;
125
- };
126
- requestEntityTooLarge<T>(body?: T, etag?: boolean): {
127
- __response: T;
128
- __status: 413;
129
- };
130
- requestUriTooLong<T>(body?: T, etag?: boolean): {
131
- __response: T;
132
- __status: 414;
133
- };
134
- unsupportedMediaType<T>(body?: T, etag?: boolean): {
135
- __response: T;
136
- __status: 415;
137
- };
138
- requestedRangeNotSatisfiable<T>(body?: T, etag?: boolean): {
139
- __response: T;
140
- __status: 416;
141
- };
142
- expectationFailed<T>(body?: T, etag?: boolean): {
143
- __response: T;
144
- __status: 417;
145
- };
146
- unprocessableEntity<T>(body?: T, etag?: boolean): {
147
- __response: T;
148
- __status: 422;
149
- };
150
- tooManyRequests<T>(body?: T, etag?: boolean): {
151
- __response: T;
152
- __status: 429;
153
- };
154
- internalServerError<T>(body?: T, etag?: boolean): {
155
- __response: T;
156
- __status: 500;
157
- };
158
- notImplemented<T>(body?: T, etag?: boolean): {
159
- __response: T;
160
- __status: 501;
161
- };
162
- badGateway<T>(body?: T, etag?: boolean): {
163
- __response: T;
164
- __status: 502;
165
- };
166
- serviceUnavailable<T>(body?: T, etag?: boolean): {
167
- __response: T;
168
- __status: 503;
169
- };
170
- gatewayTimeout<T>(body?: T, etag?: boolean): {
171
- __response: T;
172
- __status: 504;
173
- };
174
- httpVersionNotSupported<T>(body?: T, etag?: boolean): {
175
- __response: T;
176
- __status: 505;
177
- };
178
- json<T>(body: T, generateEtag?: boolean): {
179
- __response: T;
180
- __status: 200;
181
- };
182
- }
183
- }
184
- declare class TuyauProvider {
185
- protected app: ApplicationService;
186
- constructor(app: ApplicationService);
187
- register(): Promise<void>;
188
- }
189
-
190
- export { TuyauProvider as default };
@@ -1,13 +0,0 @@
1
- import "../chunk-ADS4GRIL.js";
2
-
3
- // providers/tuyau_provider.ts
4
- var TuyauProvider = class {
5
- constructor(app) {
6
- this.app = app;
7
- }
8
- async register() {
9
- }
10
- };
11
- export {
12
- TuyauProvider as default
13
- };
@@ -1,5 +0,0 @@
1
- import { AssemblerHookHandler } from '@adonisjs/core/types/app';
2
-
3
- declare function tuyauBuildHook({ logger }: Parameters<AssemblerHookHandler>[0]): Promise<void>;
4
-
5
- export { tuyauBuildHook as default };
@@ -1,14 +0,0 @@
1
- import "../../chunk-ADS4GRIL.js";
2
-
3
- // src/hooks/build_hook.ts
4
- import util from "util";
5
- import { exec as cpExec } from "child_process";
6
- var exec = util.promisify(cpExec);
7
- async function tuyauBuildHook({ logger }) {
8
- logger.info("generating tuyau codegen file", { suffix: "tuyau" });
9
- const { stderr } = await exec("node ace tuyau:generate");
10
- if (stderr) throw new Error(stderr);
11
- }
12
- export {
13
- tuyauBuildHook as default
14
- };
@@ -1,25 +0,0 @@
1
- import { RouteJSON } from '@adonisjs/core/types/http';
2
-
3
- type Without<T, U> = {
4
- [P in Exclude<keyof T, keyof U>]?: never;
5
- };
6
- type XOR<T, U> = T | U extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U;
7
- type FilterConfig<FilterType> = XOR<{
8
- only: FilterType;
9
- }, {
10
- except: FilterType;
11
- }>;
12
- interface TuyauConfig {
13
- codegen?: {
14
- /**
15
- * Filters the definitions to be generated
16
- */
17
- definitions?: FilterConfig<Array<string | RegExp> | ((route: RouteJSON) => boolean)>;
18
- /**
19
- * Filters the named routes to be generated
20
- */
21
- routes?: FilterConfig<Array<string | RegExp> | ((route: RouteJSON) => boolean)>;
22
- };
23
- }
24
-
25
- export type { FilterConfig, TuyauConfig };
File without changes