@adonisjs/assembler 6.1.3-23 → 6.1.3-25

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,213 +1,397 @@
1
- /*
2
- * @adonisjs/assembler
3
- *
4
- * (c) AdonisJS
5
- *
6
- * For the full copyright and license information, please view the LICENSE
7
- * file that was distributed with this source code.
8
- */
9
- import { join } from 'node:path';
10
- import { fileURLToPath } from 'node:url';
11
- import { Node, Project, SyntaxKind } from 'ts-morph';
12
- import { RcFileTransformer } from './rc_file_transformer.js';
13
- /**
14
- * This class is responsible for updating
15
- */
16
- export class CodeTransformer {
17
- /**
18
- * Directory of the adonisjs project
19
- */
20
- #cwd;
21
- /**
22
- * The TsMorph project
23
- */
24
- #project;
25
- /**
26
- * Settings to use when persisting files
27
- */
28
- #editorSettings = {
29
- indentSize: 2,
30
- convertTabsToSpaces: true,
31
- trimTrailingWhitespace: true,
32
- };
33
- constructor(cwd) {
34
- this.#cwd = cwd;
35
- this.#project = new Project({
36
- tsConfigFilePath: join(fileURLToPath(this.#cwd), 'tsconfig.json'),
37
- });
1
+ // src/code_transformer/main.ts
2
+ import { join } from "node:path";
3
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
4
+ import { Node as Node2, Project as Project2, SyntaxKind as SyntaxKind2 } from "ts-morph";
5
+
6
+ // src/code_transformer/rc_file_transformer.ts
7
+ import { fileURLToPath } from "node:url";
8
+ import {
9
+ Node,
10
+ SyntaxKind
11
+ } from "ts-morph";
12
+ var RcFileTransformer = class {
13
+ #cwd;
14
+ #project;
15
+ /**
16
+ * Settings to use when persisting files
17
+ */
18
+ #editorSettings = {
19
+ indentSize: 2,
20
+ convertTabsToSpaces: true,
21
+ trimTrailingWhitespace: true
22
+ };
23
+ constructor(cwd, project) {
24
+ this.#cwd = cwd;
25
+ this.#project = project;
26
+ }
27
+ /**
28
+ * Get the `adonisrc.ts` source file
29
+ */
30
+ #getRcFileOrThrow() {
31
+ const kernelUrl = fileURLToPath(new URL("./adonisrc.ts", this.#cwd));
32
+ return this.#project.getSourceFileOrThrow(kernelUrl);
33
+ }
34
+ /**
35
+ * Check if environments array has a subset of available environments
36
+ */
37
+ #isInSpecificEnvironment(environments) {
38
+ if (!environments)
39
+ return false;
40
+ return !!["web", "console", "test", "repl"].find(
41
+ (env) => !environments.includes(env)
42
+ );
43
+ }
44
+ /**
45
+ * Locate the `defineConfig` call inside the `adonisrc.ts` file
46
+ */
47
+ #locateDefineConfigCallOrThrow(file) {
48
+ const call = file.getDescendantsOfKind(SyntaxKind.CallExpression).find((statement) => statement.getExpression().getText() === "defineConfig");
49
+ if (!call) {
50
+ throw new Error("Could not locate the defineConfig call.");
38
51
  }
39
- /**
40
- * Update the `adonisrc.ts` file
41
- */
42
- async updateRcFile(callback) {
43
- const rcFileTransformer = new RcFileTransformer(this.#cwd, this.#project);
44
- callback(rcFileTransformer);
45
- await rcFileTransformer.save();
46
- }
47
- /**
48
- * Add a new middleware to the middleware array of the
49
- * given file
50
- */
51
- #addToMiddlewareArray(file, target, middlewareEntry) {
52
- const callExpressions = file
53
- .getDescendantsOfKind(SyntaxKind.CallExpression)
54
- .filter((statement) => statement.getExpression().getText() === target);
55
- if (!callExpressions.length) {
56
- throw new Error(`Cannot find ${target} statement in the file.`);
57
- }
58
- const arrayLiteralExpression = callExpressions[0].getArguments()[0];
59
- if (!arrayLiteralExpression || !Node.isArrayLiteralExpression(arrayLiteralExpression)) {
60
- throw new Error(`Cannot find middleware array in ${target} statement.`);
61
- }
62
- const middleware = `() => import('${middlewareEntry.path}')`;
63
- /**
64
- * Delete the existing middleware if it exists
65
- */
66
- const existingMiddlewareIndex = arrayLiteralExpression
67
- .getElements()
68
- .findIndex((element) => element.getText() === middleware);
69
- if (existingMiddlewareIndex === -1) {
70
- /**
71
- * Add the middleware to the top or bottom of the array
72
- */
73
- if (middlewareEntry.position === 'before') {
74
- arrayLiteralExpression.insertElement(0, middleware);
75
- }
76
- else {
77
- arrayLiteralExpression.addElement(middleware);
78
- }
79
- }
80
- }
81
- /**
82
- * Add a new middleware to the named middleware of the given file
83
- */
84
- #addToNamedMiddleware(file, middlewareEntry) {
85
- if (!middlewareEntry.name) {
86
- throw new Error('Named middleware requires a name.');
87
- }
88
- const callArguments = file
89
- .getVariableDeclarationOrThrow('middleware')
90
- .getInitializerIfKindOrThrow(SyntaxKind.CallExpression)
91
- .getArguments();
92
- if (callArguments.length === 0) {
93
- throw new Error('Named middleware call has no arguments.');
94
- }
95
- const namedMiddlewareObject = callArguments[0];
96
- if (!Node.isObjectLiteralExpression(namedMiddlewareObject)) {
97
- throw new Error('The argument of the named middleware call is not an object literal.');
98
- }
99
- /**
100
- * Check if property is already defined. If so, remove it
101
- */
102
- const existingProperty = namedMiddlewareObject.getProperty(middlewareEntry.name);
103
- if (!existingProperty) {
104
- /**
105
- * Add the named middleware
106
- */
107
- const middleware = `${middlewareEntry.name}: () => import('${middlewareEntry.path}')`;
108
- namedMiddlewareObject.insertProperty(0, middleware);
109
- }
110
- }
111
- /**
112
- * Write a leading comment
113
- */
114
- #addLeadingComment(writer, comment) {
115
- if (!comment) {
116
- return writer.blankLine();
117
- }
118
- return writer
119
- .blankLine()
120
- .writeLine('/*')
121
- .writeLine(`|----------------------------------------------------------`)
122
- .writeLine(`| ${comment}`)
123
- .writeLine(`|----------------------------------------------------------`)
124
- .writeLine(`*/`);
125
- }
126
- /**
127
- * Define new middlewares inside the `start/kernel.ts`
128
- * file
129
- *
130
- * This function is highly based on some assumptions
131
- * and will not work if you significantly tweaked
132
- * your `start/kernel.ts` file.
133
- */
134
- async addMiddlewareToStack(stack, middleware) {
135
- /**
136
- * Get the `start/kernel.ts` source file
137
- */
138
- const kernelUrl = fileURLToPath(new URL('./start/kernel.ts', this.#cwd));
139
- const file = this.#project.getSourceFileOrThrow(kernelUrl);
140
- /**
141
- * Process each middleware entry
142
- */
143
- for (const middlewareEntry of middleware) {
144
- if (stack === 'named') {
145
- this.#addToNamedMiddleware(file, middlewareEntry);
146
- }
147
- else {
148
- this.#addToMiddlewareArray(file, `${stack}.use`, middlewareEntry);
149
- }
150
- }
151
- file.formatText(this.#editorSettings);
152
- await file.save();
153
- }
154
- /**
155
- * Add new env variable validation in the
156
- * `env.ts` file
157
- */
158
- async defineEnvValidations(definition) {
159
- /**
160
- * Get the `start/env.ts` source file
161
- */
162
- const kernelUrl = fileURLToPath(new URL('./start/env.ts', this.#cwd));
163
- const file = this.#project.getSourceFileOrThrow(kernelUrl);
164
- /**
165
- * Get the `Env.create` call expression
166
- */
167
- const callExpressions = file
168
- .getDescendantsOfKind(SyntaxKind.CallExpression)
169
- .filter((statement) => statement.getExpression().getText() === 'Env.create');
170
- if (!callExpressions.length) {
171
- throw new Error(`Cannot find Env.create statement in the file.`);
172
- }
173
- const objectLiteralExpression = callExpressions[0].getArguments()[1];
174
- if (!Node.isObjectLiteralExpression(objectLiteralExpression)) {
175
- throw new Error(`The second argument of Env.create is not an object literal.`);
176
- }
177
- let shouldAddComment = true;
178
- /**
179
- * Add each variable validation
180
- */
181
- for (const [variable, validation] of Object.entries(definition.variables)) {
182
- /**
183
- * Check if the variable is already defined. If so, remove it
184
- */
185
- const existingProperty = objectLiteralExpression.getProperty(variable);
186
- /**
187
- * Do not add leading comment if one or more properties
188
- * already exists
189
- */
190
- if (existingProperty) {
191
- shouldAddComment = false;
192
- }
193
- /**
194
- * Add property only when the property does not exist
195
- */
196
- if (!existingProperty) {
197
- objectLiteralExpression.addPropertyAssignment({
198
- name: variable,
199
- initializer: validation,
200
- leadingTrivia: (writer) => {
201
- if (!shouldAddComment) {
202
- return;
203
- }
204
- shouldAddComment = false;
205
- return this.#addLeadingComment(writer, definition.leadingComment);
206
- },
207
- });
52
+ return call;
53
+ }
54
+ /**
55
+ * Return the ObjectLiteralExpression of the defineConfig call
56
+ */
57
+ #getDefineConfigObjectOrThrow(defineConfigCall) {
58
+ const configObject = defineConfigCall.getArguments()[0].asKindOrThrow(SyntaxKind.ObjectLiteralExpression);
59
+ return configObject;
60
+ }
61
+ /**
62
+ * Check if the defineConfig() call has the property assignment
63
+ * inside it or not. If not, it will create one and return it.
64
+ */
65
+ #getPropertyAssignmentInDefineConfigCall(propertyName, initializer) {
66
+ const file = this.#getRcFileOrThrow();
67
+ const defineConfigCall = this.#locateDefineConfigCallOrThrow(file);
68
+ const configObject = this.#getDefineConfigObjectOrThrow(defineConfigCall);
69
+ let property = configObject.getProperty(propertyName);
70
+ if (!property) {
71
+ configObject.addPropertyAssignment({ name: propertyName, initializer });
72
+ property = configObject.getProperty(propertyName);
73
+ }
74
+ return property;
75
+ }
76
+ /**
77
+ * Extract list of imported modules from an ArrayLiteralExpression
78
+ *
79
+ * It assumes that the array can have two types of elements:
80
+ *
81
+ * - Simple lazy imported modules: [() => import('path/to/file')]
82
+ * - Or an object entry: [{ file: () => import('path/to/file'), environment: ['web', 'console'] }]
83
+ * where the `file` property is a lazy imported module.
84
+ */
85
+ #extractModulesFromArray(array) {
86
+ const modules = array.getElements().map((element) => {
87
+ if (Node.isArrowFunction(element)) {
88
+ const importExp = element.getFirstDescendantByKindOrThrow(SyntaxKind.CallExpression);
89
+ const literal = importExp.getFirstDescendantByKindOrThrow(SyntaxKind.StringLiteral);
90
+ return literal.getLiteralValue();
91
+ }
92
+ if (Node.isObjectLiteralExpression(element)) {
93
+ const fileProp = element.getPropertyOrThrow("file");
94
+ const arrowFn = fileProp.getFirstDescendantByKindOrThrow(SyntaxKind.ArrowFunction);
95
+ const importExp = arrowFn.getFirstDescendantByKindOrThrow(SyntaxKind.CallExpression);
96
+ const literal = importExp.getFirstDescendantByKindOrThrow(SyntaxKind.StringLiteral);
97
+ return literal.getLiteralValue();
98
+ }
99
+ });
100
+ return modules.filter(Boolean);
101
+ }
102
+ /**
103
+ * Extract a specific property from an ArrayLiteralExpression
104
+ * that contains object entries.
105
+ *
106
+ * This function is mainly used for extractring the `pattern` property
107
+ * when adding a new meta files entry, or the `name` property when
108
+ * adding a new test suite.
109
+ */
110
+ #extractPropertyFromArray(array, propertyName) {
111
+ const property = array.getElements().map((el) => {
112
+ if (!Node.isObjectLiteralExpression(el))
113
+ return;
114
+ const nameProp = el.getPropertyOrThrow(propertyName);
115
+ if (!Node.isPropertyAssignment(nameProp))
116
+ return;
117
+ const name = nameProp.getInitializerIfKindOrThrow(SyntaxKind.StringLiteral);
118
+ return name.getLiteralValue();
119
+ });
120
+ return property.filter(Boolean);
121
+ }
122
+ /**
123
+ * Build a new module entry for the preloads and providers array
124
+ * based upon the environments specified
125
+ */
126
+ #buildNewModuleEntry(modulePath, environments) {
127
+ if (!this.#isInSpecificEnvironment(environments)) {
128
+ return `() => import('${modulePath}')`;
129
+ }
130
+ return `{
131
+ file: () => import('${modulePath}'),
132
+ environment: [${environments?.map((env) => `'${env}'`).join(", ")}],
133
+ }`;
134
+ }
135
+ /**
136
+ * Add a new command to the rcFile
137
+ */
138
+ addCommand(commandPath) {
139
+ const commandsProperty = this.#getPropertyAssignmentInDefineConfigCall("commands", "[]");
140
+ const commandsArray = commandsProperty.getInitializerIfKindOrThrow(
141
+ SyntaxKind.ArrayLiteralExpression
142
+ );
143
+ const commandString = `() => import('${commandPath}')`;
144
+ if (commandsArray.getElements().some((el) => el.getText() === commandString)) {
145
+ return this;
146
+ }
147
+ commandsArray.addElement(commandString);
148
+ return this;
149
+ }
150
+ /**
151
+ * Add a new preloaded file to the rcFile
152
+ */
153
+ addPreloadFile(modulePath, environments) {
154
+ const preloadsProperty = this.#getPropertyAssignmentInDefineConfigCall("preloads", "[]");
155
+ const preloadsArray = preloadsProperty.getInitializerIfKindOrThrow(
156
+ SyntaxKind.ArrayLiteralExpression
157
+ );
158
+ const existingPreloadedFiles = this.#extractModulesFromArray(preloadsArray);
159
+ const isDuplicate = existingPreloadedFiles.includes(modulePath);
160
+ if (isDuplicate) {
161
+ return this;
162
+ }
163
+ preloadsArray.addElement(this.#buildNewModuleEntry(modulePath, environments));
164
+ return this;
165
+ }
166
+ /**
167
+ * Add a new provider to the rcFile
168
+ */
169
+ addProvider(providerPath, environments) {
170
+ const property = this.#getPropertyAssignmentInDefineConfigCall("providers", "[]");
171
+ const providersArray = property.getInitializerIfKindOrThrow(SyntaxKind.ArrayLiteralExpression);
172
+ const existingProviderPaths = this.#extractModulesFromArray(providersArray);
173
+ const isDuplicate = existingProviderPaths.includes(providerPath);
174
+ if (isDuplicate) {
175
+ return this;
176
+ }
177
+ providersArray.addElement(this.#buildNewModuleEntry(providerPath, environments));
178
+ return this;
179
+ }
180
+ /**
181
+ * Add a new meta file to the rcFile
182
+ */
183
+ addMetaFile(globPattern, reloadServer = false) {
184
+ const property = this.#getPropertyAssignmentInDefineConfigCall("metaFiles", "[]");
185
+ const metaFilesArray = property.getInitializerIfKindOrThrow(SyntaxKind.ArrayLiteralExpression);
186
+ const alreadyDefinedPatterns = this.#extractPropertyFromArray(metaFilesArray, "pattern");
187
+ if (alreadyDefinedPatterns.includes(globPattern)) {
188
+ return this;
189
+ }
190
+ metaFilesArray.addElement(
191
+ `{
192
+ pattern: '${globPattern}',
193
+ reloadServer: ${reloadServer},
194
+ }`
195
+ );
196
+ return this;
197
+ }
198
+ /**
199
+ * Set directory name and path
200
+ */
201
+ setDirectory(key, value) {
202
+ const property = this.#getPropertyAssignmentInDefineConfigCall("directories", "{}");
203
+ const directories = property.getInitializerIfKindOrThrow(SyntaxKind.ObjectLiteralExpression);
204
+ directories.addPropertyAssignment({ name: key, initializer: `'${value}'` });
205
+ return this;
206
+ }
207
+ /**
208
+ * Set command alias
209
+ */
210
+ setCommandAlias(alias, command) {
211
+ const aliasProperty = this.#getPropertyAssignmentInDefineConfigCall("commandsAliases", "{}");
212
+ const aliases = aliasProperty.getInitializerIfKindOrThrow(SyntaxKind.ObjectLiteralExpression);
213
+ aliases.addPropertyAssignment({ name: alias, initializer: `'${command}'` });
214
+ return this;
215
+ }
216
+ /**
217
+ * Add a new test suite to the rcFile
218
+ */
219
+ addSuite(suiteName, files, timeout) {
220
+ const testProperty = this.#getPropertyAssignmentInDefineConfigCall(
221
+ "tests",
222
+ `{ suites: [], forceExit: true, timeout: 2000 }`
223
+ );
224
+ const property = testProperty.getInitializerIfKindOrThrow(SyntaxKind.ObjectLiteralExpression).getPropertyOrThrow("suites");
225
+ const suitesArray = property.getInitializerIfKindOrThrow(SyntaxKind.ArrayLiteralExpression);
226
+ const existingSuitesNames = this.#extractPropertyFromArray(suitesArray, "name");
227
+ if (existingSuitesNames.includes(suiteName)) {
228
+ return this;
229
+ }
230
+ const filesArray = Array.isArray(files) ? files : [files];
231
+ suitesArray.addElement(
232
+ `{
233
+ name: '${suiteName}',
234
+ files: [${filesArray.map((file) => `'${file}'`).join(", ")}],
235
+ timeout: ${timeout ?? 2e3},
236
+ }`
237
+ );
238
+ return this;
239
+ }
240
+ /**
241
+ * Save the adonisrc.ts file
242
+ */
243
+ save() {
244
+ const file = this.#getRcFileOrThrow();
245
+ file.formatText(this.#editorSettings);
246
+ return file.save();
247
+ }
248
+ };
249
+
250
+ // src/code_transformer/main.ts
251
+ var CodeTransformer = class {
252
+ /**
253
+ * Directory of the adonisjs project
254
+ */
255
+ #cwd;
256
+ /**
257
+ * The TsMorph project
258
+ */
259
+ #project;
260
+ /**
261
+ * Settings to use when persisting files
262
+ */
263
+ #editorSettings = {
264
+ indentSize: 2,
265
+ convertTabsToSpaces: true,
266
+ trimTrailingWhitespace: true
267
+ };
268
+ constructor(cwd) {
269
+ this.#cwd = cwd;
270
+ this.#project = new Project2({
271
+ tsConfigFilePath: join(fileURLToPath2(this.#cwd), "tsconfig.json")
272
+ });
273
+ }
274
+ /**
275
+ * Update the `adonisrc.ts` file
276
+ */
277
+ async updateRcFile(callback) {
278
+ const rcFileTransformer = new RcFileTransformer(this.#cwd, this.#project);
279
+ callback(rcFileTransformer);
280
+ await rcFileTransformer.save();
281
+ }
282
+ /**
283
+ * Add a new middleware to the middleware array of the
284
+ * given file
285
+ */
286
+ #addToMiddlewareArray(file, target, middlewareEntry) {
287
+ const callExpressions = file.getDescendantsOfKind(SyntaxKind2.CallExpression).filter((statement) => statement.getExpression().getText() === target);
288
+ if (!callExpressions.length) {
289
+ throw new Error(`Cannot find ${target} statement in the file.`);
290
+ }
291
+ const arrayLiteralExpression = callExpressions[0].getArguments()[0];
292
+ if (!arrayLiteralExpression || !Node2.isArrayLiteralExpression(arrayLiteralExpression)) {
293
+ throw new Error(`Cannot find middleware array in ${target} statement.`);
294
+ }
295
+ const middleware = `() => import('${middlewareEntry.path}')`;
296
+ const existingMiddlewareIndex = arrayLiteralExpression.getElements().findIndex((element) => element.getText() === middleware);
297
+ if (existingMiddlewareIndex === -1) {
298
+ if (middlewareEntry.position === "before") {
299
+ arrayLiteralExpression.insertElement(0, middleware);
300
+ } else {
301
+ arrayLiteralExpression.addElement(middleware);
302
+ }
303
+ }
304
+ }
305
+ /**
306
+ * Add a new middleware to the named middleware of the given file
307
+ */
308
+ #addToNamedMiddleware(file, middlewareEntry) {
309
+ if (!middlewareEntry.name) {
310
+ throw new Error("Named middleware requires a name.");
311
+ }
312
+ const callArguments = file.getVariableDeclarationOrThrow("middleware").getInitializerIfKindOrThrow(SyntaxKind2.CallExpression).getArguments();
313
+ if (callArguments.length === 0) {
314
+ throw new Error("Named middleware call has no arguments.");
315
+ }
316
+ const namedMiddlewareObject = callArguments[0];
317
+ if (!Node2.isObjectLiteralExpression(namedMiddlewareObject)) {
318
+ throw new Error("The argument of the named middleware call is not an object literal.");
319
+ }
320
+ const existingProperty = namedMiddlewareObject.getProperty(middlewareEntry.name);
321
+ if (!existingProperty) {
322
+ const middleware = `${middlewareEntry.name}: () => import('${middlewareEntry.path}')`;
323
+ namedMiddlewareObject.insertProperty(0, middleware);
324
+ }
325
+ }
326
+ /**
327
+ * Write a leading comment
328
+ */
329
+ #addLeadingComment(writer, comment) {
330
+ if (!comment) {
331
+ return writer.blankLine();
332
+ }
333
+ return writer.blankLine().writeLine("/*").writeLine(`|----------------------------------------------------------`).writeLine(`| ${comment}`).writeLine(`|----------------------------------------------------------`).writeLine(`*/`);
334
+ }
335
+ /**
336
+ * Define new middlewares inside the `start/kernel.ts`
337
+ * file
338
+ *
339
+ * This function is highly based on some assumptions
340
+ * and will not work if you significantly tweaked
341
+ * your `start/kernel.ts` file.
342
+ */
343
+ async addMiddlewareToStack(stack, middleware) {
344
+ const kernelUrl = fileURLToPath2(new URL("./start/kernel.ts", this.#cwd));
345
+ const file = this.#project.getSourceFileOrThrow(kernelUrl);
346
+ for (const middlewareEntry of middleware) {
347
+ if (stack === "named") {
348
+ this.#addToNamedMiddleware(file, middlewareEntry);
349
+ } else {
350
+ this.#addToMiddlewareArray(file, `${stack}.use`, middlewareEntry);
351
+ }
352
+ }
353
+ file.formatText(this.#editorSettings);
354
+ await file.save();
355
+ }
356
+ /**
357
+ * Add new env variable validation in the
358
+ * `env.ts` file
359
+ */
360
+ async defineEnvValidations(definition) {
361
+ const kernelUrl = fileURLToPath2(new URL("./start/env.ts", this.#cwd));
362
+ const file = this.#project.getSourceFileOrThrow(kernelUrl);
363
+ const callExpressions = file.getDescendantsOfKind(SyntaxKind2.CallExpression).filter((statement) => statement.getExpression().getText() === "Env.create");
364
+ if (!callExpressions.length) {
365
+ throw new Error(`Cannot find Env.create statement in the file.`);
366
+ }
367
+ const objectLiteralExpression = callExpressions[0].getArguments()[1];
368
+ if (!Node2.isObjectLiteralExpression(objectLiteralExpression)) {
369
+ throw new Error(`The second argument of Env.create is not an object literal.`);
370
+ }
371
+ let shouldAddComment = true;
372
+ for (const [variable, validation] of Object.entries(definition.variables)) {
373
+ const existingProperty = objectLiteralExpression.getProperty(variable);
374
+ if (existingProperty) {
375
+ shouldAddComment = false;
376
+ }
377
+ if (!existingProperty) {
378
+ objectLiteralExpression.addPropertyAssignment({
379
+ name: variable,
380
+ initializer: validation,
381
+ leadingTrivia: (writer) => {
382
+ if (!shouldAddComment) {
383
+ return;
208
384
  }
209
- }
210
- file.formatText(this.#editorSettings);
211
- await file.save();
385
+ shouldAddComment = false;
386
+ return this.#addLeadingComment(writer, definition.leadingComment);
387
+ }
388
+ });
389
+ }
212
390
  }
213
- }
391
+ file.formatText(this.#editorSettings);
392
+ await file.save();
393
+ }
394
+ };
395
+ export {
396
+ CodeTransformer
397
+ };