@nx/eslint 0.0.0-pr-31222-862e973 → 0.0.0-pr-31313-387cdca
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/LICENSE +1 -1
- package/README.md +1 -1
- package/migrations.json +69 -112
- package/package.json +6 -7
- package/src/executors/lint/utility/eslint-utils.js +6 -0
- package/src/generators/convert-to-flat-config/converters/json-converter.d.ts +1 -1
- package/src/generators/convert-to-flat-config/converters/json-converter.js +10 -18
- package/src/generators/convert-to-flat-config/generator.js +18 -17
- package/src/generators/convert-to-flat-config/schema.d.ts +2 -0
- package/src/generators/convert-to-inferred/convert-to-inferred.js +2 -1
- package/src/generators/init/global-eslint-config.d.ts +1 -1
- package/src/generators/init/global-eslint-config.js +17 -6
- package/src/generators/init/init-migration.d.ts +1 -1
- package/src/generators/init/init-migration.js +18 -13
- package/src/generators/init/init.d.ts +1 -0
- package/src/generators/init/init.js +31 -6
- package/src/generators/lint-project/lint-project.d.ts +1 -0
- package/src/generators/lint-project/lint-project.js +37 -15
- package/src/generators/lint-project/setup-root-eslint.d.ts +1 -0
- package/src/generators/lint-project/setup-root-eslint.js +2 -1
- package/src/generators/utils/eslint-file.d.ts +3 -2
- package/src/generators/utils/eslint-file.js +160 -28
- package/src/generators/utils/flat-config/ast-utils.d.ts +12 -4
- package/src/generators/utils/flat-config/ast-utils.js +412 -63
- package/src/generators/utils/linter.d.ts +3 -0
- package/src/generators/utils/linter.js +2 -2
- package/src/generators/workspace-rule/files/__name__.spec.ts__tmpl__ +11 -2
- package/src/generators/workspace-rule/workspace-rule.d.ts +2 -2
- package/src/generators/workspace-rule/workspace-rule.js +11 -3
- package/src/generators/workspace-rules-project/workspace-rules-project.js +4 -1
- package/src/migrations/update-20-2-0/update-typescript-eslint-v8-13-0.d.ts +2 -0
- package/src/migrations/update-20-2-0/update-typescript-eslint-v8-13-0.js +23 -0
- package/src/migrations/update-20-3-0/add-file-extensions-to-overrides.d.ts +2 -0
- package/src/migrations/update-20-3-0/add-file-extensions-to-overrides.js +49 -0
- package/src/plugins/plugin.js +21 -10
- package/src/utils/config-file.d.ts +3 -1
- package/src/utils/config-file.js +5 -2
- package/src/utils/flat-config.d.ts +1 -0
- package/src/utils/flat-config.js +9 -3
- package/src/utils/version-utils.d.ts +1 -0
- package/src/utils/version-utils.js +13 -9
- package/src/utils/versions.d.ts +3 -2
- package/src/utils/versions.js +4 -3
- package/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.d.ts +0 -2
- package/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.js +0 -9
- package/src/migrations/update-16-8-0-add-ignored-files/update-16-8-0-add-ignored-files.d.ts +0 -2
- package/src/migrations/update-16-8-0-add-ignored-files/update-16-8-0-add-ignored-files.js +0 -44
- package/src/migrations/update-17-0-0-rename-to-eslint/update-17-0-0-rename-to-eslint.d.ts +0 -2
- package/src/migrations/update-17-0-0-rename-to-eslint/update-17-0-0-rename-to-eslint.js +0 -47
- package/src/migrations/update-17-1-0/update-typescript-eslint.d.ts +0 -2
- package/src/migrations/update-17-1-0/update-typescript-eslint.js +0 -74
- package/src/migrations/update-17-2-0/simplify-eslint-patterns.d.ts +0 -2
- package/src/migrations/update-17-2-0/simplify-eslint-patterns.js +0 -46
- package/src/migrations/update-17-2-9/move-options-to-target-defaults.d.ts +0 -2
- package/src/migrations/update-17-2-9/move-options-to-target-defaults.js +0 -107
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.removeOverridesFromLintConfig = removeOverridesFromLintConfig;
|
|
4
|
+
exports.addPatternsToFlatConfigIgnoresBlock = addPatternsToFlatConfigIgnoresBlock;
|
|
5
|
+
exports.hasFlatConfigIgnoresBlock = hasFlatConfigIgnoresBlock;
|
|
4
6
|
exports.hasOverride = hasOverride;
|
|
5
7
|
exports.replaceOverride = replaceOverride;
|
|
6
8
|
exports.addImportToFlatConfig = addImportToFlatConfig;
|
|
@@ -17,6 +19,7 @@ exports.generatePluginExtendsElement = generatePluginExtendsElement;
|
|
|
17
19
|
exports.generatePluginExtendsElementWithCompatFixup = generatePluginExtendsElementWithCompatFixup;
|
|
18
20
|
exports.stringifyNodeList = stringifyNodeList;
|
|
19
21
|
exports.generateRequire = generateRequire;
|
|
22
|
+
exports.generateESMImport = generateESMImport;
|
|
20
23
|
exports.overrideNeedsCompat = overrideNeedsCompat;
|
|
21
24
|
exports.generateFlatOverride = generateFlatOverride;
|
|
22
25
|
exports.generateFlatPredefinedConfig = generateFlatPredefinedConfig;
|
|
@@ -35,7 +38,8 @@ const SPREAD_ELEMENTS_REGEXP = /\s*\.\.\.[a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*,?\n?/g;
|
|
|
35
38
|
*/
|
|
36
39
|
function removeOverridesFromLintConfig(content) {
|
|
37
40
|
const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
|
|
38
|
-
const
|
|
41
|
+
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
|
42
|
+
const exportsArray = format === 'mjs' ? findExportDefault(source) : findModuleExports(source);
|
|
39
43
|
if (!exportsArray) {
|
|
40
44
|
return content;
|
|
41
45
|
}
|
|
@@ -52,7 +56,16 @@ function removeOverridesFromLintConfig(content) {
|
|
|
52
56
|
});
|
|
53
57
|
return (0, devkit_1.applyChangesToString)(content, changes);
|
|
54
58
|
}
|
|
55
|
-
|
|
59
|
+
// TODO Change name
|
|
60
|
+
function findExportDefault(source) {
|
|
61
|
+
return ts.forEachChild(source, function analyze(node) {
|
|
62
|
+
if (ts.isExportAssignment(node) &&
|
|
63
|
+
ts.isArrayLiteralExpression(node.expression)) {
|
|
64
|
+
return node.expression.elements;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function findModuleExports(source) {
|
|
56
69
|
return ts.forEachChild(source, function analyze(node) {
|
|
57
70
|
if (ts.isExpressionStatement(node) &&
|
|
58
71
|
ts.isBinaryExpression(node.expression) &&
|
|
@@ -62,9 +75,58 @@ function findAllBlocks(source) {
|
|
|
62
75
|
}
|
|
63
76
|
});
|
|
64
77
|
}
|
|
78
|
+
function addPatternsToFlatConfigIgnoresBlock(content, ignorePatterns) {
|
|
79
|
+
const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
|
|
80
|
+
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
|
81
|
+
const exportsArray = format === 'mjs' ? findExportDefault(source) : findModuleExports(source);
|
|
82
|
+
if (!exportsArray) {
|
|
83
|
+
return content;
|
|
84
|
+
}
|
|
85
|
+
const changes = [];
|
|
86
|
+
for (const node of exportsArray) {
|
|
87
|
+
if (!isFlatConfigIgnoresBlock(node)) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const start = node.properties.pos + 1; // keep leading line break
|
|
91
|
+
const data = parseTextToJson(node.getFullText());
|
|
92
|
+
changes.push({
|
|
93
|
+
type: devkit_1.ChangeType.Delete,
|
|
94
|
+
start,
|
|
95
|
+
length: node.properties.end - start,
|
|
96
|
+
});
|
|
97
|
+
data.ignores = Array.from(new Set([...(data.ignores ?? []), ...ignorePatterns]));
|
|
98
|
+
changes.push({
|
|
99
|
+
type: devkit_1.ChangeType.Insert,
|
|
100
|
+
index: start,
|
|
101
|
+
text: ' ' +
|
|
102
|
+
JSON.stringify(data, null, 2)
|
|
103
|
+
.slice(2, -2) // Remove curly braces and start/end line breaks
|
|
104
|
+
.replaceAll(/\n/g, '\n '), // Maintain indentation
|
|
105
|
+
});
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
return (0, devkit_1.applyChangesToString)(content, changes);
|
|
109
|
+
}
|
|
110
|
+
function hasFlatConfigIgnoresBlock(content) {
|
|
111
|
+
const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
|
|
112
|
+
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
|
113
|
+
const exportsArray = format === 'mjs' ? findExportDefault(source) : findModuleExports(source);
|
|
114
|
+
if (!exportsArray) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
return exportsArray.some(isFlatConfigIgnoresBlock);
|
|
118
|
+
}
|
|
119
|
+
function isFlatConfigIgnoresBlock(node) {
|
|
120
|
+
return (ts.isObjectLiteralExpression(node) &&
|
|
121
|
+
node.properties.length === 1 &&
|
|
122
|
+
(node.properties[0].name.getText() === 'ignores' ||
|
|
123
|
+
node.properties[0].name.getText() === '"ignores"') &&
|
|
124
|
+
ts.isPropertyAssignment(node.properties[0]) &&
|
|
125
|
+
ts.isArrayLiteralExpression(node.properties[0].initializer));
|
|
126
|
+
}
|
|
65
127
|
function isOverride(node) {
|
|
66
128
|
return ((ts.isObjectLiteralExpression(node) &&
|
|
67
|
-
node.properties.some((p) => p.name.getText() === 'files')) ||
|
|
129
|
+
node.properties.some((p) => p.name.getText() === 'files' || p.name.getText() === '"files"')) ||
|
|
68
130
|
// detect ...compat.config(...).map(...)
|
|
69
131
|
(ts.isSpreadElement(node) &&
|
|
70
132
|
ts.isCallExpression(node.expression) &&
|
|
@@ -74,7 +136,8 @@ function isOverride(node) {
|
|
|
74
136
|
}
|
|
75
137
|
function hasOverride(content, lookup) {
|
|
76
138
|
const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
|
|
77
|
-
const
|
|
139
|
+
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
|
140
|
+
const exportsArray = format === 'mjs' ? findExportDefault(source) : findModuleExports(source);
|
|
78
141
|
if (!exportsArray) {
|
|
79
142
|
return false;
|
|
80
143
|
}
|
|
@@ -105,14 +168,16 @@ function parseTextToJson(text) {
|
|
|
105
168
|
.replace(/'/g, '"')
|
|
106
169
|
.replace(/\s([a-zA-Z0-9_]+)\s*:/g, ' "$1": ')
|
|
107
170
|
// stringify any require calls to avoid JSON parsing errors, turn them into just the string value being required
|
|
108
|
-
.replace(/require\(['"]([^'"]+)['"]\)/g, '"$1"')
|
|
171
|
+
.replace(/require\(['"]([^'"]+)['"]\)/g, '"$1"')
|
|
172
|
+
.replace(/\(?await import\(['"]([^'"]+)['"]\)\)?/g, '"$1"'));
|
|
109
173
|
}
|
|
110
174
|
/**
|
|
111
175
|
* Finds an override matching the lookup function and applies the update function to it
|
|
112
176
|
*/
|
|
113
177
|
function replaceOverride(content, root, lookup, update) {
|
|
114
178
|
const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
|
|
115
|
-
const
|
|
179
|
+
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
|
180
|
+
const exportsArray = format === 'mjs' ? findExportDefault(source) : findModuleExports(source);
|
|
116
181
|
if (!exportsArray) {
|
|
117
182
|
return content;
|
|
118
183
|
}
|
|
@@ -145,15 +210,17 @@ function replaceOverride(content, root, lookup, update) {
|
|
|
145
210
|
let updatedData = update(data);
|
|
146
211
|
if (updatedData) {
|
|
147
212
|
updatedData = mapFilePaths(updatedData);
|
|
213
|
+
const parserReplacement = format === 'mjs'
|
|
214
|
+
? (parser) => `(await import('${parser}'))`
|
|
215
|
+
: (parser) => `require('${parser}')`;
|
|
148
216
|
changes.push({
|
|
149
217
|
type: devkit_1.ChangeType.Insert,
|
|
150
218
|
index: start,
|
|
151
|
-
text:
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
.slice(2, -2), // remove curly braces and start/end line breaks since we are injecting just properties
|
|
219
|
+
text: ' ' +
|
|
220
|
+
JSON.stringify(updatedData, null, 2)
|
|
221
|
+
.replace(/"parser": "([^"]+)"/g, (_, parser) => `"parser": ${parserReplacement(parser)}`)
|
|
222
|
+
.slice(2, -2) // Remove curly braces and start/end line breaks
|
|
223
|
+
.replaceAll(/\n/g, '\n '), // Maintain indentation
|
|
157
224
|
});
|
|
158
225
|
}
|
|
159
226
|
}
|
|
@@ -162,11 +229,89 @@ function replaceOverride(content, root, lookup, update) {
|
|
|
162
229
|
return (0, devkit_1.applyChangesToString)(content, changes);
|
|
163
230
|
}
|
|
164
231
|
/**
|
|
165
|
-
* Adding
|
|
232
|
+
* Adding import statement to the top of the file
|
|
233
|
+
* The imports are added based on a few rules:
|
|
234
|
+
* 1. If it's a default import and matches the variable, return content unchanged.
|
|
235
|
+
* 2. If it's a named import and the variables are not part of the import object, add them.
|
|
236
|
+
* 3. If no existing import and variable is a string, add a default import.
|
|
237
|
+
* 4. If no existing import and variable is an array, add it as an object import.
|
|
166
238
|
*/
|
|
167
239
|
function addImportToFlatConfig(content, variable, imp) {
|
|
168
240
|
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
169
241
|
const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
|
|
242
|
+
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
|
243
|
+
if (format === 'mjs') {
|
|
244
|
+
return addESMImportToFlatConfig(source, printer, content, variable, imp);
|
|
245
|
+
}
|
|
246
|
+
return addCJSImportToFlatConfig(source, printer, content, variable, imp);
|
|
247
|
+
}
|
|
248
|
+
function addESMImportToFlatConfig(source, printer, content, variable, imp) {
|
|
249
|
+
let existingImport;
|
|
250
|
+
ts.forEachChild(source, (node) => {
|
|
251
|
+
if (ts.isImportDeclaration(node) &&
|
|
252
|
+
ts.isStringLiteral(node.moduleSpecifier) &&
|
|
253
|
+
node.moduleSpecifier.text === imp) {
|
|
254
|
+
existingImport = node;
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
// Rule 1:
|
|
258
|
+
if (existingImport &&
|
|
259
|
+
typeof variable === 'string' &&
|
|
260
|
+
existingImport.importClause?.name?.getText() === variable) {
|
|
261
|
+
return content;
|
|
262
|
+
}
|
|
263
|
+
// Rule 2:
|
|
264
|
+
if (existingImport &&
|
|
265
|
+
existingImport.importClause?.namedBindings &&
|
|
266
|
+
Array.isArray(variable)) {
|
|
267
|
+
const namedImports = existingImport.importClause
|
|
268
|
+
.namedBindings;
|
|
269
|
+
const existingElements = namedImports.elements;
|
|
270
|
+
// Filter out variables that are already imported
|
|
271
|
+
const newVariables = variable.filter((v) => !existingElements.some((e) => e.name.getText() === v));
|
|
272
|
+
if (newVariables.length === 0) {
|
|
273
|
+
return content;
|
|
274
|
+
}
|
|
275
|
+
const newImportSpecifiers = newVariables.map((v) => ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(v)));
|
|
276
|
+
const lastElement = existingElements[existingElements.length - 1];
|
|
277
|
+
const insertIndex = lastElement
|
|
278
|
+
? lastElement.getEnd()
|
|
279
|
+
: namedImports.getEnd();
|
|
280
|
+
const insertText = printer.printList(ts.ListFormat.NamedImportsOrExportsElements, ts.factory.createNodeArray(newImportSpecifiers), source);
|
|
281
|
+
return (0, devkit_1.applyChangesToString)(content, [
|
|
282
|
+
{
|
|
283
|
+
type: devkit_1.ChangeType.Insert,
|
|
284
|
+
index: insertIndex,
|
|
285
|
+
text: `, ${insertText}`,
|
|
286
|
+
},
|
|
287
|
+
]);
|
|
288
|
+
}
|
|
289
|
+
// Rule 3:
|
|
290
|
+
if (!existingImport && typeof variable === 'string') {
|
|
291
|
+
const defaultImport = ts.factory.createImportDeclaration(undefined, ts.factory.createImportClause(false, ts.factory.createIdentifier(variable), undefined), ts.factory.createStringLiteral(imp));
|
|
292
|
+
const insert = printer.printNode(ts.EmitHint.Unspecified, defaultImport, source);
|
|
293
|
+
return (0, devkit_1.applyChangesToString)(content, [
|
|
294
|
+
{
|
|
295
|
+
type: devkit_1.ChangeType.Insert,
|
|
296
|
+
index: 0,
|
|
297
|
+
text: `${insert}\n`,
|
|
298
|
+
},
|
|
299
|
+
]);
|
|
300
|
+
}
|
|
301
|
+
// Rule 4:
|
|
302
|
+
if (!existingImport && Array.isArray(variable)) {
|
|
303
|
+
const objectImport = ts.factory.createImportDeclaration(undefined, ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports(variable.map((v) => ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(v))))), ts.factory.createStringLiteral(imp));
|
|
304
|
+
const insert = printer.printNode(ts.EmitHint.Unspecified, objectImport, source);
|
|
305
|
+
return (0, devkit_1.applyChangesToString)(content, [
|
|
306
|
+
{
|
|
307
|
+
type: devkit_1.ChangeType.Insert,
|
|
308
|
+
index: 0,
|
|
309
|
+
text: `${insert}\n`,
|
|
310
|
+
},
|
|
311
|
+
]);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
function addCJSImportToFlatConfig(source, printer, content, variable, imp) {
|
|
170
315
|
const foundBindingVars = ts.forEachChild(source, function analyze(node) {
|
|
171
316
|
// we can only combine object binding patterns
|
|
172
317
|
if (!Array.isArray(variable)) {
|
|
@@ -235,11 +380,48 @@ function addImportToFlatConfig(content, variable, imp) {
|
|
|
235
380
|
},
|
|
236
381
|
]);
|
|
237
382
|
}
|
|
383
|
+
function existsAsNamedOrDefaultImport(node, variable) {
|
|
384
|
+
const isNamed = node.importClause.namedBindings &&
|
|
385
|
+
ts.isNamedImports(node.importClause.namedBindings);
|
|
386
|
+
if (Array.isArray(variable)) {
|
|
387
|
+
return isNamed || variable.includes(node.importClause?.name?.getText());
|
|
388
|
+
}
|
|
389
|
+
return ((node.importClause.namedBindings &&
|
|
390
|
+
ts.isNamedImports(node.importClause.namedBindings)) ||
|
|
391
|
+
node.importClause?.name?.getText() === variable);
|
|
392
|
+
}
|
|
238
393
|
/**
|
|
239
394
|
* Remove an import from flat config
|
|
240
395
|
*/
|
|
241
396
|
function removeImportFromFlatConfig(content, variable, imp) {
|
|
242
397
|
const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
|
|
398
|
+
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
|
399
|
+
if (format === 'mjs') {
|
|
400
|
+
return removeImportFromFlatConfigESM(source, content, variable, imp);
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
return removeImportFromFlatConfigCJS(source, content, variable, imp);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
function removeImportFromFlatConfigESM(source, content, variable, imp) {
|
|
407
|
+
const changes = [];
|
|
408
|
+
ts.forEachChild(source, (node) => {
|
|
409
|
+
// we can only combine object binding patterns
|
|
410
|
+
if (ts.isImportDeclaration(node) &&
|
|
411
|
+
ts.isStringLiteral(node.moduleSpecifier) &&
|
|
412
|
+
node.moduleSpecifier.text === imp &&
|
|
413
|
+
node.importClause &&
|
|
414
|
+
existsAsNamedOrDefaultImport(node, variable)) {
|
|
415
|
+
changes.push({
|
|
416
|
+
type: devkit_1.ChangeType.Delete,
|
|
417
|
+
start: node.pos,
|
|
418
|
+
length: node.end - node.pos,
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
return (0, devkit_1.applyChangesToString)(content, changes);
|
|
423
|
+
}
|
|
424
|
+
function removeImportFromFlatConfigCJS(source, content, variable, imp) {
|
|
243
425
|
const changes = [];
|
|
244
426
|
ts.forEachChild(source, (node) => {
|
|
245
427
|
// we can only combine object binding patterns
|
|
@@ -262,13 +444,44 @@ function removeImportFromFlatConfig(content, variable, imp) {
|
|
|
262
444
|
return (0, devkit_1.applyChangesToString)(content, changes);
|
|
263
445
|
}
|
|
264
446
|
/**
|
|
265
|
-
* Injects new ts.expression to the end of the module.exports array.
|
|
447
|
+
* Injects new ts.expression to the end of the module.exports or export default array.
|
|
266
448
|
*/
|
|
267
449
|
function addBlockToFlatConfigExport(content, config, options = {
|
|
268
450
|
insertAtTheEnd: true,
|
|
269
451
|
}) {
|
|
270
452
|
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
271
453
|
const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
|
|
454
|
+
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
|
455
|
+
// find the export default array statement
|
|
456
|
+
if (format === 'mjs') {
|
|
457
|
+
return addBlockToFlatConfigExportESM(content, config, source, printer, options);
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
return addBlockToFlatConfigExportCJS(content, config, source, printer, options);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
function addBlockToFlatConfigExportESM(content, config, source, printer, options = {
|
|
464
|
+
insertAtTheEnd: true,
|
|
465
|
+
}) {
|
|
466
|
+
const exportDefaultStatement = source.statements.find((statement) => ts.isExportAssignment(statement) &&
|
|
467
|
+
ts.isArrayLiteralExpression(statement.expression));
|
|
468
|
+
if (!exportDefaultStatement)
|
|
469
|
+
return content;
|
|
470
|
+
const exportArrayLiteral = exportDefaultStatement.expression;
|
|
471
|
+
const updatedArrayElements = options.insertAtTheEnd
|
|
472
|
+
? [...exportArrayLiteral.elements, config]
|
|
473
|
+
: [config, ...exportArrayLiteral.elements];
|
|
474
|
+
const updatedExportDefault = ts.factory.createExportAssignment(undefined, false, ts.factory.createArrayLiteralExpression(updatedArrayElements, true));
|
|
475
|
+
// update the existing export default array
|
|
476
|
+
const updatedStatements = source.statements.map((statement) => statement === exportDefaultStatement ? updatedExportDefault : statement);
|
|
477
|
+
const updatedSource = ts.factory.updateSourceFile(source, updatedStatements);
|
|
478
|
+
return printer
|
|
479
|
+
.printFile(updatedSource)
|
|
480
|
+
.replace(/export default/, '\nexport default');
|
|
481
|
+
}
|
|
482
|
+
function addBlockToFlatConfigExportCJS(content, config, source, printer, options = {
|
|
483
|
+
insertAtTheEnd: true,
|
|
484
|
+
}) {
|
|
272
485
|
const exportsArray = ts.forEachChild(source, function analyze(node) {
|
|
273
486
|
if (ts.isExpressionStatement(node) &&
|
|
274
487
|
ts.isBinaryExpression(node.expression) &&
|
|
@@ -282,7 +495,10 @@ function addBlockToFlatConfigExport(content, config, options = {
|
|
|
282
495
|
// base config was not generated by Nx.
|
|
283
496
|
if (!exportsArray)
|
|
284
497
|
return content;
|
|
285
|
-
const insert =
|
|
498
|
+
const insert = ' ' +
|
|
499
|
+
printer
|
|
500
|
+
.printNode(ts.EmitHint.Expression, config, source)
|
|
501
|
+
.replaceAll(/\n/g, '\n ');
|
|
286
502
|
if (options.insertAtTheEnd) {
|
|
287
503
|
const index = exportsArray.length > 0
|
|
288
504
|
? exportsArray.at(exportsArray.length - 1).end
|
|
@@ -301,35 +517,54 @@ function addBlockToFlatConfigExport(content, config, options = {
|
|
|
301
517
|
{
|
|
302
518
|
type: devkit_1.ChangeType.Insert,
|
|
303
519
|
index,
|
|
304
|
-
text: `\n${insert}
|
|
520
|
+
text: `\n${insert},\n`,
|
|
305
521
|
},
|
|
306
522
|
]);
|
|
307
523
|
}
|
|
308
524
|
}
|
|
309
525
|
function removePlugin(content, pluginName, pluginImport) {
|
|
310
526
|
const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
|
|
527
|
+
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
|
311
528
|
const changes = [];
|
|
529
|
+
if (format === 'mjs') {
|
|
530
|
+
ts.forEachChild(source, function analyze(node) {
|
|
531
|
+
if (ts.isImportDeclaration(node) &&
|
|
532
|
+
ts.isStringLiteral(node.moduleSpecifier) &&
|
|
533
|
+
node.moduleSpecifier.text === pluginImport) {
|
|
534
|
+
const importClause = node.importClause;
|
|
535
|
+
if ((importClause && importClause.name) ||
|
|
536
|
+
(importClause.namedBindings &&
|
|
537
|
+
ts.isNamedImports(importClause.namedBindings))) {
|
|
538
|
+
changes.push({
|
|
539
|
+
type: devkit_1.ChangeType.Delete,
|
|
540
|
+
start: node.pos,
|
|
541
|
+
length: node.end - node.pos,
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
else {
|
|
548
|
+
ts.forEachChild(source, function analyze(node) {
|
|
549
|
+
if (ts.isVariableStatement(node) &&
|
|
550
|
+
ts.isVariableDeclaration(node.declarationList.declarations[0]) &&
|
|
551
|
+
ts.isCallExpression(node.declarationList.declarations[0].initializer) &&
|
|
552
|
+
node.declarationList.declarations[0].initializer.arguments.length &&
|
|
553
|
+
ts.isStringLiteral(node.declarationList.declarations[0].initializer.arguments[0]) &&
|
|
554
|
+
node.declarationList.declarations[0].initializer.arguments[0].text ===
|
|
555
|
+
pluginImport) {
|
|
556
|
+
changes.push({
|
|
557
|
+
type: devkit_1.ChangeType.Delete,
|
|
558
|
+
start: node.pos,
|
|
559
|
+
length: node.end - node.pos,
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
});
|
|
563
|
+
}
|
|
312
564
|
ts.forEachChild(source, function analyze(node) {
|
|
313
|
-
if (ts.
|
|
314
|
-
ts.
|
|
315
|
-
|
|
316
|
-
node.declarationList.declarations[0].initializer.arguments.length &&
|
|
317
|
-
ts.isStringLiteral(node.declarationList.declarations[0].initializer.arguments[0]) &&
|
|
318
|
-
node.declarationList.declarations[0].initializer.arguments[0].text ===
|
|
319
|
-
pluginImport) {
|
|
320
|
-
changes.push({
|
|
321
|
-
type: devkit_1.ChangeType.Delete,
|
|
322
|
-
start: node.pos,
|
|
323
|
-
length: node.end - node.pos,
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
});
|
|
327
|
-
ts.forEachChild(source, function analyze(node) {
|
|
328
|
-
if (ts.isExpressionStatement(node) &&
|
|
329
|
-
ts.isBinaryExpression(node.expression) &&
|
|
330
|
-
node.expression.left.getText() === 'module.exports' &&
|
|
331
|
-
ts.isArrayLiteralExpression(node.expression.right)) {
|
|
332
|
-
const blockElements = node.expression.right.elements;
|
|
565
|
+
if (ts.isExportAssignment(node) &&
|
|
566
|
+
ts.isArrayLiteralExpression(node.expression)) {
|
|
567
|
+
const blockElements = node.expression.elements;
|
|
333
568
|
blockElements.forEach((element) => {
|
|
334
569
|
if (ts.isObjectLiteralExpression(element)) {
|
|
335
570
|
const pluginsElem = element.properties.find((prop) => prop.name?.getText() === 'plugins');
|
|
@@ -419,7 +654,12 @@ function removePlugin(content, pluginName, pluginImport) {
|
|
|
419
654
|
function removeCompatExtends(content, compatExtends) {
|
|
420
655
|
const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
|
|
421
656
|
const changes = [];
|
|
422
|
-
|
|
657
|
+
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
|
658
|
+
const exportsArray = format === 'mjs' ? findExportDefault(source) : findModuleExports(source);
|
|
659
|
+
if (!exportsArray) {
|
|
660
|
+
return content;
|
|
661
|
+
}
|
|
662
|
+
exportsArray.forEach((node) => {
|
|
423
663
|
if (ts.isSpreadElement(node) &&
|
|
424
664
|
ts.isCallExpression(node.expression) &&
|
|
425
665
|
ts.isArrowFunction(node.expression.arguments[0]) &&
|
|
@@ -453,9 +693,14 @@ function removeCompatExtends(content, compatExtends) {
|
|
|
453
693
|
}
|
|
454
694
|
function removePredefinedConfigs(content, moduleImport, moduleVariable, configs) {
|
|
455
695
|
const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
|
|
696
|
+
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
|
456
697
|
const changes = [];
|
|
457
698
|
let removeImport = true;
|
|
458
|
-
|
|
699
|
+
const exportsArray = format === 'mjs' ? findExportDefault(source) : findModuleExports(source);
|
|
700
|
+
if (!exportsArray) {
|
|
701
|
+
return content;
|
|
702
|
+
}
|
|
703
|
+
exportsArray.forEach((node) => {
|
|
459
704
|
if (ts.isSpreadElement(node) &&
|
|
460
705
|
ts.isElementAccessExpression(node.expression) &&
|
|
461
706
|
ts.isPropertyAccessExpression(node.expression.expression) &&
|
|
@@ -500,14 +745,22 @@ function addPluginsToExportsBlock(content, plugins) {
|
|
|
500
745
|
* Adds compat if missing to flat config
|
|
501
746
|
*/
|
|
502
747
|
function addFlatCompatToFlatConfig(content) {
|
|
503
|
-
|
|
504
|
-
|
|
748
|
+
const result = addImportToFlatConfig(content, 'js', '@eslint/js');
|
|
749
|
+
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
|
505
750
|
if (result.includes('const compat = new FlatCompat')) {
|
|
506
751
|
return result;
|
|
507
752
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
753
|
+
if (format === 'mjs') {
|
|
754
|
+
return addFlatCompatToFlatConfigESM(result);
|
|
755
|
+
}
|
|
756
|
+
else {
|
|
757
|
+
return addFlatCompatToFlatConfigCJS(result);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
function addFlatCompatToFlatConfigCJS(content) {
|
|
761
|
+
content = addImportToFlatConfig(content, ['FlatCompat'], '@eslint/eslintrc');
|
|
762
|
+
const index = content.indexOf('module.exports');
|
|
763
|
+
return (0, devkit_1.applyChangesToString)(content, [
|
|
511
764
|
{
|
|
512
765
|
type: devkit_1.ChangeType.Insert,
|
|
513
766
|
index: index - 1,
|
|
@@ -520,25 +773,62 @@ const compat = new FlatCompat({
|
|
|
520
773
|
},
|
|
521
774
|
]);
|
|
522
775
|
}
|
|
776
|
+
function addFlatCompatToFlatConfigESM(content) {
|
|
777
|
+
const importsToAdd = [
|
|
778
|
+
{ variable: 'js', module: '@eslint/js' },
|
|
779
|
+
{ variable: ['fileURLToPath'], module: 'url' },
|
|
780
|
+
{ variable: ['dirname'], module: 'path' },
|
|
781
|
+
{ variable: ['FlatCompat'], module: '@eslint/eslintrc' },
|
|
782
|
+
];
|
|
783
|
+
for (const { variable, module } of importsToAdd) {
|
|
784
|
+
content = addImportToFlatConfig(content, variable, module);
|
|
785
|
+
}
|
|
786
|
+
const index = content.indexOf('export default');
|
|
787
|
+
return (0, devkit_1.applyChangesToString)(content, [
|
|
788
|
+
{
|
|
789
|
+
type: devkit_1.ChangeType.Insert,
|
|
790
|
+
index: index - 1,
|
|
791
|
+
text: `
|
|
792
|
+
const compat = new FlatCompat({
|
|
793
|
+
baseDirectory: dirname(fileURLToPath(import.meta.url)),
|
|
794
|
+
recommendedConfig: js.configs.recommended,
|
|
795
|
+
});\n
|
|
796
|
+
`,
|
|
797
|
+
},
|
|
798
|
+
]);
|
|
799
|
+
}
|
|
523
800
|
/**
|
|
524
801
|
* Generate node list representing the imports and the exports blocks
|
|
525
802
|
* Optionally add flat compat initialization
|
|
526
803
|
*/
|
|
527
|
-
function createNodeList(importsMap, exportElements) {
|
|
804
|
+
function createNodeList(importsMap, exportElements, format) {
|
|
528
805
|
const importsList = [];
|
|
529
|
-
// generateRequire(varName, imp, ts.factory);
|
|
530
806
|
Array.from(importsMap.entries()).forEach(([imp, varName]) => {
|
|
531
|
-
|
|
807
|
+
if (format === 'mjs') {
|
|
808
|
+
importsList.push(generateESMImport(varName, imp));
|
|
809
|
+
}
|
|
810
|
+
else {
|
|
811
|
+
importsList.push(generateRequire(varName, imp));
|
|
812
|
+
}
|
|
532
813
|
});
|
|
814
|
+
const exports = format === 'mjs'
|
|
815
|
+
? generateESMExport(exportElements)
|
|
816
|
+
: generateCJSExport(exportElements);
|
|
533
817
|
return ts.factory.createNodeArray([
|
|
534
818
|
// add plugin imports
|
|
535
819
|
...importsList,
|
|
536
820
|
ts.createSourceFile('', '', ts.ScriptTarget.Latest, false, ts.ScriptKind.JS),
|
|
537
|
-
|
|
538
|
-
// module.exports = [ ... ];
|
|
539
|
-
ts.factory.createExpressionStatement(ts.factory.createBinaryExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('module'), ts.factory.createIdentifier('exports')), ts.factory.createToken(ts.SyntaxKind.EqualsToken), ts.factory.createArrayLiteralExpression(exportElements, true))),
|
|
821
|
+
exports,
|
|
540
822
|
]);
|
|
541
823
|
}
|
|
824
|
+
function generateESMExport(elements) {
|
|
825
|
+
// creates: export default = [...]
|
|
826
|
+
return ts.factory.createExportAssignment(undefined, false, ts.factory.createArrayLiteralExpression(elements, true));
|
|
827
|
+
}
|
|
828
|
+
function generateCJSExport(elements) {
|
|
829
|
+
// creates: module.exports = [...]
|
|
830
|
+
return ts.factory.createExpressionStatement(ts.factory.createBinaryExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('module'), ts.factory.createIdentifier('exports')), ts.factory.createToken(ts.SyntaxKind.EqualsToken), ts.factory.createArrayLiteralExpression(elements, true)));
|
|
831
|
+
}
|
|
542
832
|
function generateSpreadElement(name) {
|
|
543
833
|
return ts.factory.createSpreadElement(ts.factory.createIdentifier(name));
|
|
544
834
|
}
|
|
@@ -556,12 +846,17 @@ function generatePluginExtendsElementWithCompatFixup(plugin) {
|
|
|
556
846
|
function stringifyNodeList(nodes) {
|
|
557
847
|
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
558
848
|
const resultFile = ts.createSourceFile('', '', ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
|
|
559
|
-
|
|
849
|
+
const result = printer
|
|
560
850
|
.printList(ts.ListFormat.MultiLine, nodes, resultFile)
|
|
561
851
|
// add new line before compat initialization
|
|
562
|
-
.replace(/const compat = new FlatCompat/, '\nconst compat = new FlatCompat')
|
|
563
|
-
|
|
564
|
-
|
|
852
|
+
.replace(/const compat = new FlatCompat/, '\nconst compat = new FlatCompat');
|
|
853
|
+
if (result.includes('export default')) {
|
|
854
|
+
return result // add new line before export default = ...
|
|
855
|
+
.replace(/export default/, '\nexport default');
|
|
856
|
+
}
|
|
857
|
+
else {
|
|
858
|
+
return result.replace(/module.exports/, '\nmodule.exports');
|
|
859
|
+
}
|
|
565
860
|
}
|
|
566
861
|
/**
|
|
567
862
|
* generates AST require statement
|
|
@@ -571,6 +866,26 @@ function generateRequire(variableName, imp) {
|
|
|
571
866
|
ts.factory.createVariableDeclaration(variableName, undefined, undefined, ts.factory.createCallExpression(ts.factory.createIdentifier('require'), undefined, [ts.factory.createStringLiteral(imp)])),
|
|
572
867
|
], ts.NodeFlags.Const));
|
|
573
868
|
}
|
|
869
|
+
// Top level imports
|
|
870
|
+
function generateESMImport(variableName, imp) {
|
|
871
|
+
let importClause;
|
|
872
|
+
if (typeof variableName === 'string') {
|
|
873
|
+
// For single variable import e.g import foo from 'module';
|
|
874
|
+
importClause = ts.factory.createImportClause(false, ts.factory.createIdentifier(variableName), undefined);
|
|
875
|
+
}
|
|
876
|
+
else {
|
|
877
|
+
// For object binding pattern import e.g import { a, b, c } from 'module';
|
|
878
|
+
importClause = ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports(variableName.elements.map((element) => {
|
|
879
|
+
const propertyName = element.propertyName
|
|
880
|
+
? ts.isIdentifier(element.propertyName)
|
|
881
|
+
? element.propertyName
|
|
882
|
+
: ts.factory.createIdentifier(element.propertyName.getText())
|
|
883
|
+
: undefined;
|
|
884
|
+
return ts.factory.createImportSpecifier(false, propertyName, element.name);
|
|
885
|
+
})));
|
|
886
|
+
}
|
|
887
|
+
return ts.factory.createImportDeclaration(undefined, importClause, ts.factory.createStringLiteral(imp));
|
|
888
|
+
}
|
|
574
889
|
/**
|
|
575
890
|
* FROM: https://github.com/eslint/rewrite/blob/e2a7ec809db20e638abbad250d105ddbde88a8d5/packages/migrate-config/src/migrate-config.js#L222
|
|
576
891
|
*
|
|
@@ -596,7 +911,7 @@ function overrideNeedsCompat(override) {
|
|
|
596
911
|
* Generates an AST object or spread element representing a modern flat config entry,
|
|
597
912
|
* based on a given legacy eslintrc JSON override object
|
|
598
913
|
*/
|
|
599
|
-
function generateFlatOverride(_override) {
|
|
914
|
+
function generateFlatOverride(_override, format) {
|
|
600
915
|
const override = mapFilePaths(_override);
|
|
601
916
|
// We do not need the compat tooling for this override
|
|
602
917
|
if (!overrideNeedsCompat(override)) {
|
|
@@ -652,21 +967,41 @@ function generateFlatOverride(_override) {
|
|
|
652
967
|
return propertyAssignment;
|
|
653
968
|
}
|
|
654
969
|
else {
|
|
655
|
-
// Change parser to
|
|
656
|
-
return
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
override.parser),
|
|
660
|
-
]));
|
|
970
|
+
// Change parser to import statement.
|
|
971
|
+
return format === 'mjs'
|
|
972
|
+
? generateESMParserImport(override)
|
|
973
|
+
: generateCJSParserImport(override);
|
|
661
974
|
}
|
|
662
975
|
},
|
|
663
976
|
});
|
|
664
977
|
}
|
|
665
978
|
// At this point we are applying the flat config compat tooling to the override
|
|
666
|
-
|
|
979
|
+
let { excludedFiles, parser, parserOptions, rules, files, ...rest } = override;
|
|
667
980
|
const objectLiteralElements = [
|
|
668
981
|
ts.factory.createSpreadAssignment(ts.factory.createIdentifier('config')),
|
|
669
982
|
];
|
|
983
|
+
// If converting the JS rule, then we need to match ESLint default and also include .cjs and .mjs files.
|
|
984
|
+
if ((Array.isArray(rest.extends) &&
|
|
985
|
+
rest.extends.includes('plugin:@nx/javascript')) ||
|
|
986
|
+
rest.extends === 'plugin:@nx/javascript') {
|
|
987
|
+
const newFiles = new Set(files);
|
|
988
|
+
newFiles.add('**/*.js');
|
|
989
|
+
newFiles.add('**/*.jsx');
|
|
990
|
+
newFiles.add('**/*.cjs');
|
|
991
|
+
newFiles.add('**/*.mjs');
|
|
992
|
+
files = Array.from(newFiles);
|
|
993
|
+
}
|
|
994
|
+
// If converting the TS rule, then we need to match ESLint default and also include .cts and .mts files.
|
|
995
|
+
if ((Array.isArray(rest.extends) &&
|
|
996
|
+
rest.extends.includes('plugin:@nx/typescript')) ||
|
|
997
|
+
rest.extends === 'plugin:@nx/typescript') {
|
|
998
|
+
const newFiles = new Set(files);
|
|
999
|
+
newFiles.add('**/*.ts');
|
|
1000
|
+
newFiles.add('**/*.tsx');
|
|
1001
|
+
newFiles.add('**/*.cts');
|
|
1002
|
+
newFiles.add('**/*.mts');
|
|
1003
|
+
files = Array.from(newFiles);
|
|
1004
|
+
}
|
|
670
1005
|
addTSObjectProperty(objectLiteralElements, 'files', files);
|
|
671
1006
|
addTSObjectProperty(objectLiteralElements, 'excludedFiles', excludedFiles);
|
|
672
1007
|
// Apply rules (and spread ...config.rules into it as the first assignment)
|
|
@@ -690,6 +1025,20 @@ function generateFlatOverride(_override) {
|
|
|
690
1025
|
], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createParenthesizedExpression(ts.factory.createObjectLiteralExpression(objectLiteralElements, true))),
|
|
691
1026
|
]));
|
|
692
1027
|
}
|
|
1028
|
+
function generateESMParserImport(override) {
|
|
1029
|
+
return ts.factory.createPropertyAssignment('parser', ts.factory.createAwaitExpression(ts.factory.createCallExpression(ts.factory.createIdentifier('import'), undefined, [
|
|
1030
|
+
ts.factory.createStringLiteral(override['languageOptions']?.['parserOptions']?.parser ??
|
|
1031
|
+
override['languageOptions']?.parser ??
|
|
1032
|
+
override.parser),
|
|
1033
|
+
])));
|
|
1034
|
+
}
|
|
1035
|
+
function generateCJSParserImport(override) {
|
|
1036
|
+
return ts.factory.createPropertyAssignment('parser', ts.factory.createCallExpression(ts.factory.createIdentifier('require'), undefined, [
|
|
1037
|
+
ts.factory.createStringLiteral(override['languageOptions']?.['parserOptions']?.parser ??
|
|
1038
|
+
override['languageOptions']?.parser ??
|
|
1039
|
+
override.parser),
|
|
1040
|
+
]));
|
|
1041
|
+
}
|
|
693
1042
|
function generateFlatPredefinedConfig(predefinedConfigName, moduleName = 'nx', spread = true) {
|
|
694
1043
|
const node = ts.factory.createElementAccessExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(moduleName), ts.factory.createIdentifier('configs')), ts.factory.createStringLiteral(predefinedConfigName));
|
|
695
1044
|
return spread ? ts.factory.createSpreadElement(node) : node;
|
|
@@ -722,14 +1071,14 @@ function addTSObjectProperty(elements, key, value) {
|
|
|
722
1071
|
*/
|
|
723
1072
|
function generateAst(input, propertyAssignmentReplacer) {
|
|
724
1073
|
if (Array.isArray(input)) {
|
|
725
|
-
return ts.factory.createArrayLiteralExpression(input.map((item) => generateAst(item, propertyAssignmentReplacer)),
|
|
1074
|
+
return ts.factory.createArrayLiteralExpression(input.map((item) => generateAst(item, propertyAssignmentReplacer)), true // Always treat as multiline, using item.length does not work in all cases
|
|
726
1075
|
);
|
|
727
1076
|
}
|
|
728
1077
|
if (input === null) {
|
|
729
1078
|
return ts.factory.createNull();
|
|
730
1079
|
}
|
|
731
1080
|
if (typeof input === 'object') {
|
|
732
|
-
return ts.factory.createObjectLiteralExpression(generatePropertyAssignmentsFromObjectEntries(input, propertyAssignmentReplacer), Object.keys(input).length > 1
|
|
1081
|
+
return ts.factory.createObjectLiteralExpression(generatePropertyAssignmentsFromObjectEntries(input, propertyAssignmentReplacer), true // Always treat as multiline, using Object.keys(input).length > 1 does not work in all cases
|
|
733
1082
|
);
|
|
734
1083
|
}
|
|
735
1084
|
if (typeof input === 'string') {
|