-
-
Notifications
You must be signed in to change notification settings - Fork 248
/
Copy pathnode.ts
46 lines (38 loc) · 1.39 KB
/
node.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import { createRequire } from 'module';
import * as path from '@stoplight/path';
import { Ruleset, RulesetDefinition } from '@stoplight/spectral-core';
import { bundle } from './common/bundle';
import { node } from '../presets/node';
import type { Loader } from './types';
export const bundleAndLoadRuleset: Loader = async (rulesetFile, io, plugins = []) => {
const ruleset = await bundle(
rulesetFile,
{
target: 'node',
format: 'commonjs',
plugins: [...node(io), ...plugins],
},
io,
);
return new Ruleset(load(ruleset, rulesetFile), {
severity: 'recommended',
source: rulesetFile,
});
};
function load(source: string, uri: string): RulesetDefinition {
const actualUri = path.isURL(uri) ? uri.replace(/^https?:\//, '') : uri;
// we could use plain `require`, but this approach has a number of benefits:
// - it is bundler-friendly
// - ESM compliant
// - and we have no warning raised by pkg.
const req = createRequire(actualUri);
const m: { exports?: RulesetDefinition } = {};
const paths = [path.dirname(uri), __dirname];
const _require = (id: string): unknown => req(req.resolve(id, { paths }));
// eslint-disable-next-line @typescript-eslint/no-implied-eval
Function('module, require', source)(m, _require);
if (typeof m.exports !== 'object' || m.exports === null) {
throw Error('No valid export found');
}
return m.exports;
}