-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathecmaScript.ts
53 lines (41 loc) · 1.77 KB
/
ecmaScript.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
47
48
49
50
51
52
53
import module from 'module'
import url from 'url'
import clownface from 'clownface'
import { isNamedNode } from 'is-graph-pointer'
import type { LoaderRegistry } from 'rdf-loaders-registry'
import iriResolve from './lib/iriResolve.js'
import * as ns from './namespaces.js'
import { GraphPointerLike } from './lib/types.js'
const require = module.createRequire(import.meta.url)
function parseLiteral({ term }: GraphPointerLike, { context }: { context?: unknown | null } = {}) {
if (term.termType === 'Literal' && term.datatype.equals(ns.code('EcmaScript'))) {
return (function () {
return eval(`(${term.value})`) // eslint-disable-line no-eval,no-extra-parens
}.call(context))
}
throw new Error(`Cannot load ecmaScript code from term ${term.value}`)
}
function parseNamedNode({ term, dataset }: GraphPointerLike, { basePath }: { basePath?: string } = {}) {
const link = clownface({ term, dataset }).out(ns.code('link'))
if (!isNamedNode(link)) {
throw new Error(`Cannot load ecmaScript code from term ${term.value}`)
}
const { filename, method } = iriResolve(link.value, basePath)
const path = typeof filename === 'string' ? filename : url.fileURLToPath(filename)
const code = require(path)
if (!method) {
return code
}
// split method name by . for deep structures
return method.split('.').reduce((code, property) => code[property], code)
}
export default function loader({ term, dataset }: GraphPointerLike, options = {}) {
if (term && term.termType === 'Literal') {
return parseLiteral({ term, dataset }, options)
}
return parseNamedNode({ term, dataset }, options)
}
loader.register = (registry: LoaderRegistry) => {
registry.registerNodeLoader(ns.code('EcmaScript'), loader)
registry.registerLiteralLoader(ns.code('EcmaScript'), loader)
}