|
1 | | -import { DataFactory } from 'n3'; |
2 | | -import type { NamedNode } from '@rdfjs/types'; |
3 | | - |
4 | | -// shameless copy of the Community Solid Server Vocabularies |
5 | | -/** |
6 | | - * A `Record` in which each value is a concatenation of the baseUrl and its key. |
7 | | - */ |
8 | | -type ExpandedRecord<TBase extends string, TLocal extends string> = {[K in TLocal]: `${TBase}${K}` }; |
9 | | - |
10 | | -/** |
11 | | - * Has a base URL as `namespace` value and each key has as value the concatenation with that base URL. |
12 | | - */ |
13 | | -type ValueVocabulary<TBase extends string, TLocal extends string> = |
14 | | - { namespace: TBase } & ExpandedRecord<TBase, TLocal>; |
15 | | -/** |
16 | | - * A {@link ValueVocabulary} where the URI values are {@link NamedNode}s. |
17 | | - */ |
18 | | -type TermVocabulary<T> = T extends ValueVocabulary<any, any> ? {[K in keyof T]: NamedNode<T[K]> } : never; |
19 | | - |
20 | | -/** |
21 | | - * Contains a namespace and keys linking to the entries in this namespace. |
22 | | - * The `terms` field contains the same values but as {@link NamedNode} instead of string. |
23 | | - */ |
24 | | -export type Vocabulary<TBase extends string, TKey extends string> = |
25 | | - ValueVocabulary<TBase, TKey> & { terms: TermVocabulary<ValueVocabulary<TBase, TKey>> }; |
26 | | - |
27 | | -/** |
28 | | - * A {@link Vocabulary} where all the non-namespace fields are of unknown value. |
29 | | - * This is a fallback in case {@link createVocabulary} gets called with a non-strict string array. |
30 | | - */ |
31 | | -export type PartialVocabulary<TBase extends string> = |
32 | | - { namespace: TBase } & |
33 | | - Partial<Record<string, string>> & |
34 | | - { terms: { namespace: NamedNode<TBase> } & Partial<Record<string, NamedNode>> }; |
35 | | - |
36 | | -/** |
37 | | - * A local name of a {@link Vocabulary}. |
38 | | - */ |
39 | | -export type VocabularyLocal<T> = T extends Vocabulary<any, infer TKey> ? TKey : never; |
40 | | -/** |
41 | | - * A URI string entry of a {@link Vocabulary}. |
42 | | - */ |
43 | | -export type VocabularyValue<T> = T extends Vocabulary<any, infer TKey> ? T[TKey] : never; |
44 | | -/** |
45 | | - * A {@link NamedNode} entry of a {@link Vocabulary}. |
46 | | - */ |
47 | | -export type VocabularyTerm<T> = T extends Vocabulary<any, infer TKey> ? T['terms'][TKey] : never; |
48 | | - |
49 | | -/** |
50 | | - * Creates a {@link ValueVocabulary} with the given `baseUri` as namespace and all `localNames` as entries. |
51 | | - */ |
52 | | -function createValueVocabulary<TBase extends string, TLocal extends string>(baseUri: TBase, localNames: TLocal[]): |
53 | | -ValueVocabulary<TBase, TLocal> { |
54 | | - const expanded: Partial<ExpandedRecord<TBase, TLocal>> = {}; |
55 | | - // Expose the listed local names as properties |
56 | | - for (const localName of localNames) { |
57 | | - expanded[localName] = `${baseUri}${localName}`; |
58 | | - } |
59 | | - return { |
60 | | - namespace: baseUri, |
61 | | - ...expanded as ExpandedRecord<TBase, TLocal>, |
62 | | - }; |
63 | | -} |
64 | | - |
65 | | -/** |
66 | | - * Creates a {@link TermVocabulary} based on the provided {@link ValueVocabulary}. |
67 | | - */ |
68 | | -function createTermVocabulary<TBase extends string, TLocal extends string>(values: ValueVocabulary<TBase, TLocal>): |
69 | | -TermVocabulary<ValueVocabulary<TBase, TLocal>> { |
70 | | - // Need to cast since `fromEntries` typings aren't strict enough |
71 | | - return Object.fromEntries( |
72 | | - Object.entries(values).map(([ key, value ]): [string, NamedNode] => [ key, DataFactory.namedNode(value) ]), |
73 | | - ) as TermVocabulary<ValueVocabulary<TBase, TLocal>>; |
74 | | -} |
75 | | - |
76 | | -/** |
77 | | - * Creates a {@link Vocabulary} with the given `baseUri` as namespace and all `localNames` as entries. |
78 | | - * The values are the local names expanded from the given base URI as strings. |
79 | | - * The `terms` field contains all the same values but as {@link NamedNode} instead. |
80 | | - */ |
81 | | -export function createVocabulary<TBase extends string, TLocal extends string>(baseUri: TBase, ...localNames: TLocal[]): |
82 | | -string extends TLocal ? PartialVocabulary<TBase> : Vocabulary<TBase, TLocal> { |
83 | | - const values = createValueVocabulary(baseUri, localNames); |
84 | | - return { |
85 | | - ...values, |
86 | | - terms: createTermVocabulary(values), |
87 | | - }; |
88 | | -} |
89 | | - |
90 | | -/** |
91 | | - * Creates a new {@link Vocabulary} that extends an existing one by adding new local names. |
92 | | - * @param vocabulary - The {@link Vocabulary} to extend. |
93 | | - * @param newNames - The new local names that need to be added. |
94 | | - */ |
95 | | -export function extendVocabulary<TBase extends string, TLocal extends string, TNew extends string>( |
96 | | - vocabulary: Vocabulary<TBase, TLocal>, |
97 | | - ...newNames: TNew[] |
98 | | -): |
99 | | - ReturnType<typeof createVocabulary<TBase, TLocal | TNew>> { |
100 | | - const localNames = Object.keys(vocabulary) |
101 | | - .filter((key): boolean => key !== 'terms' && key !== 'namespace') as TLocal[]; |
102 | | - const allNames = [ ...localNames, ...newNames ]; |
103 | | - return createVocabulary(vocabulary.namespace, ...allNames); |
104 | | -} |
105 | | - |
| 1 | +import { createVocabulary } from 'rdf-vocabulary'; |
106 | 2 |
|
107 | 3 | export const ODRL = createVocabulary( |
108 | 4 | 'http://www.w3.org/ns/odrl/2/', |
|
0 commit comments