forked from OKEAMAH/js-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.ts
More file actions
95 lines (88 loc) · 2.83 KB
/
parser.ts
File metadata and controls
95 lines (88 loc) · 2.83 KB
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/* eslint-disable @typescript-eslint/no-var-requires */
import * as jsonld from 'jsonld/lib';
import * as ldcontext from 'jsonld/lib/context';
/**
* LDParser can parse JSONLD schema according to specification
*
* @public
* @class LDParser
*/
export class LDParser {
/**
* ExtractTerms returns the terms definitions from the JSON-LD context
*
* @param {string} context - JSONLD context
* @returns Promise<Map<string, string>>
*/
public static async extractTerms(context: string | JSON): Promise<Map<string, unknown>> {
let data;
let res;
try {
data = typeof context === 'string' ? JSON.parse(context) : context;
res = await jsonld.processContext(ldcontext.getInitialContext({}), data, {});
} catch (e) {
throw new Error(`Failed process LD context. Error ${e}`);
}
const terms = res.mappings;
return terms;
}
/**
* GetPrefixes returns a map of potential RDF prefixes based on the JSON-LD Term Definitions
* in this context. No guarantees of the prefixes are given, beyond that it will not contain ":".
*
* onlyCommonPrefixes: If true, the result will not include "not so useful" prefixes, such as
* "term1": "http://example.com/term1", e.g. all IRIs will end with "/" or "#".
* If false, all potential prefixes are returned.
* @param {string | JSON} context - JSONLD context
* @param {boolean} onlyCommonPrefixes - only common prefixes
* @param {Array<string>} properties - available properties in type definition
* @returns Promise<<Map<string, string>>
*/
public static async getPrefixes(
context: string | JSON,
onlyCommonPrefixes: boolean,
properties?: Array<string>
): Promise<Map<string, string>> {
const prefixes: Map<string, string> = new Map();
const data = await this.extractTerms(context);
for (const [term, termDefinition] of data) {
if (term.includes(':')) {
continue;
}
if (!termDefinition) {
continue;
}
const termDefinitionMap = termDefinition as Record<string, unknown>;
const id = termDefinitionMap['@id'] as string;
if (!id) {
continue;
}
if (term.startsWith('@') || id.startsWith('@')) {
continue;
}
if (!onlyCommonPrefixes || id.endsWith('/') || id.endsWith('#')) {
prefixes.set(term, id);
}
if (properties) {
const c = termDefinitionMap['@context'] as Record<string, undefined>;
if (!c) {
prefixes.delete(term);
continue;
}
if (!this.isKeysInMap(properties, c)) {
prefixes.delete(term);
continue;
}
}
}
return prefixes;
}
private static isKeysInMap(keys: string[], rec: Record<string, undefined>): boolean {
for (const key of keys) {
if (!rec[key]) {
return false;
}
}
return true;
}
}