mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: AccountSettingsStorageDescriber (WIP)
This commit is contained in:
parent
df9062cfc5
commit
e1cb2c6e71
78
src/server/description/AccountSettingsStorageDescriber.ts
Normal file
78
src/server/description/AccountSettingsStorageDescriber.ts
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import type { NamedNode, Quad, Quad_Object, Term } from '@rdfjs/types';
|
||||||
|
import { DataFactory } from 'n3';
|
||||||
|
import { stringToTerm } from 'rdf-string';
|
||||||
|
import { StorageDescriber } from './StorageDescriber';
|
||||||
|
import quad = DataFactory.quad;
|
||||||
|
import namedNode = DataFactory.namedNode;
|
||||||
|
import type { AccountStore, AccountSettings } from '../../identity/interaction/account/util/AccountStore';
|
||||||
|
import type { PodStore } from '../../identity/interaction/pod/util/PodStore';
|
||||||
|
import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user