editorconfig 3.0.2 → 4.0.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/lib/index.js +101 -17
- package/lib/index.test.d.ts +1 -1
- package/lib/index.test.js +117 -24
- package/package.json +12 -7
package/lib/index.js
CHANGED
|
@@ -72,13 +72,13 @@ const knownProps = new Set(knownPropNames);
|
|
|
72
72
|
*/
|
|
73
73
|
function parseBuffer(data) {
|
|
74
74
|
const parsed = (0, wasm_1.parse_to_uint32array)(data);
|
|
75
|
-
let cur =
|
|
75
|
+
let cur = Object.create(null);
|
|
76
76
|
const res = [[null, cur]];
|
|
77
77
|
let key = null;
|
|
78
78
|
for (let i = 0; i < parsed.length; i += 3) {
|
|
79
79
|
switch (parsed[i]) {
|
|
80
80
|
case wasm_1.TokenTypes.Section: {
|
|
81
|
-
cur =
|
|
81
|
+
cur = Object.create(null);
|
|
82
82
|
res.push([
|
|
83
83
|
data.toString('utf8', parsed[i + 1], parsed[i + 2]),
|
|
84
84
|
cur,
|
|
@@ -122,7 +122,7 @@ function getConfigFileNames(filepath, options) {
|
|
|
122
122
|
do {
|
|
123
123
|
filepath = path.dirname(filepath);
|
|
124
124
|
paths.push(path.join(filepath, options.config));
|
|
125
|
-
} while (filepath !== options.root);
|
|
125
|
+
} while (filepath !== options.root && filepath !== path.dirname(filepath));
|
|
126
126
|
return paths;
|
|
127
127
|
}
|
|
128
128
|
/**
|
|
@@ -187,7 +187,7 @@ function buildFullGlob(pathPrefix, glob) {
|
|
|
187
187
|
* @returns
|
|
188
188
|
*/
|
|
189
189
|
function normalizeProps(options) {
|
|
190
|
-
const props =
|
|
190
|
+
const props = Object.create(null);
|
|
191
191
|
for (const key in options) {
|
|
192
192
|
if (Object.prototype.hasOwnProperty.call(options, key)) {
|
|
193
193
|
const value = options[key];
|
|
@@ -214,6 +214,50 @@ function normalizeProps(options) {
|
|
|
214
214
|
}
|
|
215
215
|
return props;
|
|
216
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* Section globs are matched against paths that are already relative to the
|
|
219
|
+
* directory holding the `.editorconfig` file, so no glob can ever refer to a
|
|
220
|
+
* parent directory. The glob engines do not resolve a `..` component against
|
|
221
|
+
* that path though; they let it consume any one directory level. That makes a
|
|
222
|
+
* section such as `[dir/../x.c]` match `x.c` sitting next to the config file,
|
|
223
|
+
* even though `x.c` is not inside `dir`. Detect those components so the
|
|
224
|
+
* section can be rejected.
|
|
225
|
+
*
|
|
226
|
+
* @param glob Section name, as written in the config file.
|
|
227
|
+
* @returns True if the glob has an unescaped `..` path component.
|
|
228
|
+
*/
|
|
229
|
+
function hasParentDirComponent(glob) {
|
|
230
|
+
return glob.split('/').some(part => {
|
|
231
|
+
let name = '';
|
|
232
|
+
for (let i = 0; i < part.length; i++) {
|
|
233
|
+
if (part[i] === '\\') {
|
|
234
|
+
// A backslash escapes the next character, so it is a literal.
|
|
235
|
+
i++;
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
name += part[i];
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return name === '..';
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Build the matcher for a single section of a config file.
|
|
246
|
+
*
|
|
247
|
+
* The global section has no name and never matches a file, and a section whose
|
|
248
|
+
* glob names a parent directory cannot match a file below the config's own
|
|
249
|
+
* directory, so both get no matcher at all.
|
|
250
|
+
*
|
|
251
|
+
* @param pathPrefix Escaped path of the directory holding the config file.
|
|
252
|
+
* @param name Section name, as written in the config file.
|
|
253
|
+
* @returns The section's matcher, or null if it cannot match anything.
|
|
254
|
+
*/
|
|
255
|
+
function buildSectionGlob(pathPrefix, name) {
|
|
256
|
+
if (!name || hasParentDirComponent(name)) {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
return buildFullGlob(pathPrefix, name);
|
|
260
|
+
}
|
|
217
261
|
/**
|
|
218
262
|
* Take the contents of a config file, and prepare it for use. If a cache is
|
|
219
263
|
* provided, the result will be stored there. As such, all of the higher-CPU
|
|
@@ -233,7 +277,7 @@ function processFileContents(filepath, contents, options) {
|
|
|
233
277
|
root: false,
|
|
234
278
|
notfound: true,
|
|
235
279
|
name: filepath,
|
|
236
|
-
config: [[null,
|
|
280
|
+
config: [[null, Object.create(null), null]],
|
|
237
281
|
};
|
|
238
282
|
}
|
|
239
283
|
else {
|
|
@@ -248,7 +292,7 @@ function processFileContents(filepath, contents, options) {
|
|
|
248
292
|
const globbed = parseBuffer(contents).map(([name, body]) => [
|
|
249
293
|
name,
|
|
250
294
|
normalizeProps(body),
|
|
251
|
-
|
|
295
|
+
buildSectionGlob(pathPrefix, name),
|
|
252
296
|
]);
|
|
253
297
|
res = {
|
|
254
298
|
root: Boolean(globbed[0][1].root), // Global section: globbed[0]
|
|
@@ -262,20 +306,20 @@ function processFileContents(filepath, contents, options) {
|
|
|
262
306
|
return res;
|
|
263
307
|
}
|
|
264
308
|
/**
|
|
265
|
-
*
|
|
266
|
-
*
|
|
309
|
+
* Reads of config files that are in progress, per cache, so that concurrent
|
|
310
|
+
* lookups of the same file share one read. Entries are removed once the read
|
|
311
|
+
* settles; the finished result lives in the cache.
|
|
312
|
+
*/
|
|
313
|
+
const pendingConfigs = new WeakMap();
|
|
314
|
+
/**
|
|
315
|
+
* Read a config file's contents from disk, process, and insert into the cache
|
|
316
|
+
* (if configured).
|
|
267
317
|
*
|
|
268
318
|
* @param filepath The fully-qualified path of the config file.
|
|
269
319
|
* @param options Access to the cache, if configured.
|
|
270
|
-
* @returns The processed file
|
|
320
|
+
* @returns The processed file.
|
|
271
321
|
*/
|
|
272
|
-
async function
|
|
273
|
-
if (options.cache) {
|
|
274
|
-
const cached = options.cache.get(filepath);
|
|
275
|
-
if (cached) {
|
|
276
|
-
return cached;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
322
|
+
async function readConfig(filepath, options) {
|
|
279
323
|
const contents = await new Promise(resolve => {
|
|
280
324
|
fs.readFile(filepath, (_, buf) => {
|
|
281
325
|
// Ignore errors. contents will be undefined
|
|
@@ -285,6 +329,46 @@ async function getConfig(filepath, options) {
|
|
|
285
329
|
});
|
|
286
330
|
return processFileContents(filepath, contents, options);
|
|
287
331
|
}
|
|
332
|
+
/**
|
|
333
|
+
* Get a file from the cache, or read its contents from disk, process, and
|
|
334
|
+
* insert into the cache (if configured). If the cache is configured,
|
|
335
|
+
* concurrent calls for the same file share one read.
|
|
336
|
+
*
|
|
337
|
+
* @param filepath The fully-qualified path of the config file.
|
|
338
|
+
* @param options Access to the cache, if configured.
|
|
339
|
+
* @returns The processed file, or undefined if there was an error reading it.
|
|
340
|
+
*/
|
|
341
|
+
async function getConfig(filepath, options) {
|
|
342
|
+
if (!options.cache) {
|
|
343
|
+
return readConfig(filepath, options);
|
|
344
|
+
}
|
|
345
|
+
const cached = options.cache.get(filepath);
|
|
346
|
+
if (cached) {
|
|
347
|
+
return cached;
|
|
348
|
+
}
|
|
349
|
+
let pending = pendingConfigs.get(options.cache);
|
|
350
|
+
let config = undefined;
|
|
351
|
+
if (pending) {
|
|
352
|
+
config = pending.get(filepath);
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
pending = new Map();
|
|
356
|
+
pendingConfigs.set(options.cache, pending);
|
|
357
|
+
}
|
|
358
|
+
if (!config) {
|
|
359
|
+
config = readConfig(filepath, options);
|
|
360
|
+
pending.set(filepath, config);
|
|
361
|
+
try {
|
|
362
|
+
// Reminder: this returns immediately with a promise, and the finally
|
|
363
|
+
// block doesn't fire until the promise is settled.
|
|
364
|
+
return await config;
|
|
365
|
+
}
|
|
366
|
+
finally {
|
|
367
|
+
pending.delete(filepath);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return config;
|
|
371
|
+
}
|
|
288
372
|
/**
|
|
289
373
|
* Get a file from the cache, or read its contents from disk, process, and
|
|
290
374
|
* insert into the cache (if configured). Synchronous.
|
|
@@ -412,7 +496,7 @@ function combine(filepath, configs, options) {
|
|
|
412
496
|
}
|
|
413
497
|
}
|
|
414
498
|
return props;
|
|
415
|
-
},
|
|
499
|
+
}, Object.create(null));
|
|
416
500
|
if (options.unset) {
|
|
417
501
|
unset(ret);
|
|
418
502
|
}
|
package/lib/index.test.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
export {};
|
package/lib/index.test.js
CHANGED
|
@@ -32,15 +32,21 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
35
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
39
|
/* eslint-disable @typescript-eslint/no-deprecated */
|
|
37
|
-
require("chai/register-should.js");
|
|
38
40
|
const editorconfig = __importStar(require("./index.js"));
|
|
39
41
|
const fs = __importStar(require("node:fs"));
|
|
42
|
+
const os = __importStar(require("node:os"));
|
|
40
43
|
const path = __importStar(require("node:path"));
|
|
44
|
+
const chai_1 = require("chai");
|
|
41
45
|
const node_buffer_1 = require("node:buffer");
|
|
46
|
+
const node_process_1 = __importDefault(require("node:process"));
|
|
47
|
+
(0, chai_1.should)();
|
|
42
48
|
describe('parse', () => {
|
|
43
|
-
const expected = {
|
|
49
|
+
const expected = Object.assign(Object.create(null), {
|
|
44
50
|
indent_style: 'space',
|
|
45
51
|
indent_size: 2,
|
|
46
52
|
end_of_line: 'lf',
|
|
@@ -51,24 +57,43 @@ describe('parse', () => {
|
|
|
51
57
|
block_comment: '*',
|
|
52
58
|
block_comment_end: '*/',
|
|
53
59
|
block_comment_start: '/**',
|
|
54
|
-
};
|
|
60
|
+
});
|
|
55
61
|
const target = path.join(__dirname, '/app.js');
|
|
56
62
|
it('async', async () => {
|
|
57
63
|
const cfg = await editorconfig.parse(target);
|
|
58
|
-
cfg.
|
|
64
|
+
(0, chai_1.expect)(cfg).to.eql(expected);
|
|
59
65
|
});
|
|
60
66
|
it('sync', () => {
|
|
61
67
|
const visited = [];
|
|
62
68
|
const cfg = editorconfig.parseSync(target, { files: visited });
|
|
63
|
-
cfg.
|
|
69
|
+
(0, chai_1.expect)(cfg).to.eql(expected);
|
|
64
70
|
visited.should.have.lengthOf(1);
|
|
65
71
|
visited[0].glob.should.eql('*');
|
|
66
72
|
visited[0].fileName.should.match(/\.editorconfig$/);
|
|
67
73
|
});
|
|
74
|
+
it('stops at the filesystem root when the configured root is not an ancestor', async () => {
|
|
75
|
+
const root = path.join(__dirname, 'not-an-ancestor');
|
|
76
|
+
const cfg = await editorconfig.parse(target, { root });
|
|
77
|
+
(0, chai_1.expect)(cfg).to.eql(expected);
|
|
78
|
+
});
|
|
79
|
+
it('stops at the filesystem root synchronously when the configured root is not an ancestor', () => {
|
|
80
|
+
const root = path.join(__dirname, 'not-an-ancestor');
|
|
81
|
+
const cfg = editorconfig.parseSync(target, { root });
|
|
82
|
+
(0, chai_1.expect)(cfg).to.eql(expected);
|
|
83
|
+
});
|
|
84
|
+
const windowsIt = node_process_1.default.platform === 'win32' ? it : it.skip;
|
|
85
|
+
windowsIt('parses Windows extended-length paths', async () => {
|
|
86
|
+
const cfg = await editorconfig.parse(path.toNamespacedPath(target));
|
|
87
|
+
(0, chai_1.expect)(cfg).to.eql(expected);
|
|
88
|
+
});
|
|
89
|
+
windowsIt('parses Windows extended-length paths synchronously', () => {
|
|
90
|
+
const cfg = editorconfig.parseSync(path.toNamespacedPath(target));
|
|
91
|
+
(0, chai_1.expect)(cfg).to.eql(expected);
|
|
92
|
+
});
|
|
68
93
|
it('caches', async () => {
|
|
69
94
|
const cache = new Map();
|
|
70
95
|
const cfg = await editorconfig.parse(target, { cache });
|
|
71
|
-
cfg.
|
|
96
|
+
(0, chai_1.expect)(cfg).to.eql(expected);
|
|
72
97
|
cache.size.should.be.eql(2);
|
|
73
98
|
await editorconfig.parse(target, { cache });
|
|
74
99
|
cache.size.should.be.eql(2);
|
|
@@ -76,11 +101,28 @@ describe('parse', () => {
|
|
|
76
101
|
it('caches sync', () => {
|
|
77
102
|
const cache = new Map();
|
|
78
103
|
const cfg = editorconfig.parseSync(target, { cache });
|
|
79
|
-
cfg.
|
|
104
|
+
(0, chai_1.expect)(cfg).to.eql(expected);
|
|
80
105
|
cache.size.should.be.eql(2);
|
|
81
106
|
editorconfig.parseSync(target, { cache });
|
|
82
107
|
cache.size.should.be.eql(2);
|
|
83
108
|
});
|
|
109
|
+
it('shares concurrent reads through the cache', async () => {
|
|
110
|
+
const cache = new Map();
|
|
111
|
+
let sets = 0;
|
|
112
|
+
const counting = {
|
|
113
|
+
get: p => cache.get(p),
|
|
114
|
+
set(p, config) {
|
|
115
|
+
sets++;
|
|
116
|
+
cache.set(p, config);
|
|
117
|
+
return this;
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
const cfgs = await Promise.all(Array.from({ length: 10 }, () => editorconfig.parse(target, { cache: counting })));
|
|
121
|
+
for (const cfg of cfgs) {
|
|
122
|
+
(0, chai_1.expect)(cfg).to.eql(expected);
|
|
123
|
+
}
|
|
124
|
+
sets.should.be.eql(2);
|
|
125
|
+
});
|
|
84
126
|
});
|
|
85
127
|
describe('parseFromFiles', () => {
|
|
86
128
|
const expected = {
|
|
@@ -108,35 +150,35 @@ describe('parseFromFiles', () => {
|
|
|
108
150
|
];
|
|
109
151
|
it('async', async () => {
|
|
110
152
|
const cfg = await editorconfig.parseFromFiles(target, Promise.resolve(configs));
|
|
111
|
-
cfg.
|
|
153
|
+
(0, chai_1.expect)(cfg).to.eql(expected);
|
|
112
154
|
});
|
|
113
155
|
it('sync', () => {
|
|
114
156
|
const cfg = editorconfig.parseFromFilesSync(target, configs);
|
|
115
|
-
cfg.
|
|
157
|
+
(0, chai_1.expect)(cfg).to.eql(expected);
|
|
116
158
|
});
|
|
117
159
|
it('handles null', () => {
|
|
118
160
|
const cfg = editorconfig.parseFromFilesSync(target, [{
|
|
119
161
|
name: configPath,
|
|
120
162
|
contents: node_buffer_1.Buffer.from('[*]\nfoo = null\n'),
|
|
121
163
|
}]);
|
|
122
|
-
cfg.
|
|
164
|
+
(0, chai_1.expect)(cfg).to.eql({ foo: 'null' });
|
|
123
165
|
});
|
|
124
166
|
it('caches async', async () => {
|
|
125
167
|
const cache = new Map();
|
|
126
168
|
const cfg = await editorconfig.parseFromFiles(target, Promise.resolve(configs2), { cache });
|
|
127
|
-
cfg.
|
|
169
|
+
(0, chai_1.expect)(cfg).to.eql(expected);
|
|
128
170
|
cache.size.should.be.eql(2);
|
|
129
171
|
const cfg2 = await editorconfig.parseFromFiles(target, Promise.resolve(configs2), { cache });
|
|
130
|
-
cfg2.
|
|
172
|
+
(0, chai_1.expect)(cfg2).to.eql(expected);
|
|
131
173
|
cache.size.should.be.eql(2);
|
|
132
174
|
});
|
|
133
175
|
it('caches sync', () => {
|
|
134
176
|
const cache = new Map();
|
|
135
177
|
const cfg = editorconfig.parseFromFilesSync(target, configs2, { cache });
|
|
136
|
-
cfg.
|
|
178
|
+
(0, chai_1.expect)(cfg).to.eql(expected);
|
|
137
179
|
cache.size.should.be.eql(2);
|
|
138
180
|
const cfg2 = editorconfig.parseFromFilesSync(target, configs2, { cache });
|
|
139
|
-
cfg2.
|
|
181
|
+
(0, chai_1.expect)(cfg2).to.eql(expected);
|
|
140
182
|
cache.size.should.be.eql(2);
|
|
141
183
|
});
|
|
142
184
|
it('handles minimatch escapables', () => {
|
|
@@ -153,7 +195,7 @@ describe('parseFromFiles', () => {
|
|
|
153
195
|
];
|
|
154
196
|
const escTarget = `${bogusPath}/app.js`;
|
|
155
197
|
const cfg = editorconfig.parseFromFilesSync(escTarget, escConfigs);
|
|
156
|
-
cfg.
|
|
198
|
+
(0, chai_1.expect)(cfg).to.eql(expected);
|
|
157
199
|
});
|
|
158
200
|
});
|
|
159
201
|
describe('parseString', () => {
|
|
@@ -176,19 +218,70 @@ describe('parseString', () => {
|
|
|
176
218
|
const contents = fs.readFileSync(configPath, 'utf8');
|
|
177
219
|
it('sync', () => {
|
|
178
220
|
const cfg = editorconfig.parseString(contents);
|
|
179
|
-
cfg.
|
|
221
|
+
(0, chai_1.expect)(cfg).to.eql(expected);
|
|
180
222
|
});
|
|
181
223
|
it('handles errors', () => {
|
|
182
224
|
const cfg = editorconfig.parseString('root: ');
|
|
183
|
-
cfg.
|
|
225
|
+
(0, chai_1.expect)(cfg).to.eql([[null, Object.create(null)]]);
|
|
184
226
|
});
|
|
185
227
|
it('handles backslashes in glob', () => {
|
|
186
228
|
const cfg = editorconfig.parseString('[a\\\\b]');
|
|
187
|
-
cfg.
|
|
229
|
+
(0, chai_1.expect)(cfg).to.eql([[null, {}], ['a\\\\b', Object.create(null)]]);
|
|
188
230
|
});
|
|
189
231
|
it('handles blank comments', () => {
|
|
190
232
|
const cfg = editorconfig.parseString('#');
|
|
191
|
-
cfg.
|
|
233
|
+
(0, chai_1.expect)(cfg).to.eql([[null, Object.create(null)]]);
|
|
234
|
+
});
|
|
235
|
+
it('handles __proto__', () => {
|
|
236
|
+
const cfg = editorconfig.parseString('__proto__ = foo');
|
|
237
|
+
const obj = Object.create(null);
|
|
238
|
+
// eslint-disable-next-line no-proto
|
|
239
|
+
obj.__proto__ = 'foo';
|
|
240
|
+
(0, chai_1.expect)(cfg).to.eql([[null, obj]]);
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
describe('parent directory components in section globs', () => {
|
|
244
|
+
let dir = '';
|
|
245
|
+
let target = '';
|
|
246
|
+
before(() => {
|
|
247
|
+
dir = fs.mkdtempSync(path.join(os.tmpdir(), 'editorconfig-'));
|
|
248
|
+
target = path.join(dir, 'x.c');
|
|
249
|
+
fs.writeFileSync(target, '');
|
|
250
|
+
});
|
|
251
|
+
after(() => {
|
|
252
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
253
|
+
});
|
|
254
|
+
/**
|
|
255
|
+
* Write a one-section config and return the properties for `x.c`.
|
|
256
|
+
*
|
|
257
|
+
* @param glob Section name to test.
|
|
258
|
+
* @returns Properties found for the target file.
|
|
259
|
+
*/
|
|
260
|
+
function configFor(glob) {
|
|
261
|
+
fs.writeFileSync(path.join(dir, '.editorconfig'), `root = true\n\n[${glob}]\nhit = yes\n`);
|
|
262
|
+
return editorconfig.parseSync(target);
|
|
263
|
+
}
|
|
264
|
+
it('does not let a `..` component consume a directory', () => {
|
|
265
|
+
// `[dir/../x.c]` must not match `x.c`, which is not inside `dir`.
|
|
266
|
+
(0, chai_1.expect)(configFor('dir/../x.c')).to.not.have.property('hit');
|
|
267
|
+
(0, chai_1.expect)(configFor('a/../b/../x.c')).to.not.have.property('hit');
|
|
268
|
+
(0, chai_1.expect)(configFor('**/../x.c')).to.not.have.property('hit');
|
|
269
|
+
(0, chai_1.expect)(configFor('../x.c')).to.not.have.property('hit');
|
|
270
|
+
(0, chai_1.expect)(configFor('./x.c')).to.not.have.property('hit');
|
|
271
|
+
});
|
|
272
|
+
it('still matches a plain name and a `**` pattern', () => {
|
|
273
|
+
(0, chai_1.expect)(configFor('x.c')).to.have.property('hit', 'yes');
|
|
274
|
+
(0, chai_1.expect)(configFor('**/x.c')).to.have.property('hit', 'yes');
|
|
275
|
+
(0, chai_1.expect)(configFor('*.c')).to.have.property('hit', 'yes');
|
|
276
|
+
});
|
|
277
|
+
it('treats an escaped `..` as a literal name', () => {
|
|
278
|
+
// `a\.\.` is a file called `a..`, not a parent-directory reference.
|
|
279
|
+
(0, chai_1.expect)(configFor('a\\.\\.c')).to.not.have.property('hit');
|
|
280
|
+
});
|
|
281
|
+
it('does not match through the async parse either', async () => {
|
|
282
|
+
fs.writeFileSync(path.join(dir, '.editorconfig'), 'root = true\n\n[dir/../x.c]\nhit = yes\n');
|
|
283
|
+
const cfg = await editorconfig.parse(target);
|
|
284
|
+
(0, chai_1.expect)(cfg).to.not.have.property('hit');
|
|
192
285
|
});
|
|
193
286
|
});
|
|
194
287
|
describe('extra behavior', () => {
|
|
@@ -202,12 +295,12 @@ indent_size = 4
|
|
|
202
295
|
|
|
203
296
|
[!(package).json]
|
|
204
297
|
indent_size = 3`));
|
|
205
|
-
matcher(path.join(__dirname, 'package.json')).
|
|
206
|
-
matcher(path.join(__dirname, 'foo.json')).
|
|
298
|
+
(0, chai_1.expect)(matcher(path.join(__dirname, 'package.json'))).to.include({ indent_size: 4 });
|
|
299
|
+
(0, chai_1.expect)(matcher(path.join(__dirname, 'foo.json'))).to.include({ indent_size: 3 });
|
|
207
300
|
});
|
|
208
301
|
});
|
|
209
302
|
describe('unset', () => {
|
|
210
|
-
it('pair
|
|
303
|
+
it('pair with the value `unset`', () => {
|
|
211
304
|
const matcher = editorconfig.matcher({
|
|
212
305
|
root: __dirname,
|
|
213
306
|
unset: true,
|
|
@@ -218,7 +311,7 @@ indent_size = 4
|
|
|
218
311
|
[*.json]
|
|
219
312
|
indent_size = unset
|
|
220
313
|
`));
|
|
221
|
-
matcher(path.join(__dirname, 'index.js')).
|
|
222
|
-
matcher(path.join(__dirname, 'index.json')).
|
|
314
|
+
(0, chai_1.expect)(matcher(path.join(__dirname, 'index.js'))).to.include({ indent_size: 4 });
|
|
315
|
+
(0, chai_1.expect)(matcher(path.join(__dirname, 'index.json'))).to.be.eql(Object.create(null));
|
|
223
316
|
});
|
|
224
317
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "editorconfig",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "EditorConfig File Locator and Interpreter for Node.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"editorconfig",
|
|
@@ -17,7 +17,11 @@
|
|
|
17
17
|
"Trey Hunner (http://treyhunner.com)",
|
|
18
18
|
"Joe Hildebrand (https://github.com/hildjj/)",
|
|
19
19
|
"SunsetTechuila (https://github.com/SunsetTechuila/)",
|
|
20
|
-
"Rex Lorenzo (https://github.com/rlorenzo/)"
|
|
20
|
+
"Rex Lorenzo (https://github.com/rlorenzo/)",
|
|
21
|
+
"Gareth Jones (https://github.com/G-Rath)",
|
|
22
|
+
"Lorie (https://github.com/Lorie-Capella)",
|
|
23
|
+
"simpleqt (https://github.com/simpleqt)",
|
|
24
|
+
"Eli (https://github.com/lishaduck)"
|
|
21
25
|
],
|
|
22
26
|
"directories": {
|
|
23
27
|
"bin": "./bin",
|
|
@@ -31,12 +35,13 @@
|
|
|
31
35
|
"author": "EditorConfig Team",
|
|
32
36
|
"license": "MIT",
|
|
33
37
|
"dependencies": {
|
|
34
|
-
"@one-ini/wasm": "0.2.
|
|
35
|
-
"commander": "^
|
|
36
|
-
"minimatch": "~
|
|
37
|
-
"semver": "^7.
|
|
38
|
+
"@one-ini/wasm": "0.2.3",
|
|
39
|
+
"commander": "^15.0.0",
|
|
40
|
+
"minimatch": "~11.0.4",
|
|
41
|
+
"semver": "^7.8.6"
|
|
38
42
|
},
|
|
43
|
+
"packageManager": "pnpm@12.17.0",
|
|
39
44
|
"engines": {
|
|
40
|
-
"node": ">=
|
|
45
|
+
"node": ">=22"
|
|
41
46
|
}
|
|
42
47
|
}
|