@adonisjs/assembler 8.0.0-next.27 → 8.0.0-next.29

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.
@@ -0,0 +1,137 @@
1
+ var CodemodException = class CodemodException extends Error {
2
+ instructions;
3
+ filePath;
4
+ constructor(message, options) {
5
+ super(message);
6
+ this.name = "CodemodException";
7
+ this.instructions = options?.instructions;
8
+ this.filePath = options?.filePath;
9
+ }
10
+ static #formatEnvValidations(definition) {
11
+ const lines = [];
12
+ if (definition.leadingComment) {
13
+ lines.push(`/*`);
14
+ lines.push(`|----------------------------------------------------------`);
15
+ lines.push(`| ${definition.leadingComment}`);
16
+ lines.push(`|----------------------------------------------------------`);
17
+ lines.push(`*/`);
18
+ }
19
+ for (const [variable, validation] of Object.entries(definition.variables)) lines.push(`${variable}: ${validation},`);
20
+ return lines.join("\n");
21
+ }
22
+ static #formatMiddleware(stack, middleware) {
23
+ if (stack === "named") return `export const middleware = router.named({\n ${middleware.filter((m) => m.name).map((m) => `${m.name}: () => import('${m.path}')`).join(",\n ")}\n})`;
24
+ return `${stack}.use([\n ${middleware.map((m) => `() => import('${m.path}')`).join(",\n ")}\n])`;
25
+ }
26
+ static #formatPolicies(policies) {
27
+ return `export const policies = {\n ${policies.map((p) => `${p.name}: () => import('${p.path}')`).join(",\n ")}\n}`;
28
+ }
29
+ static #formatVitePlugin(pluginCall, importDeclarations) {
30
+ return `${importDeclarations.map((decl) => decl.isNamed ? `import { ${decl.identifier} } from '${decl.module}'` : `import ${decl.identifier} from '${decl.module}'`).join("\n")}\n\nexport default defineConfig({\n plugins: [${pluginCall}]\n})`;
31
+ }
32
+ static #formatJapaPlugin(pluginCall, importDeclarations) {
33
+ return `${importDeclarations.map((decl) => decl.isNamed ? `import { ${decl.identifier} } from '${decl.module}'` : `import ${decl.identifier} from '${decl.module}'`).join("\n")}\n\nexport const plugins: Config['plugins'] = [\n ${pluginCall}\n]`;
34
+ }
35
+ static missingEnvFile(filePath, definition) {
36
+ const code = this.#formatEnvValidations(definition);
37
+ return new CodemodException(`Could not find source file at path: "${filePath}"`, {
38
+ filePath,
39
+ instructions: `Add the following code to "${filePath}":\n\n${code}`
40
+ });
41
+ }
42
+ static missingEnvCreate(filePath, definition) {
43
+ return new CodemodException(`Cannot find Env.create statement in the file.`, {
44
+ filePath,
45
+ instructions: `Add the following code inside Env.create() in "${filePath}":\n\n${this.#formatEnvValidations(definition)}`
46
+ });
47
+ }
48
+ static invalidEnvCreate(filePath, definition) {
49
+ return new CodemodException(`The second argument of Env.create is not an object literal.`, {
50
+ filePath,
51
+ instructions: `Add the following code inside Env.create() in "${filePath}":\n\n${this.#formatEnvValidations(definition)}`
52
+ });
53
+ }
54
+ static missingKernelFile(filePath, stack, middleware) {
55
+ const code = this.#formatMiddleware(stack, middleware);
56
+ return new CodemodException(`Could not find source file at path: "${filePath}"`, {
57
+ filePath,
58
+ instructions: `Add the following code to "${filePath}":\n\n${code}`
59
+ });
60
+ }
61
+ static missingMiddlewareStack(filePath, stack, middleware) {
62
+ const code = this.#formatMiddleware(stack, middleware);
63
+ return new CodemodException(`Cannot find ${stack === "named" ? "middleware variable" : `${stack}.use`} statement in the file.`, {
64
+ filePath,
65
+ instructions: `Add the following code to "${filePath}":\n\n${code}`
66
+ });
67
+ }
68
+ static invalidMiddlewareStack(filePath, stack, middleware, reason) {
69
+ return new CodemodException(reason, {
70
+ filePath,
71
+ instructions: `Add the following code to "${filePath}":\n\n${this.#formatMiddleware(stack, middleware)}`
72
+ });
73
+ }
74
+ static missingPoliciesFile(filePath, policies) {
75
+ const code = this.#formatPolicies(policies);
76
+ return new CodemodException(`Could not find source file at path: "${filePath}"`, {
77
+ filePath,
78
+ instructions: `Add the following code to "${filePath}":\n\n${code}`
79
+ });
80
+ }
81
+ static invalidPoliciesFile(filePath, policies, reason) {
82
+ return new CodemodException(reason, {
83
+ filePath,
84
+ instructions: `Add the following code to "${filePath}":\n\n${this.#formatPolicies(policies)}`
85
+ });
86
+ }
87
+ static missingViteConfig(filePath, pluginCall, importDeclarations) {
88
+ return new CodemodException(`Cannot find vite.config.ts file. Make sure to rename vite.config.js to vite.config.ts`, {
89
+ filePath,
90
+ instructions: `Add the following code to "${filePath}":\n\n${this.#formatVitePlugin(pluginCall, importDeclarations)}`
91
+ });
92
+ }
93
+ static invalidViteConfig(filePath, pluginCall, importDeclarations, reason) {
94
+ return new CodemodException(reason, {
95
+ filePath,
96
+ instructions: `Add the following code to "${filePath}":\n\n${this.#formatVitePlugin(pluginCall, importDeclarations)}`
97
+ });
98
+ }
99
+ static missingJapaBootstrap(filePath, pluginCall, importDeclarations) {
100
+ const code = this.#formatJapaPlugin(pluginCall, importDeclarations);
101
+ return new CodemodException(`Could not find source file at path: "${filePath}"`, {
102
+ filePath,
103
+ instructions: `Add the following code to "${filePath}":\n\n${code}`
104
+ });
105
+ }
106
+ static invalidJapaBootstrap(filePath, pluginCall, importDeclarations, reason) {
107
+ return new CodemodException(reason, {
108
+ filePath,
109
+ instructions: `Add the following code to "${filePath}":\n\n${this.#formatJapaPlugin(pluginCall, importDeclarations)}`
110
+ });
111
+ }
112
+ static missingRcFile(filePath, codeToAdd) {
113
+ return new CodemodException(`Could not find source file at path: "${filePath}"`, {
114
+ filePath,
115
+ instructions: `Add the following code to "${filePath}":\n\n${codeToAdd}`
116
+ });
117
+ }
118
+ static invalidRcFile(filePath, codeToAdd, reason) {
119
+ return new CodemodException(reason, {
120
+ filePath,
121
+ instructions: `Add the following code to "${filePath}":\n\n${codeToAdd}`
122
+ });
123
+ }
124
+ static E_CODEMOD_FILE_NOT_FOUND(filePath, codeToAdd) {
125
+ return new CodemodException(`Could not find source file at path: "${filePath}"`, {
126
+ filePath,
127
+ instructions: `Add the following code to "${filePath}":\n\n${codeToAdd}`
128
+ });
129
+ }
130
+ static E_CODEMOD_INVALID_STRUCTURE(message, filePath, codeToAdd) {
131
+ return new CodemodException(message, {
132
+ filePath,
133
+ instructions: `Add the following code to "${filePath}":\n\n${codeToAdd}`
134
+ });
135
+ }
136
+ };
137
+ export { CodemodException as t };
package/build/index.d.ts CHANGED
@@ -3,4 +3,5 @@ export { DevServer } from './src/dev_server.ts';
3
3
  export { TestRunner } from './src/test_runner.ts';
4
4
  export { FileBuffer } from './src/file_buffer.ts';
5
5
  export { VirtualFileSystem } from './src/virtual_file_system.ts';
6
+ export { CodemodException } from './src/exceptions/codemod_exception.ts';
6
7
  export { SUPPORTED_PACKAGE_MANAGERS } from './src/bundler.ts';
package/build/index.js CHANGED
@@ -2,6 +2,7 @@ import { a as loadHooks, c as readTsConfig, d as runNode, f as throttle, m as de
2
2
  import { n as FileBuffer, t as IndexGenerator } from "./main-XUXlmlEy.js";
3
3
  import { t as RoutesScanner } from "./main-BeV45LeF.js";
4
4
  import "./helpers-DDurYRsZ.js";
5
+ import { t as CodemodException } from "./codemod_exception-vyN1VXuX.js";
5
6
  import dedent from "dedent";
6
7
  import fs, { readFile, unlink } from "node:fs/promises";
7
8
  import { cliui } from "@poppinss/cliui";
@@ -934,4 +935,4 @@ var TestRunner = class {
934
935
  });
935
936
  }
936
937
  };
937
- export { Bundler, DevServer, FileBuffer, SUPPORTED_PACKAGE_MANAGERS, TestRunner, VirtualFileSystem };
938
+ export { Bundler, CodemodException, DevServer, FileBuffer, SUPPORTED_PACKAGE_MANAGERS, TestRunner, VirtualFileSystem };
@@ -39,6 +39,15 @@ export declare class CodeTransformer {
39
39
  * @param cwd - The current working directory URL
40
40
  */
41
41
  constructor(cwd: URL);
42
+ /**
43
+ * Get directories configured in adonisrc.ts, with defaults fallback.
44
+ *
45
+ * This method reads the adonisrc.ts file and extracts the directories
46
+ * configuration. If a directory is not configured, the default value is used.
47
+ *
48
+ * @returns Object containing directory paths
49
+ */
50
+ getDirectories(): Record<string, string>;
42
51
  /**
43
52
  * Add new env variable validation in the `env.ts` file
44
53
  *
@@ -1,3 +1,4 @@
1
+ import { t as CodemodException } from "../../codemod_exception-vyN1VXuX.js";
1
2
  import { fileURLToPath } from "node:url";
2
3
  import { detectPackageManager, installPackage } from "@antfu/install-pkg";
3
4
  import { join } from "node:path";
@@ -24,8 +25,15 @@ var RcFileTransformer = class {
24
25
  this.#project = project;
25
26
  }
26
27
  #getRcFileOrThrow() {
27
- const kernelUrl = fileURLToPath(new URL("./adonisrc.ts", this.#cwd));
28
- return this.#project.getSourceFileOrThrow(kernelUrl);
28
+ const filePath = "adonisrc.ts";
29
+ const rcFileUrl = fileURLToPath(new URL(`./${filePath}`, this.#cwd));
30
+ const file = this.#project.getSourceFile(rcFileUrl);
31
+ if (!file) throw CodemodException.missingRcFile(filePath, `import { defineConfig } from '@adonisjs/core/app'
32
+
33
+ export default defineConfig({
34
+ // Add your configuration here
35
+ })`);
36
+ return file;
29
37
  }
30
38
  #isInSpecificEnvironment(environments) {
31
39
  if (!environments) return false;
@@ -33,7 +41,11 @@ var RcFileTransformer = class {
33
41
  }
34
42
  #locateDefineConfigCallOrThrow(file) {
35
43
  const call = file.getDescendantsOfKind(SyntaxKind.CallExpression).find((statement) => statement.getExpression().getText() === "defineConfig");
36
- if (!call) throw new Error("Could not locate the defineConfig call.");
44
+ if (!call) throw CodemodException.invalidRcFile("adonisrc.ts", `import { defineConfig } from '@adonisjs/core/app'
45
+
46
+ export default defineConfig({
47
+ // Add your configuration here
48
+ })`, "Could not locate the defineConfig call.");
37
49
  return call;
38
50
  }
39
51
  #getDefineConfigObjectOrThrow(defineConfigCall) {
@@ -127,7 +139,7 @@ var RcFileTransformer = class {
127
139
  }`);
128
140
  return this;
129
141
  }
130
- addAssemblerHook(type, path) {
142
+ addAssemblerHook(type, value, raw = false) {
131
143
  const hooks = this.#getPropertyAssignmentInDefineConfigCall("hooks", "{}").getInitializerIfKindOrThrow(SyntaxKind.ObjectLiteralExpression);
132
144
  let hookArray = hooks.getProperty(type);
133
145
  if (!hookArray) {
@@ -138,10 +150,44 @@ var RcFileTransformer = class {
138
150
  hookArray = hooks.getProperty(type);
139
151
  }
140
152
  const hooksArray = hookArray.getInitializerIfKindOrThrow(SyntaxKind.ArrayLiteralExpression);
141
- if (this.#extractModulesFromArray(hooksArray).includes(path)) return this;
142
- hooksArray.addElement(`() => import('${path}')`);
153
+ if (raw) hooksArray.addElement(value);
154
+ else {
155
+ if (this.#extractModulesFromArray(hooksArray).includes(value)) return this;
156
+ hooksArray.addElement(`() => import('${value}')`);
157
+ }
158
+ return this;
159
+ }
160
+ addNamedImport(specifier, names) {
161
+ this.#getRcFileOrThrow().addImportDeclaration({
162
+ moduleSpecifier: specifier,
163
+ namedImports: names
164
+ });
143
165
  return this;
144
166
  }
167
+ addDefaultImport(specifier, name) {
168
+ this.#getRcFileOrThrow().addImportDeclaration({
169
+ moduleSpecifier: specifier,
170
+ defaultImport: name
171
+ });
172
+ return this;
173
+ }
174
+ getDirectory(key, defaultValue) {
175
+ try {
176
+ const file = this.#getRcFileOrThrow();
177
+ const defineConfigCall = this.#locateDefineConfigCallOrThrow(file);
178
+ const directoriesProperty = this.#getDefineConfigObjectOrThrow(defineConfigCall).getProperty("directories");
179
+ if (!directoriesProperty || !Node.isPropertyAssignment(directoriesProperty)) return defaultValue;
180
+ const directoriesObject = directoriesProperty.getInitializer();
181
+ if (!directoriesObject || !Node.isObjectLiteralExpression(directoriesObject)) return defaultValue;
182
+ const property = directoriesObject.getProperty(key);
183
+ if (!property || !Node.isPropertyAssignment(property)) return defaultValue;
184
+ const initializer = property.getInitializer();
185
+ if (!initializer || !Node.isStringLiteral(initializer)) return defaultValue;
186
+ return initializer.getLiteralValue();
187
+ } catch {
188
+ return defaultValue;
189
+ }
190
+ }
145
191
  save() {
146
192
  const file = this.#getRcFileOrThrow();
147
193
  file.formatText(this.#editorSettings);
@@ -170,6 +216,14 @@ var CodeTransformer = class {
170
216
  manipulationSettings: { quoteKind: QuoteKind.Single }
171
217
  });
172
218
  }
219
+ getDirectories() {
220
+ const rcFileTransformer = new RcFileTransformer(this.#cwd, this.project);
221
+ return {
222
+ start: rcFileTransformer.getDirectory("start", "start"),
223
+ tests: rcFileTransformer.getDirectory("tests", "tests"),
224
+ policies: rcFileTransformer.getDirectory("policies", "app/policies")
225
+ };
226
+ }
173
227
  #addToMiddlewareArray(file, target, middlewareEntry) {
174
228
  const callExpressions = file.getDescendantsOfKind(SyntaxKind.CallExpression).filter((statement) => statement.getExpression().getText() === target);
175
229
  if (!callExpressions.length) throw new Error(`Cannot find ${target} statement in the file.`);
@@ -217,12 +271,14 @@ var CodeTransformer = class {
217
271
  return writer.blankLine().writeLine("/*").writeLine(`|----------------------------------------------------------`).writeLine(`| ${comment}`).writeLine(`|----------------------------------------------------------`).writeLine(`*/`);
218
272
  }
219
273
  async defineEnvValidations(definition) {
220
- const kernelUrl = join(this.#cwdPath, "./start/env.ts");
221
- const file = this.project.getSourceFileOrThrow(kernelUrl);
274
+ const filePath = `${this.getDirectories().start}/env.ts`;
275
+ const envUrl = join(this.#cwdPath, `./${filePath}`);
276
+ const file = this.project.getSourceFile(envUrl);
277
+ if (!file) throw CodemodException.missingEnvFile(filePath, definition);
222
278
  const callExpressions = file.getDescendantsOfKind(SyntaxKind.CallExpression).filter((statement) => statement.getExpression().getText() === "Env.create");
223
- if (!callExpressions.length) throw new Error(`Cannot find Env.create statement in the file.`);
279
+ if (!callExpressions.length) throw CodemodException.missingEnvCreate(filePath, definition);
224
280
  const objectLiteralExpression = callExpressions[0].getArguments()[1];
225
- if (!Node.isObjectLiteralExpression(objectLiteralExpression)) throw new Error(`The second argument of Env.create is not an object literal.`);
281
+ if (!Node.isObjectLiteralExpression(objectLiteralExpression)) throw CodemodException.invalidEnvCreate(filePath, definition);
226
282
  let shouldAddComment = true;
227
283
  for (const [variable, validation] of Object.entries(definition.variables)) {
228
284
  const existingProperty = objectLiteralExpression.getProperty(variable);
@@ -241,10 +297,17 @@ var CodeTransformer = class {
241
297
  await file.save();
242
298
  }
243
299
  async addMiddlewareToStack(stack, middleware) {
244
- const kernelUrl = join(this.#cwdPath, "./start/kernel.ts");
245
- const file = this.project.getSourceFileOrThrow(kernelUrl);
246
- for (const middlewareEntry of middleware) if (stack === "named") this.#addToNamedMiddleware(file, middlewareEntry);
247
- else this.#addToMiddlewareArray(file, `${stack}.use`, middlewareEntry);
300
+ const filePath = `${this.getDirectories().start}/kernel.ts`;
301
+ const kernelUrl = join(this.#cwdPath, `./${filePath}`);
302
+ const file = this.project.getSourceFile(kernelUrl);
303
+ if (!file) throw CodemodException.missingKernelFile(filePath, stack, middleware);
304
+ try {
305
+ for (const middlewareEntry of middleware) if (stack === "named") this.#addToNamedMiddleware(file, middlewareEntry);
306
+ else this.#addToMiddlewareArray(file, `${stack}.use`, middlewareEntry);
307
+ } catch (error) {
308
+ if (error instanceof Error) throw CodemodException.invalidMiddlewareStack(filePath, stack, middleware, error.message);
309
+ throw error;
310
+ }
248
311
  file.formatText(this.#editorSettings);
249
312
  await file.save();
250
313
  }
@@ -254,8 +317,10 @@ var CodeTransformer = class {
254
317
  await rcFileTransformer.save();
255
318
  }
256
319
  async addJapaPlugin(pluginCall, importDeclarations) {
257
- const testBootstrapUrl = join(this.#cwdPath, "./tests/bootstrap.ts");
258
- const file = this.project.getSourceFileOrThrow(testBootstrapUrl);
320
+ const filePath = `${this.getDirectories().tests}/bootstrap.ts`;
321
+ const testBootstrapUrl = join(this.#cwdPath, `./${filePath}`);
322
+ const file = this.project.getSourceFile(testBootstrapUrl);
323
+ if (!file) throw CodemodException.missingJapaBootstrap(filePath, pluginCall, importDeclarations);
259
324
  this.#addImportDeclarations(file, importDeclarations);
260
325
  const pluginsArray = file.getVariableDeclaration("plugins")?.getInitializerIfKind(SyntaxKind.ArrayLiteralExpression);
261
326
  if (pluginsArray) {
@@ -265,22 +330,36 @@ var CodeTransformer = class {
265
330
  await file.save();
266
331
  }
267
332
  async addVitePlugin(pluginCall, importDeclarations) {
268
- const viteConfigTsUrl = join(this.#cwdPath, "./vite.config.ts");
333
+ const filePath = "vite.config.ts";
334
+ const viteConfigTsUrl = join(this.#cwdPath, `./${filePath}`);
269
335
  const file = this.project.getSourceFile(viteConfigTsUrl);
270
- if (!file) throw new Error("Cannot find vite.config.ts file. Make sure to rename vite.config.js to vite.config.ts");
271
- this.#addImportDeclarations(file, importDeclarations);
272
- const defaultExport = file.getDefaultExportSymbol();
273
- if (!defaultExport) throw new Error("Cannot find the default export in vite.config.ts");
274
- const declaration = defaultExport.getDeclarations()[0];
275
- const pluginsArray = (declaration.getChildrenOfKind(SyntaxKind.ObjectLiteralExpression)[0] || declaration.getChildrenOfKind(SyntaxKind.CallExpression)[0].getArguments()[0]).getPropertyOrThrow("plugins").getFirstChildByKindOrThrow(SyntaxKind.ArrayLiteralExpression);
276
- if (!pluginsArray.getElements().find((element) => element.getText() === pluginCall)) pluginsArray.addElement(pluginCall);
336
+ if (!file) throw CodemodException.missingViteConfig(filePath, pluginCall, importDeclarations);
337
+ try {
338
+ this.#addImportDeclarations(file, importDeclarations);
339
+ const defaultExport = file.getDefaultExportSymbol();
340
+ if (!defaultExport) throw new Error("Cannot find the default export in vite.config.ts");
341
+ const declaration = defaultExport.getDeclarations()[0];
342
+ const pluginsArray = (declaration.getChildrenOfKind(SyntaxKind.ObjectLiteralExpression)[0] || declaration.getChildrenOfKind(SyntaxKind.CallExpression)[0].getArguments()[0]).getPropertyOrThrow("plugins").getFirstChildByKindOrThrow(SyntaxKind.ArrayLiteralExpression);
343
+ if (!pluginsArray.getElements().find((element) => element.getText() === pluginCall)) pluginsArray.addElement(pluginCall);
344
+ } catch (error) {
345
+ if (error instanceof CodemodException) throw error;
346
+ if (error instanceof Error) throw CodemodException.invalidViteConfig(filePath, pluginCall, importDeclarations, error.message);
347
+ throw error;
348
+ }
277
349
  file.formatText(this.#editorSettings);
278
350
  await file.save();
279
351
  }
280
352
  async addPolicies(policies) {
281
- const kernelUrl = join(this.#cwdPath, "./app/policies/main.ts");
282
- const file = this.project.getSourceFileOrThrow(kernelUrl);
283
- for (const policy of policies) this.#addToPoliciesList(file, policy);
353
+ const filePath = `${this.getDirectories().policies}/main.ts`;
354
+ const policiesUrl = join(this.#cwdPath, `./${filePath}`);
355
+ const file = this.project.getSourceFile(policiesUrl);
356
+ if (!file) throw CodemodException.missingPoliciesFile(filePath, policies);
357
+ try {
358
+ for (const policy of policies) this.#addToPoliciesList(file, policy);
359
+ } catch (error) {
360
+ if (error instanceof Error) throw CodemodException.invalidPoliciesFile(filePath, policies, error.message);
361
+ throw error;
362
+ }
284
363
  file.formatText(this.#editorSettings);
285
364
  await file.save();
286
365
  }
@@ -82,12 +82,38 @@ export declare class RcFileTransformer {
82
82
  addSuite(suiteName: string, files: string | string[], timeout?: number): this;
83
83
  /**
84
84
  * Add a new assembler hook
85
+ * The format `thunk` write `() => import(path)`.
85
86
  *
86
87
  * @param type - The type of hook to add
87
- * @param path - The path to the hook file
88
+ * @param value - The path to the hook file or value to write
89
+ * @param raw - Wether to write a thunk import or as raw value
88
90
  * @returns This RcFileTransformer instance for method chaining
89
91
  */
90
- addAssemblerHook(type: keyof Exclude<AssemblerRcFile['hooks'], undefined>, path: string): this;
92
+ addAssemblerHook(type: keyof Exclude<AssemblerRcFile['hooks'], undefined>, value: string, raw?: boolean): this;
93
+ /**
94
+ * Add a named import
95
+ *
96
+ * @param specifier - The module specifier to import
97
+ * @param names - Names to import from the module
98
+ * @returns This RcFileTransformer instance for method chaining
99
+ */
100
+ addNamedImport(specifier: string, names: string[]): this;
101
+ /**
102
+ * Add a default import
103
+ *
104
+ * @param specifier - The module specifier to import
105
+ * @param name - Name of the default import
106
+ * @returns This RcFileTransformer instance for method chaining
107
+ */
108
+ addDefaultImport(specifier: string, name: string): this;
109
+ /**
110
+ * Get a directory value from the directories configuration.
111
+ *
112
+ * @param key - The directory key to retrieve
113
+ * @param defaultValue - The default value if not configured
114
+ * @returns The configured directory path or the default value
115
+ */
116
+ getDirectory(key: string, defaultValue: string): string;
91
117
  /**
92
118
  * Save the adonisrc.ts file with all applied transformations
93
119
  *
@@ -0,0 +1,178 @@
1
+ import type { MiddlewareNode, EnvValidationNode, BouncerPolicyNode } from '../types/code_transformer.ts';
2
+ /**
3
+ * Options for creating a CodemodException
4
+ */
5
+ export interface CodemodExceptionOptions {
6
+ /**
7
+ * Instructions for the user to manually perform the codemod action
8
+ */
9
+ instructions?: string;
10
+ /**
11
+ * The file path that was being modified
12
+ */
13
+ filePath?: string;
14
+ }
15
+ /**
16
+ * Custom exception for codemod errors that provides helpful instructions
17
+ * to the user when automatic code transformation fails.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * throw CodemodException.missingEnvFile('start/env.ts', {
22
+ * variables: { MY_VAR: 'Env.schema.string()' }
23
+ * })
24
+ * ```
25
+ */
26
+ export declare class CodemodException extends Error {
27
+ #private;
28
+ /**
29
+ * Instructions for the user to manually perform the codemod action
30
+ */
31
+ instructions?: string;
32
+ /**
33
+ * The file path that was being modified
34
+ */
35
+ filePath?: string;
36
+ constructor(message: string, options?: CodemodExceptionOptions);
37
+ /**
38
+ * Creates an exception when start/env.ts file is missing
39
+ *
40
+ * @param filePath - The path to the missing file
41
+ * @param definition - The environment validation definition that was being added
42
+ */
43
+ static missingEnvFile(filePath: string, definition: EnvValidationNode): CodemodException;
44
+ /**
45
+ * Creates an exception when Env.create is not found in the file
46
+ *
47
+ * @param filePath - The path to the file being modified
48
+ * @param definition - The environment validation definition that was being added
49
+ */
50
+ static missingEnvCreate(filePath: string, definition: EnvValidationNode): CodemodException;
51
+ /**
52
+ * Creates an exception when Env.create has invalid structure
53
+ *
54
+ * @param filePath - The path to the file being modified
55
+ * @param definition - The environment validation definition that was being added
56
+ */
57
+ static invalidEnvCreate(filePath: string, definition: EnvValidationNode): CodemodException;
58
+ /**
59
+ * Creates an exception when start/kernel.ts file is missing
60
+ *
61
+ * @param filePath - The path to the missing file
62
+ * @param stack - The middleware stack that was being modified
63
+ * @param middleware - The middleware entries that were being added
64
+ */
65
+ static missingKernelFile(filePath: string, stack: 'server' | 'router' | 'named', middleware: MiddlewareNode[]): CodemodException;
66
+ /**
67
+ * Creates an exception when server.use/router.use is not found
68
+ *
69
+ * @param filePath - The path to the file being modified
70
+ * @param stack - The middleware stack that was being modified
71
+ * @param middleware - The middleware entries that were being added
72
+ */
73
+ static missingMiddlewareStack(filePath: string, stack: 'server' | 'router' | 'named', middleware: MiddlewareNode[]): CodemodException;
74
+ /**
75
+ * Creates an exception when middleware array structure is invalid
76
+ *
77
+ * @param filePath - The path to the file being modified
78
+ * @param stack - The middleware stack that was being modified
79
+ * @param middleware - The middleware entries that were being added
80
+ * @param reason - The reason why the structure is invalid
81
+ */
82
+ static invalidMiddlewareStack(filePath: string, stack: 'server' | 'router' | 'named', middleware: MiddlewareNode[], reason: string): CodemodException;
83
+ /**
84
+ * Creates an exception when app/policies/main.ts file is missing
85
+ *
86
+ * @param filePath - The path to the missing file
87
+ * @param policies - The policies that were being added
88
+ */
89
+ static missingPoliciesFile(filePath: string, policies: BouncerPolicyNode[]): CodemodException;
90
+ /**
91
+ * Creates an exception when policies structure is invalid
92
+ *
93
+ * @param filePath - The path to the file being modified
94
+ * @param policies - The policies that were being added
95
+ * @param reason - The reason why the structure is invalid
96
+ */
97
+ static invalidPoliciesFile(filePath: string, policies: BouncerPolicyNode[], reason: string): CodemodException;
98
+ /**
99
+ * Creates an exception when vite.config.ts file is missing
100
+ *
101
+ * @param filePath - The path to the missing file
102
+ * @param pluginCall - The plugin call that was being added
103
+ * @param importDeclarations - The import declarations needed for the plugin
104
+ */
105
+ static missingViteConfig(filePath: string, pluginCall: string, importDeclarations: {
106
+ isNamed: boolean;
107
+ module: string;
108
+ identifier: string;
109
+ }[]): CodemodException;
110
+ /**
111
+ * Creates an exception when vite.config.ts structure is invalid
112
+ *
113
+ * @param filePath - The path to the file being modified
114
+ * @param pluginCall - The plugin call that was being added
115
+ * @param importDeclarations - The import declarations needed for the plugin
116
+ * @param reason - The reason why the structure is invalid
117
+ */
118
+ static invalidViteConfig(filePath: string, pluginCall: string, importDeclarations: {
119
+ isNamed: boolean;
120
+ module: string;
121
+ identifier: string;
122
+ }[], reason: string): CodemodException;
123
+ /**
124
+ * Creates an exception when tests/bootstrap.ts file is missing
125
+ *
126
+ * @param filePath - The path to the missing file
127
+ * @param pluginCall - The plugin call that was being added
128
+ * @param importDeclarations - The import declarations needed for the plugin
129
+ */
130
+ static missingJapaBootstrap(filePath: string, pluginCall: string, importDeclarations: {
131
+ isNamed: boolean;
132
+ module: string;
133
+ identifier: string;
134
+ }[]): CodemodException;
135
+ /**
136
+ * Creates an exception when tests/bootstrap.ts structure is invalid
137
+ *
138
+ * @param filePath - The path to the file being modified
139
+ * @param pluginCall - The plugin call that was being added
140
+ * @param importDeclarations - The import declarations needed for the plugin
141
+ * @param reason - The reason why the structure is invalid
142
+ */
143
+ static invalidJapaBootstrap(filePath: string, pluginCall: string, importDeclarations: {
144
+ isNamed: boolean;
145
+ module: string;
146
+ identifier: string;
147
+ }[], reason: string): CodemodException;
148
+ /**
149
+ * Creates an exception when adonisrc.ts file is missing
150
+ *
151
+ * @param filePath - The path to the missing file
152
+ * @param codeToAdd - The code that should be added manually
153
+ */
154
+ static missingRcFile(filePath: string, codeToAdd: string): CodemodException;
155
+ /**
156
+ * Creates an exception when adonisrc.ts structure is invalid
157
+ *
158
+ * @param filePath - The path to the file being modified
159
+ * @param codeToAdd - The code that should be added manually
160
+ * @param reason - The reason why the structure is invalid
161
+ */
162
+ static invalidRcFile(filePath: string, codeToAdd: string, reason: string): CodemodException;
163
+ /**
164
+ * Creates an exception when a file required for transformation is not found.
165
+ *
166
+ * @param filePath - The path to the missing file
167
+ * @param codeToAdd - The code that should be added manually
168
+ */
169
+ static E_CODEMOD_FILE_NOT_FOUND(filePath: string, codeToAdd: string): CodemodException;
170
+ /**
171
+ * Creates an exception when the file structure doesn't match expected patterns.
172
+ *
173
+ * @param message - Description of what structure was expected
174
+ * @param filePath - The path to the file being modified
175
+ * @param codeToAdd - The code that should be added manually
176
+ */
177
+ static E_CODEMOD_INVALID_STRUCTURE(message: string, filePath: string, codeToAdd: string): CodemodException;
178
+ }
@@ -90,6 +90,14 @@ export type EnvValidationNode = {
90
90
  */
91
91
  variables: Record<string, string>;
92
92
  };
93
+ export type HookNode = {
94
+ type: 'thunk';
95
+ path: string;
96
+ } | {
97
+ type: 'import';
98
+ path: string;
99
+ name?: string;
100
+ };
93
101
  /**
94
102
  * The supported package managers for installing packages and managing lockfiles.
95
103
  * Each package manager has specific lockfiles and install commands.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@adonisjs/assembler",
3
3
  "description": "Provides utilities to run AdonisJS development server and build project for production",
4
- "version": "8.0.0-next.27",
4
+ "version": "8.0.0-next.29",
5
5
  "engines": {
6
6
  "node": ">=24.0.0"
7
7
  },
@@ -37,7 +37,7 @@
37
37
  "quick:test": "cross-env NODE_DEBUG=adonisjs:assembler node --enable-source-maps --import=@poppinss/ts-exec bin/test.ts"
38
38
  },
39
39
  "devDependencies": {
40
- "@adonisjs/eslint-config": "^3.0.0-next.5",
40
+ "@adonisjs/eslint-config": "^3.0.0-next.9",
41
41
  "@adonisjs/prettier-config": "^1.4.5",
42
42
  "@adonisjs/tsconfig": "^2.0.0-next.3",
43
43
  "@japa/assert": "^4.2.0",
@@ -45,8 +45,8 @@
45
45
  "@japa/runner": "^5.0.0",
46
46
  "@japa/snapshot": "^2.0.10",
47
47
  "@poppinss/ts-exec": "^1.4.1",
48
- "@release-it/conventional-changelog": "^10.0.3",
49
- "@types/node": "^25.0.2",
48
+ "@release-it/conventional-changelog": "^10.0.4",
49
+ "@types/node": "^25.0.3",
50
50
  "@types/picomatch": "^4.0.2",
51
51
  "@types/pretty-hrtime": "^1.0.3",
52
52
  "c8": "^10.1.3",
@@ -54,22 +54,22 @@
54
54
  "del-cli": "^7.0.0",
55
55
  "eslint": "^9.39.2",
56
56
  "hot-hook": "^0.4.1-next.2",
57
- "p-event": "^7.0.1",
57
+ "p-event": "^7.0.2",
58
58
  "prettier": "^3.7.4",
59
- "release-it": "^19.1.0",
60
- "tsdown": "^0.17.4",
59
+ "release-it": "^19.2.2",
60
+ "tsdown": "^0.18.4",
61
61
  "typedoc": "^0.28.15",
62
62
  "typescript": "^5.9.3"
63
63
  },
64
64
  "dependencies": {
65
- "@adonisjs/env": "^7.0.0-next.2",
65
+ "@adonisjs/env": "^7.0.0-next.3",
66
66
  "@antfu/install-pkg": "^1.1.0",
67
- "@ast-grep/napi": "^0.40.1",
67
+ "@ast-grep/napi": "^0.40.3",
68
68
  "@poppinss/cliui": "^6.6.0",
69
69
  "@poppinss/hooks": "^7.3.0",
70
- "@poppinss/utils": "^7.0.0-next.3",
70
+ "@poppinss/utils": "^7.0.0-next.5",
71
71
  "chokidar": "^5.0.0",
72
- "dedent": "^1.7.0",
72
+ "dedent": "^1.7.1",
73
73
  "execa": "^9.6.1",
74
74
  "fast-glob": "^3.3.3",
75
75
  "fdir": "^6.5.0",