@adonisjs/assembler 6.1.3-23 → 6.1.3-24
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.
- package/build/index.d.ts +109 -3
- package/build/index.js +913 -11
- package/build/src/code_transformer/main.d.ts +48 -4
- package/build/src/code_transformer/main.js +394 -210
- package/build/src/types.d.ts +12 -11
- package/build/src/types.js +0 -9
- package/package.json +27 -16
- package/build/src/assets_dev_server.d.ts +0 -32
- package/build/src/assets_dev_server.js +0 -158
- package/build/src/bundler.d.ts +0 -19
- package/build/src/bundler.js +0 -205
- package/build/src/code_transformer/rc_file_transformer.d.ts +0 -43
- package/build/src/code_transformer/rc_file_transformer.js +0 -272
- package/build/src/debug.d.ts +0 -3
- package/build/src/debug.js +0 -10
- package/build/src/dev_server.d.ts +0 -47
- package/build/src/dev_server.js +0 -253
- package/build/src/helpers.d.ts +0 -50
- package/build/src/helpers.js +0 -183
- package/build/src/test_runner.d.ts +0 -47
- package/build/src/test_runner.js +0 -310
|
@@ -1,213 +1,397 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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
|
-
|
|
211
|
-
|
|
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
|
+
};
|