@markuplint/file-resolver 3.0.0-dev.25 → 3.0.0-dev.300
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/auto-load-rules.js +6 -34
- package/lib/config-provider.d.ts +6 -4
- package/lib/config-provider.js +128 -78
- package/lib/cosmiconfig.js +33 -17
- package/lib/index.d.ts +7 -7
- package/lib/index.js +6 -9
- package/lib/ml-file/get-anonymous-file.d.ts +1 -1
- package/lib/ml-file/get-anonymous-file.js +3 -7
- package/lib/ml-file/get-file.d.ts +1 -1
- package/lib/ml-file/get-file.js +3 -7
- package/lib/ml-file/get-files.d.ts +1 -1
- package/lib/ml-file/get-files.js +5 -17
- package/lib/ml-file/index.d.ts +4 -4
- package/lib/ml-file/index.js +3 -6
- package/lib/ml-file/ml-file.d.ts +2 -1
- package/lib/ml-file/ml-file.js +56 -41
- package/lib/resolve-files.d.ts +3 -3
- package/lib/resolve-files.js +4 -8
- package/lib/resolve-parser.d.ts +2 -2
- package/lib/resolve-parser.js +13 -17
- package/lib/resolve-plugins.d.ts +1 -1
- package/lib/resolve-plugins.js +11 -36
- package/lib/resolve-rules.d.ts +2 -3
- package/lib/resolve-rules.js +8 -35
- package/lib/resolve-specs.js +8 -17
- package/lib/types.d.ts +7 -8
- package/lib/types.js +1 -2
- package/lib/utils.d.ts +0 -2
- package/lib/utils.js +6 -17
- package/package.json +26 -16
- package/__mocks__/markuplint-angular-parser.js +0 -3
- package/__mocks__/markuplint-rule-fake.js +0 -1
- package/__mocks__/packaged-config.js +0 -3
- package/test/fixtures/001/package.json +0 -15
- package/test/fixtures/001/target.html +0 -0
- package/test/fixtures/002/.markuplintrc.json +0 -52
- package/test/fixtures/002/target.html +0 -0
- package/test/fixtures/003/.markuplintrc +0 -50
- package/test/fixtures/003/dir/target.html +0 -0
- package/test/fixtures/004/.markuplintrc +0 -4
- package/test/fixtures/004/dir/.markuplintrc +0 -4
- package/test/fixtures/004/dir/dir/.markuplintrc +0 -4
- package/test/fixtures/004/dir/dir/dir/.markuplintrc +0 -4
- package/test/fixtures/004/dir/dir/dir/dir/.markuplintrc +0 -4
- package/test/fixtures/004/dir/dir/dir/dir/dir/.markuplintrc +0 -4
- package/test/fixtures/004/dir/dir/dir/dir/dir/deep-target.html +0 -0
- package/test/fixtures/005/.markuplintrc +0 -4
- package/test/fixtures/005/target.html +0 -0
- package/test/fixtures/006/.markuplintrc +0 -12
- package/test/fixtures/006/target.html +0 -0
- package/test/fixtures/007/.markuplintrc +0 -3
- package/test/fixtures/007/target.html +0 -0
- package/test/plugins/001.js +0 -27
- package/test/plugins/002.js +0 -9
- package/tsconfig.test.json +0 -3
- package/tsconfig.tsbuildinfo +0 -1
package/lib/auto-load-rules.js
CHANGED
|
@@ -1,36 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var _a, _b;
|
|
26
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
-
exports.autoLoadRules = void 0;
|
|
28
|
-
const ml_core_1 = require("@markuplint/ml-core");
|
|
1
|
+
import { MLRule } from '@markuplint/ml-core';
|
|
29
2
|
const cache = new Map();
|
|
30
3
|
/**
|
|
31
4
|
* @deprecated
|
|
32
5
|
*/
|
|
33
|
-
async function autoLoadRules(ruleset) {
|
|
6
|
+
export async function autoLoadRules(ruleset) {
|
|
34
7
|
const rules = [];
|
|
35
8
|
const errors = [];
|
|
36
9
|
for (const ruleName of Object.keys(ruleset.rules)) {
|
|
@@ -41,7 +14,7 @@ async function autoLoadRules(ruleset) {
|
|
|
41
14
|
}
|
|
42
15
|
let seed = null;
|
|
43
16
|
try {
|
|
44
|
-
const _module = await (
|
|
17
|
+
const _module = await import(`@markuplint/rule-${ruleName}`);
|
|
45
18
|
seed = _module.default;
|
|
46
19
|
if (!(seed && 'defaultValue' in seed && 'defaultOptions' in seed && 'verify' in seed)) {
|
|
47
20
|
seed = null;
|
|
@@ -51,7 +24,7 @@ async function autoLoadRules(ruleset) {
|
|
|
51
24
|
errors.push(e);
|
|
52
25
|
}
|
|
53
26
|
if (seed) {
|
|
54
|
-
const rule = new
|
|
27
|
+
const rule = new MLRule({
|
|
55
28
|
name: ruleName,
|
|
56
29
|
...seed,
|
|
57
30
|
});
|
|
@@ -60,7 +33,7 @@ async function autoLoadRules(ruleset) {
|
|
|
60
33
|
continue;
|
|
61
34
|
}
|
|
62
35
|
try {
|
|
63
|
-
const _module = await (
|
|
36
|
+
const _module = await import(`markuplint-rule-${ruleName}`);
|
|
64
37
|
seed = _module.default;
|
|
65
38
|
if (!(seed && 'defaultValue' in seed && 'defaultOptions' in seed && 'verify' in seed)) {
|
|
66
39
|
seed = null;
|
|
@@ -70,7 +43,7 @@ async function autoLoadRules(ruleset) {
|
|
|
70
43
|
errors.push(e);
|
|
71
44
|
}
|
|
72
45
|
if (seed) {
|
|
73
|
-
const rule = new
|
|
46
|
+
const rule = new MLRule({
|
|
74
47
|
name: ruleName,
|
|
75
48
|
...seed,
|
|
76
49
|
});
|
|
@@ -86,4 +59,3 @@ async function autoLoadRules(ruleset) {
|
|
|
86
59
|
errors: errors.slice(),
|
|
87
60
|
};
|
|
88
61
|
}
|
|
89
|
-
exports.autoLoadRules = autoLoadRules;
|
package/lib/config-provider.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import type { MLFile } from './ml-file';
|
|
2
|
-
import type { ConfigSet
|
|
1
|
+
import type { MLFile } from './ml-file/index.js';
|
|
2
|
+
import type { ConfigSet } from './types.js';
|
|
3
3
|
import type { Config } from '@markuplint/ml-config';
|
|
4
|
+
import type { Nullable } from '@markuplint/shared';
|
|
4
5
|
export declare class ConfigProvider {
|
|
5
6
|
#private;
|
|
6
|
-
resolve(targetFile: MLFile
|
|
7
|
-
search(targetFile: MLFile): Promise<string | null>;
|
|
7
|
+
resolve(targetFile: Readonly<MLFile>, names: readonly Nullable<string>[], cache?: boolean): Promise<ConfigSet>;
|
|
8
|
+
search(targetFile: Readonly<MLFile>): Promise<string | null>;
|
|
8
9
|
set(config: Config, key?: string): string;
|
|
9
10
|
private _load;
|
|
10
11
|
private _mergeConfigs;
|
|
11
12
|
private _pathResolve;
|
|
12
13
|
private _recursiveLoad;
|
|
14
|
+
private _validateConfig;
|
|
13
15
|
}
|
package/lib/config-provider.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var _ConfigProvider_cache, _ConfigProvider_held, _ConfigProvider_recursiveLoadKeyAndDepth, _ConfigProvider_store;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
import { __classPrivateFieldGet } from "tslib";
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { mergeConfig } from '@markuplint/ml-config';
|
|
6
|
+
import { getPreset } from '@markuplint/ml-core';
|
|
7
|
+
import { ConfigParserError } from '@markuplint/parser-utils';
|
|
8
|
+
import { InvalidSelectorError, createSelector } from '@markuplint/selector';
|
|
9
|
+
import { nonNullableFilter, toNoEmptyStringArrayFromStringOrArray } from '@markuplint/shared';
|
|
10
|
+
import { load as loadConfig, search } from './cosmiconfig.js';
|
|
11
|
+
import { cacheClear, resolvePlugins } from './resolve-plugins.js';
|
|
12
|
+
import { fileExists, uuid } from './utils.js';
|
|
13
|
+
const require = createRequire(import.meta.url);
|
|
12
14
|
const KEY_SEPARATOR = '__ML_CONFIG_MERGE__';
|
|
13
|
-
class ConfigProvider {
|
|
15
|
+
export class ConfigProvider {
|
|
14
16
|
constructor() {
|
|
15
17
|
_ConfigProvider_cache.set(this, new Map());
|
|
16
18
|
_ConfigProvider_held.set(this, new Set());
|
|
@@ -18,28 +20,35 @@ class ConfigProvider {
|
|
|
18
20
|
_ConfigProvider_store.set(this, new Map());
|
|
19
21
|
}
|
|
20
22
|
async resolve(targetFile, names, cache = true) {
|
|
21
|
-
var _a;
|
|
22
23
|
if (!cache) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
__classPrivateFieldGet(this, _ConfigProvider_store, "f").clear();
|
|
25
|
+
__classPrivateFieldGet(this, _ConfigProvider_cache, "f").clear();
|
|
26
|
+
cacheClear();
|
|
26
27
|
}
|
|
27
|
-
const keys = names.filter(
|
|
28
|
+
const keys = names.filter(nonNullableFilter);
|
|
28
29
|
const key = keys.join(KEY_SEPARATOR);
|
|
29
|
-
const currentConfig =
|
|
30
|
+
const currentConfig = __classPrivateFieldGet(this, _ConfigProvider_cache, "f").get(key);
|
|
30
31
|
if (currentConfig) {
|
|
31
32
|
return currentConfig;
|
|
32
33
|
}
|
|
33
34
|
let configSet = await this._mergeConfigs(keys, cache);
|
|
34
|
-
const
|
|
35
|
-
if (
|
|
36
|
-
|
|
35
|
+
const filePath = Array.from(configSet.files).reverse()[0];
|
|
36
|
+
if (!filePath) {
|
|
37
|
+
throw new ConfigParserError('Config file not found', {
|
|
38
|
+
filePath: targetFile.path,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
const errors = this._validateConfig(configSet.config, filePath);
|
|
42
|
+
configSet.errs.push(...errors);
|
|
43
|
+
const plugins = await resolvePlugins(configSet.config.plugins);
|
|
44
|
+
if (__classPrivateFieldGet(this, _ConfigProvider_held, "f").size > 0) {
|
|
45
|
+
const extendHelds = Array.from(__classPrivateFieldGet(this, _ConfigProvider_held, "f").values());
|
|
37
46
|
for (const held of extendHelds) {
|
|
38
|
-
const [, prefix, namespace, name] = held.match(/^([a-z]+:)([^/]+)(?:\/(.+))?$/)
|
|
47
|
+
const [, prefix, namespace, name] = held.match(/^([a-z]+:)([^/]+)(?:\/(.+))?$/) ?? [];
|
|
39
48
|
switch (prefix) {
|
|
40
49
|
case 'plugin:': {
|
|
41
50
|
const plugin = plugins.find(plugin => plugin.name === namespace);
|
|
42
|
-
const config =
|
|
51
|
+
const config = plugin?.configs?.[name ?? ''];
|
|
43
52
|
if (config) {
|
|
44
53
|
this.set(config, held);
|
|
45
54
|
}
|
|
@@ -48,7 +57,7 @@ class ConfigProvider {
|
|
|
48
57
|
}
|
|
49
58
|
}
|
|
50
59
|
configSet = await this._mergeConfigs([...keys, ...extendHelds], cache);
|
|
51
|
-
|
|
60
|
+
__classPrivateFieldGet(this, _ConfigProvider_held, "f").clear();
|
|
52
61
|
}
|
|
53
62
|
// Resolves `overrides`
|
|
54
63
|
if (configSet.config.overrides) {
|
|
@@ -56,9 +65,10 @@ class ConfigProvider {
|
|
|
56
65
|
const globs = Object.keys(overrides);
|
|
57
66
|
for (const glob of globs) {
|
|
58
67
|
const isMatched = targetFile.matches(glob);
|
|
59
|
-
|
|
68
|
+
const config = overrides[glob];
|
|
69
|
+
if (isMatched && config) {
|
|
60
70
|
// Note: Original config disappears
|
|
61
|
-
configSet.config =
|
|
71
|
+
configSet.config = config;
|
|
62
72
|
}
|
|
63
73
|
}
|
|
64
74
|
}
|
|
@@ -66,59 +76,59 @@ class ConfigProvider {
|
|
|
66
76
|
...configSet,
|
|
67
77
|
plugins,
|
|
68
78
|
};
|
|
69
|
-
|
|
79
|
+
__classPrivateFieldGet(this, _ConfigProvider_cache, "f").set(key, result);
|
|
70
80
|
return result;
|
|
71
81
|
}
|
|
72
82
|
async search(targetFile) {
|
|
73
83
|
if (!(await targetFile.dirExists())) {
|
|
74
84
|
return null;
|
|
75
85
|
}
|
|
76
|
-
const res = await
|
|
86
|
+
const res = await search(targetFile.path, false);
|
|
77
87
|
if (!res) {
|
|
78
88
|
return null;
|
|
79
89
|
}
|
|
80
90
|
const { filePath, config } = res;
|
|
81
|
-
const pathResolvedConfig = this._pathResolve(config, filePath);
|
|
82
|
-
|
|
91
|
+
const pathResolvedConfig = await this._pathResolve(config, filePath);
|
|
92
|
+
__classPrivateFieldGet(this, _ConfigProvider_store, "f").set(filePath, pathResolvedConfig);
|
|
83
93
|
return filePath;
|
|
84
94
|
}
|
|
85
95
|
set(config, key) {
|
|
86
|
-
key = key
|
|
87
|
-
|
|
96
|
+
key = key ?? uuid();
|
|
97
|
+
__classPrivateFieldGet(this, _ConfigProvider_store, "f").set(key, config);
|
|
88
98
|
return key;
|
|
89
99
|
}
|
|
90
100
|
async _load(filePath, cache) {
|
|
91
|
-
const entity =
|
|
101
|
+
const entity = __classPrivateFieldGet(this, _ConfigProvider_store, "f").get(filePath);
|
|
92
102
|
if (entity) {
|
|
93
103
|
return entity;
|
|
94
104
|
}
|
|
95
105
|
if (isPreset(filePath)) {
|
|
96
|
-
const [, name] = filePath.match(/^markuplint:(.+)$/i)
|
|
97
|
-
const config = await
|
|
98
|
-
const pathResolvedConfig = this._pathResolve(config, filePath);
|
|
99
|
-
|
|
106
|
+
const [, name] = filePath.match(/^markuplint:(.+)$/i) ?? [];
|
|
107
|
+
const config = await getPreset(name ?? filePath);
|
|
108
|
+
const pathResolvedConfig = await this._pathResolve(config, filePath);
|
|
109
|
+
__classPrivateFieldGet(this, _ConfigProvider_store, "f").set(filePath, pathResolvedConfig);
|
|
100
110
|
return pathResolvedConfig;
|
|
101
111
|
}
|
|
102
112
|
if (isPlugin(filePath)) {
|
|
103
|
-
|
|
113
|
+
__classPrivateFieldGet(this, _ConfigProvider_held, "f").add(filePath);
|
|
104
114
|
return null;
|
|
105
115
|
}
|
|
106
|
-
if (!moduleExists(filePath) && !
|
|
116
|
+
if (!(await moduleExists(filePath)) && !path.isAbsolute(filePath)) {
|
|
107
117
|
throw new TypeError(`${filePath} is not an absolute path`);
|
|
108
118
|
}
|
|
109
119
|
const config = await load(filePath, cache);
|
|
110
120
|
if (!config) {
|
|
111
121
|
return null;
|
|
112
122
|
}
|
|
113
|
-
const pathResolvedConfig = this._pathResolve(config, filePath);
|
|
114
|
-
|
|
123
|
+
const pathResolvedConfig = await this._pathResolve(config, filePath);
|
|
124
|
+
__classPrivateFieldGet(this, _ConfigProvider_store, "f").set(filePath, pathResolvedConfig);
|
|
115
125
|
return pathResolvedConfig;
|
|
116
126
|
}
|
|
117
127
|
async _mergeConfigs(keys, cache) {
|
|
118
128
|
const resolvedKeys = new Set();
|
|
119
129
|
const errs = [];
|
|
120
130
|
for (const key of keys) {
|
|
121
|
-
|
|
131
|
+
__classPrivateFieldGet(this, _ConfigProvider_recursiveLoadKeyAndDepth, "f").clear();
|
|
122
132
|
const keySet = await this._recursiveLoad(key, cache);
|
|
123
133
|
for (const k of keySet.stack) {
|
|
124
134
|
resolvedKeys.add(k);
|
|
@@ -128,11 +138,11 @@ class ConfigProvider {
|
|
|
128
138
|
}
|
|
129
139
|
}
|
|
130
140
|
const configs = Array.from(resolvedKeys)
|
|
131
|
-
.map(name =>
|
|
132
|
-
.filter(
|
|
141
|
+
.map(name => __classPrivateFieldGet(this, _ConfigProvider_store, "f").get(name))
|
|
142
|
+
.filter(nonNullableFilter);
|
|
133
143
|
let resultConfig = {};
|
|
134
144
|
for (const config of configs) {
|
|
135
|
-
resultConfig =
|
|
145
|
+
resultConfig = mergeConfig(resultConfig, config);
|
|
136
146
|
}
|
|
137
147
|
return {
|
|
138
148
|
config: resultConfig,
|
|
@@ -140,37 +150,37 @@ class ConfigProvider {
|
|
|
140
150
|
errs,
|
|
141
151
|
};
|
|
142
152
|
}
|
|
143
|
-
_pathResolve(config, filePath) {
|
|
144
|
-
const dir =
|
|
153
|
+
async _pathResolve(config, filePath) {
|
|
154
|
+
const dir = path.dirname(filePath);
|
|
145
155
|
return {
|
|
146
156
|
...config,
|
|
147
|
-
extends: pathResolve(dir, config.extends),
|
|
148
|
-
plugins: pathResolve(dir, config.plugins, ['name']),
|
|
149
|
-
parser: pathResolve(dir, config.parser),
|
|
150
|
-
specs: pathResolve(dir, config.specs),
|
|
151
|
-
excludeFiles: pathResolve(dir, config.excludeFiles),
|
|
152
|
-
overrides: pathResolve(dir, config.overrides, undefined, true),
|
|
157
|
+
extends: await pathResolve(dir, config.extends),
|
|
158
|
+
plugins: await pathResolve(dir, config.plugins, ['name']),
|
|
159
|
+
parser: await pathResolve(dir, config.parser),
|
|
160
|
+
specs: await pathResolve(dir, config.specs),
|
|
161
|
+
excludeFiles: await pathResolve(dir, config.excludeFiles),
|
|
162
|
+
overrides: await pathResolve(dir, config.overrides, undefined, true),
|
|
153
163
|
};
|
|
154
164
|
}
|
|
155
165
|
async _recursiveLoad(key, cache, depth = 1) {
|
|
156
166
|
const stack = new Set();
|
|
157
167
|
const errs = [];
|
|
158
|
-
const ancestorDepth =
|
|
168
|
+
const ancestorDepth = __classPrivateFieldGet(this, _ConfigProvider_recursiveLoadKeyAndDepth, "f").get(key);
|
|
159
169
|
if (ancestorDepth != null && ancestorDepth < depth) {
|
|
160
170
|
return {
|
|
161
171
|
stack,
|
|
162
172
|
errs: [new CircularReferenceError(`Circular reference detected: ${key}`)],
|
|
163
173
|
};
|
|
164
174
|
}
|
|
165
|
-
|
|
166
|
-
let config =
|
|
175
|
+
__classPrivateFieldGet(this, _ConfigProvider_recursiveLoadKeyAndDepth, "f").set(key, depth);
|
|
176
|
+
let config = __classPrivateFieldGet(this, _ConfigProvider_store, "f").get(key) ?? null;
|
|
167
177
|
if (!config) {
|
|
168
178
|
config = await this._load(key, cache);
|
|
169
179
|
}
|
|
170
180
|
if (!config) {
|
|
171
181
|
return { stack, errs: null };
|
|
172
182
|
}
|
|
173
|
-
const depKeys = config.extends
|
|
183
|
+
const depKeys = config.extends !== null ? toNoEmptyStringArrayFromStringOrArray(config.extends) : null;
|
|
174
184
|
if (depKeys) {
|
|
175
185
|
for (const depKey of depKeys) {
|
|
176
186
|
const keys = await this._recursiveLoad(depKey, cache, depth + 1);
|
|
@@ -185,23 +195,40 @@ class ConfigProvider {
|
|
|
185
195
|
stack.add(key);
|
|
186
196
|
return { stack, errs };
|
|
187
197
|
}
|
|
198
|
+
_validateConfig(config, filePath) {
|
|
199
|
+
const errors = [];
|
|
200
|
+
config.nodeRules?.forEach(rule => {
|
|
201
|
+
if (rule.selector) {
|
|
202
|
+
try {
|
|
203
|
+
createSelector(rule.selector);
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
if (error instanceof InvalidSelectorError) {
|
|
207
|
+
errors.push(new ConfigParserError(error.message, {
|
|
208
|
+
filePath,
|
|
209
|
+
raw: rule.selector,
|
|
210
|
+
}));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
return errors;
|
|
216
|
+
}
|
|
188
217
|
}
|
|
189
|
-
exports.ConfigProvider = ConfigProvider;
|
|
190
218
|
_ConfigProvider_cache = new WeakMap(), _ConfigProvider_held = new WeakMap(), _ConfigProvider_recursiveLoadKeyAndDepth = new WeakMap(), _ConfigProvider_store = new WeakMap();
|
|
191
219
|
async function load(filePath, cache) {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
const
|
|
195
|
-
const config = (mod === null || mod === void 0 ? void 0 : mod.default) || null;
|
|
220
|
+
if (!fileExists(filePath) && (await moduleExists(filePath))) {
|
|
221
|
+
const mod = await import(filePath);
|
|
222
|
+
const config = mod?.default ?? null;
|
|
196
223
|
return config;
|
|
197
224
|
}
|
|
198
|
-
const res = await (
|
|
225
|
+
const res = await loadConfig(filePath, !cache);
|
|
199
226
|
if (!res) {
|
|
200
227
|
return null;
|
|
201
228
|
}
|
|
202
229
|
return res.config;
|
|
203
230
|
}
|
|
204
|
-
function pathResolve(dir, filePath, resolveProps, resolveKey = false) {
|
|
231
|
+
async function pathResolve(dir, filePath, resolveProps, resolveKey = false) {
|
|
205
232
|
if (filePath == null) {
|
|
206
233
|
// @ts-ignore
|
|
207
234
|
return undefined;
|
|
@@ -212,20 +239,20 @@ function pathResolve(dir, filePath, resolveProps, resolveKey = false) {
|
|
|
212
239
|
}
|
|
213
240
|
if (Array.isArray(filePath)) {
|
|
214
241
|
// @ts-ignore
|
|
215
|
-
return filePath.map(fp => pathResolve(dir, fp, resolveProps));
|
|
242
|
+
return Promise.all(filePath.map(fp => pathResolve(dir, fp, resolveProps)));
|
|
216
243
|
}
|
|
217
244
|
const res = {};
|
|
218
245
|
for (const [key, fp] of Object.entries(filePath)) {
|
|
219
246
|
let _key = key;
|
|
220
247
|
if (resolveKey) {
|
|
221
|
-
_key = resolve(dir, key);
|
|
248
|
+
_key = await resolve(dir, key);
|
|
222
249
|
}
|
|
223
250
|
if (typeof fp === 'string') {
|
|
224
251
|
if (!resolveProps) {
|
|
225
|
-
res[_key] = resolve(dir, fp);
|
|
252
|
+
res[_key] = await resolve(dir, fp);
|
|
226
253
|
}
|
|
227
254
|
else if (resolveProps.includes(key)) {
|
|
228
|
-
res[_key] = resolve(dir, fp);
|
|
255
|
+
res[_key] = await resolve(dir, fp);
|
|
229
256
|
}
|
|
230
257
|
else {
|
|
231
258
|
res[_key] = fp;
|
|
@@ -238,25 +265,48 @@ function pathResolve(dir, filePath, resolveProps, resolveKey = false) {
|
|
|
238
265
|
// @ts-ignore
|
|
239
266
|
return res;
|
|
240
267
|
}
|
|
241
|
-
function resolve(dir, pathOrModName) {
|
|
242
|
-
if (moduleExists(pathOrModName) || isPreset(pathOrModName) || isPlugin(pathOrModName)) {
|
|
268
|
+
async function resolve(dir, pathOrModName) {
|
|
269
|
+
if ((await moduleExists(pathOrModName)) || isPreset(pathOrModName) || isPlugin(pathOrModName)) {
|
|
243
270
|
return pathOrModName;
|
|
244
271
|
}
|
|
245
|
-
|
|
272
|
+
const bangAndPath = /^(!)(.*)/.exec(pathOrModName) ?? [];
|
|
273
|
+
const bang = bangAndPath[1] ?? '';
|
|
274
|
+
const pathname = bangAndPath[2] ?? pathOrModName;
|
|
275
|
+
const absPath = path.resolve(dir, pathname);
|
|
276
|
+
return bang + absPath;
|
|
246
277
|
}
|
|
247
|
-
function moduleExists(name) {
|
|
278
|
+
async function moduleExists(name) {
|
|
248
279
|
try {
|
|
249
|
-
|
|
280
|
+
await import(name);
|
|
250
281
|
}
|
|
251
282
|
catch (err) {
|
|
252
|
-
if (
|
|
253
|
-
|
|
254
|
-
|
|
283
|
+
if (err instanceof Error) {
|
|
284
|
+
if (/^Parse failure/i.test(err.message)) {
|
|
285
|
+
return true;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
try {
|
|
289
|
+
require.resolve(name);
|
|
290
|
+
}
|
|
291
|
+
catch (err) {
|
|
292
|
+
if (
|
|
255
293
|
// @ts-ignore
|
|
256
|
-
|
|
257
|
-
|
|
294
|
+
'code' in err &&
|
|
295
|
+
// @ts-ignore
|
|
296
|
+
err.code === 'ERR_PACKAGE_PATH_NOT_EXPORTED') {
|
|
297
|
+
// Even if there are issues with the fields,
|
|
298
|
+
// assume that the module exists and return true.
|
|
299
|
+
return true;
|
|
300
|
+
}
|
|
301
|
+
if (
|
|
302
|
+
// @ts-ignore
|
|
303
|
+
'code' in err &&
|
|
304
|
+
// @ts-ignore
|
|
305
|
+
err.code === 'MODULE_NOT_FOUND') {
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
throw err;
|
|
258
309
|
}
|
|
259
|
-
throw err;
|
|
260
310
|
}
|
|
261
311
|
return true;
|
|
262
312
|
}
|
package/lib/cosmiconfig.js
CHANGED
|
@@ -1,31 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const cosmiconfig_1 = require("cosmiconfig");
|
|
7
|
-
const jsonc_1 = require("jsonc");
|
|
8
|
-
const explorer = (0, cosmiconfig_1.cosmiconfig)('markuplint', {
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { ConfigParserError } from '@markuplint/parser-utils';
|
|
3
|
+
import { cosmiconfig, defaultLoaders } from 'cosmiconfig';
|
|
4
|
+
import { jsonc } from 'jsonc';
|
|
5
|
+
const explorer = cosmiconfig('markuplint', {
|
|
9
6
|
loaders: {
|
|
10
7
|
noExt: ((path, content) => {
|
|
11
8
|
try {
|
|
12
|
-
return
|
|
9
|
+
return jsonc.parse(content);
|
|
13
10
|
}
|
|
14
11
|
catch (error) {
|
|
15
12
|
if (error instanceof Error && error.name === 'JSONError') {
|
|
16
|
-
return
|
|
13
|
+
return defaultLoaders['noExt'](path, content);
|
|
17
14
|
}
|
|
18
15
|
throw error;
|
|
19
16
|
}
|
|
20
17
|
}),
|
|
21
18
|
},
|
|
22
19
|
});
|
|
23
|
-
async function search(dir, cacheClear) {
|
|
20
|
+
export async function search(dir, cacheClear) {
|
|
24
21
|
if (cacheClear) {
|
|
25
22
|
explorer.clearCaches();
|
|
26
23
|
}
|
|
27
|
-
dir =
|
|
28
|
-
const result = await explorer.search(dir);
|
|
24
|
+
dir = path.dirname(dir);
|
|
25
|
+
const result = await explorer.search(dir).catch(cacheConfigError(dir));
|
|
29
26
|
if (!result || result.isEmpty) {
|
|
30
27
|
return null;
|
|
31
28
|
}
|
|
@@ -34,12 +31,11 @@ async function search(dir, cacheClear) {
|
|
|
34
31
|
config: result.config,
|
|
35
32
|
};
|
|
36
33
|
}
|
|
37
|
-
|
|
38
|
-
async function load(filePath, cacheClear) {
|
|
34
|
+
export async function load(filePath, cacheClear) {
|
|
39
35
|
if (cacheClear) {
|
|
40
36
|
explorer.clearCaches();
|
|
41
37
|
}
|
|
42
|
-
const result = await explorer.load(filePath);
|
|
38
|
+
const result = await explorer.load(filePath).catch(cacheConfigError(filePath));
|
|
43
39
|
if (!result || result.isEmpty) {
|
|
44
40
|
return null;
|
|
45
41
|
}
|
|
@@ -48,4 +44,24 @@ async function load(filePath, cacheClear) {
|
|
|
48
44
|
config: result.config,
|
|
49
45
|
};
|
|
50
46
|
}
|
|
51
|
-
|
|
47
|
+
class ConfigLoadError extends Error {
|
|
48
|
+
constructor(message, filePath) {
|
|
49
|
+
super(message + ` in ${filePath}`);
|
|
50
|
+
this.name = 'ConfigLoadError';
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function cacheConfigError(fileOrDirPath) {
|
|
54
|
+
return (reason) => {
|
|
55
|
+
if (reason instanceof Error) {
|
|
56
|
+
switch (reason.name) {
|
|
57
|
+
case 'YAMLException':
|
|
58
|
+
throw new ConfigParserError(reason.message, {
|
|
59
|
+
// @ts-ignore
|
|
60
|
+
filePath: reason.filepath ?? fileOrDirPath,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
throw new ConfigLoadError(reason.message, fileOrDirPath);
|
|
64
|
+
}
|
|
65
|
+
throw reason;
|
|
66
|
+
};
|
|
67
|
+
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export type { MLFile } from './ml-file';
|
|
2
|
-
export * from './config-provider';
|
|
3
|
-
export * from './resolve-files';
|
|
4
|
-
export * from './resolve-parser';
|
|
5
|
-
export * from './resolve-rules';
|
|
6
|
-
export * from './resolve-specs';
|
|
7
|
-
export * from './types';
|
|
1
|
+
export type { MLFile } from './ml-file/index.js';
|
|
2
|
+
export * from './config-provider.js';
|
|
3
|
+
export * from './resolve-files.js';
|
|
4
|
+
export * from './resolve-parser.js';
|
|
5
|
+
export * from './resolve-rules.js';
|
|
6
|
+
export * from './resolve-specs.js';
|
|
7
|
+
export * from './types.js';
|
package/lib/index.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
tslib_1.__exportStar(require("./resolve-rules"), exports);
|
|
8
|
-
tslib_1.__exportStar(require("./resolve-specs"), exports);
|
|
9
|
-
tslib_1.__exportStar(require("./types"), exports);
|
|
1
|
+
export * from './config-provider.js';
|
|
2
|
+
export * from './resolve-files.js';
|
|
3
|
+
export * from './resolve-parser.js';
|
|
4
|
+
export * from './resolve-rules.js';
|
|
5
|
+
export * from './resolve-specs.js';
|
|
6
|
+
export * from './types.js';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { MLFile } from './ml-file';
|
|
1
|
+
import { MLFile } from './ml-file.js';
|
|
2
2
|
export declare function getAnonymousFile(context: string, workspace?: string, name?: string): MLFile;
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const ml_file_1 = require("./ml-file");
|
|
5
|
-
function getAnonymousFile(context, workspace, name) {
|
|
6
|
-
const file = new ml_file_1.MLFile({
|
|
1
|
+
import { MLFile } from './ml-file.js';
|
|
2
|
+
export function getAnonymousFile(context, workspace, name) {
|
|
3
|
+
const file = new MLFile({
|
|
7
4
|
sourceCode: context,
|
|
8
5
|
workspace,
|
|
9
6
|
name,
|
|
10
7
|
});
|
|
11
8
|
return file;
|
|
12
9
|
}
|
|
13
|
-
exports.getAnonymousFile = getAnonymousFile;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { MLFile } from './ml-file';
|
|
1
|
+
import { MLFile } from './ml-file.js';
|
|
2
2
|
export declare function getFile(filePath: string): MLFile;
|
package/lib/ml-file/get-file.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const ml_file_1 = require("./ml-file");
|
|
5
|
-
function getFile(filePath) {
|
|
6
|
-
const file = new ml_file_1.MLFile(filePath);
|
|
1
|
+
import { MLFile } from './ml-file.js';
|
|
2
|
+
export function getFile(filePath) {
|
|
3
|
+
const file = new MLFile(filePath);
|
|
7
4
|
return file;
|
|
8
5
|
}
|
|
9
|
-
exports.getFile = getFile;
|