@standard-config/prettier 1.4.0 → 1.6.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/.editorconfig +43 -0
- package/README.md +12 -0
- package/dist/index.d.mts +82 -2
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +173 -62
- package/dist/index.mjs.map +1 -1
- package/package.json +18 -11
package/.editorconfig
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
root = true
|
|
2
|
+
|
|
3
|
+
[*]
|
|
4
|
+
charset = utf-8
|
|
5
|
+
end_of_line = lf
|
|
6
|
+
indent_size = 2
|
|
7
|
+
indent_style = space
|
|
8
|
+
insert_final_newline = true
|
|
9
|
+
max_line_length = 80
|
|
10
|
+
trim_trailing_whitespace = true
|
|
11
|
+
|
|
12
|
+
[*.{css,scss}]
|
|
13
|
+
indent_size = 4
|
|
14
|
+
indent_style = tab
|
|
15
|
+
max_line_length = 100
|
|
16
|
+
|
|
17
|
+
[*.{graphql,graphqls,gql}]
|
|
18
|
+
indent_size = 4
|
|
19
|
+
indent_style = tab
|
|
20
|
+
|
|
21
|
+
[*.{html,htm}]
|
|
22
|
+
indent_size = 4
|
|
23
|
+
indent_style = tab
|
|
24
|
+
max_line_length = 100
|
|
25
|
+
|
|
26
|
+
[*.{js,jsx,cjs,mjs}]
|
|
27
|
+
indent_size = 4
|
|
28
|
+
indent_style = tab
|
|
29
|
+
|
|
30
|
+
[*.{json,jsonc,json5}]
|
|
31
|
+
indent_size = 4
|
|
32
|
+
indent_style = tab
|
|
33
|
+
|
|
34
|
+
[*.{md,mdx}]
|
|
35
|
+
indent_size = 4
|
|
36
|
+
|
|
37
|
+
[*.{ts,tsx,cts,mts}]
|
|
38
|
+
indent_size = 4
|
|
39
|
+
indent_style = tab
|
|
40
|
+
|
|
41
|
+
[*.{xml,plist,svg}]
|
|
42
|
+
indent_size = 4
|
|
43
|
+
indent_style = tab
|
package/README.md
CHANGED
|
@@ -39,3 +39,15 @@ export default defineConfig({
|
|
|
39
39
|
useTabs: false,
|
|
40
40
|
});
|
|
41
41
|
```
|
|
42
|
+
|
|
43
|
+
### .editorconfig
|
|
44
|
+
|
|
45
|
+
For a consistent editor experience, you can use the included [`.editorconfig`](https://editorconfig.org) file in addition to the Prettier configuration.
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
ln -s node_modules/@standard-config/prettier/.editorconfig
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## License
|
|
52
|
+
|
|
53
|
+
MIT © [Dom Porada](https://dom.engineering)
|
package/dist/index.d.mts
CHANGED
|
@@ -1,9 +1,89 @@
|
|
|
1
|
-
import { Config } from "prettier";
|
|
1
|
+
import { Config, Options } from "prettier";
|
|
2
2
|
|
|
3
|
+
//#region src/types/index.d.ts
|
|
4
|
+
type PrettierPlugin = NonNullable<Options['plugins']>[number];
|
|
5
|
+
type DefaultOptions = {
|
|
6
|
+
/**
|
|
7
|
+
* Print spaces between brackets in object literals.
|
|
8
|
+
* @default true
|
|
9
|
+
*/
|
|
10
|
+
bracketSpacing?: Options['bracketSpacing'];
|
|
11
|
+
/**
|
|
12
|
+
* Define a custom sort order for JSON files.
|
|
13
|
+
*/
|
|
14
|
+
jsonSortOrder?: string | string[] | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Maximum line length before wrapping.
|
|
17
|
+
* @default 80
|
|
18
|
+
*/
|
|
19
|
+
printWidth?: Options['printWidth'];
|
|
20
|
+
/**
|
|
21
|
+
* Change when properties in objects are quoted.
|
|
22
|
+
* @default 'consistent'
|
|
23
|
+
*/
|
|
24
|
+
quoteProps?: Options['quoteProps'];
|
|
25
|
+
/**
|
|
26
|
+
* Indentation width for shell scripts.
|
|
27
|
+
* @default 2
|
|
28
|
+
*/
|
|
29
|
+
shellTabWidth?: Options['tabWidth'];
|
|
30
|
+
/**
|
|
31
|
+
* Use tabs instead of spaces for shell scripts.
|
|
32
|
+
* @default false
|
|
33
|
+
*/
|
|
34
|
+
shellUseTabs?: Options['useTabs'];
|
|
35
|
+
/**
|
|
36
|
+
* Use single quotes instead of double quotes.
|
|
37
|
+
* @default true
|
|
38
|
+
*/
|
|
39
|
+
singleQuote?: Options['singleQuote'];
|
|
40
|
+
/**
|
|
41
|
+
* Indentation width for all non-shell files.
|
|
42
|
+
* @default 4
|
|
43
|
+
*/
|
|
44
|
+
tabWidth?: Options['tabWidth'];
|
|
45
|
+
/**
|
|
46
|
+
* Print trailing commas where valid in ES5.
|
|
47
|
+
* @default 'es5'
|
|
48
|
+
*/
|
|
49
|
+
trailingComma?: Options['trailingComma'];
|
|
50
|
+
/**
|
|
51
|
+
* Use tabs instead of spaces for all non-shell files.
|
|
52
|
+
* @default true
|
|
53
|
+
*/
|
|
54
|
+
useTabs?: Options['useTabs'];
|
|
55
|
+
};
|
|
56
|
+
type StandardOptions = { // Prettier’s `Options` is a mapped type, so overlapping keys must
|
|
57
|
+
// be explicitly omitted before merging with `DefaultOptions`
|
|
58
|
+
[K in keyof Options as K extends keyof DefaultOptions ? never : K]: Options[K] } & DefaultOptions;
|
|
59
|
+
type StandardConfigOverride = {
|
|
60
|
+
excludeFiles?: string[];
|
|
61
|
+
files: string[];
|
|
62
|
+
options: StandardOptions;
|
|
63
|
+
};
|
|
64
|
+
type StandardConfigOverrides = StandardConfigOverride[];
|
|
65
|
+
type StandardConfigPluginOverrides = Record<string, PrettierPlugin | undefined>;
|
|
66
|
+
type StandardConfig = StandardOptions & {
|
|
67
|
+
/**
|
|
68
|
+
* File-based config overrides.
|
|
69
|
+
*/
|
|
70
|
+
overrides?: StandardConfigOverrides;
|
|
71
|
+
/**
|
|
72
|
+
* @deprecated Intended for development use and not covered by semver.
|
|
73
|
+
*/
|
|
74
|
+
pluginOverrides?: StandardConfigPluginOverrides;
|
|
75
|
+
};
|
|
76
|
+
//#endregion
|
|
3
77
|
//#region src/define-config/index.d.ts
|
|
4
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Combine Standard Config with optional config overrides.
|
|
80
|
+
*/
|
|
81
|
+
declare function defineConfig(config?: StandardConfig): Config;
|
|
5
82
|
//#endregion
|
|
6
83
|
//#region src/prioritize-keys/index.d.ts
|
|
84
|
+
/**
|
|
85
|
+
* @deprecated Use an array value for the `jsonSortOrder` property instead.
|
|
86
|
+
*/
|
|
7
87
|
declare function prioritizeKeys(...keys: ReadonlyArray<string>): string;
|
|
8
88
|
//#endregion
|
|
9
89
|
export { defineConfig, prioritizeKeys };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":["Options","PrettierOptions","PrettierPlugin","NonNullable","PrettierPlugins","DefaultOptions","bracketSpacing","jsonSortOrder","printWidth","quoteProps","shellTabWidth","shellUseTabs","singleQuote","tabWidth","trailingComma","useTabs","StandardOptions","K","IndentationOptions","Pick","ShellIndentationOptions","StandardConfigOverride","excludeFiles","files","options","StandardConfigOverrides","StandardConfigPluginOverrides","Record","StandardConfig","overrides","pluginOverrides"],"sources":["../src/types/index.d.ts","../src/define-config/index.ts","../src/prioritize-keys/index.ts"],"mappings":";;;KAEYE,cAAAA,GAAiBC,WAAAA,CAAYF,OAAAA;AAAAA,KAIpCI,cAAAA;EAJmD;AAET;;;EAO9CC,cAAAA,GAAiBL,OAAAA;;;;EAIjBM,aAAAA;;;;;EAKAC,UAAAA,GAAaP,OAAAA;EAmCY;;;;EA9BzBQ,UAAAA,GAAaR,OAAAA;;;;;EAKbS,aAAAA,GAAgBT,OAAAA;;;;;EAKhBU,YAAAA,GAAeV,OAAAA;;;;;EAKfW,WAAAA,GAAcX,OAAAA;;;AAkBf;;EAbCY,QAAAA,GAAWZ,OAAAA;;;;;EAKXa,aAAAA,GAAgBb,OAAAA;;;;;EAKhBc,OAAAA,GAAUd,OAAAA;AAAAA;AAAAA,KAGCe,eAAAA;EAAAA;AAAAA,YAGCf,OAAAA,IAAmBgB,CAAAA,eAAgBZ,cAAAA,WAE5CY,CAAAA,GAAIhB,OAAAA,CAAgBgB,CAAAA,MACpBZ,cAAAA;AAAAA,KASQgB,sBAAAA;EACXC,YAAAA;EACAC,KAAAA;EACAC,OAAAA,EAASR,eAAAA;AAAAA;AAAAA,KAGES,uBAAAA,GAA0BJ,sBAAAA;AAAAA,KAE1BK,6BAAAA,GAAgCC,MAAAA,SAE3CzB,cAAAA;AAAAA,KAGW0B,cAAAA,GAAiBZ,eAAAA;;;;EAI5Ba,SAAAA,GAAYJ,uBAAAA;;;;EAIZK,eAAAA,GAAkBJ,6BAAAA;AAAAA;;;;AA5FnB;;iBCOwB,YAAA,CACvB,MAAA,GAAQ,cAAA,GACN,MAAA;;;;;;iBCRqB,cAAA,CAAA,GAAkB,IAAA,EAAM,aAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,77 +1,70 @@
|
|
|
1
|
+
import defineClone from "rfdc";
|
|
1
2
|
import * as pluginOxidation from "@prettier/plugin-oxc";
|
|
2
3
|
import * as pluginExpandJSON from "prettier-plugin-expand-json";
|
|
3
4
|
import * as pluginPackageJSON from "prettier-plugin-packagejson";
|
|
4
5
|
import * as pluginShell from "prettier-plugin-sh";
|
|
5
6
|
import * as pluginSortJSON from "prettier-plugin-sort-json";
|
|
6
|
-
import { klona } from "klona/lite";
|
|
7
7
|
|
|
8
|
-
//#region src/
|
|
9
|
-
|
|
10
|
-
const order = {};
|
|
11
|
-
for (const key of keys) order[String(key)] = null;
|
|
12
|
-
return JSON.stringify({
|
|
13
|
-
...order,
|
|
14
|
-
[/.*/]: "lexical"
|
|
15
|
-
});
|
|
16
|
-
}
|
|
8
|
+
//#region src/clone/index.ts
|
|
9
|
+
var clone_default = defineClone({ circles: true });
|
|
17
10
|
|
|
18
11
|
//#endregion
|
|
19
|
-
//#region src/config/index.ts
|
|
12
|
+
//#region src/generate-config/index.ts
|
|
20
13
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
14
|
+
* Generate the base Standard Config.
|
|
15
|
+
*
|
|
16
|
+
* Shell scripts can’t be reliably identified by name alone—they’re recognized
|
|
17
|
+
* by the shebang, not the extension. As a result, shell formatting options
|
|
23
18
|
* (two-space indentation) must be defined as the global defaults.
|
|
24
19
|
*
|
|
25
20
|
* This requires overriding those options for other file types individually
|
|
26
|
-
* with what we consider the actual defaults.
|
|
21
|
+
* with what we consider the actual defaults (`baseDefaults`). `generateConfig`
|
|
22
|
+
* is a factory that encapsulates this logic and returns the final config.
|
|
27
23
|
*/
|
|
28
|
-
|
|
29
|
-
tabWidth
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
24
|
+
function generateConfig(baseDefaults = {}, shellDefaults = {}) {
|
|
25
|
+
const { tabWidth = 4, useTabs = true } = baseDefaults;
|
|
26
|
+
const { shellTabWidth = 2, shellUseTabs = false } = shellDefaults;
|
|
27
|
+
return clone_default({
|
|
28
|
+
plugins: [
|
|
29
|
+
"@prettier/plugin-oxc",
|
|
30
|
+
"prettier-plugin-sh",
|
|
31
|
+
"prettier-plugin-expand-json"
|
|
32
|
+
],
|
|
33
|
+
bracketSpacing: true,
|
|
34
|
+
printWidth: 80,
|
|
35
|
+
quoteProps: "consistent",
|
|
36
|
+
singleQuote: true,
|
|
37
|
+
tabWidth: shellTabWidth,
|
|
38
|
+
trailingComma: "es5",
|
|
39
|
+
useTabs: shellUseTabs,
|
|
40
|
+
overrides: [...getFileTypeOverrides({
|
|
41
|
+
tabWidth,
|
|
42
|
+
useTabs
|
|
43
|
+
}), ...getFileNameOverrides()]
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function getFileTypeOverrides(baseDefaults = {}) {
|
|
47
|
+
return [
|
|
46
48
|
{
|
|
47
49
|
files: ["*.css", "*.scss"],
|
|
48
50
|
options: {
|
|
49
|
-
...
|
|
51
|
+
...baseDefaults,
|
|
50
52
|
printWidth: 100,
|
|
51
53
|
singleQuote: false
|
|
52
54
|
}
|
|
53
55
|
},
|
|
54
|
-
(
|
|
55
|
-
/**
|
|
56
|
-
* Fish file formatting follows the output of `fish_indent`, which
|
|
57
|
-
* defaults to four-space indentation.
|
|
58
|
-
*/
|
|
59
|
-
{
|
|
60
|
-
files: ["*.fish"],
|
|
61
|
-
options: { tabWidth: 4 }
|
|
62
|
-
}),
|
|
63
56
|
{
|
|
64
57
|
files: [
|
|
65
58
|
"*.graphql",
|
|
66
59
|
"*.graphqls",
|
|
67
60
|
"*.gql"
|
|
68
61
|
],
|
|
69
|
-
options: { ...
|
|
62
|
+
options: { ...baseDefaults }
|
|
70
63
|
},
|
|
71
64
|
{
|
|
72
65
|
files: ["*.html", "*.htm"],
|
|
73
66
|
options: {
|
|
74
|
-
...
|
|
67
|
+
...baseDefaults,
|
|
75
68
|
printWidth: 100
|
|
76
69
|
}
|
|
77
70
|
},
|
|
@@ -83,7 +76,7 @@ const DEFAULT_CONFIG = {
|
|
|
83
76
|
"*.mjs"
|
|
84
77
|
],
|
|
85
78
|
options: {
|
|
86
|
-
...
|
|
79
|
+
...baseDefaults,
|
|
87
80
|
parser: "oxc"
|
|
88
81
|
}
|
|
89
82
|
},
|
|
@@ -93,7 +86,7 @@ const DEFAULT_CONFIG = {
|
|
|
93
86
|
"*.jsonc",
|
|
94
87
|
"*.json5"
|
|
95
88
|
],
|
|
96
|
-
options: { ...
|
|
89
|
+
options: { ...baseDefaults }
|
|
97
90
|
},
|
|
98
91
|
{
|
|
99
92
|
files: [
|
|
@@ -103,9 +96,9 @@ const DEFAULT_CONFIG = {
|
|
|
103
96
|
],
|
|
104
97
|
excludeFiles: ["package.json"],
|
|
105
98
|
options: {
|
|
106
|
-
plugins: [
|
|
99
|
+
plugins: ["prettier-plugin-sort-json", "prettier-plugin-expand-json"],
|
|
107
100
|
jsonRecursiveSort: true,
|
|
108
|
-
jsonSortOrder:
|
|
101
|
+
jsonSortOrder: ["$schema"]
|
|
109
102
|
}
|
|
110
103
|
},
|
|
111
104
|
(
|
|
@@ -124,7 +117,7 @@ const DEFAULT_CONFIG = {
|
|
|
124
117
|
{
|
|
125
118
|
files: ["*.md", "*.mdx"],
|
|
126
119
|
options: {
|
|
127
|
-
...
|
|
120
|
+
...baseDefaults,
|
|
128
121
|
useTabs: false
|
|
129
122
|
}
|
|
130
123
|
}),
|
|
@@ -136,7 +129,7 @@ const DEFAULT_CONFIG = {
|
|
|
136
129
|
"*.mts"
|
|
137
130
|
],
|
|
138
131
|
options: {
|
|
139
|
-
...
|
|
132
|
+
...baseDefaults,
|
|
140
133
|
parser: "oxc-ts"
|
|
141
134
|
}
|
|
142
135
|
},
|
|
@@ -147,12 +140,16 @@ const DEFAULT_CONFIG = {
|
|
|
147
140
|
"*.svg"
|
|
148
141
|
],
|
|
149
142
|
options: {
|
|
150
|
-
...
|
|
143
|
+
...baseDefaults,
|
|
151
144
|
parser: "html",
|
|
152
145
|
printWidth: 80,
|
|
153
146
|
singleAttributePerLine: true
|
|
154
147
|
}
|
|
155
|
-
}
|
|
148
|
+
}
|
|
149
|
+
];
|
|
150
|
+
}
|
|
151
|
+
function getFileNameOverrides() {
|
|
152
|
+
return [
|
|
156
153
|
(
|
|
157
154
|
/**
|
|
158
155
|
* All `.oxlintrc.json` fields defined by the Oxlint documentation
|
|
@@ -169,17 +166,35 @@ const DEFAULT_CONFIG = {
|
|
|
169
166
|
".oxlintrc.*.json",
|
|
170
167
|
".oxlintrc.*.jsonc"
|
|
171
168
|
],
|
|
172
|
-
options: { jsonSortOrder:
|
|
169
|
+
options: { jsonSortOrder: [
|
|
170
|
+
"$schema",
|
|
171
|
+
"files",
|
|
172
|
+
"extends",
|
|
173
|
+
"ignorePatterns",
|
|
174
|
+
"plugins",
|
|
175
|
+
"jsPlugins",
|
|
176
|
+
"categories",
|
|
177
|
+
"env",
|
|
178
|
+
"globals",
|
|
179
|
+
"settings",
|
|
180
|
+
"rules",
|
|
181
|
+
"overrides"
|
|
182
|
+
] }
|
|
173
183
|
}),
|
|
174
184
|
(
|
|
175
185
|
/**
|
|
186
|
+
* By default, Prettier uses a different parser for `package.json`
|
|
187
|
+
* files, which causes most JSON plugins to skip them entirely.
|
|
188
|
+
* This override ensures `package.json` is treated (and sorted)
|
|
189
|
+
* like any other `*.json` file.
|
|
190
|
+
*
|
|
176
191
|
* All `package.json` fields defined in the `npm@11` specification
|
|
177
192
|
* are sorted, along with additional commonly used fields.
|
|
178
193
|
*/
|
|
179
194
|
{
|
|
180
195
|
files: ["package.json"],
|
|
181
196
|
options: {
|
|
182
|
-
plugins: [
|
|
197
|
+
plugins: ["prettier-plugin-packagejson", "prettier-plugin-expand-json"],
|
|
183
198
|
packageSortOrder: [
|
|
184
199
|
"$schema",
|
|
185
200
|
"name",
|
|
@@ -241,17 +256,49 @@ const DEFAULT_CONFIG = {
|
|
|
241
256
|
"jsconfig.json",
|
|
242
257
|
"jsconfig.*.json"
|
|
243
258
|
],
|
|
244
|
-
options: { jsonSortOrder:
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
259
|
+
options: { jsonSortOrder: [
|
|
260
|
+
"$schema",
|
|
261
|
+
"extends",
|
|
262
|
+
"enable",
|
|
263
|
+
"references",
|
|
264
|
+
"compilerOptions",
|
|
265
|
+
"typeAcquisition",
|
|
266
|
+
"files",
|
|
267
|
+
"include",
|
|
268
|
+
"exclude",
|
|
269
|
+
"watchOptions",
|
|
270
|
+
"watchDirectory",
|
|
271
|
+
"watchFile",
|
|
272
|
+
"fallbackPolling",
|
|
273
|
+
"synchronousWatchDirectory",
|
|
274
|
+
"compileOnSave"
|
|
275
|
+
] }
|
|
276
|
+
}),
|
|
277
|
+
{
|
|
278
|
+
files: [".vscode/mcp.json"],
|
|
279
|
+
options: { jsonSortOrder: ["$schema", "command"] }
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
files: [".vscode/sessions.json"],
|
|
283
|
+
options: { jsonSortOrder: [
|
|
284
|
+
"$schema",
|
|
285
|
+
"name",
|
|
286
|
+
"commands",
|
|
287
|
+
"active"
|
|
288
|
+
] }
|
|
289
|
+
}
|
|
290
|
+
];
|
|
291
|
+
}
|
|
248
292
|
|
|
249
293
|
//#endregion
|
|
250
294
|
//#region src/merge-config/index.ts
|
|
295
|
+
/**
|
|
296
|
+
* Deep-merge two Standard Config objects.
|
|
297
|
+
*/
|
|
251
298
|
function mergeConfig(baseConfig, extensionConfig) {
|
|
252
|
-
if (!(typeof baseConfig === "object" && typeof extensionConfig === "object")) throw new TypeError("
|
|
253
|
-
const result =
|
|
254
|
-
for (const [key, value] of Object.entries(
|
|
299
|
+
if (!(typeof baseConfig === "object" && typeof extensionConfig === "object")) throw new TypeError("Standard Config error: expected config to be an object");
|
|
300
|
+
const result = clone_default(baseConfig);
|
|
301
|
+
for (const [key, value] of Object.entries(clone_default(extensionConfig))) {
|
|
255
302
|
if (value === void 0) {
|
|
256
303
|
delete result[key];
|
|
257
304
|
continue;
|
|
@@ -268,10 +315,74 @@ function isArray(value) {
|
|
|
268
315
|
return Array.isArray(value);
|
|
269
316
|
}
|
|
270
317
|
|
|
318
|
+
//#endregion
|
|
319
|
+
//#region src/prioritize-keys/index.ts
|
|
320
|
+
/**
|
|
321
|
+
* @deprecated Use an array value for the `jsonSortOrder` property instead.
|
|
322
|
+
*/
|
|
323
|
+
function prioritizeKeys(...keys) {
|
|
324
|
+
const order = {};
|
|
325
|
+
for (const key of keys) order[String(key)] = null;
|
|
326
|
+
return JSON.stringify({
|
|
327
|
+
...order,
|
|
328
|
+
[/.*/]: "lexical"
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
//#endregion
|
|
333
|
+
//#region src/transform-config/index.ts
|
|
334
|
+
/**
|
|
335
|
+
* Convert Standard Config to an exportable, Prettier-compatible format.
|
|
336
|
+
*/
|
|
337
|
+
function transformConfig(config, pluginOverrides = {}) {
|
|
338
|
+
config = clone_default(config);
|
|
339
|
+
const transform = (options) => {
|
|
340
|
+
if (options.jsonSortOrder) options.jsonSortOrder = transformJSONSortOrder(options.jsonSortOrder);
|
|
341
|
+
if (options.plugins) {
|
|
342
|
+
const plugins = transformPlugins(options.plugins, pluginOverrides);
|
|
343
|
+
if (plugins.length > 0) options.plugins = plugins;
|
|
344
|
+
else delete options.plugins;
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
transform(config);
|
|
348
|
+
if (config.overrides) for (const override of config.overrides) transform(override.options);
|
|
349
|
+
return config;
|
|
350
|
+
}
|
|
351
|
+
function transformJSONSortOrder(jsonSortOrder) {
|
|
352
|
+
if (Array.isArray(jsonSortOrder)) return prioritizeKeys(...jsonSortOrder);
|
|
353
|
+
return jsonSortOrder;
|
|
354
|
+
}
|
|
355
|
+
function transformPlugins(plugins, pluginOverrides) {
|
|
356
|
+
const pluginMap = {
|
|
357
|
+
"@prettier/plugin-oxc": pluginOxidation,
|
|
358
|
+
"prettier-plugin-expand-json": pluginExpandJSON,
|
|
359
|
+
"prettier-plugin-packagejson": pluginPackageJSON,
|
|
360
|
+
"prettier-plugin-sh": pluginShell,
|
|
361
|
+
"prettier-plugin-sort-json": pluginSortJSON,
|
|
362
|
+
...pluginOverrides
|
|
363
|
+
};
|
|
364
|
+
const resolved = [];
|
|
365
|
+
for (const plugin of plugins) {
|
|
366
|
+
const resolvedPlugin = typeof plugin === "string" && Object.hasOwn(pluginMap, plugin) ? pluginMap[plugin] : plugin;
|
|
367
|
+
if (resolvedPlugin) resolved.push(resolvedPlugin);
|
|
368
|
+
}
|
|
369
|
+
return resolved;
|
|
370
|
+
}
|
|
371
|
+
|
|
271
372
|
//#endregion
|
|
272
373
|
//#region src/define-config/index.ts
|
|
374
|
+
/**
|
|
375
|
+
* Combine Standard Config with optional config overrides.
|
|
376
|
+
*/
|
|
273
377
|
function defineConfig(config = {}) {
|
|
274
|
-
|
|
378
|
+
const { pluginOverrides, shellTabWidth, shellUseTabs, tabWidth, useTabs, ...extensionConfig } = config;
|
|
379
|
+
return transformConfig(mergeConfig(generateConfig({
|
|
380
|
+
useTabs,
|
|
381
|
+
tabWidth
|
|
382
|
+
}, {
|
|
383
|
+
shellUseTabs,
|
|
384
|
+
shellTabWidth
|
|
385
|
+
}), extensionConfig), pluginOverrides);
|
|
275
386
|
}
|
|
276
387
|
|
|
277
388
|
//#endregion
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["clone"],"sources":["../src/prioritize-keys/index.ts","../src/config/index.ts","../src/merge-config/index.ts","../src/define-config/index.ts"],"sourcesContent":["export default function prioritizeKeys(...keys: ReadonlyArray<string>): string {\n\t/* oxlint-disable-next-line typescript/no-restricted-types */\n\tconst order: Record<string, null> = {};\n\n\tfor (const key of keys) {\n\t\torder[String(key)] = null;\n\t}\n\n\treturn JSON.stringify({\n\t\t...order,\n\t\t/* oxlint-disable-next-line typescript/no-explicit-any */\n\t\t[/.*/ as any]: 'lexical',\n\t});\n}\n","import type { Config, Options } from 'prettier';\nimport * as pluginOxidation from '@prettier/plugin-oxc';\nimport * as pluginExpandJSON from 'prettier-plugin-expand-json';\nimport * as pluginPackageJSON from 'prettier-plugin-packagejson';\nimport * as pluginShell from 'prettier-plugin-sh';\nimport * as pluginSortJSON from 'prettier-plugin-sort-json';\nimport prioritizeKeys from '../prioritize-keys/index.ts';\n\n/**\n * Shell files can’t be reliably identified by name alone—they’re recognized by\n * the shebang, not the extension. As a result, shell formatting options\n * (two-space indentation) must be defined as the global defaults.\n *\n * This requires overriding those options for other file types individually\n * with what we consider the actual defaults. This object defines them.\n */\nexport const DEFAULT_OPTIONS = {\n\ttabWidth: 4,\n\tuseTabs: true,\n} as const satisfies Options;\n\nexport const DEFAULT_CONFIG = {\n\tplugins: [pluginOxidation, pluginShell, pluginExpandJSON],\n\tbracketSpacing: true,\n\tprintWidth: 80,\n\tquoteProps: 'consistent',\n\tsingleQuote: true,\n\ttabWidth: 2,\n\ttrailingComma: 'es5',\n\tuseTabs: false,\n\toverrides: [\n\t\t{\n\t\t\tfiles: ['*.css', '*.scss'],\n\t\t\toptions: {\n\t\t\t\t...DEFAULT_OPTIONS,\n\t\t\t\tprintWidth: 100,\n\t\t\t\tsingleQuote: false,\n\t\t\t},\n\t\t},\n\t\t/**\n\t\t * Fish file formatting follows the output of `fish_indent`, which\n\t\t * defaults to four-space indentation.\n\t\t */\n\t\t{\n\t\t\tfiles: ['*.fish'],\n\t\t\toptions: {\n\t\t\t\ttabWidth: 4,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tfiles: ['*.graphql', '*.graphqls', '*.gql'],\n\t\t\toptions: {\n\t\t\t\t...DEFAULT_OPTIONS,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tfiles: ['*.html', '*.htm'],\n\t\t\toptions: {\n\t\t\t\t...DEFAULT_OPTIONS,\n\t\t\t\tprintWidth: 100,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tfiles: ['*.js', '*.jsx', '*.cjs', '*.mjs'],\n\t\t\toptions: {\n\t\t\t\t...DEFAULT_OPTIONS,\n\t\t\t\tparser: 'oxc',\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tfiles: ['*.json', '*.jsonc', '*.json5'],\n\t\t\toptions: {\n\t\t\t\t...DEFAULT_OPTIONS,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tfiles: ['*.json', '*.jsonc', '*.json5'],\n\t\t\texcludeFiles: ['package.json'],\n\t\t\toptions: {\n\t\t\t\tplugins: [pluginSortJSON, pluginExpandJSON],\n\t\t\t\tjsonRecursiveSort: true,\n\t\t\t\tjsonSortOrder: prioritizeKeys('$schema'),\n\t\t\t},\n\t\t},\n\t\t/**\n\t\t * Tab-based indentation becomes inconvenient when rendered outside the\n\t\t * context of a code editor. In documentation, tabs in code blocks\n\t\t * require special handling that very few renderers support.\n\t\t *\n\t\t * At the time of writing, GitHub renders tabs correctly on the web, but\n\t\t * not in its mobile app. `npm`, often the point of discovery for\n\t\t * packages, does not provide any special handling for tabs either.\n\t\t *\n\t\t * To maximize the readability of code blocks in documentation, spaces\n\t\t * are the right compromise.\n\t\t */\n\t\t{\n\t\t\tfiles: ['*.md', '*.mdx'],\n\t\t\toptions: {\n\t\t\t\t...DEFAULT_OPTIONS,\n\t\t\t\tuseTabs: false,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tfiles: ['*.ts', '*.tsx', '*.cts', '*.mts'],\n\t\t\toptions: {\n\t\t\t\t...DEFAULT_OPTIONS,\n\t\t\t\tparser: 'oxc-ts',\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tfiles: ['*.xml', '*.plist', '*.svg'],\n\t\t\toptions: {\n\t\t\t\t...DEFAULT_OPTIONS,\n\t\t\t\tparser: 'html',\n\t\t\t\tprintWidth: 80,\n\t\t\t\tsingleAttributePerLine: true,\n\t\t\t},\n\t\t},\n\t\t/**\n\t\t * All `.oxlintrc.json` fields defined by the Oxlint documentation\n\t\t * are sorted, including nested fields.\n\t\t */\n\t\t{\n\t\t\tfiles: [\n\t\t\t\t'oxlintrc.json',\n\t\t\t\t'oxlintrc.jsonc',\n\t\t\t\t'oxlintrc.*.json',\n\t\t\t\t'oxlintrc.*.jsonc',\n\t\t\t\t'.oxlintrc.json',\n\t\t\t\t'.oxlintrc.jsonc',\n\t\t\t\t'.oxlintrc.*.json',\n\t\t\t\t'.oxlintrc.*.jsonc',\n\t\t\t],\n\t\t\toptions: {\n\t\t\t\tjsonSortOrder: prioritizeKeys(\n\t\t\t\t\t'$schema',\n\t\t\t\t\t'files',\n\t\t\t\t\t'extends',\n\t\t\t\t\t'ignorePatterns',\n\t\t\t\t\t'plugins',\n\t\t\t\t\t'jsPlugins',\n\t\t\t\t\t'categories',\n\t\t\t\t\t'env',\n\t\t\t\t\t'globals',\n\t\t\t\t\t'settings',\n\t\t\t\t\t'rules',\n\t\t\t\t\t'overrides'\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t\t/**\n\t\t * All `package.json` fields defined in the `npm@11` specification\n\t\t * are sorted, along with additional commonly used fields.\n\t\t */\n\t\t{\n\t\t\tfiles: ['package.json'],\n\t\t\toptions: {\n\t\t\t\tplugins: [pluginPackageJSON, pluginExpandJSON],\n\t\t\t\tpackageSortOrder: [\n\t\t\t\t\t'$schema',\n\t\t\t\t\t'name',\n\t\t\t\t\t'version',\n\t\t\t\t\t'private',\n\t\t\t\t\t'description',\n\t\t\t\t\t'license',\n\t\t\t\t\t'author',\n\t\t\t\t\t'contributors',\n\t\t\t\t\t'funding',\n\t\t\t\t\t'homepage',\n\t\t\t\t\t'repository',\n\t\t\t\t\t'bugs',\n\t\t\t\t\t'keywords',\n\t\t\t\t\t'workspaces',\n\t\t\t\t\t'directories',\n\t\t\t\t\t'files',\n\t\t\t\t\t'type',\n\t\t\t\t\t'browser',\n\t\t\t\t\t'sideEffects',\n\t\t\t\t\t'main',\n\t\t\t\t\t'module',\n\t\t\t\t\t'exports',\n\t\t\t\t\t'types',\n\t\t\t\t\t'typesVersions',\n\t\t\t\t\t'bin',\n\t\t\t\t\t'man',\n\t\t\t\t\t'imports',\n\t\t\t\t\t'engines',\n\t\t\t\t\t'os',\n\t\t\t\t\t'cpu',\n\t\t\t\t\t'libc',\n\t\t\t\t\t'gypfile',\n\t\t\t\t\t'packageManager',\n\t\t\t\t\t'devEngines',\n\t\t\t\t\t'dependencies',\n\t\t\t\t\t'bundleDependencies',\n\t\t\t\t\t'peerDependencies',\n\t\t\t\t\t'peerDependenciesMeta',\n\t\t\t\t\t'optionalDependencies',\n\t\t\t\t\t'devDependencies',\n\t\t\t\t\t'overrides',\n\t\t\t\t\t'pnpm',\n\t\t\t\t\t'config',\n\t\t\t\t\t'publishConfig',\n\t\t\t\t\t'scripts',\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\t/**\n\t\t * All `tsconfig.json` fields defined by the TypeScript documentation\n\t\t * are sorted, including nested fields.\n\t\t */\n\t\t{\n\t\t\tfiles: [\n\t\t\t\t'tsconfig.json',\n\t\t\t\t'tsconfig.*.json',\n\t\t\t\t'jsconfig.json',\n\t\t\t\t'jsconfig.*.json',\n\t\t\t],\n\t\t\toptions: {\n\t\t\t\tjsonSortOrder: prioritizeKeys(\n\t\t\t\t\t'$schema',\n\t\t\t\t\t'extends',\n\t\t\t\t\t'enable',\n\t\t\t\t\t'references',\n\t\t\t\t\t'compilerOptions',\n\t\t\t\t\t'typeAcquisition',\n\t\t\t\t\t'files',\n\t\t\t\t\t'include',\n\t\t\t\t\t'exclude',\n\t\t\t\t\t'watchOptions',\n\t\t\t\t\t'watchDirectory',\n\t\t\t\t\t'watchFile',\n\t\t\t\t\t'fallbackPolling',\n\t\t\t\t\t'synchronousWatchDirectory',\n\t\t\t\t\t'compileOnSave'\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t],\n} as const satisfies Config;\n","import type { Config } from 'prettier';\nimport { klona as clone } from 'klona/lite';\n\nexport default function mergeConfig(\n\tbaseConfig: Config,\n\textensionConfig: Config\n): Config {\n\tif (\n\t\t!(typeof baseConfig === 'object' && typeof extensionConfig === 'object')\n\t) {\n\t\tthrow new TypeError(\n\t\t\t'Prettier config error: expected config to be an object'\n\t\t);\n\t}\n\n\tconst result = clone(baseConfig);\n\n\tfor (const [key, value] of Object.entries(clone(extensionConfig))) {\n\t\tif (value === undefined) {\n\t\t\t/* oxlint-disable-next-line typescript/no-dynamic-delete */\n\t\t\tdelete result[key];\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (isArray(value) && isArray(result[key])) {\n\t\t\tresult[key] = [...result[key], ...value];\n\t\t\tcontinue;\n\t\t}\n\n\t\tresult[key] = value;\n\t}\n\n\treturn result;\n}\n\nfunction isArray(value: unknown): value is unknown[] {\n\treturn Array.isArray(value);\n}\n","import type { Config } from 'prettier';\nimport { DEFAULT_CONFIG } from '../config/index.ts';\nimport mergeConfig from '../merge-config/index.ts';\n\nexport default function defineConfig(config: Config = {}): Config {\n\treturn mergeConfig(DEFAULT_CONFIG, config);\n}\n"],"mappings":";;;;;;;;AAAA,SAAwB,eAAe,GAAG,MAAqC;CAE9E,MAAM,QAA8B,EAAE;AAEtC,MAAK,MAAM,OAAO,KACjB,OAAM,OAAO,IAAI,IAAI;AAGtB,QAAO,KAAK,UAAU;EACrB,GAAG;GAEF,OAAc;EACf,CAAC;;;;;;;;;;;;;ACIH,MAAa,kBAAkB;CAC9B,UAAU;CACV,SAAS;CACT;AAED,MAAa,iBAAiB;CAC7B,SAAS;EAAC;EAAiB;EAAa;EAAiB;CACzD,gBAAgB;CAChB,YAAY;CACZ,YAAY;CACZ,aAAa;CACb,UAAU;CACV,eAAe;CACf,SAAS;CACT,WAAW;EACV;GACC,OAAO,CAAC,SAAS,SAAS;GAC1B,SAAS;IACR,GAAG;IACH,YAAY;IACZ,aAAa;IACb;GACD;;;;;;EAKD;GACC,OAAO,CAAC,SAAS;GACjB,SAAS,EACR,UAAU,GACV;GACD;EACD;GACC,OAAO;IAAC;IAAa;IAAc;IAAQ;GAC3C,SAAS,EACR,GAAG,iBACH;GACD;EACD;GACC,OAAO,CAAC,UAAU,QAAQ;GAC1B,SAAS;IACR,GAAG;IACH,YAAY;IACZ;GACD;EACD;GACC,OAAO;IAAC;IAAQ;IAAS;IAAS;IAAQ;GAC1C,SAAS;IACR,GAAG;IACH,QAAQ;IACR;GACD;EACD;GACC,OAAO;IAAC;IAAU;IAAW;IAAU;GACvC,SAAS,EACR,GAAG,iBACH;GACD;EACD;GACC,OAAO;IAAC;IAAU;IAAW;IAAU;GACvC,cAAc,CAAC,eAAe;GAC9B,SAAS;IACR,SAAS,CAAC,gBAAgB,iBAAiB;IAC3C,mBAAmB;IACnB,eAAe,eAAe,UAAU;IACxC;GACD;;;;;;;;;;;;;;EAaD;GACC,OAAO,CAAC,QAAQ,QAAQ;GACxB,SAAS;IACR,GAAG;IACH,SAAS;IACT;GACD;EACD;GACC,OAAO;IAAC;IAAQ;IAAS;IAAS;IAAQ;GAC1C,SAAS;IACR,GAAG;IACH,QAAQ;IACR;GACD;EACD;GACC,OAAO;IAAC;IAAS;IAAW;IAAQ;GACpC,SAAS;IACR,GAAG;IACH,QAAQ;IACR,YAAY;IACZ,wBAAwB;IACxB;GACD;;;;;;EAKD;GACC,OAAO;IACN;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACD,SAAS,EACR,eAAe,eACd,WACA,SACA,WACA,kBACA,WACA,aACA,cACA,OACA,WACA,YACA,SACA,YACA,EACD;GACD;;;;;;EAKD;GACC,OAAO,CAAC,eAAe;GACvB,SAAS;IACR,SAAS,CAAC,mBAAmB,iBAAiB;IAC9C,kBAAkB;KACjB;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;IACD;GACD;;;;;;EAKD;GACC,OAAO;IACN;IACA;IACA;IACA;IACA;GACD,SAAS,EACR,eAAe,eACd,WACA,WACA,UACA,cACA,mBACA,mBACA,SACA,WACA,WACA,gBACA,kBACA,aACA,mBACA,6BACA,gBACA,EACD;GACD;EACD;CACD;;;;AC7OD,SAAwB,YACvB,YACA,iBACS;AACT,KACC,EAAE,OAAO,eAAe,YAAY,OAAO,oBAAoB,UAE/D,OAAM,IAAI,UACT,yDACA;CAGF,MAAM,SAASA,MAAM,WAAW;AAEhC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQA,MAAM,gBAAgB,CAAC,EAAE;AAClE,MAAI,UAAU,QAAW;AAExB,UAAO,OAAO;AACd;;AAGD,MAAI,QAAQ,MAAM,IAAI,QAAQ,OAAO,KAAK,EAAE;AAC3C,UAAO,OAAO,CAAC,GAAG,OAAO,MAAM,GAAG,MAAM;AACxC;;AAGD,SAAO,OAAO;;AAGf,QAAO;;AAGR,SAAS,QAAQ,OAAoC;AACpD,QAAO,MAAM,QAAQ,MAAM;;;;;AChC5B,SAAwB,aAAa,SAAiB,EAAE,EAAU;AACjE,QAAO,YAAY,gBAAgB,OAAO"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["clone","clone","clone"],"sources":["../src/clone/index.ts","../src/generate-config/index.ts","../src/merge-config/index.ts","../src/prioritize-keys/index.ts","../src/transform-config/index.ts","../src/define-config/index.ts"],"sourcesContent":["import defineClone from 'rfdc';\n\nexport default defineClone({ circles: true });\n","import type {\n\tIndentationOptions,\n\tShellIndentationOptions,\n\tStandardConfig,\n\tStandardConfigOverrides,\n} from '../types/index.d.ts';\nimport clone from '../clone/index.ts';\n\n/**\n * Generate the base Standard Config.\n *\n * Shell scripts can’t be reliably identified by name alone—they’re recognized\n * by the shebang, not the extension. As a result, shell formatting options\n * (two-space indentation) must be defined as the global defaults.\n *\n * This requires overriding those options for other file types individually\n * with what we consider the actual defaults (`baseDefaults`). `generateConfig`\n * is a factory that encapsulates this logic and returns the final config.\n */\nexport default function generateConfig(\n\tbaseDefaults: IndentationOptions = {},\n\tshellDefaults: ShellIndentationOptions = {}\n): StandardConfig {\n\tconst { tabWidth = 4, useTabs = true } = baseDefaults;\n\tconst { shellTabWidth = 2, shellUseTabs = false } = shellDefaults;\n\n\treturn clone({\n\t\tplugins: [\n\t\t\t'@prettier/plugin-oxc',\n\t\t\t'prettier-plugin-sh',\n\t\t\t'prettier-plugin-expand-json',\n\t\t],\n\t\tbracketSpacing: true,\n\t\tprintWidth: 80,\n\t\tquoteProps: 'consistent',\n\t\tsingleQuote: true,\n\t\ttabWidth: shellTabWidth,\n\t\ttrailingComma: 'es5',\n\t\tuseTabs: shellUseTabs,\n\t\toverrides: [\n\t\t\t...getFileTypeOverrides({ tabWidth, useTabs }),\n\t\t\t...getFileNameOverrides(),\n\t\t],\n\t});\n}\n\nfunction getFileTypeOverrides(\n\tbaseDefaults: IndentationOptions = {}\n): StandardConfigOverrides {\n\treturn [\n\t\t{\n\t\t\tfiles: ['*.css', '*.scss'],\n\t\t\toptions: {\n\t\t\t\t...baseDefaults,\n\t\t\t\tprintWidth: 100,\n\t\t\t\tsingleQuote: false,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tfiles: ['*.graphql', '*.graphqls', '*.gql'],\n\t\t\toptions: {\n\t\t\t\t...baseDefaults,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tfiles: ['*.html', '*.htm'],\n\t\t\toptions: {\n\t\t\t\t...baseDefaults,\n\t\t\t\tprintWidth: 100,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tfiles: ['*.js', '*.jsx', '*.cjs', '*.mjs'],\n\t\t\toptions: {\n\t\t\t\t...baseDefaults,\n\t\t\t\tparser: 'oxc',\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tfiles: ['*.json', '*.jsonc', '*.json5'],\n\t\t\toptions: {\n\t\t\t\t...baseDefaults,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tfiles: ['*.json', '*.jsonc', '*.json5'],\n\t\t\texcludeFiles: ['package.json'],\n\t\t\toptions: {\n\t\t\t\tplugins: [\n\t\t\t\t\t'prettier-plugin-sort-json',\n\t\t\t\t\t'prettier-plugin-expand-json',\n\t\t\t\t],\n\t\t\t\tjsonRecursiveSort: true,\n\t\t\t\tjsonSortOrder: ['$schema'],\n\t\t\t},\n\t\t},\n\t\t/**\n\t\t * Tab-based indentation becomes inconvenient when rendered outside the\n\t\t * context of a code editor. In documentation, tabs in code blocks\n\t\t * require special handling that very few renderers support.\n\t\t *\n\t\t * At the time of writing, GitHub renders tabs correctly on the web, but\n\t\t * not in its mobile app. `npm`, often the point of discovery for\n\t\t * packages, does not provide any special handling for tabs either.\n\t\t *\n\t\t * To maximize the readability of code blocks in documentation, spaces\n\t\t * are the right compromise.\n\t\t */\n\t\t{\n\t\t\tfiles: ['*.md', '*.mdx'],\n\t\t\toptions: {\n\t\t\t\t...baseDefaults,\n\t\t\t\tuseTabs: false,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tfiles: ['*.ts', '*.tsx', '*.cts', '*.mts'],\n\t\t\toptions: {\n\t\t\t\t...baseDefaults,\n\t\t\t\tparser: 'oxc-ts',\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tfiles: ['*.xml', '*.plist', '*.svg'],\n\t\t\toptions: {\n\t\t\t\t...baseDefaults,\n\t\t\t\tparser: 'html',\n\t\t\t\tprintWidth: 80,\n\t\t\t\tsingleAttributePerLine: true,\n\t\t\t},\n\t\t},\n\t];\n}\n\nfunction getFileNameOverrides(): StandardConfigOverrides {\n\treturn [\n\t\t/**\n\t\t * All `.oxlintrc.json` fields defined by the Oxlint documentation\n\t\t * are sorted, including nested fields.\n\t\t */\n\t\t{\n\t\t\tfiles: [\n\t\t\t\t'oxlintrc.json',\n\t\t\t\t'oxlintrc.jsonc',\n\t\t\t\t'oxlintrc.*.json',\n\t\t\t\t'oxlintrc.*.jsonc',\n\t\t\t\t'.oxlintrc.json',\n\t\t\t\t'.oxlintrc.jsonc',\n\t\t\t\t'.oxlintrc.*.json',\n\t\t\t\t'.oxlintrc.*.jsonc',\n\t\t\t],\n\t\t\toptions: {\n\t\t\t\tjsonSortOrder: [\n\t\t\t\t\t'$schema',\n\t\t\t\t\t'files',\n\t\t\t\t\t'extends',\n\t\t\t\t\t'ignorePatterns',\n\t\t\t\t\t'plugins',\n\t\t\t\t\t'jsPlugins',\n\t\t\t\t\t'categories',\n\t\t\t\t\t'env',\n\t\t\t\t\t'globals',\n\t\t\t\t\t'settings',\n\t\t\t\t\t'rules',\n\t\t\t\t\t'overrides',\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\t/**\n\t\t * By default, Prettier uses a different parser for `package.json`\n\t\t * files, which causes most JSON plugins to skip them entirely.\n\t\t * This override ensures `package.json` is treated (and sorted)\n\t\t * like any other `*.json` file.\n\t\t *\n\t\t * All `package.json` fields defined in the `npm@11` specification\n\t\t * are sorted, along with additional commonly used fields.\n\t\t */\n\t\t{\n\t\t\tfiles: ['package.json'],\n\t\t\toptions: {\n\t\t\t\tplugins: [\n\t\t\t\t\t'prettier-plugin-packagejson',\n\t\t\t\t\t'prettier-plugin-expand-json',\n\t\t\t\t],\n\t\t\t\tpackageSortOrder: [\n\t\t\t\t\t'$schema',\n\t\t\t\t\t'name',\n\t\t\t\t\t'version',\n\t\t\t\t\t'private',\n\t\t\t\t\t'description',\n\t\t\t\t\t'license',\n\t\t\t\t\t'author',\n\t\t\t\t\t'contributors',\n\t\t\t\t\t'funding',\n\t\t\t\t\t'homepage',\n\t\t\t\t\t'repository',\n\t\t\t\t\t'bugs',\n\t\t\t\t\t'keywords',\n\t\t\t\t\t'workspaces',\n\t\t\t\t\t'directories',\n\t\t\t\t\t'files',\n\t\t\t\t\t'type',\n\t\t\t\t\t'browser',\n\t\t\t\t\t'sideEffects',\n\t\t\t\t\t'main',\n\t\t\t\t\t'module',\n\t\t\t\t\t'exports',\n\t\t\t\t\t'types',\n\t\t\t\t\t'typesVersions',\n\t\t\t\t\t'bin',\n\t\t\t\t\t'man',\n\t\t\t\t\t'imports',\n\t\t\t\t\t'engines',\n\t\t\t\t\t'os',\n\t\t\t\t\t'cpu',\n\t\t\t\t\t'libc',\n\t\t\t\t\t'gypfile',\n\t\t\t\t\t'packageManager',\n\t\t\t\t\t'devEngines',\n\t\t\t\t\t'dependencies',\n\t\t\t\t\t'bundleDependencies',\n\t\t\t\t\t'peerDependencies',\n\t\t\t\t\t'peerDependenciesMeta',\n\t\t\t\t\t'optionalDependencies',\n\t\t\t\t\t'devDependencies',\n\t\t\t\t\t'overrides',\n\t\t\t\t\t'pnpm',\n\t\t\t\t\t'config',\n\t\t\t\t\t'publishConfig',\n\t\t\t\t\t'scripts',\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\t/**\n\t\t * All `tsconfig.json` fields defined by the TypeScript documentation\n\t\t * are sorted, including nested fields.\n\t\t */\n\t\t{\n\t\t\tfiles: [\n\t\t\t\t'tsconfig.json',\n\t\t\t\t'tsconfig.*.json',\n\t\t\t\t'jsconfig.json',\n\t\t\t\t'jsconfig.*.json',\n\t\t\t],\n\t\t\toptions: {\n\t\t\t\tjsonSortOrder: [\n\t\t\t\t\t'$schema',\n\t\t\t\t\t'extends',\n\t\t\t\t\t'enable',\n\t\t\t\t\t'references',\n\t\t\t\t\t'compilerOptions',\n\t\t\t\t\t'typeAcquisition',\n\t\t\t\t\t'files',\n\t\t\t\t\t'include',\n\t\t\t\t\t'exclude',\n\t\t\t\t\t'watchOptions',\n\t\t\t\t\t'watchDirectory',\n\t\t\t\t\t'watchFile',\n\t\t\t\t\t'fallbackPolling',\n\t\t\t\t\t'synchronousWatchDirectory',\n\t\t\t\t\t'compileOnSave',\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tfiles: ['.vscode/mcp.json'],\n\t\t\toptions: {\n\t\t\t\tjsonSortOrder: ['$schema', 'command'],\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tfiles: ['.vscode/sessions.json'],\n\t\t\toptions: {\n\t\t\t\tjsonSortOrder: ['$schema', 'name', 'commands', 'active'],\n\t\t\t},\n\t\t},\n\t];\n}\n","import type { StandardConfig } from '../types/index.d.ts';\nimport clone from '../clone/index.ts';\n\n/**\n * Deep-merge two Standard Config objects.\n */\nexport default function mergeConfig(\n\tbaseConfig: StandardConfig,\n\textensionConfig: StandardConfig\n): StandardConfig {\n\tif (\n\t\t!(typeof baseConfig === 'object' && typeof extensionConfig === 'object')\n\t) {\n\t\tthrow new TypeError(\n\t\t\t'Standard Config error: expected config to be an object'\n\t\t);\n\t}\n\n\tconst result = clone(baseConfig);\n\n\tfor (const [key, value] of Object.entries(clone(extensionConfig))) {\n\t\tif (value === undefined) {\n\t\t\t/* oxlint-disable-next-line typescript/no-dynamic-delete */\n\t\t\tdelete result[key];\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (isArray(value) && isArray(result[key])) {\n\t\t\tresult[key] = [...result[key], ...value];\n\t\t\tcontinue;\n\t\t}\n\n\t\tresult[key] = value;\n\t}\n\n\treturn result;\n}\n\nfunction isArray(value: unknown): value is unknown[] {\n\treturn Array.isArray(value);\n}\n","/**\n * @deprecated Use an array value for the `jsonSortOrder` property instead.\n */\nexport default function prioritizeKeys(...keys: ReadonlyArray<string>): string {\n\t/* oxlint-disable-next-line typescript/no-restricted-types */\n\tconst order: Record<string, null> = {};\n\n\tfor (const key of keys) {\n\t\torder[String(key)] = null;\n\t}\n\n\treturn JSON.stringify({\n\t\t...order,\n\t\t/* oxlint-disable-next-line typescript/no-explicit-any */\n\t\t[/.*/ as any]: 'lexical',\n\t});\n}\n","import type { Config as PrettierConfig } from 'prettier';\nimport type {\n\tPrettierPlugins,\n\tStandardConfig,\n\tStandardConfigPluginOverrides,\n\tStandardOptions,\n} from '../types/index.d.ts';\nimport * as pluginOxidation from '@prettier/plugin-oxc';\nimport * as pluginExpandJSON from 'prettier-plugin-expand-json';\nimport * as pluginPackageJSON from 'prettier-plugin-packagejson';\nimport * as pluginShell from 'prettier-plugin-sh';\nimport * as pluginSortJSON from 'prettier-plugin-sort-json';\nimport clone from '../clone/index.ts';\nimport prioritizeKeys from '../prioritize-keys/index.ts';\n\n/**\n * Convert Standard Config to an exportable, Prettier-compatible format.\n */\nexport default function transformConfig(\n\tconfig: StandardConfig,\n\tpluginOverrides: StandardConfigPluginOverrides = {}\n): PrettierConfig {\n\t/* oxlint-disable-next-line eslint/no-param-reassign */\n\tconfig = clone(config);\n\n\tconst transform = (options: StandardOptions) => {\n\t\tif (options.jsonSortOrder) {\n\t\t\toptions.jsonSortOrder = transformJSONSortOrder(\n\t\t\t\toptions.jsonSortOrder\n\t\t\t);\n\t\t}\n\n\t\tif (options.plugins) {\n\t\t\tconst plugins = transformPlugins(options.plugins, pluginOverrides);\n\n\t\t\tif (plugins.length > 0) {\n\t\t\t\toptions.plugins = plugins;\n\t\t\t} else {\n\t\t\t\tdelete options.plugins;\n\t\t\t}\n\t\t}\n\t};\n\n\ttransform(config);\n\n\tif (config.overrides) {\n\t\tfor (const override of config.overrides) {\n\t\t\ttransform(override.options);\n\t\t}\n\t}\n\n\treturn config as PrettierConfig;\n}\n\nfunction transformJSONSortOrder(jsonSortOrder: string | string[]): string {\n\tif (Array.isArray(jsonSortOrder)) {\n\t\treturn prioritizeKeys(...jsonSortOrder);\n\t}\n\n\treturn jsonSortOrder;\n}\n\nfunction transformPlugins(\n\tplugins: PrettierPlugins,\n\tpluginOverrides: StandardConfigPluginOverrides\n): PrettierPlugins {\n\tconst pluginMap: StandardConfigPluginOverrides = {\n\t\t'@prettier/plugin-oxc': pluginOxidation,\n\t\t'prettier-plugin-expand-json': pluginExpandJSON,\n\t\t'prettier-plugin-packagejson': pluginPackageJSON,\n\t\t'prettier-plugin-sh': pluginShell,\n\t\t'prettier-plugin-sort-json': pluginSortJSON,\n\t\t...pluginOverrides,\n\t};\n\n\tconst resolved: PrettierPlugins = [];\n\n\tfor (const plugin of plugins) {\n\t\tconst resolvedPlugin =\n\t\t\ttypeof plugin === 'string' && Object.hasOwn(pluginMap, plugin)\n\t\t\t\t? pluginMap[plugin]\n\t\t\t\t: plugin;\n\n\t\tif (resolvedPlugin) {\n\t\t\tresolved.push(resolvedPlugin);\n\t\t}\n\t}\n\n\treturn resolved;\n}\n","import type { Config as PrettierConfig } from 'prettier';\nimport type { StandardConfig } from '../types/index.d.ts';\nimport generateConfig from '../generate-config/index.ts';\nimport mergeConfig from '../merge-config/index.ts';\nimport transformConfig from '../transform-config/index.ts';\n\n/**\n * Combine Standard Config with optional config overrides.\n */\nexport default function defineConfig(\n\tconfig: StandardConfig = {}\n): PrettierConfig {\n\tconst {\n\t\tpluginOverrides,\n\t\tshellTabWidth,\n\t\tshellUseTabs,\n\t\ttabWidth,\n\t\tuseTabs,\n\t\t...extensionConfig\n\t} = config;\n\n\tconst baseConfig = generateConfig(\n\t\t{ useTabs, tabWidth },\n\t\t{ shellUseTabs, shellTabWidth }\n\t);\n\n\tconst extendedConfig = mergeConfig(baseConfig, extensionConfig);\n\n\treturn transformConfig(extendedConfig, pluginOverrides);\n}\n"],"mappings":";;;;;;;;AAEA,oBAAe,YAAY,EAAE,SAAS,MAAM,CAAC;;;;;;;;;;;;;;;ACiB7C,SAAwB,eACvB,eAAmC,EAAE,EACrC,gBAAyC,EAAE,EAC1B;CACjB,MAAM,EAAE,WAAW,GAAG,UAAU,SAAS;CACzC,MAAM,EAAE,gBAAgB,GAAG,eAAe,UAAU;AAEpD,QAAOA,cAAM;EACZ,SAAS;GACR;GACA;GACA;GACA;EACD,gBAAgB;EAChB,YAAY;EACZ,YAAY;EACZ,aAAa;EACb,UAAU;EACV,eAAe;EACf,SAAS;EACT,WAAW,CACV,GAAG,qBAAqB;GAAE;GAAU;GAAS,CAAC,EAC9C,GAAG,sBAAsB,CACzB;EACD,CAAC;;AAGH,SAAS,qBACR,eAAmC,EAAE,EACX;AAC1B,QAAO;EACN;GACC,OAAO,CAAC,SAAS,SAAS;GAC1B,SAAS;IACR,GAAG;IACH,YAAY;IACZ,aAAa;IACb;GACD;EACD;GACC,OAAO;IAAC;IAAa;IAAc;IAAQ;GAC3C,SAAS,EACR,GAAG,cACH;GACD;EACD;GACC,OAAO,CAAC,UAAU,QAAQ;GAC1B,SAAS;IACR,GAAG;IACH,YAAY;IACZ;GACD;EACD;GACC,OAAO;IAAC;IAAQ;IAAS;IAAS;IAAQ;GAC1C,SAAS;IACR,GAAG;IACH,QAAQ;IACR;GACD;EACD;GACC,OAAO;IAAC;IAAU;IAAW;IAAU;GACvC,SAAS,EACR,GAAG,cACH;GACD;EACD;GACC,OAAO;IAAC;IAAU;IAAW;IAAU;GACvC,cAAc,CAAC,eAAe;GAC9B,SAAS;IACR,SAAS,CACR,6BACA,8BACA;IACD,mBAAmB;IACnB,eAAe,CAAC,UAAU;IAC1B;GACD;;;;;;;;;;;;;;EAaD;GACC,OAAO,CAAC,QAAQ,QAAQ;GACxB,SAAS;IACR,GAAG;IACH,SAAS;IACT;GACD;EACD;GACC,OAAO;IAAC;IAAQ;IAAS;IAAS;IAAQ;GAC1C,SAAS;IACR,GAAG;IACH,QAAQ;IACR;GACD;EACD;GACC,OAAO;IAAC;IAAS;IAAW;IAAQ;GACpC,SAAS;IACR,GAAG;IACH,QAAQ;IACR,YAAY;IACZ,wBAAwB;IACxB;GACD;EACD;;AAGF,SAAS,uBAAgD;AACxD,QAAO;;;;;;EAKN;GACC,OAAO;IACN;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACD,SAAS,EACR,eAAe;IACd;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,EACD;GACD;;;;;;;;;;;EAUD;GACC,OAAO,CAAC,eAAe;GACvB,SAAS;IACR,SAAS,CACR,+BACA,8BACA;IACD,kBAAkB;KACjB;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;IACD;GACD;;;;;;EAKD;GACC,OAAO;IACN;IACA;IACA;IACA;IACA;GACD,SAAS,EACR,eAAe;IACd;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,EACD;GACD;EACD;GACC,OAAO,CAAC,mBAAmB;GAC3B,SAAS,EACR,eAAe,CAAC,WAAW,UAAU,EACrC;GACD;EACD;GACC,OAAO,CAAC,wBAAwB;GAChC,SAAS,EACR,eAAe;IAAC;IAAW;IAAQ;IAAY;IAAS,EACxD;GACD;EACD;;;;;;;;AC9QF,SAAwB,YACvB,YACA,iBACiB;AACjB,KACC,EAAE,OAAO,eAAe,YAAY,OAAO,oBAAoB,UAE/D,OAAM,IAAI,UACT,yDACA;CAGF,MAAM,SAASC,cAAM,WAAW;AAEhC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQA,cAAM,gBAAgB,CAAC,EAAE;AAClE,MAAI,UAAU,QAAW;AAExB,UAAO,OAAO;AACd;;AAGD,MAAI,QAAQ,MAAM,IAAI,QAAQ,OAAO,KAAK,EAAE;AAC3C,UAAO,OAAO,CAAC,GAAG,OAAO,MAAM,GAAG,MAAM;AACxC;;AAGD,SAAO,OAAO;;AAGf,QAAO;;AAGR,SAAS,QAAQ,OAAoC;AACpD,QAAO,MAAM,QAAQ,MAAM;;;;;;;;ACpC5B,SAAwB,eAAe,GAAG,MAAqC;CAE9E,MAAM,QAA8B,EAAE;AAEtC,MAAK,MAAM,OAAO,KACjB,OAAM,OAAO,IAAI,IAAI;AAGtB,QAAO,KAAK,UAAU;EACrB,GAAG;GAEF,OAAc;EACf,CAAC;;;;;;;;ACGH,SAAwB,gBACvB,QACA,kBAAiD,EAAE,EAClC;AAEjB,UAASC,cAAM,OAAO;CAEtB,MAAM,aAAa,YAA6B;AAC/C,MAAI,QAAQ,cACX,SAAQ,gBAAgB,uBACvB,QAAQ,cACR;AAGF,MAAI,QAAQ,SAAS;GACpB,MAAM,UAAU,iBAAiB,QAAQ,SAAS,gBAAgB;AAElE,OAAI,QAAQ,SAAS,EACpB,SAAQ,UAAU;OAElB,QAAO,QAAQ;;;AAKlB,WAAU,OAAO;AAEjB,KAAI,OAAO,UACV,MAAK,MAAM,YAAY,OAAO,UAC7B,WAAU,SAAS,QAAQ;AAI7B,QAAO;;AAGR,SAAS,uBAAuB,eAA0C;AACzE,KAAI,MAAM,QAAQ,cAAc,CAC/B,QAAO,eAAe,GAAG,cAAc;AAGxC,QAAO;;AAGR,SAAS,iBACR,SACA,iBACkB;CAClB,MAAM,YAA2C;EAChD,wBAAwB;EACxB,+BAA+B;EAC/B,+BAA+B;EAC/B,sBAAsB;EACtB,6BAA6B;EAC7B,GAAG;EACH;CAED,MAAM,WAA4B,EAAE;AAEpC,MAAK,MAAM,UAAU,SAAS;EAC7B,MAAM,iBACL,OAAO,WAAW,YAAY,OAAO,OAAO,WAAW,OAAO,GAC3D,UAAU,UACV;AAEJ,MAAI,eACH,UAAS,KAAK,eAAe;;AAI/B,QAAO;;;;;;;;AC/ER,SAAwB,aACvB,SAAyB,EAAE,EACV;CACjB,MAAM,EACL,iBACA,eACA,cACA,UACA,SACA,GAAG,oBACA;AASJ,QAAO,gBAFgB,YALJ,eAClB;EAAE;EAAS;EAAU,EACrB;EAAE;EAAc;EAAe,CAC/B,EAE8C,gBAAgB,EAExB,gBAAgB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@standard-config/prettier",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "TypeScript-first Prettier config",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"typescript"
|
|
21
21
|
],
|
|
22
22
|
"files": [
|
|
23
|
+
".editorconfig",
|
|
23
24
|
"dist/**"
|
|
24
25
|
],
|
|
25
26
|
"type": "module",
|
|
@@ -32,37 +33,43 @@
|
|
|
32
33
|
"packageManager": "pnpm@10.28.1",
|
|
33
34
|
"dependencies": {
|
|
34
35
|
"@prettier/plugin-oxc": "^0.1.3",
|
|
35
|
-
"
|
|
36
|
-
"prettier-plugin-expand-json": "^1.0.0",
|
|
36
|
+
"prettier-plugin-expand-json": "^1.0.2",
|
|
37
37
|
"prettier-plugin-packagejson": "^3.0.0",
|
|
38
38
|
"prettier-plugin-sh": "^0.18.0",
|
|
39
|
-
"prettier-plugin-sort-json": "^4.2.0"
|
|
39
|
+
"prettier-plugin-sort-json": "^4.2.0",
|
|
40
|
+
"rfdc": "^1.4.1"
|
|
40
41
|
},
|
|
41
42
|
"peerDependencies": {
|
|
42
43
|
"prettier": ">=3.7"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
46
|
+
"@standard-config/eslint": "1.0.1",
|
|
45
47
|
"@standard-config/tsconfig": "2.0.0",
|
|
46
|
-
"@vitest/coverage-v8": "4.0.
|
|
48
|
+
"@vitest/coverage-v8": "4.0.18",
|
|
49
|
+
"eslint": "9.39.2",
|
|
47
50
|
"husky": "9.1.7",
|
|
51
|
+
"jiti": "2.6.1",
|
|
48
52
|
"oxlint": "1.41.0",
|
|
49
53
|
"oxlint-tsgolint": "0.11.1",
|
|
50
|
-
"prettier": "3.8.
|
|
51
|
-
"publint": "0.3.
|
|
52
|
-
"tsdown": "0.
|
|
54
|
+
"prettier": "3.8.1",
|
|
55
|
+
"publint": "0.3.17",
|
|
56
|
+
"tsdown": "0.20.1",
|
|
53
57
|
"typescript": "5.9.3",
|
|
54
|
-
"vitest": "4.0.
|
|
58
|
+
"vitest": "4.0.18"
|
|
55
59
|
},
|
|
56
60
|
"scripts": {
|
|
57
61
|
"build": "tsdown",
|
|
58
62
|
"fix": "pnpm format && pnpm lint",
|
|
63
|
+
"fixtures:scramble": "prettier --config fixtures/config.ts --write fixtures && sleep 1",
|
|
64
|
+
"fixtures:unscramble": "pnpm prettier --write fixtures && sleep 1",
|
|
59
65
|
"format": "prettier --write --ignore-unknown .",
|
|
60
66
|
"format:check": "prettier --check --ignore-unknown .",
|
|
61
|
-
"lint": "oxlint --fix --type-aware --type-check --deny-warnings --report-unused-disable-directives",
|
|
62
|
-
"lint:check": "oxlint --type-aware --type-check --deny-warnings --report-unused-disable-directives",
|
|
67
|
+
"lint": "oxlint --fix --type-aware --type-check --deny-warnings --report-unused-disable-directives && eslint . --fix",
|
|
68
|
+
"lint:check": "oxlint --type-aware --type-check --deny-warnings --report-unused-disable-directives && eslint .",
|
|
63
69
|
"prepack": "pnpm run '/^(format:check|lint:check|test|typecheck)$/' && pnpm build",
|
|
64
70
|
"prepare": "husky",
|
|
65
71
|
"test": "vitest run",
|
|
72
|
+
"test:fixtures": "pnpm run '/^fixtures:/' && git diff --exit-code fixtures",
|
|
66
73
|
"typecheck": "tsc --noEmit"
|
|
67
74
|
}
|
|
68
75
|
}
|