@taiga-ui/prettier-config 0.446.0 → 0.448.0
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/index.js +9 -6
- package/package.json +9 -9
- package/plugins/prettier-plugin-sort.js +227 -0
- package/project.json +1 -1
- package/plugins/prettier-plugin-sort-package.js +0 -46
package/index.js
CHANGED
|
@@ -32,16 +32,19 @@ module.exports = {
|
|
|
32
32
|
},
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
|
-
files: [
|
|
35
|
+
files: [
|
|
36
|
+
'package.json',
|
|
37
|
+
'ng-package.json',
|
|
38
|
+
'project.json',
|
|
39
|
+
'renovate.json',
|
|
40
|
+
'default.json',
|
|
41
|
+
'tsconfig*.json',
|
|
42
|
+
],
|
|
36
43
|
options: {
|
|
37
44
|
parser: 'json-stringify',
|
|
38
45
|
plugins: [
|
|
39
46
|
require.resolve(
|
|
40
|
-
path.resolve(
|
|
41
|
-
__dirname,
|
|
42
|
-
'plugins',
|
|
43
|
-
'prettier-plugin-sort-package.js',
|
|
44
|
-
),
|
|
47
|
+
path.resolve(__dirname, 'plugins', 'prettier-plugin-sort.js'),
|
|
45
48
|
),
|
|
46
49
|
],
|
|
47
50
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taiga-ui/prettier-config",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.448.0",
|
|
4
4
|
"description": "Taiga-ui prettier config",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"prettier",
|
|
@@ -13,20 +13,20 @@
|
|
|
13
13
|
"license": "Apache-2.0",
|
|
14
14
|
"contributors": [
|
|
15
15
|
{
|
|
16
|
-
"
|
|
17
|
-
"
|
|
16
|
+
"email": "alexander@inkin.ru",
|
|
17
|
+
"name": "Alex Inkin"
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
|
-
"
|
|
21
|
-
"
|
|
20
|
+
"email": "splincodewd@yandex.ru",
|
|
21
|
+
"name": "Maksim Ivanov"
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
|
-
"
|
|
25
|
-
"
|
|
24
|
+
"email": "vladimir.potekh@gmail.com",
|
|
25
|
+
"name": "Vladimir Potekhin"
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
|
-
"
|
|
29
|
-
"
|
|
28
|
+
"email": "nikita.s.barsukov@gmail.com",
|
|
29
|
+
"name": "Nikita Barsukov"
|
|
30
30
|
}
|
|
31
31
|
],
|
|
32
32
|
"main": "index.js",
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
const prettier = import('prettier');
|
|
2
|
+
const sortPackageJson = import('sort-package-json');
|
|
3
|
+
const {parsers} = require('prettier/parser-babel');
|
|
4
|
+
const {doc} = require('prettier');
|
|
5
|
+
|
|
6
|
+
const {join} = doc.builders;
|
|
7
|
+
|
|
8
|
+
const jsonStringifyParser = parsers['json-stringify'];
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Key order for `compilerOptions` in tsconfig files.
|
|
12
|
+
* Keys listed here appear first (in this order); remaining keys are sorted alphabetically.
|
|
13
|
+
*/
|
|
14
|
+
const COMPILER_OPTIONS_KEY_ORDER = ['baseUrl', 'rootDir', 'strict'];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Top-level key order for tsconfig files.
|
|
18
|
+
* Keys listed here will appear first (in this order); remaining keys keep their original order.
|
|
19
|
+
*/
|
|
20
|
+
const TSCONFIG_KEY_ORDER = [
|
|
21
|
+
'$schema',
|
|
22
|
+
'extends',
|
|
23
|
+
'compileOnSave',
|
|
24
|
+
'compilerOptions',
|
|
25
|
+
'angularCompilerOptions',
|
|
26
|
+
'files',
|
|
27
|
+
'include',
|
|
28
|
+
'exclude',
|
|
29
|
+
'references',
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Recursively sorts all plain-object keys alphabetically.
|
|
34
|
+
* Arrays are traversed but their element order is preserved.
|
|
35
|
+
*
|
|
36
|
+
* @param {unknown} value
|
|
37
|
+
* @returns {unknown}
|
|
38
|
+
*/
|
|
39
|
+
function sortAlphabetically(value) {
|
|
40
|
+
if (Array.isArray(value)) {
|
|
41
|
+
return value.map(sortAlphabetically);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (typeof value === 'object' && value !== null) {
|
|
45
|
+
/** @type {Record<string, unknown>} */
|
|
46
|
+
const result = {};
|
|
47
|
+
|
|
48
|
+
for (const key of Object.keys(value).sort()) {
|
|
49
|
+
result[key] = sortAlphabetically(
|
|
50
|
+
/** @type {Record<string, unknown>} */ value[key],
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Reorders the top-level keys of a plain object according to `keyOrder`.
|
|
62
|
+
* Keys not listed in `keyOrder` are appended afterward, sorted alphabetically.
|
|
63
|
+
*
|
|
64
|
+
* @param {Record<string, unknown>} obj
|
|
65
|
+
* @param {string[]} keyOrder
|
|
66
|
+
* @returns {Record<string, unknown>}
|
|
67
|
+
*/
|
|
68
|
+
function sortKeysByOrder(obj, keyOrder) {
|
|
69
|
+
const result = /** @type {Record<string, unknown>} */ {};
|
|
70
|
+
|
|
71
|
+
for (const key of keyOrder) {
|
|
72
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
73
|
+
result[key] = obj[key];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
for (const key of Object.keys(obj).sort()) {
|
|
78
|
+
if (!Object.prototype.hasOwnProperty.call(result, key)) {
|
|
79
|
+
result[key] = obj[key];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
exports.parsers = {
|
|
87
|
+
'json-stringify': {
|
|
88
|
+
...jsonStringifyParser,
|
|
89
|
+
/**
|
|
90
|
+
* @param {string} text
|
|
91
|
+
* @param {{ filepath: string | undefined; }} options
|
|
92
|
+
*/
|
|
93
|
+
async parse(text, options) {
|
|
94
|
+
const filepath = options.filepath ?? '';
|
|
95
|
+
|
|
96
|
+
if (filepath.endsWith('package-lock.json')) {
|
|
97
|
+
return jsonStringifyParser.parse(text, options);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// To avoid parsing errors
|
|
101
|
+
text = await (await prettier).format(text, {filepath: options.filepath});
|
|
102
|
+
|
|
103
|
+
if (jsonStringifyParser.preprocess) {
|
|
104
|
+
text = jsonStringifyParser.preprocess(text, options);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const json = JSON.parse(text);
|
|
108
|
+
let sorted;
|
|
109
|
+
|
|
110
|
+
if (/tsconfig[^/\\]*\.json$/.test(filepath)) {
|
|
111
|
+
// For tsconfig files use a dedicated key order instead of sort-package-json,
|
|
112
|
+
// which treats unknown keys as package.json fields and orders them badly.
|
|
113
|
+
sorted = sortKeysByOrder(json, TSCONFIG_KEY_ORDER);
|
|
114
|
+
} else {
|
|
115
|
+
const unsortedScripts = JSON.parse(JSON.stringify(json?.scripts || {}));
|
|
116
|
+
|
|
117
|
+
sorted = (await sortPackageJson).default(json);
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @note: add the scripts field if it's provided
|
|
121
|
+
* the scripts must be unsorted
|
|
122
|
+
*/
|
|
123
|
+
if (
|
|
124
|
+
filepath.endsWith('package.json') &&
|
|
125
|
+
json?.hasOwnProperty('scripts')
|
|
126
|
+
) {
|
|
127
|
+
sorted.scripts = unsortedScripts;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Sort all nested objects alphabetically.
|
|
132
|
+
// Top-level key order is already set above; here we only recurse into values.
|
|
133
|
+
// `scripts` in package.json is intentionally left unsorted.
|
|
134
|
+
for (const key of Object.keys(sorted)) {
|
|
135
|
+
if (key === 'scripts' && filepath.endsWith('package.json')) {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (typeof sorted[key] === 'object' && sorted[key] !== null) {
|
|
140
|
+
sorted[key] =
|
|
141
|
+
key === 'compilerOptions'
|
|
142
|
+
? sortKeysByOrder(
|
|
143
|
+
/** @type {Record<string, unknown>} */ sorted[key],
|
|
144
|
+
COMPILER_OPTIONS_KEY_ORDER,
|
|
145
|
+
)
|
|
146
|
+
: sortAlphabetically(sorted[key]);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
text = JSON.stringify(sorted);
|
|
151
|
+
|
|
152
|
+
return jsonStringifyParser.parse(text, options);
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Returns true for AST nodes that represent a primitive JSON value (string, number, boolean, null).
|
|
159
|
+
*
|
|
160
|
+
* @param {unknown} node
|
|
161
|
+
* @returns {boolean}
|
|
162
|
+
*/
|
|
163
|
+
function isPrimitiveLiteral(node) {
|
|
164
|
+
if (!node || typeof node !== 'object') {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const {type} = /** @type {{type: string}} */ node;
|
|
169
|
+
|
|
170
|
+
return (
|
|
171
|
+
type === 'StringLiteral' ||
|
|
172
|
+
type === 'NumericLiteral' ||
|
|
173
|
+
type === 'BooleanLiteral' ||
|
|
174
|
+
type === 'NullLiteral' ||
|
|
175
|
+
// Fallback for parsers that produce generic `Literal` nodes
|
|
176
|
+
(type === 'Literal' &&
|
|
177
|
+
/** @type {{value: unknown}} */ node.value !==
|
|
178
|
+
Object(/** @type {{value: unknown}} */ node.value))
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Override the `estree-json` printer (used by both `json` and `json-stringify` parsers).
|
|
184
|
+
* The only change: arrays with 1–2 primitive elements are kept on a single line.
|
|
185
|
+
* Objects are always expanded by the original printer.
|
|
186
|
+
*/
|
|
187
|
+
let originalEstreeJsonPrinter;
|
|
188
|
+
|
|
189
|
+
try {
|
|
190
|
+
originalEstreeJsonPrinter =
|
|
191
|
+
/** @type {{printers: Record<string, import('prettier').Printer>}} */ require('prettier/plugins/estree')
|
|
192
|
+
.printers?.['estree-json'];
|
|
193
|
+
} catch {}
|
|
194
|
+
|
|
195
|
+
if (originalEstreeJsonPrinter) {
|
|
196
|
+
exports.printers = {
|
|
197
|
+
'estree-json': {
|
|
198
|
+
...originalEstreeJsonPrinter,
|
|
199
|
+
/**
|
|
200
|
+
* @param {import('prettier').AstPath} path
|
|
201
|
+
* @param {import('prettier').ParserOptions} options
|
|
202
|
+
* @param {(path: import('prettier').AstPath) => import('prettier').Doc} print
|
|
203
|
+
* @returns {import('prettier').Doc}
|
|
204
|
+
*/
|
|
205
|
+
print(path, options, print) {
|
|
206
|
+
const node = /** @type {{type: string; elements: unknown[]}} */ path.node;
|
|
207
|
+
|
|
208
|
+
if (
|
|
209
|
+
node.type === 'ArrayExpression' &&
|
|
210
|
+
node.elements.length >= 1 &&
|
|
211
|
+
node.elements.length <= 2 &&
|
|
212
|
+
node.elements.every(isPrimitiveLiteral)
|
|
213
|
+
) {
|
|
214
|
+
const elements = /** @type {import('prettier').Doc[]} */ [];
|
|
215
|
+
|
|
216
|
+
path.each((p) => {
|
|
217
|
+
elements.push(print(p));
|
|
218
|
+
}, 'elements');
|
|
219
|
+
|
|
220
|
+
return ['[', join(', ', elements), ']'];
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return originalEstreeJsonPrinter.print(path, options, print);
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
}
|
package/project.json
CHANGED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
const prettier = import('prettier');
|
|
2
|
-
const sortPackageJson = import('sort-package-json');
|
|
3
|
-
const {parsers} = require('prettier/parser-babel');
|
|
4
|
-
|
|
5
|
-
const parser = parsers['json-stringify'];
|
|
6
|
-
|
|
7
|
-
exports.parsers = {
|
|
8
|
-
'json-stringify': {
|
|
9
|
-
...parser,
|
|
10
|
-
/**
|
|
11
|
-
* @param {string} text
|
|
12
|
-
* @param {{ filepath: string | undefined; }} options
|
|
13
|
-
*/
|
|
14
|
-
async parse(text, options) {
|
|
15
|
-
if (options.filepath?.endsWith('package-lock.json')) {
|
|
16
|
-
return parser.parse(text, options);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// To avoid parsing errors
|
|
20
|
-
text = await (await prettier).format(text, {filepath: options.filepath});
|
|
21
|
-
|
|
22
|
-
if (parser.preprocess) {
|
|
23
|
-
text = parser.preprocess(text, options);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const json = JSON.parse(text);
|
|
27
|
-
const unsortedScripts = JSON.parse(JSON.stringify(json?.scripts || {}));
|
|
28
|
-
const sorted = (await sortPackageJson).default(json);
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @note: add the scripts field if it's provided
|
|
32
|
-
* the scripts must be unsorted
|
|
33
|
-
*/
|
|
34
|
-
if (
|
|
35
|
-
options.filepath?.endsWith('package.json') &&
|
|
36
|
-
json?.hasOwnProperty('scripts')
|
|
37
|
-
) {
|
|
38
|
-
sorted.scripts = unsortedScripts;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
text = JSON.stringify(sorted);
|
|
42
|
-
|
|
43
|
-
return parser.parse(text, options);
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
};
|