-
-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathcommon.ts
97 lines (81 loc) · 3.45 KB
/
common.ts
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
38
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
import { imports, exports, common } from '@sveltejs/cli-core/js';
import { parseScript, parseSvelte } from '@sveltejs/cli-core/parsers';
import process from 'node:process';
export function addEslintConfigPrettier(content: string): string {
const { ast, generateCode } = parseScript(content);
// if a default import for `eslint-plugin-svelte` already exists, then we'll use their specifier's name instead
const importNodes = ast.body.filter((n) => n.type === 'ImportDeclaration');
const sveltePluginImport = importNodes.find(
(n) =>
n.type === 'ImportDeclaration' &&
n.source.value === 'eslint-plugin-svelte' &&
n.specifiers?.some((n) => n.type === 'ImportDefaultSpecifier')
);
let svelteImportName: string;
for (const specifier of sveltePluginImport?.specifiers ?? []) {
if (specifier.type === 'ImportDefaultSpecifier' && specifier.local?.name) {
svelteImportName = specifier.local.name as string;
}
}
svelteImportName ??= 'svelte';
imports.addDefault(ast, 'eslint-plugin-svelte', svelteImportName);
imports.addDefault(ast, 'eslint-config-prettier', 'prettier');
const fallbackConfig = common.expressionFromString('[]');
const defaultExport = exports.defaultExport(ast, fallbackConfig);
const eslintConfig = defaultExport.value;
if (eslintConfig.type !== 'ArrayExpression' && eslintConfig.type !== 'CallExpression')
return content;
const prettier = common.expressionFromString('prettier');
const sveltePrettierConfig = common.expressionFromString(`${svelteImportName}.configs.prettier`);
const configSpread = common.createSpreadElement(sveltePrettierConfig);
const nodesToInsert = [];
if (!common.hasNode(eslintConfig, prettier)) nodesToInsert.push(prettier);
if (!common.hasNode(eslintConfig, configSpread)) nodesToInsert.push(configSpread);
const elements =
eslintConfig.type === 'ArrayExpression' ? eslintConfig.elements : eslintConfig.arguments;
// finds index of `...svelte.configs["..."]`
const idx = elements.findIndex(
(el) =>
el?.type === 'SpreadElement' &&
el.argument.type === 'MemberExpression' &&
el.argument.object.type === 'MemberExpression' &&
el.argument.object.property.type === 'Identifier' &&
el.argument.object.property.name === 'configs' &&
el.argument.object.object.type === 'Identifier' &&
el.argument.object.object.name === svelteImportName
);
if (idx !== -1) {
elements.splice(idx + 1, 0, ...nodesToInsert);
} else {
// append to the end as a fallback
elements.push(...nodesToInsert);
}
return generateCode();
}
export function addToDemoPage(content: string, path: string): string {
const { template, generateCode } = parseSvelte(content);
for (const node of template.ast.childNodes) {
if (node.type === 'tag' && node.attribs['href'] === `/demo/${path}`) {
return content;
}
}
const newLine = template.source ? '\n' : '';
const src = template.source + `${newLine}<a href="/demo/${path}">${path}</a>`;
return generateCode({ template: src });
}
/**
* Returns the corresponding `@types/node` version for the version of Node.js running in the current process.
*
* If the installed version of Node.js is from a `Current` release, then the major is decremented to
* the nearest `LTS` release version.
*/
export function getNodeTypesVersion(): string {
const nodeVersion = process.versions.node;
const [major] = nodeVersion.split('.');
const isLTS = Number(major) % 2 === 0;
if (isLTS) {
return `^${major}`;
}
const previousLTSMajor = Number(major) - 1;
return `^${previousLTSMajor}`;
}