bpmnlint 11.14.1 → 12.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/bin/bpmnlint.js +11 -416
- package/lib/linter.js +2 -542
- package/lib/product.js +6 -0
- package/lib/resolver/helper.js +1 -12
- package/lib/resolver/node-resolver.js +6 -135
- package/lib/resolver/static-resolver.js +1 -48
- package/lib/support/compile-config.js +5 -200
- package/lib/test-rule.js +1 -107
- package/lib/testers/helper.js +14 -70
- package/lib/testers/rule-tester.d.ts +10 -28
- package/lib/testers/rule-tester.js +10 -140
- package/lib/traverse.js +1 -56
- package/lib/types.d.ts +20 -81
- package/package.json +46 -12
- package/rules/no-overlapping-elements.js +88 -23
package/lib/linter.js
CHANGED
|
@@ -1,543 +1,3 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { createLinter } = require('@bpmn-io/lint-core/lib/linter');
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @typedef { import('./types.js').ModdleElement } ModdleElement
|
|
6
|
-
*
|
|
7
|
-
* @typedef { import('./types.js').ReportingCategory } ReportingCategory
|
|
8
|
-
* @typedef { import('./types.js').ReportingCategoryMap } ReportingCategoryMap
|
|
9
|
-
* @typedef { import('./types.js').RuleErrorCategory } RuleErrorCategory
|
|
10
|
-
*
|
|
11
|
-
* @typedef { import('./types.js').Resolver } Resolver
|
|
12
|
-
* @typedef { import('./types.js').Config } Config
|
|
13
|
-
*
|
|
14
|
-
* @typedef { import('./types.js').RuleFactory } RuleFactory
|
|
15
|
-
*
|
|
16
|
-
* @typedef { import('./types.js').RuleDefinition } RuleDefinition
|
|
17
|
-
* @typedef { import('./types.js').RuleConfigs } RuleConfigs
|
|
18
|
-
* @typedef { import('./types.js').RuleConfig } RuleConfig
|
|
19
|
-
*
|
|
20
|
-
* @typedef { {
|
|
21
|
-
* name: string,
|
|
22
|
-
* rule: RuleDefinition,
|
|
23
|
-
* config: any,
|
|
24
|
-
* category: ReportingCategory
|
|
25
|
-
* } } ResolvedRuleDefinition
|
|
26
|
-
*
|
|
27
|
-
* @typedef { import('./types.js').Report } Report
|
|
28
|
-
* @typedef { Report & Pick<RuleDefinition, 'meta'> & {
|
|
29
|
-
* category: ReportingCategory | RuleErrorCategory
|
|
30
|
-
* } } AnnotatedReport
|
|
31
|
-
*
|
|
32
|
-
* @typedef { import('./types.js').TransformRuleFn } TransformRuleFn
|
|
33
|
-
*
|
|
34
|
-
* @typedef { Record<string, AnnotatedReport[]> } LintResults
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Transform a rule after it is loaded.
|
|
40
|
-
*
|
|
41
|
-
* @param { RuleDefinition } rule
|
|
42
|
-
* @param { { pkg: string, ruleName: string } } options
|
|
43
|
-
*/
|
|
44
|
-
const noopTransformRule = (rule, options) => {
|
|
45
|
-
return rule;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* @typeof { ReportingCategoryMap }
|
|
51
|
-
*/
|
|
52
|
-
const categoryMap = {
|
|
53
|
-
0: 'off',
|
|
54
|
-
1: 'warn',
|
|
55
|
-
2: 'error',
|
|
56
|
-
3: 'info'
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* @type { RuleErrorCategory }
|
|
61
|
-
*/
|
|
62
|
-
const ruleErrorCategory = 'rule-error';
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* @param { {
|
|
66
|
-
* config?: Config,
|
|
67
|
-
* resolver: Resolver,
|
|
68
|
-
* transformRule?: TransformRuleFn
|
|
69
|
-
* } } options
|
|
70
|
-
*/
|
|
71
|
-
function Linter(options) {
|
|
72
|
-
|
|
73
|
-
const {
|
|
74
|
-
config = {},
|
|
75
|
-
resolver,
|
|
76
|
-
transformRule = noopTransformRule
|
|
77
|
-
} = options || {};
|
|
78
|
-
|
|
79
|
-
if (typeof resolver === 'undefined') {
|
|
80
|
-
throw new Error('must provide <options.resolver>');
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
this.config = config;
|
|
84
|
-
this.resolver = resolver;
|
|
85
|
-
|
|
86
|
-
this.transformRule = transformRule;
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* @type { Record<string, RuleDefinition> }
|
|
90
|
-
*/
|
|
91
|
-
this.cachedRules = {};
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* @type { Record<string, Config> }
|
|
95
|
-
*/
|
|
96
|
-
this.cachedConfigs = {};
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
module.exports = Linter;
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Applies a rule on the moddleRoot and adds reports to the finalReport
|
|
104
|
-
*
|
|
105
|
-
* @param { ModdleElement } moddleRoot
|
|
106
|
-
*
|
|
107
|
-
* @param { ResolvedRuleDefinition } ruleDefinition
|
|
108
|
-
*
|
|
109
|
-
* @return { AnnotatedReport[] } reports
|
|
110
|
-
*/
|
|
111
|
-
Linter.prototype.applyRule = function applyRule(moddleRoot, ruleDefinition) {
|
|
112
|
-
|
|
113
|
-
const {
|
|
114
|
-
config,
|
|
115
|
-
rule,
|
|
116
|
-
category,
|
|
117
|
-
name
|
|
118
|
-
} = ruleDefinition;
|
|
119
|
-
|
|
120
|
-
try {
|
|
121
|
-
|
|
122
|
-
const reports = testRule({
|
|
123
|
-
moddleRoot,
|
|
124
|
-
rule,
|
|
125
|
-
config
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
return reports.map(function(report) {
|
|
129
|
-
return {
|
|
130
|
-
...report,
|
|
131
|
-
meta: rule.meta,
|
|
132
|
-
category
|
|
133
|
-
};
|
|
134
|
-
});
|
|
135
|
-
} catch (e) {
|
|
136
|
-
console.error('rule <' + name + '> failed with error: ', e);
|
|
137
|
-
|
|
138
|
-
return [
|
|
139
|
-
{
|
|
140
|
-
message: /** @type { Error } */ (e).message,
|
|
141
|
-
category: ruleErrorCategory
|
|
142
|
-
}
|
|
143
|
-
];
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* @param { string } name
|
|
151
|
-
* @param { RuleConfig } config
|
|
152
|
-
*
|
|
153
|
-
* @return { Promise<RuleDefinition> }
|
|
154
|
-
*/
|
|
155
|
-
Linter.prototype.resolveRule = function(name, config) {
|
|
156
|
-
|
|
157
|
-
const {
|
|
158
|
-
pkg,
|
|
159
|
-
ruleName
|
|
160
|
-
} = this.parseRuleName(name);
|
|
161
|
-
|
|
162
|
-
const id = `${pkg}-${ruleName}`;
|
|
163
|
-
|
|
164
|
-
const rule = this.cachedRules[id];
|
|
165
|
-
|
|
166
|
-
if (rule) {
|
|
167
|
-
return Promise.resolve(rule);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
return Promise.resolve(this.resolver.resolveRule(pkg, ruleName)).then((ruleFactory) => {
|
|
171
|
-
|
|
172
|
-
if (!ruleFactory) {
|
|
173
|
-
throw new Error(`unknown rule <${name}>`);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const rule = this.cachedRules[id] = this.transformRule(ruleFactory(config), { pkg, ruleName });
|
|
177
|
-
|
|
178
|
-
return rule;
|
|
179
|
-
});
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* @param {string} name
|
|
184
|
-
*
|
|
185
|
-
* @return {Promise<Config>}
|
|
186
|
-
*/
|
|
187
|
-
Linter.prototype.resolveConfig = function(name) {
|
|
188
|
-
|
|
189
|
-
const {
|
|
190
|
-
pkg,
|
|
191
|
-
configName
|
|
192
|
-
} = this.parseConfigName(name);
|
|
193
|
-
|
|
194
|
-
const id = `${pkg}-${configName}`;
|
|
195
|
-
|
|
196
|
-
const config = this.cachedConfigs[id];
|
|
197
|
-
|
|
198
|
-
if (config) {
|
|
199
|
-
return Promise.resolve(config);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return Promise.resolve(this.resolver.resolveConfig(pkg, configName)).then((config) => {
|
|
203
|
-
|
|
204
|
-
if (!config) {
|
|
205
|
-
throw new Error(`unknown config <${name}>`);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const actualConfig = this.cachedConfigs[id] = this.normalizeConfig(config, pkg);
|
|
209
|
-
|
|
210
|
-
return actualConfig;
|
|
211
|
-
});
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Take a linter config and return list of resolved rules.
|
|
216
|
-
*
|
|
217
|
-
* @param { Config } config
|
|
218
|
-
*
|
|
219
|
-
* @return { Promise<ResolvedRuleDefinition[]> }
|
|
220
|
-
*/
|
|
221
|
-
Linter.prototype.resolveRules = function(config) {
|
|
222
|
-
|
|
223
|
-
return this.resolveConfiguredRules(config).then((rulesConfig) => {
|
|
224
|
-
|
|
225
|
-
// parse rule values
|
|
226
|
-
const parsedRules = Object.entries(rulesConfig).map(([ name, value ]) => {
|
|
227
|
-
const {
|
|
228
|
-
category,
|
|
229
|
-
config
|
|
230
|
-
} = this.parseRuleValue(value);
|
|
231
|
-
|
|
232
|
-
return {
|
|
233
|
-
name,
|
|
234
|
-
category,
|
|
235
|
-
config
|
|
236
|
-
};
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
// filter only for enabled rules
|
|
240
|
-
const enabledRules = parsedRules.filter(definition => definition.category !== 'off');
|
|
241
|
-
|
|
242
|
-
// load enabled rules
|
|
243
|
-
const loaders = enabledRules.map((definition) => {
|
|
244
|
-
|
|
245
|
-
const {
|
|
246
|
-
name,
|
|
247
|
-
config
|
|
248
|
-
} = definition;
|
|
249
|
-
|
|
250
|
-
return this.resolveRule(name, config).then(function(rule) {
|
|
251
|
-
return {
|
|
252
|
-
...definition,
|
|
253
|
-
rule
|
|
254
|
-
};
|
|
255
|
-
});
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
return Promise.all(loaders);
|
|
259
|
-
});
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* @param { Config } config
|
|
264
|
-
*
|
|
265
|
-
* @return { Promise<RuleConfigs> }
|
|
266
|
-
*/
|
|
267
|
-
Linter.prototype.resolveConfiguredRules = function(config) {
|
|
268
|
-
|
|
269
|
-
let parents = config.extends;
|
|
270
|
-
|
|
271
|
-
if (typeof parents === 'string') {
|
|
272
|
-
parents = [ parents ];
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
if (typeof parents === 'undefined') {
|
|
276
|
-
parents = [];
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
return Promise.all(
|
|
280
|
-
parents.map((configName) => {
|
|
281
|
-
return this.resolveConfig(configName).then((config) => {
|
|
282
|
-
return this.resolveConfiguredRules(config);
|
|
283
|
-
});
|
|
284
|
-
})
|
|
285
|
-
).then((inheritedRules) => {
|
|
286
|
-
|
|
287
|
-
const overrideRules = this.normalizeConfig(config, 'bpmnlint').rules;
|
|
288
|
-
|
|
289
|
-
const rules = [ ...inheritedRules, overrideRules ].reduce((rules, currentRules) => {
|
|
290
|
-
return {
|
|
291
|
-
...rules,
|
|
292
|
-
...currentRules
|
|
293
|
-
};
|
|
294
|
-
}, {});
|
|
295
|
-
|
|
296
|
-
return rules;
|
|
297
|
-
});
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Lint the given model root, using the specified linter config.
|
|
303
|
-
*
|
|
304
|
-
* @param { ModdleElement } moddleRoot
|
|
305
|
-
* @param { Config } [config] the bpmnlint configuration to use
|
|
306
|
-
*
|
|
307
|
-
* @return { Promise<LintResults> } lint results, keyed by rule names
|
|
308
|
-
*/
|
|
309
|
-
Linter.prototype.lint = function(moddleRoot, config) {
|
|
310
|
-
|
|
311
|
-
config = config || this.config;
|
|
312
|
-
|
|
313
|
-
// load rules
|
|
314
|
-
return this.resolveRules(config).then((ruleDefinitions) => {
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* @type { LintResults }
|
|
318
|
-
*/
|
|
319
|
-
const allReports = {};
|
|
320
|
-
|
|
321
|
-
ruleDefinitions.forEach((ruleDefinition) => {
|
|
322
|
-
|
|
323
|
-
const {
|
|
324
|
-
name
|
|
325
|
-
} = ruleDefinition;
|
|
326
|
-
|
|
327
|
-
const reports = this.applyRule(moddleRoot, ruleDefinition);
|
|
328
|
-
|
|
329
|
-
if (reports.length) {
|
|
330
|
-
allReports[name] = reports;
|
|
331
|
-
}
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
return allReports;
|
|
335
|
-
});
|
|
336
|
-
};
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* @param { import('./types.js').RuleConfig } value
|
|
340
|
-
*
|
|
341
|
-
* @return { { config: any, category: ReportingCategory } }
|
|
342
|
-
*/
|
|
343
|
-
Linter.prototype.parseRuleValue = function(value) {
|
|
344
|
-
|
|
345
|
-
let category;
|
|
346
|
-
let config;
|
|
347
|
-
|
|
348
|
-
if (Array.isArray(value)) {
|
|
349
|
-
category = value[0];
|
|
350
|
-
config = value[1];
|
|
351
|
-
} else {
|
|
352
|
-
category = value;
|
|
353
|
-
config = {};
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// normalize rule flag to <error> and <warn> which
|
|
357
|
-
// may be upper case or a number at this point
|
|
358
|
-
if (typeof category === 'string') {
|
|
359
|
-
category = category.toLowerCase();
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
category = categoryMap[category] || category;
|
|
363
|
-
|
|
364
|
-
return {
|
|
365
|
-
config,
|
|
366
|
-
category
|
|
367
|
-
};
|
|
368
|
-
};
|
|
369
|
-
|
|
370
|
-
Linter.prototype.parseRuleName = function(name, localPackage = 'bpmnlint') {
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* We recognize the following rule name patterns:
|
|
374
|
-
*
|
|
375
|
-
* {RULE_NAME} => PKG = 'bpmnlint'
|
|
376
|
-
* bpmnlint/{RULE_NAME} => PKG = 'bpmnlint'
|
|
377
|
-
* {PACKAGE_SHORTCUT}/{RULE_NAME} => PKG = 'bpmnlint-plugin-{PACKAGE_SHORTCUT}'
|
|
378
|
-
* bpmnlint-plugin-{PACKAGE_SHORTCUT}/{RULE_NAME} => PKG = 'bpmnlint-plugin-{PACKAGE_SHORTCUT}'
|
|
379
|
-
* @scope/{PACKAGE_SHORTCUT}/{RULE_NAME} => PKG = '@scope/bpmnlint-plugin-{PACKAGE_SHORTCUT}'
|
|
380
|
-
* @scope/bpmnlint-plugin-{PACKAGE_SHORTCUT}/{RULE_NAME} => PKG = '@scope/bpmnlint-plugin-{PACKAGE_SHORTCUT}'
|
|
381
|
-
*/
|
|
382
|
-
|
|
383
|
-
const match = /^(?:(?:(@[^/]+)\/)?([^@]{1}[^/]*)\/)?([^/]+)$/.exec(name);
|
|
384
|
-
|
|
385
|
-
if (!match) {
|
|
386
|
-
throw new Error(`unparseable rule name <${name}>`);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
const [
|
|
390
|
-
_,
|
|
391
|
-
ns,
|
|
392
|
-
packageName,
|
|
393
|
-
ruleName
|
|
394
|
-
] = match;
|
|
395
|
-
|
|
396
|
-
if (!packageName) {
|
|
397
|
-
return {
|
|
398
|
-
pkg: localPackage,
|
|
399
|
-
ruleName
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
const pkg = `${ns ? ns + '/' : '' }${prefixPackage(packageName)}`;
|
|
404
|
-
|
|
405
|
-
return {
|
|
406
|
-
pkg,
|
|
407
|
-
ruleName
|
|
408
|
-
};
|
|
409
|
-
};
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
Linter.prototype.parseConfigName = function(name) {
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
* We recognize the following config name patterns:
|
|
416
|
-
*
|
|
417
|
-
* bpmnlint:{CONFIG_NAME} => PKG = 'bpmnlint'
|
|
418
|
-
* plugin:{PACKAGE_SHORTCUT}/{CONFIG_NAME} => PKG = 'bpmnlint-plugin-{PACKAGE_SHORTCUT}'
|
|
419
|
-
* plugin:bpmnlint-plugin-{PACKAGE_SHORTCUT}/{CONFIG_NAME} => PKG = 'bpmnlint-plugin-{PACKAGE_SHORTCUT}'
|
|
420
|
-
* plugin:@scope/{PACKAGE_SHORTCUT}/{CONFIG_NAME} => PKG = '@scope/bpmnlint-plugin-{PACKAGE_SHORTCUT}'
|
|
421
|
-
* plugin:@scope/bpmnlint-plugin-{PACKAGE_SHORTCUT}/{CONFIG_NAME} => PKG = '@scope/bpmnlint-plugin-{PACKAGE_SHORTCUT}'
|
|
422
|
-
*/
|
|
423
|
-
|
|
424
|
-
const match = /^(?:(?:plugin:(?:(@[^/]+)\/)?([^@]{1}[^/]*)\/)|bpmnlint:)([^/]+)$/.exec(name);
|
|
425
|
-
|
|
426
|
-
if (!match) {
|
|
427
|
-
throw new Error(`unparseable config name <${name}>`);
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
const [
|
|
431
|
-
_,
|
|
432
|
-
ns,
|
|
433
|
-
packageName,
|
|
434
|
-
configName
|
|
435
|
-
] = match;
|
|
436
|
-
|
|
437
|
-
if (!packageName) {
|
|
438
|
-
return {
|
|
439
|
-
pkg: 'bpmnlint',
|
|
440
|
-
configName
|
|
441
|
-
};
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
const pkg = `${ns ? ns + '/' : '' }${prefixPackage(packageName)}`;
|
|
445
|
-
|
|
446
|
-
return {
|
|
447
|
-
pkg,
|
|
448
|
-
configName
|
|
449
|
-
};
|
|
450
|
-
};
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
Linter.prototype.getSimplePackageName = function(name) {
|
|
454
|
-
|
|
455
|
-
/**
|
|
456
|
-
* We recognize the following package name patterns:
|
|
457
|
-
*
|
|
458
|
-
* bpmnlint => PKG = 'bpmnlint'
|
|
459
|
-
* {PACKAGE_SHORTCUT} => PKG = PACKAGE_SHORTCUT
|
|
460
|
-
* bpmnlint-plugin-{PACKAGE_SHORTCUT}' => PKG = PACKAGE_SHORTCUT
|
|
461
|
-
* @scope/{PACKAGE_SHORTCUT} => PKG = '@scope/{PACKAGE_SHORTCUT}'
|
|
462
|
-
* @scope/bpmnlint-plugin-{PACKAGE_SHORTCUT}' => PKG = '@scope/PACKAGE_SHORTCUT'
|
|
463
|
-
*/
|
|
464
|
-
|
|
465
|
-
const match = /^(?:(@[^/]+)\/)?([^/]+)$/.exec(name);
|
|
466
|
-
|
|
467
|
-
if (!match) {
|
|
468
|
-
throw new Error(`unparseable package name <${name}>`);
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
const [
|
|
472
|
-
_,
|
|
473
|
-
ns,
|
|
474
|
-
packageName
|
|
475
|
-
] = match;
|
|
476
|
-
|
|
477
|
-
return `${ns ? ns + '/' : '' }${unprefixPackage(packageName)}`;
|
|
478
|
-
};
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
/**
|
|
482
|
-
* Validate and return validated config.
|
|
483
|
-
*
|
|
484
|
-
* @param {Object} config
|
|
485
|
-
* @param {String} localPackage
|
|
486
|
-
*
|
|
487
|
-
* @return {Object} validated config
|
|
488
|
-
*/
|
|
489
|
-
Linter.prototype.normalizeConfig = function(config, localPackage) {
|
|
490
|
-
|
|
491
|
-
const rules = config.rules || {};
|
|
492
|
-
|
|
493
|
-
const validatedRules = Object.keys(rules).reduce((normalizedRules, name) => {
|
|
494
|
-
|
|
495
|
-
const value = rules[name];
|
|
496
|
-
|
|
497
|
-
const {
|
|
498
|
-
pkg,
|
|
499
|
-
ruleName
|
|
500
|
-
} = this.parseRuleName(name, localPackage);
|
|
501
|
-
|
|
502
|
-
const normalizedName = (
|
|
503
|
-
pkg === 'bpmnlint'
|
|
504
|
-
? ruleName
|
|
505
|
-
: `${this.getSimplePackageName(pkg)}/${ruleName}`
|
|
506
|
-
);
|
|
507
|
-
|
|
508
|
-
normalizedRules[normalizedName] = value;
|
|
509
|
-
|
|
510
|
-
return normalizedRules;
|
|
511
|
-
}, {});
|
|
512
|
-
|
|
513
|
-
return {
|
|
514
|
-
...config,
|
|
515
|
-
rules: validatedRules
|
|
516
|
-
};
|
|
517
|
-
};
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
// helpers ///////////////////////////
|
|
521
|
-
|
|
522
|
-
function prefixPackage(pkg) {
|
|
523
|
-
|
|
524
|
-
if (pkg === 'bpmnlint') {
|
|
525
|
-
return 'bpmnlint';
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
if (pkg.startsWith('bpmnlint-plugin-')) {
|
|
529
|
-
return pkg;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
return `bpmnlint-plugin-${pkg}`;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
function unprefixPackage(pkg) {
|
|
537
|
-
|
|
538
|
-
if (pkg.startsWith('bpmnlint-plugin-')) {
|
|
539
|
-
return pkg.substring('bpmnlint-plugin-'.length);
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
return pkg;
|
|
543
|
-
}
|
|
3
|
+
module.exports = createLinter(require('./product'));
|
package/lib/product.js
ADDED
package/lib/resolver/helper.js
CHANGED
|
@@ -1,12 +1 @@
|
|
|
1
|
-
|
|
2
|
-
const path = require('node:path');
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Create require function for a given path.
|
|
6
|
-
*
|
|
7
|
-
* @param {string} cwd
|
|
8
|
-
* @returns {NodeRequire}
|
|
9
|
-
*/
|
|
10
|
-
module.exports.createScopedRequire = function(cwd) {
|
|
11
|
-
return Module.createRequire(path.join(cwd, '__placeholder__.js'));
|
|
12
|
-
};
|
|
1
|
+
module.exports = require('@bpmn-io/lint-core/lib/resolver/helper');
|
|
@@ -1,136 +1,7 @@
|
|
|
1
|
-
const
|
|
2
|
-
const { cwd } = require('node:process');
|
|
1
|
+
const { createNodeResolver } = require('@bpmn-io/lint-core/lib/resolver/node-resolver');
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
const { createScopedRequire } = require('./helper');
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* A resolver that locates rules and configurations
|
|
15
|
-
* using node module resolution.
|
|
16
|
-
*
|
|
17
|
-
* @param { { require?: NodeRequire, requireLocal?: NodeRequire } } [options]
|
|
18
|
-
*/
|
|
19
|
-
function NodeResolver(options) {
|
|
20
|
-
this.require = options && options.require || createScopedRequire(cwd());
|
|
21
|
-
|
|
22
|
-
this.requireLocal = options && options.requireLocal || require;
|
|
23
|
-
|
|
24
|
-
try {
|
|
25
|
-
this.pkg = this.require('./package.json').name;
|
|
26
|
-
} catch (err) {
|
|
27
|
-
this.pkg = '__unknown';
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
module.exports = NodeResolver;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* @param { string } pkg
|
|
36
|
-
* @param { string } ruleName
|
|
37
|
-
*
|
|
38
|
-
* @return { RuleFactory }
|
|
39
|
-
*/
|
|
40
|
-
NodeResolver.prototype.resolveRule = function(pkg, ruleName) {
|
|
41
|
-
|
|
42
|
-
const originalPkg = pkg;
|
|
43
|
-
|
|
44
|
-
pkg = this.normalizePkg(pkg);
|
|
45
|
-
|
|
46
|
-
let pkgInstance;
|
|
47
|
-
|
|
48
|
-
// (1) try resolving rule via $PKG.rules[$NAME]
|
|
49
|
-
try {
|
|
50
|
-
pkgInstance = this.require(pkg);
|
|
51
|
-
} catch (err) {
|
|
52
|
-
|
|
53
|
-
/* ignore */
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (pkgInstance) {
|
|
57
|
-
const rules = pkgInstance.rules || {};
|
|
58
|
-
|
|
59
|
-
if (ruleName in rules) {
|
|
60
|
-
const rule = rules[ruleName];
|
|
61
|
-
|
|
62
|
-
if (!isString(rule)) {
|
|
63
|
-
throw new Error('cannot resolve rule <' + ruleName + '> from <' + originalPkg + '>: illegal rule export (expected path reference)');
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// local reference, resolved relative to pkg location
|
|
67
|
-
if (rule.startsWith('.')) {
|
|
68
|
-
const pkgDir = path.dirname(this.require.resolve(pkg));
|
|
69
|
-
|
|
70
|
-
return this.require(path.posix.normalize(`${ pkgDir }/${ rule }`));
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// absolute reference
|
|
74
|
-
return this.require(rule);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// (2) try resolving rule via $PKG/rules/$NAME
|
|
79
|
-
try {
|
|
80
|
-
if (pkg === 'bpmnlint') {
|
|
81
|
-
return this.requireLocal(`../../rules/${ruleName}`);
|
|
82
|
-
} else {
|
|
83
|
-
return this.require(`${pkg}/rules/${ruleName}`);
|
|
84
|
-
}
|
|
85
|
-
} catch (err) { /* ignore */ }
|
|
86
|
-
|
|
87
|
-
throw new Error('cannot resolve rule <' + ruleName + '> from <' + originalPkg + '>');
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* @param { string } pkg
|
|
92
|
-
* @param { string } configName
|
|
93
|
-
*
|
|
94
|
-
* @return { Config }
|
|
95
|
-
*/
|
|
96
|
-
NodeResolver.prototype.resolveConfig = function(pkg, configName) {
|
|
97
|
-
|
|
98
|
-
const originalPkg = pkg;
|
|
99
|
-
|
|
100
|
-
pkg = this.normalizePkg(pkg);
|
|
101
|
-
|
|
102
|
-
// (1) try resolving config via $PKG.configs[$NAME]
|
|
103
|
-
try {
|
|
104
|
-
const instance = this.require(pkg);
|
|
105
|
-
|
|
106
|
-
const configs = instance.configs || {};
|
|
107
|
-
|
|
108
|
-
if (configName in configs) {
|
|
109
|
-
return configs[configName];
|
|
110
|
-
}
|
|
111
|
-
} catch (err) {
|
|
112
|
-
|
|
113
|
-
/* ignore */
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// (2) try resolving config via $PKG/config/$NAME
|
|
117
|
-
try {
|
|
118
|
-
if (pkg === 'bpmnlint') {
|
|
119
|
-
return this.requireLocal(`../../config/${configName}`);
|
|
120
|
-
} else {
|
|
121
|
-
return this.require(`${pkg}/config/${configName}`);
|
|
122
|
-
}
|
|
123
|
-
} catch (err) { /* ignore */ }
|
|
124
|
-
|
|
125
|
-
throw new Error(
|
|
126
|
-
'cannot resolve config <' + configName + '> from <' + originalPkg + '>'
|
|
127
|
-
);
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
NodeResolver.prototype.normalizePkg = function(pkg) {
|
|
131
|
-
if (pkg !== 'bpmnlint' && pkg === this.pkg) {
|
|
132
|
-
pkg = '.';
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return pkg;
|
|
136
|
-
};
|
|
3
|
+
// rules and configs of this package are resolved relative to this file,
|
|
4
|
+
// i.e. via ../../rules/* and ../../config/*
|
|
5
|
+
module.exports = createNodeResolver(require('../product'), {
|
|
6
|
+
requireLocal: require
|
|
7
|
+
});
|