-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathAccountSettingsStorageDescriber.ts
More file actions
76 lines (59 loc) · 2.34 KB
/
AccountSettingsStorageDescriber.ts
File metadata and controls
76 lines (59 loc) · 2.34 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
import type { NamedNode, Quad, Quad_Object, Term } from '@rdfjs/types';
import type { AccountSettings, AccountStore, PodStore, ResourceIdentifier } from '@solid/community-server';
import { StorageDescriber } from '@solid/community-server';
import { DataFactory } from 'n3';
import { stringToTerm } from 'rdf-string';
const {quad, namedNode} = DataFactory
/**
* Adds triples to the storage description resource, based on the settings of
* the account that created the storage.
*
* The resource identifier of the storage is used as subject.
*/
export class AccountSettingsStorageDescriber extends StorageDescriber {
private readonly terms: ReadonlyMap<NamedNode, keyof AccountSettings>;
public constructor(
private podStore: PodStore,
private accountStore: AccountStore,
terms: Record<string, keyof AccountSettings>,
) {
super();
const termMap = new Map<NamedNode, keyof AccountSettings>();
for (const [ predicate, settingsKey ] of Object.entries(terms)) {
const predTerm = stringToTerm(predicate);
if (predTerm.termType !== 'NamedNode') {
throw new Error('Predicate needs to be a named node.');
}
termMap.set(predTerm, settingsKey);
}
this.terms = termMap;
}
public async handle(target: ResourceIdentifier): Promise<Quad[]> {
const subject = namedNode(target.path);
const pod = await this.podStore.findByBaseUrl(target.path);
if (!pod) throw new Error(`Cannot find pod for storage path ${target.path}`);
const quads: Quad[] = [];
for await (const quad of this.generateTriples(subject, pod.accountId)) {
quads.push(quad);
}
return quads;
}
private async* generateTriples(subject: NamedNode, account: string): AsyncGenerator<Quad> {
for (const [ predicate, settingsKey ] of this.terms.entries()) {
const settingsValue = await this.accountStore.getSetting(account, settingsKey);
if (settingsValue === undefined) continue;
const objects = (Array.isArray(settingsValue) ? settingsValue : [ settingsValue ]).map((value): Quad_Object => {
let term: Term;
try {
term = stringToTerm(`${value}`);
} catch {
term = stringToTerm(`"${value}"`);
}
return term as Quad_Object;
});
for (const object of objects) {
yield quad(subject, predicate, object);
}
}
}
}