@adonisjs/assembler 8.0.0-next.9 → 8.0.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.
Files changed (35) hide show
  1. package/README.md +260 -0
  2. package/build/chunk-DF48asd8.js +9 -0
  3. package/build/codemod_exception-BMNJZ0i1.js +280 -0
  4. package/build/index.d.ts +1 -1
  5. package/build/index.js +1854 -1724
  6. package/build/main-Cpfvmdw6.js +562 -0
  7. package/build/main-INOi9swJ.js +471 -0
  8. package/build/src/bundler.d.ts +2 -0
  9. package/build/src/code_scanners/routes_scanner/main.d.ts +16 -2
  10. package/build/src/code_scanners/routes_scanner/main.js +4 -445
  11. package/build/src/code_transformer/main.d.ts +14 -1
  12. package/build/src/code_transformer/main.js +981 -622
  13. package/build/src/code_transformer/rc_file_transformer.d.ts +28 -2
  14. package/build/src/debug.d.ts +1 -1
  15. package/build/src/dev_server.d.ts +60 -12
  16. package/build/src/exceptions/codemod_exception.d.ts +178 -0
  17. package/build/src/file_buffer.d.ts +19 -0
  18. package/build/src/file_system.d.ts +3 -3
  19. package/build/src/helpers.js +205 -16
  20. package/build/src/index_generator/main.js +4 -7
  21. package/build/src/paths_resolver.d.ts +2 -1
  22. package/build/src/test_runner.d.ts +3 -2
  23. package/build/src/types/code_scanners.d.ts +29 -13
  24. package/build/src/types/code_transformer.d.ts +127 -0
  25. package/build/src/types/common.d.ts +98 -2
  26. package/build/src/types/hooks.d.ts +4 -1
  27. package/build/src/types/main.js +2 -0
  28. package/build/src/utils.d.ts +7 -3
  29. package/build/src/virtual_file_system.d.ts +1 -1
  30. package/build/virtual_file_system-dzfXNwEp.js +572 -0
  31. package/package.json +41 -39
  32. package/build/chunk-7XU453QB.js +0 -418
  33. package/build/chunk-PORDZS62.js +0 -391
  34. package/build/chunk-TIKQQRMX.js +0 -116
  35. package/build/src/hooks.d.ts +0 -224
@@ -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
  *
@@ -10,5 +10,5 @@
10
10
  * // NODE_DEBUG=adonisjs:assembler node ace serve
11
11
  * debug('Starting development server...')
12
12
  */
13
- declare const _default: import("util").DebugLogger;
13
+ declare const _default: import("node:util").DebugLogger;
14
14
  export default _default;
@@ -1,15 +1,16 @@
1
- import type tsStatic from 'typescript';
2
1
  import type { DevServerOptions } from './types/common.ts';
3
2
  /**
4
- * Exposes the API to start the development server in HMR, watch or static mode.
3
+ * Exposes the API to start the development server in HMR, watch or static mode
5
4
  *
6
5
  * In HMR mode, the DevServer will exec the "bin/server.ts" file and let hot-hook
7
6
  * manage the changes using hot module reloading.
8
7
  *
9
- * In watch mode, the DevServer will start an internal watcher and restarts the after
10
- * every file change. The files must be part of the TypeScript project (via tsconfig.json),
8
+ * In watch mode, the DevServer will start an internal watcher and restarts the server
9
+ * after every file change. The files must be part of the TypeScript project (via tsconfig.json),
11
10
  * or registered as metaFiles.
12
11
  *
12
+ * In static mode, the server runs without file watching or hot reloading.
13
+ *
13
14
  * @example
14
15
  * const devServer = new DevServer(cwd, { hmr: true, hooks: [] })
15
16
  * await devServer.start(ts)
@@ -24,6 +25,7 @@ export declare class DevServer {
24
25
  logger: import("@poppinss/cliui").Logger;
25
26
  table: (tableOptions?: Partial<import("@poppinss/cliui/types").TableOptions>) => import("@poppinss/cliui").Table;
26
27
  tasks: (tasksOptions?: Partial<import("@poppinss/cliui/types").TaskManagerOptions>) => import("@poppinss/cliui").TaskManager;
28
+ steps: () => import("@poppinss/cliui").Steps;
27
29
  icons: {
28
30
  tick: string;
29
31
  cross: string;
@@ -33,6 +35,7 @@ export declare class DevServer {
33
35
  info: string;
34
36
  warning: string;
35
37
  squareSmallFilled: string;
38
+ borderVertical: string;
36
39
  };
37
40
  sticker: () => import("@poppinss/cliui").Instructions;
38
41
  instructions: () => import("@poppinss/cliui").Instructions;
@@ -41,7 +44,12 @@ export declare class DevServer {
41
44
  useColors(colorsToUse: import("@poppinss/colors/types").Colors): void;
42
45
  };
43
46
  /**
44
- * The mode in which the DevServer is running.
47
+ * The mode in which the DevServer is running
48
+ *
49
+ * Returns the current operating mode of the development server:
50
+ * - 'hmr': Hot Module Reloading enabled
51
+ * - 'watch': File system watching with full restarts
52
+ * - 'static': No file watching or hot reloading
45
53
  */
46
54
  get mode(): "hmr" | "watch" | "static";
47
55
  /**
@@ -68,36 +76,76 @@ export declare class DevServer {
68
76
  */
69
77
  constructor(cwd: URL, options: DevServerOptions);
70
78
  /**
71
- * Add listener to get notified when dev server is closed
79
+ * Adds listener to get notified when dev server is closed
80
+ *
81
+ * Registers a callback function that will be invoked when the development
82
+ * server's child process exits. The callback receives the exit code.
72
83
  *
73
84
  * @param callback - Function to call when dev server closes
74
85
  * @returns This DevServer instance for method chaining
86
+ *
87
+ * @example
88
+ * devServer.onClose((exitCode) => {
89
+ * console.log(`Server closed with exit code: ${exitCode}`)
90
+ * })
75
91
  */
76
92
  onClose(callback: (exitCode: number) => any): this;
77
93
  /**
78
- * Add listener to get notified when dev server encounters an error
94
+ * Adds listener to get notified when dev server encounters an error
95
+ *
96
+ * Registers a callback function that will be invoked when the development
97
+ * server's child process encounters an error or fails to start.
79
98
  *
80
99
  * @param callback - Function to call when dev server encounters an error
81
100
  * @returns This DevServer instance for method chaining
101
+ *
102
+ * @example
103
+ * devServer.onError((error) => {
104
+ * console.error('Dev server error:', error.message)
105
+ * })
82
106
  */
83
107
  onError(callback: (error: any) => any): this;
84
108
  /**
85
- * Close watchers and the running child process
109
+ * Closes watchers and terminates the running child process
110
+ *
111
+ * Cleans up keyboard shortcuts, stops file system watchers, and kills
112
+ * the HTTP server child process. This should be called when shutting down
113
+ * the development server.
114
+ *
115
+ * @example
116
+ * await devServer.close()
86
117
  */
87
118
  close(): Promise<void>;
88
119
  /**
89
- * Start the development server in static or HMR mode
120
+ * Starts the development server in static or HMR mode
121
+ *
122
+ * Initializes the server and starts the HTTP server. The mode is determined
123
+ * by the `hmr` option in DevServerOptions. In HMR mode, hot-hook is configured
124
+ * to enable hot module reloading.
90
125
  *
91
126
  * @param ts - TypeScript module reference
127
+ *
128
+ * @example
129
+ * const devServer = new DevServer(cwd, { hmr: true, hooks: [] })
130
+ * await devServer.start(ts)
92
131
  */
93
- start(ts: typeof tsStatic): Promise<void>;
132
+ start(): Promise<void>;
94
133
  /**
95
- * Start the development server in watch mode and restart on file changes
134
+ * Starts the development server in watch mode and restarts on file changes
135
+ *
136
+ * Initializes the server, starts the HTTP server, and sets up a file system
137
+ * watcher that monitors for changes. When files are added, modified, or deleted,
138
+ * the server automatically restarts. The watcher respects TypeScript project
139
+ * configuration and metaFiles settings.
96
140
  *
97
141
  * @param ts - TypeScript module reference
98
142
  * @param options - Watch options including polling mode
143
+ *
144
+ * @example
145
+ * const devServer = new DevServer(cwd, { hooks: [] })
146
+ * await devServer.startAndWatch(ts, { poll: false })
99
147
  */
100
- startAndWatch(ts: typeof tsStatic, options?: {
148
+ startAndWatch(options?: {
101
149
  poll: boolean;
102
150
  }): Promise<void>;
103
151
  }
@@ -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
+ }
@@ -29,6 +29,17 @@ export declare class FileBuffer {
29
29
  * @returns The number of lines in the buffer
30
30
  */
31
31
  get size(): number;
32
+ /**
33
+ * Enable or disable end-of-line character at the end of output
34
+ *
35
+ * @param enabled - Whether to add EOL character
36
+ * @returns This FileBuffer instance for method chaining
37
+ *
38
+ * @example
39
+ * const buffer = new FileBuffer()
40
+ * buffer.eol(true).writeLine('Hello').flush() // 'Hello\n\n'
41
+ */
42
+ eol(enabled: boolean): this;
32
43
  /**
33
44
  * Write a new line to the output with current indentation
34
45
  *
@@ -55,6 +66,14 @@ export declare class FileBuffer {
55
66
  * @returns This FileBuffer instance for method chaining
56
67
  */
57
68
  dedent(): this;
69
+ /**
70
+ * Convert the buffer to a string representation
71
+ *
72
+ * @example
73
+ * const buffer = new FileBuffer()
74
+ * buffer.writeLine('Hello')
75
+ * console.log(buffer.toString())
76
+ */
58
77
  toString(): string;
59
78
  /**
60
79
  * Return template as a string, joining all buffer lines
@@ -1,4 +1,4 @@
1
- import type tsStatic from 'typescript';
1
+ import { type TsConfigResult } from 'get-tsconfig';
2
2
  import { type InspectedFile, type AssemblerRcFile } from './types/common.ts';
3
3
  /**
4
4
  * Exposes an intutive API to run actions when different kind of files
@@ -37,7 +37,7 @@ export declare class FileSystem {
37
37
  *
38
38
  * Following patterns are always ignored
39
39
  *
40
- * '.git/**', 'coverage/**', '.github/**'
40
+ * '.git/**', 'coverage/**', '.github/**', '.adonisjs/**', 'tmp/**', 'storage/**', 'build/**'
41
41
  */
42
42
  get excludes(): string[];
43
43
  /**
@@ -83,7 +83,7 @@ export declare class FileSystem {
83
83
  * @param tsConfig - Parsed TypeScript configuration
84
84
  * @param rcFile - AdonisJS RC file configuration
85
85
  */
86
- constructor(cwd: string, tsConfig: tsStatic.ParsedCommandLine, rcFile: AssemblerRcFile);
86
+ constructor(cwd: string, tsConfig: TsConfigResult, rcFile: AssemblerRcFile);
87
87
  /**
88
88
  * Returns true if the file should be watched. Chokidar sends
89
89
  * absolute unix paths to the ignored callback.
@@ -1,16 +1,205 @@
1
- import {
2
- findImport,
3
- inspectClass,
4
- inspectClassMethods,
5
- inspectMethodArguments,
6
- nodeToPlainText,
7
- searchValidatorDirectUsage
8
- } from "../chunk-TIKQQRMX.js";
9
- export {
10
- findImport,
11
- inspectClass,
12
- inspectClassMethods,
13
- inspectMethodArguments,
14
- nodeToPlainText,
15
- searchValidatorDirectUsage
16
- };
1
+ import "../chunk-DF48asd8.js";
2
+ import { parseImports } from "parse-imports";
3
+ //#region src/helpers.ts
4
+ /**
5
+ * Finds an import reference inside a code snippet by analyzing the import statements
6
+ * and matching against the provided import reference identifier.
7
+ *
8
+ * The function searches through all import statements in the code and matches
9
+ * against default, namespace, or named imports based on the import reference.
10
+ *
11
+ * @param code - The code snippet to search for imports
12
+ * @param importReference - The import reference identifier to find (can include dot notation)
13
+ * @returns Promise that resolves to an Import object or null if not found
14
+ *
15
+ * @example
16
+ * const importInfo = await findImport(code, 'validateUser')
17
+ * if (importInfo) {
18
+ * console.log(importInfo.specifier) // '@/validators/user'
19
+ * }
20
+ */
21
+ async function findImport(code, importReference) {
22
+ const importIdentifier = importReference.split(".")[0];
23
+ for (const $import of await parseImports(code, {})) {
24
+ /**
25
+ * An import without any clause
26
+ */
27
+ if (!$import.importClause) continue;
28
+ /**
29
+ * An import without any clause
30
+ */
31
+ if (!$import.moduleSpecifier.value) continue;
32
+ /**
33
+ * Import identifier matches a default import
34
+ */
35
+ if ($import.importClause.default === importIdentifier) return {
36
+ specifier: $import.moduleSpecifier.value,
37
+ isConstant: $import.moduleSpecifier.isConstant,
38
+ clause: {
39
+ type: "default",
40
+ value: importIdentifier
41
+ }
42
+ };
43
+ /**
44
+ * Import identifier matches a namespace import
45
+ */
46
+ if ($import.importClause.namespace === importIdentifier) return {
47
+ specifier: $import.moduleSpecifier.value,
48
+ isConstant: $import.moduleSpecifier.isConstant,
49
+ clause: {
50
+ type: "namespace",
51
+ value: importIdentifier
52
+ }
53
+ };
54
+ const namedImport = $import.importClause.named.find(({ binding }) => {
55
+ return binding === importIdentifier;
56
+ });
57
+ /**
58
+ * Import identifier matches a named import
59
+ */
60
+ if (namedImport) return {
61
+ specifier: $import.moduleSpecifier.value,
62
+ isConstant: $import.moduleSpecifier.isConstant,
63
+ clause: {
64
+ type: "named",
65
+ value: namedImport.specifier,
66
+ ...namedImport.binding !== namedImport.specifier ? { alias: namedImport.binding } : {}
67
+ }
68
+ };
69
+ }
70
+ return null;
71
+ }
72
+ /**
73
+ * Returns a node that represents a TypeScript class or null
74
+ * when unable to find the class.
75
+ *
76
+ * This function searches for class declarations within the provided AST node
77
+ * using ast-grep's pattern matching capabilities.
78
+ *
79
+ * @param node - The AST node to search within for class declarations
80
+ * @returns The SgNode representing the class or null if not found
81
+ *
82
+ * @example
83
+ * const classNode = inspectClass(rootNode)
84
+ * if (classNode) {
85
+ * console.log('Found class:', classNode.text())
86
+ * }
87
+ */
88
+ function inspectClass(node) {
89
+ return node.find({ rule: { kind: "class_declaration" } });
90
+ }
91
+ /**
92
+ * Returns an array of SgNodes for class methods. The input node
93
+ * must represent a class.
94
+ *
95
+ * This function finds all method definitions within a class node,
96
+ * including both regular methods and static methods.
97
+ *
98
+ * @param node - The AST node representing a class to search for methods
99
+ * @returns Array of SgNodes representing method definitions within the class
100
+ *
101
+ * @example
102
+ * const classNode = inspectClass(rootNode)
103
+ * if (classNode) {
104
+ * const methods = inspectClassMethods(classNode)
105
+ * methods.forEach(method => console.log('Method:', method.text()))
106
+ * }
107
+ */
108
+ function inspectClassMethods(node) {
109
+ return node.findAll({ rule: { kind: "method_definition" } });
110
+ }
111
+ /**
112
+ * Converts an SgNode to plain text by removing whitespaces,
113
+ * indentation and comments in between. Tested with the following
114
+ * children nodes only.
115
+ *
116
+ * - MemberExpression
117
+ * - Identifier
118
+ *
119
+ * This function recursively traverses the AST node and extracts only
120
+ * the meaningful text content without any formatting or whitespace.
121
+ *
122
+ * @param node - The AST node to convert to plain text
123
+ * @returns String representation of the node without formatting
124
+ *
125
+ * @example
126
+ * const memberExpression = node.find({ rule: { kind: 'member_expression' } })
127
+ * const plainText = nodeToPlainText(memberExpression)
128
+ * console.log(plainText) // 'user.validate'
129
+ */
130
+ function nodeToPlainText(node) {
131
+ let out = [];
132
+ function toText(one) {
133
+ const children = one.children();
134
+ if (!children.length) out.push(one.text());
135
+ else children.forEach((child) => toText(child));
136
+ }
137
+ toText(node);
138
+ return out.join("");
139
+ }
140
+ /**
141
+ * Inspects arguments for one or more method calls. If you want to
142
+ * scope the search within a specific context, then make sure to
143
+ * first narrow down the AST and pass a specific SgNode.
144
+ *
145
+ * For example: In case of validators, we will first find the Controller
146
+ * method for which we want the validation method calls.
147
+ *
148
+ * This function searches for call expressions that match the provided method
149
+ * names and returns their argument nodes for further analysis.
150
+ *
151
+ * @param node - The AST node to search within for method calls
152
+ * @param methodCalls - Array of method call names to search for (supports dot notation)
153
+ * @returns Array of SgNodes representing the arguments of matching method calls
154
+ *
155
+ * @example
156
+ * const controllerMethod = classNode.find({ rule: { kind: 'method_definition' } })
157
+ * const validatorArgs = inspectMethodArguments(controllerMethod, ['validate', 'request.validate'])
158
+ * validatorArgs.forEach(arg => console.log('Validator argument:', arg.text()))
159
+ */
160
+ function inspectMethodArguments(node, methodCalls) {
161
+ return node.findAll({ rule: { any: methodCalls.map((methodCall) => {
162
+ return { pattern: {
163
+ context: `${methodCall}($$$ARGUMENTS)`,
164
+ selector: "call_expression"
165
+ } };
166
+ }) } }).flatMap((matchingExpression) => {
167
+ return matchingExpression.findAll({ rule: { kind: "arguments" } });
168
+ });
169
+ }
170
+ /**
171
+ * Inspect the validator direct usage code snippets. A member expression
172
+ * calling the ".validate" method is considered as direct usage of
173
+ * the validator.
174
+ *
175
+ * This function specifically looks for patterns where validators are called
176
+ * directly with the `.validate()` method, which is common in AdonisJS applications.
177
+ *
178
+ * @param node - The AST node to search within for validator direct usage
179
+ * @returns Array of SgNodes representing validator expressions that call validate method
180
+ *
181
+ * @example
182
+ * const methodNode = classNode.find({ rule: { kind: 'method_definition' } })
183
+ * const validators = searchValidatorDirectUsage(methodNode)
184
+ * validators.forEach(validator => {
185
+ * console.log('Direct validator usage:', nodeToPlainText(validator))
186
+ * })
187
+ */
188
+ function searchValidatorDirectUsage(node) {
189
+ return node.findAll({ rule: { pattern: {
190
+ context: "$$$VALIDATOR.validate($$$)",
191
+ selector: "call_expression"
192
+ } } }).flatMap((expression) => {
193
+ /**
194
+ * Since we capture all "$$$.validate" calls, the first node
195
+ * within the call expression will be a member expression
196
+ * and its property identifier will be "validate".
197
+ *
198
+ * What we need is the text of this member expression without the
199
+ * comments
200
+ */
201
+ return expression.getMultipleMatches("VALIDATOR");
202
+ });
203
+ }
204
+ //#endregion
205
+ export { findImport, inspectClass, inspectClassMethods, inspectMethodArguments, nodeToPlainText, searchValidatorDirectUsage };
@@ -1,7 +1,4 @@
1
- import {
2
- IndexGenerator
3
- } from "../../chunk-7XU453QB.js";
4
- import "../../chunk-PORDZS62.js";
5
- export {
6
- IndexGenerator
7
- };
1
+ import "../../chunk-DF48asd8.js";
2
+ import "../../virtual_file_system-dzfXNwEp.js";
3
+ import { t as IndexGenerator } from "../../main-INOi9swJ.js";
4
+ export { IndexGenerator };
@@ -13,6 +13,7 @@
13
13
  */
14
14
  export declare class PathsResolver {
15
15
  #private;
16
+ constructor(appRoot: string);
16
17
  /**
17
18
  * Define a custom resolver that resolves a path
18
19
  *
@@ -36,5 +37,5 @@ export declare class PathsResolver {
36
37
  * const path = resolver.resolve('#app/models/user')
37
38
  * const path2 = resolver.resolve('@/utils/helper')
38
39
  */
39
- resolve(specifier: string): string;
40
+ resolve(specifier: string, rewriteAliasImportExtension?: boolean): string;
40
41
  }