1 | ;
|
2 |
|
3 | Object.defineProperty(exports, '__esModule', { value: true });
|
4 |
|
5 | function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
6 |
|
7 | var crossFetch = require('cross-fetch');
|
8 | var LinkHeader = _interopDefault(require('http-link-header'));
|
9 | var dataset = require('@rdfjs/dataset');
|
10 | var n3 = require('n3');
|
11 |
|
12 | /*! *****************************************************************************
|
13 | Copyright (c) Microsoft Corporation.
|
14 |
|
15 | Permission to use, copy, modify, and/or distribute this software for any
|
16 | purpose with or without fee is hereby granted.
|
17 |
|
18 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
19 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
20 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
21 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
22 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
23 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
24 | PERFORMANCE OF THIS SOFTWARE.
|
25 | ***************************************************************************** */
|
26 |
|
27 | function __awaiter(thisArg, _arguments, P, generator) {
|
28 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
29 | return new (P || (P = Promise))(function (resolve, reject) {
|
30 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
31 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
32 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
33 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
34 | });
|
35 | }
|
36 |
|
37 | /**
|
38 | * Copyright 2020 Inrupt Inc.
|
39 | *
|
40 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
41 | * of this software and associated documentation files (the "Software"), to deal in
|
42 | * the Software without restriction, including without limitation the rights to use,
|
43 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
44 | * Software, and to permit persons to whom the Software is furnished to do so,
|
45 | * subject to the following conditions:
|
46 | *
|
47 | * The above copyright notice and this permission notice shall be included in
|
48 | * all copies or substantial portions of the Software.
|
49 | *
|
50 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
51 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
52 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
53 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
54 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
55 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
56 | */
|
57 | /**
|
58 | * @ignore Internal fallback for when no fetcher is provided; not to be used downstream.
|
59 | */
|
60 | const fetch = (resource, init) => {
|
61 | // Implementation note: it's up to the client application to resolve these module names to the
|
62 | // respective npm packages. At least one commonly used tool (Webpack) is only able to do that if
|
63 | // the module names are literal strings.
|
64 | // Additionally, Webpack throws a warning in a way that halts compilation for at least Next.js
|
65 | // when using native Javascript dynamic imports (`import()`), whereas `require()` just logs a
|
66 | // warning. Since the use of package names instead of file names requires a bundles anyway, this
|
67 | // should not have any practical consequences. For more background, see:
|
68 | // https://github.com/webpack/webpack/issues/7713
|
69 | let fetch;
|
70 | try {
|
71 | fetch = require("@inrupt/solid-auth-fetcher").fetch;
|
72 | }
|
73 | catch (e) {
|
74 | try {
|
75 | fetch = require("solid-auth-client").fetch;
|
76 | }
|
77 | catch (e) {
|
78 | fetch = require("cross-fetch");
|
79 | }
|
80 | }
|
81 | return fetch(resource, init);
|
82 | };
|
83 |
|
84 | /**
|
85 | * Copyright 2020 Inrupt Inc.
|
86 | *
|
87 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
88 | * of this software and associated documentation files (the "Software"), to deal in
|
89 | * the Software without restriction, including without limitation the rights to use,
|
90 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
91 | * Software, and to permit persons to whom the Software is furnished to do so,
|
92 | * subject to the following conditions:
|
93 | *
|
94 | * The above copyright notice and this permission notice shall be included in
|
95 | * all copies or substantial portions of the Software.
|
96 | *
|
97 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
98 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
99 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
100 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
101 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
102 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
103 | */
|
104 | const defaultFetchFileOptions = {
|
105 | fetch: fetch,
|
106 | };
|
107 | const RESERVED_HEADERS = ["Slug", "If-None-Match", "Content-Type"];
|
108 | /**
|
109 | * Some of the headers must be set by the library, rather than directly.
|
110 | */
|
111 | function containsReserved(header) {
|
112 | return RESERVED_HEADERS.some((reserved) => header.has(reserved));
|
113 | }
|
114 | /**
|
115 | * Fetches a file at a given URL, and returns it as a blob of data.
|
116 | *
|
117 | * Please note that this function is still experimental: its API can change in non-major releases.
|
118 | *
|
119 | * @param url The URL of the fetched file
|
120 | * @param options Fetching options: a custom fetcher and/or headers.
|
121 | */
|
122 | function unstable_fetchFile(input, options = defaultFetchFileOptions) {
|
123 | return __awaiter(this, void 0, void 0, function* () {
|
124 | const config = Object.assign(Object.assign({}, defaultFetchFileOptions), options);
|
125 | return config.fetch(input, config.init);
|
126 | });
|
127 | }
|
128 | /**
|
129 | * Deletes a file at a given URL
|
130 | *
|
131 | * Please note that this function is still experimental: its API can change in non-major releases.
|
132 | *
|
133 | * @param input The URL of the file to delete
|
134 | */
|
135 | function unstable_deleteFile(input, options = defaultFetchFileOptions) {
|
136 | return __awaiter(this, void 0, void 0, function* () {
|
137 | const config = Object.assign(Object.assign({}, defaultFetchFileOptions), options);
|
138 | return config.fetch(input, Object.assign(Object.assign({}, config.init), { method: "DELETE" }));
|
139 | });
|
140 | }
|
141 | /**
|
142 | * Saves a file in a folder at a given URL. The server will return the final
|
143 | * filename (which may or may not be the given `slug`), it will return it in
|
144 | * the response's Location header.
|
145 | *
|
146 | * @param folderUrl The URL of the folder where the new file is saved
|
147 | * @param file The file to be written
|
148 | * @param options Additional parameters for file creation (e.g. a slug)
|
149 | */
|
150 | function unstable_saveFileInContainer(folderUrl, file, options = defaultFetchFileOptions) {
|
151 | return __awaiter(this, void 0, void 0, function* () {
|
152 | return writeFile(folderUrl, file, "POST", options);
|
153 | });
|
154 | }
|
155 | /**
|
156 | * Saves a file at a given URL, erasing any previous content.
|
157 | *
|
158 | * @param fileUrl The URL where the file is saved
|
159 | * @param file The file to be written
|
160 | * @param options Additional parameters for file creation (e.g. a slug)
|
161 | */
|
162 | function unstable_overwriteFile(fileUrl, file, options = defaultFetchFileOptions) {
|
163 | return __awaiter(this, void 0, void 0, function* () {
|
164 | return writeFile(fileUrl, file, "PUT", options);
|
165 | });
|
166 | }
|
167 | /**
|
168 | * Internal function that performs the actual write HTTP query, either POST
|
169 | * or PUT depending on the use case.
|
170 | *
|
171 | * @param fileUrl The URL where the file is saved
|
172 | * @param file The file to be written
|
173 | * @param method The HTTP method
|
174 | * @param options Additional parameters for file creation (e.g. a slug)
|
175 | */
|
176 | function writeFile(targetUrl, file, method, options) {
|
177 | var _a, _b;
|
178 | return __awaiter(this, void 0, void 0, function* () {
|
179 | const config = Object.assign(Object.assign({}, defaultFetchFileOptions), options);
|
180 | const headers = new crossFetch.Headers((_b = (_a = config.init) === null || _a === void 0 ? void 0 : _a.headers) !== null && _b !== void 0 ? _b : {});
|
181 | if (containsReserved(headers)) {
|
182 | throw new Error(`No reserved header (${RESERVED_HEADERS.join(", ")}) should be set in the optional RequestInit.`);
|
183 | }
|
184 | // If a slug is in the parameters, set the request headers accordingly
|
185 | if (config.slug !== undefined) {
|
186 | headers.append("Slug", config.slug);
|
187 | }
|
188 | headers.append("Content-Type", file.type);
|
189 | return yield config.fetch(targetUrl, Object.assign(Object.assign({}, config.init), { headers,
|
190 | method, body: file }));
|
191 | });
|
192 | }
|
193 |
|
194 | /**
|
195 | * Copyright 2020 Inrupt Inc.
|
196 | *
|
197 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
198 | * of this software and associated documentation files (the "Software"), to deal in
|
199 | * the Software without restriction, including without limitation the rights to use,
|
200 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
201 | * Software, and to permit persons to whom the Software is furnished to do so,
|
202 | * subject to the following conditions:
|
203 | *
|
204 | * The above copyright notice and this permission notice shall be included in
|
205 | * all copies or substantial portions of the Software.
|
206 | *
|
207 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
208 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
209 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
210 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
211 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
212 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
213 | */
|
214 | /**
|
215 | * @internal
|
216 | */
|
217 | const DataFactory = { quad: dataset.quad, literal: dataset.literal, namedNode: dataset.namedNode, blankNode: dataset.blankNode };
|
218 | /**
|
219 | * Clone a Dataset.
|
220 | *
|
221 | * Note that the Quads are not cloned, i.e. if you modify the Quads in the output Dataset, the Quads
|
222 | * in the input Dataset will also be changed.
|
223 | *
|
224 | * @internal
|
225 | * @param input Dataset to clone.
|
226 | * @returns A new Dataset with the same Quads as `input`.
|
227 | */
|
228 | function clone(input) {
|
229 | const output = dataset.dataset();
|
230 | for (const quad of input) {
|
231 | output.add(quad);
|
232 | }
|
233 | return output;
|
234 | }
|
235 | /**
|
236 | * @internal
|
237 | * @param input Dataset to clone.
|
238 | * @param callback Function that takes a Quad, and returns a boolean indicating whether that Quad should be included in the cloned Dataset.
|
239 | * @returns A new Dataset with the same Quads as `input`, excluding the ones for which `callback` returned `false`.
|
240 | */
|
241 | function filter(input, callback) {
|
242 | const output = dataset.dataset();
|
243 | for (const quad of input) {
|
244 | if (callback(quad)) {
|
245 | output.add(quad);
|
246 | }
|
247 | }
|
248 | return output;
|
249 | }
|
250 |
|
251 | /**
|
252 | * Copyright 2020 Inrupt Inc.
|
253 | *
|
254 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
255 | * of this software and associated documentation files (the "Software"), to deal in
|
256 | * the Software without restriction, including without limitation the rights to use,
|
257 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
258 | * Software, and to permit persons to whom the Software is furnished to do so,
|
259 | * subject to the following conditions:
|
260 | *
|
261 | * The above copyright notice and this permission notice shall be included in
|
262 | * all copies or substantial portions of the Software.
|
263 | *
|
264 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
265 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
266 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
267 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
268 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
269 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
270 | */
|
271 | /**
|
272 | * @param quads Triples that should be serialised to Turtle
|
273 | * @internal Utility method for internal use; not part of the public API.
|
274 | */
|
275 | function triplesToTurtle(quads) {
|
276 | return __awaiter(this, void 0, void 0, function* () {
|
277 | const format = "text/turtle";
|
278 | const writer = new n3.Writer({ format: format });
|
279 | // Remove any potentially lingering references to Named Graphs in Quads;
|
280 | // they'll be determined by the URL the Turtle will be sent to:
|
281 | const triples = quads.map((quad) => DataFactory.quad(quad.subject, quad.predicate, quad.object, undefined));
|
282 | writer.addQuads(triples);
|
283 | const writePromise = new Promise((resolve, reject) => {
|
284 | writer.end((error, result) => {
|
285 | /* istanbul ignore if [n3.js doesn't actually pass an error nor a result, apparently: https://github.com/rdfjs/N3.js/blob/62682e48c02d8965b4d728cb5f2cbec6b5d1b1b8/src/N3Writer.js#L290] */
|
286 | if (error) {
|
287 | return reject(error);
|
288 | }
|
289 | resolve(result);
|
290 | });
|
291 | });
|
292 | const rawTurtle = yield writePromise;
|
293 | return rawTurtle;
|
294 | });
|
295 | }
|
296 | /**
|
297 | * @param raw Turtle that should be parsed into Triples
|
298 | * @internal Utility method for internal use; not part of the public API.
|
299 | */
|
300 | function turtleToTriples(raw, resourceIri) {
|
301 | return __awaiter(this, void 0, void 0, function* () {
|
302 | const format = "text/turtle";
|
303 | const parser = new n3.Parser({ format: format, baseIRI: resourceIri });
|
304 | const parsingPromise = new Promise((resolve, reject) => {
|
305 | const parsedTriples = [];
|
306 | parser.parse(raw, (error, triple, _prefixes) => {
|
307 | if (error) {
|
308 | return reject(error);
|
309 | }
|
310 | if (triple) {
|
311 | parsedTriples.push(triple);
|
312 | }
|
313 | else {
|
314 | resolve(parsedTriples);
|
315 | }
|
316 | });
|
317 | });
|
318 | return parsingPromise;
|
319 | });
|
320 | }
|
321 |
|
322 | /**
|
323 | * Copyright 2020 Inrupt Inc.
|
324 | *
|
325 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
326 | * of this software and associated documentation files (the "Software"), to deal in
|
327 | * the Software without restriction, including without limitation the rights to use,
|
328 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
329 | * Software, and to permit persons to whom the Software is furnished to do so,
|
330 | * subject to the following conditions:
|
331 | *
|
332 | * The above copyright notice and this permission notice shall be included in
|
333 | * all copies or substantial portions of the Software.
|
334 | *
|
335 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
336 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
337 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
338 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
339 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
340 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
341 | */
|
342 | /**
|
343 | * IRIs of the XML Schema data types we support
|
344 | * @internal
|
345 | */
|
346 | const xmlSchemaTypes = {
|
347 | boolean: "http://www.w3.org/2001/XMLSchema#boolean",
|
348 | dateTime: "http://www.w3.org/2001/XMLSchema#dateTime",
|
349 | decimal: "http://www.w3.org/2001/XMLSchema#decimal",
|
350 | integer: "http://www.w3.org/2001/XMLSchema#integer",
|
351 | string: "http://www.w3.org/2001/XMLSchema#string",
|
352 | langString: "http://www.w3.org/1999/02/22-rdf-syntax-ns#langString",
|
353 | };
|
354 | /**
|
355 | * @internal
|
356 | * @param value Value to serialise.
|
357 | * @returns String representation of `value`.
|
358 | */
|
359 | function serializeBoolean(value) {
|
360 | return value ? "1" : "0";
|
361 | }
|
362 | /**
|
363 | * @internal
|
364 | * @param value Value to deserialise.
|
365 | * @returns Deserialized boolean, or null if the given value is not a valid serialised boolean.
|
366 | */
|
367 | function deserializeBoolean(value) {
|
368 | if (value === "1") {
|
369 | return true;
|
370 | }
|
371 | else if (value === "0") {
|
372 | return false;
|
373 | }
|
374 | else {
|
375 | return null;
|
376 | }
|
377 | }
|
378 | /**
|
379 | * @internal
|
380 | * @param value Value to serialise.
|
381 | * @returns String representation of `value`.
|
382 | */
|
383 | function serializeDatetime(value) {
|
384 | // To align with rdflib, we ignore miliseconds:
|
385 | // https://github.com/linkeddata/rdflib.js/blob/d84af88f367b8b5f617c753d8241c5a2035458e8/src/literal.js#L74
|
386 | const roundedDate = new Date(Date.UTC(value.getUTCFullYear(), value.getUTCMonth(), value.getUTCDate(), value.getUTCHours(), value.getUTCMinutes(), value.getUTCSeconds(), 0));
|
387 | // Truncate the `.000Z` at the end (i.e. the miliseconds), to plain `Z`:
|
388 | const rdflibStyleString = roundedDate.toISOString().replace(/\.000Z$/, "Z");
|
389 | return rdflibStyleString;
|
390 | }
|
391 | /**
|
392 | * @internal
|
393 | * @param value Value to deserialise.
|
394 | * @returns Deserialized datetime, or null if the given value is not a valid serialised datetime.
|
395 | */
|
396 | function deserializeDatetime(literalString) {
|
397 | if (literalString === null ||
|
398 | literalString.length <= 17 ||
|
399 | literalString.indexOf("Z") === -1) {
|
400 | return null;
|
401 | }
|
402 | // See https://github.com/linkeddata/rdflib.js/blob/d84af88f367b8b5f617c753d8241c5a2035458e8/src/literal.js#L87
|
403 | const utcFullYear = parseInt(literalString.substring(0, 4), 10);
|
404 | const utcMonth = parseInt(literalString.substring(5, 7), 10) - 1;
|
405 | const utcDate = parseInt(literalString.substring(8, 10), 10);
|
406 | const utcHours = parseInt(literalString.substring(11, 13), 10);
|
407 | const utcMinutes = parseInt(literalString.substring(14, 16), 10);
|
408 | const utcSeconds = parseInt(literalString.substring(17, literalString.indexOf("Z")), 10);
|
409 | const date = new Date(0);
|
410 | date.setUTCFullYear(utcFullYear);
|
411 | date.setUTCMonth(utcMonth);
|
412 | date.setUTCDate(utcDate);
|
413 | date.setUTCHours(utcHours);
|
414 | date.setUTCMinutes(utcMinutes);
|
415 | date.setUTCSeconds(utcSeconds);
|
416 | return date;
|
417 | }
|
418 | /**
|
419 | * @internal
|
420 | * @param value Value to serialise.
|
421 | * @returns String representation of `value`.
|
422 | */
|
423 | function serializeDecimal(value) {
|
424 | return value.toString();
|
425 | }
|
426 | /**
|
427 | * @internal
|
428 | * @param value Value to deserialise.
|
429 | * @returns Deserialized decimal, or null if the given value is not a valid serialised decimal.
|
430 | */
|
431 | function deserializeDecimal(literalString) {
|
432 | const deserialized = Number.parseFloat(literalString);
|
433 | if (Number.isNaN(deserialized)) {
|
434 | return null;
|
435 | }
|
436 | return deserialized;
|
437 | }
|
438 | /**
|
439 | * @internal
|
440 | * @param value Value to serialise.
|
441 | * @returns String representation of `value`.
|
442 | */
|
443 | function serializeInteger(value) {
|
444 | return value.toString();
|
445 | }
|
446 | /**
|
447 | * @internal
|
448 | * @param value Value to deserialise.
|
449 | * @returns Deserialized integer, or null if the given value is not a valid serialised integer.
|
450 | */
|
451 | function deserializeInteger(literalString) {
|
452 | const deserialized = Number.parseInt(literalString, 10);
|
453 | if (Number.isNaN(deserialized)) {
|
454 | return null;
|
455 | }
|
456 | return deserialized;
|
457 | }
|
458 | /**
|
459 | * @internal
|
460 | * @param locale Locale to transform into a consistent format.
|
461 | */
|
462 | function normalizeLocale(locale) {
|
463 | return locale.toLowerCase();
|
464 | }
|
465 | /**
|
466 | * @internal Library users shouldn't need to be exposed to raw NamedNodes.
|
467 | * @param value The value that might or might not be a Named Node.
|
468 | * @returns Whether `value` is a Named Node.
|
469 | */
|
470 | function isNamedNode(value) {
|
471 | return (typeof value === "object" &&
|
472 | typeof value.termType === "string" &&
|
473 | value.termType === "NamedNode");
|
474 | }
|
475 | /**
|
476 | * @internal Library users shouldn't need to be exposed to raw Literals.
|
477 | * @param value The value that might or might not be a Literal.
|
478 | * @returns Whether `value` is a Literal.
|
479 | */
|
480 | function isLiteral(value) {
|
481 | return (typeof value === "object" &&
|
482 | typeof value.termType === "string" &&
|
483 | value.termType === "Literal");
|
484 | }
|
485 | /**
|
486 | * @internal Library users shouldn't need to be exposed to LocalNodes.
|
487 | * @param value The value that might or might not be a Node with no known IRI yet.
|
488 | * @returns Whether `value` is a Node with no known IRI yet.
|
489 | */
|
490 | function isLocalNode(value) {
|
491 | return (typeof value === "object" &&
|
492 | typeof value.termType === "string" &&
|
493 | value.termType === "BlankNode" &&
|
494 | typeof value.name === "string");
|
495 | }
|
496 | /**
|
497 | * Construct a new LocalNode.
|
498 | *
|
499 | * @internal Library users shouldn't need to be exposed to LocalNodes.
|
500 | * @param name Name to identify this node by.
|
501 | * @returns A LocalNode whose name will be resolved when it is persisted to a Pod.
|
502 | */
|
503 | function getLocalNode(name) {
|
504 | const localNode = Object.assign(DataFactory.blankNode(), {
|
505 | name: name,
|
506 | });
|
507 | return localNode;
|
508 | }
|
509 | /**
|
510 | * Ensure that a given value is a Named Node.
|
511 | *
|
512 | * If the given parameter is a Named Node already, it will be returned as-is. If it is a string, it
|
513 | * will check whether it is a valid IRI. If not, it will throw an error; otherwise a Named Node
|
514 | * representing the given IRI will be returned.
|
515 | *
|
516 | * @internal Library users shouldn't need to be exposed to raw NamedNodes.
|
517 | * @param iri The IRI that should be converted into a Named Node, if it isn't one yet.
|
518 | */
|
519 | function asNamedNode(iri) {
|
520 | if (isNamedNode(iri)) {
|
521 | return iri;
|
522 | }
|
523 | // If the runtime environment supports URL, instantiate one.
|
524 | // If thte given IRI is not a valid URL, it will throw an error.
|
525 | // See: https://developer.mozilla.org/en-US/docs/Web/API/URL
|
526 | /* istanbul ignore else [URL is available in our testing environment, so we cannot test the alternative] */
|
527 | if (typeof URL !== "undefined") {
|
528 | new URL(iri);
|
529 | }
|
530 | return DataFactory.namedNode(iri);
|
531 | }
|
532 | /**
|
533 | * Check whether two current- or potential NamedNodes are/will be equal.
|
534 | *
|
535 | * @internal Utility method; library users should not need to interact with LocalNodes directly.
|
536 | */
|
537 | function isEqual(node1, node2, options = {}) {
|
538 | if (isNamedNode(node1) && isNamedNode(node2)) {
|
539 | return node1.equals(node2);
|
540 | }
|
541 | if (isLocalNode(node1) && isLocalNode(node2)) {
|
542 | return node1.name === node2.name;
|
543 | }
|
544 | if (typeof options.resourceIri === "undefined") {
|
545 | // If we don't know what IRI to resolve the LocalNode to,
|
546 | // we cannot conclude that it is equal to the NamedNode's full IRI:
|
547 | return false;
|
548 | }
|
549 | const namedNode1 = isNamedNode(node1)
|
550 | ? node1
|
551 | : resolveIriForLocalNode(node1, options.resourceIri);
|
552 | const namedNode2 = isNamedNode(node2)
|
553 | ? node2
|
554 | : resolveIriForLocalNode(node2, options.resourceIri);
|
555 | return namedNode1.equals(namedNode2);
|
556 | }
|
557 | /**
|
558 | * @internal Utility method; library users should not need to interact with LocalNodes directly.
|
559 | * @param quad The Quad to resolve LocalNodes in.
|
560 | * @param resourceIri The IRI of the Resource to resolve the LocalNodes against.
|
561 | */
|
562 | function resolveIriForLocalNodes(quad, resourceIri) {
|
563 | const subject = isLocalNode(quad.subject)
|
564 | ? resolveIriForLocalNode(quad.subject, resourceIri)
|
565 | : quad.subject;
|
566 | const object = isLocalNode(quad.object)
|
567 | ? resolveIriForLocalNode(quad.object, resourceIri)
|
568 | : quad.object;
|
569 | return Object.assign(Object.assign({}, quad), { subject: subject, object: object });
|
570 | }
|
571 | /**
|
572 | * @internal Utility method; library users should not need to interact with LocalNodes directly.
|
573 | * @param localNode The LocalNode to resolve to a NamedNode.
|
574 | * @param resourceIri The Resource in which the Node will be saved.
|
575 | */
|
576 | function resolveIriForLocalNode(localNode, resourceIri) {
|
577 | return DataFactory.namedNode(resolveLocalIri(localNode.name, resourceIri));
|
578 | }
|
579 | /**
|
580 | * @internal API for internal use only.
|
581 | * @param name The name identifying a Thing.
|
582 | * @param resourceIri The Resource in which the Thing can be found.
|
583 | */
|
584 | function resolveLocalIri(name, resourceIri) {
|
585 | /* istanbul ignore if [The URL interface is available in the testing environment, so we cannot test this] */
|
586 | if (typeof URL === "undefined") {
|
587 | throw new Error("The URL interface is not available, so an IRI cannot be determined.");
|
588 | }
|
589 | const thingIri = new URL(resourceIri);
|
590 | thingIri.hash = name;
|
591 | return thingIri.href;
|
592 | }
|
593 |
|
594 | /**
|
595 | * Copyright 2020 Inrupt Inc.
|
596 | *
|
597 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
598 | * of this software and associated documentation files (the "Software"), to deal in
|
599 | * the Software without restriction, including without limitation the rights to use,
|
600 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
601 | * Software, and to permit persons to whom the Software is furnished to do so,
|
602 | * subject to the following conditions:
|
603 | *
|
604 | * The above copyright notice and this permission notice shall be included in
|
605 | * all copies or substantial portions of the Software.
|
606 | *
|
607 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
608 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
609 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
610 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
611 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
612 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
613 | */
|
614 | // TODO: These should be replaced by auto-generated constants,
|
615 | // if we can ensure that unused constants will be excluded from bundles.
|
616 | /** @internal */
|
617 | const acl = {
|
618 | Authorization: "http://www.w3.org/ns/auth/acl#Authorization",
|
619 | accessTo: "http://www.w3.org/ns/auth/acl#accessTo",
|
620 | agent: "http://www.w3.org/ns/auth/acl#agent",
|
621 | default: "http://www.w3.org/ns/auth/acl#default",
|
622 | mode: "http://www.w3.org/ns/auth/acl#mode",
|
623 | };
|
624 | /** @internal */
|
625 | const rdf = {
|
626 | type: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
|
627 | };
|
628 |
|
629 | /**
|
630 | * Copyright 2020 Inrupt Inc.
|
631 | *
|
632 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
633 | * of this software and associated documentation files (the "Software"), to deal in
|
634 | * the Software without restriction, including without limitation the rights to use,
|
635 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
636 | * Software, and to permit persons to whom the Software is furnished to do so,
|
637 | * subject to the following conditions:
|
638 | *
|
639 | * The above copyright notice and this permission notice shall be included in
|
640 | * all copies or substantial portions of the Software.
|
641 | *
|
642 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
643 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
644 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
645 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
646 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
647 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
648 | */
|
649 | /**
|
650 | * Verify whether a given LitDataset includes metadata about where it was retrieved from.
|
651 | *
|
652 | * @param dataset A [[LitDataset]] that may have metadata attached about the Resource it was retrieved from.
|
653 | * @returns True if `dataset` includes metadata about the Resource it was retrieved from, false if not.
|
654 | */
|
655 | function hasDatasetInfo(dataset) {
|
656 | const potentialDatasetInfo = dataset;
|
657 | return typeof potentialDatasetInfo.datasetInfo === "object";
|
658 | }
|
659 | /** @internal */
|
660 | function hasChangelog(dataset) {
|
661 | const potentialChangeLog = dataset;
|
662 | return (typeof potentialChangeLog.changeLog === "object" &&
|
663 | Array.isArray(potentialChangeLog.changeLog.additions) &&
|
664 | Array.isArray(potentialChangeLog.changeLog.deletions));
|
665 | }
|
666 | /**
|
667 | * Given a [[LitDataset]], verify whether it has ACL data attached to it.
|
668 | *
|
669 | * This should generally only be true for LitDatasets fetched by
|
670 | * [[unstable_fetchLitDatasetWithAcl]].
|
671 | *
|
672 | * @param dataset A [[LitDataset]].
|
673 | * @returns Whether the given `dataset` has ACL data attached to it.
|
674 | * @internal
|
675 | */
|
676 | function unstable_hasAccessibleAcl(dataset) {
|
677 | return typeof dataset.datasetInfo.unstable_aclUrl === "string";
|
678 | }
|
679 |
|
680 | /**
|
681 | * Copyright 2020 Inrupt Inc.
|
682 | *
|
683 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
684 | * of this software and associated documentation files (the "Software"), to deal in
|
685 | * the Software without restriction, including without limitation the rights to use,
|
686 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
687 | * Software, and to permit persons to whom the Software is furnished to do so,
|
688 | * subject to the following conditions:
|
689 | *
|
690 | * The above copyright notice and this permission notice shall be included in
|
691 | * all copies or substantial portions of the Software.
|
692 | *
|
693 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
694 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
695 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
696 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
697 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
698 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
699 | */
|
700 | /**
|
701 | * Extract Quads with a given Subject from a [[LitDataset]] into a [[Thing]].
|
702 | *
|
703 | * @param litDataset The [[LitDataset]] to extract the [[Thing]] from.
|
704 | * @param thingUrl The URL of the desired [[Thing]].
|
705 | * @param options Not yet implemented.
|
706 | */
|
707 | function getThingOne(litDataset, thingUrl, options = {}) {
|
708 | const subject = isLocalNode(thingUrl) ? thingUrl : asNamedNode(thingUrl);
|
709 | const scope = options.scope
|
710 | ? asNamedNode(options.scope)
|
711 | : null;
|
712 | const thingDataset = litDataset.match(subject, null, null, scope);
|
713 | if (isLocalNode(subject)) {
|
714 | const thing = Object.assign(thingDataset, {
|
715 | name: subject.name,
|
716 | });
|
717 | return thing;
|
718 | }
|
719 | else {
|
720 | const thing = Object.assign(thingDataset, {
|
721 | url: subject.value,
|
722 | });
|
723 | return thing;
|
724 | }
|
725 | }
|
726 | /**
|
727 | * Get all [[Thing]]s about which a [[LitDataset]] contains Quads.
|
728 | *
|
729 | * @param litDataset The [[LitDataset]] to extract the [[Thing]]s from.
|
730 | * @param options Not yet implemented.
|
731 | */
|
732 | function getThingAll(litDataset, options = {}) {
|
733 | const subjectNodes = new Array();
|
734 | for (const quad of litDataset) {
|
735 | // Because NamedNode objects with the same IRI are actually different
|
736 | // object instances, we have to manually check whether `subjectNodes` does
|
737 | // not yet include `quadSubject` before adding it.
|
738 | const quadSubject = quad.subject;
|
739 | if (isNamedNode(quadSubject) &&
|
740 | !subjectNodes.some((subjectNode) => isEqual(subjectNode, quadSubject))) {
|
741 | subjectNodes.push(quadSubject);
|
742 | }
|
743 | if (isLocalNode(quadSubject) &&
|
744 | !subjectNodes.some((subjectNode) => isEqual(subjectNode, quadSubject))) {
|
745 | subjectNodes.push(quadSubject);
|
746 | }
|
747 | }
|
748 | const things = subjectNodes.map((subjectNode) => getThingOne(litDataset, subjectNode, options));
|
749 | return things;
|
750 | }
|
751 | /**
|
752 | * Insert a [[Thing]] into a [[LitDataset]], replacing previous instances of that Thing.
|
753 | *
|
754 | * @param litDataset The LitDataset to insert a Thing into.
|
755 | * @param thing The Thing to insert into the given LitDataset.
|
756 | * @returns A new LitDataset equal to the given LitDataset, but with the given Thing.
|
757 | */
|
758 | function setThing(litDataset, thing) {
|
759 | const newDataset = removeThing(litDataset, thing);
|
760 | for (const quad of thing) {
|
761 | newDataset.add(quad);
|
762 | newDataset.changeLog.additions.push(quad);
|
763 | }
|
764 | return newDataset;
|
765 | }
|
766 | /**
|
767 | * Remove a Thing from a LitDataset.
|
768 | *
|
769 | * @param litDataset The LitDataset to remove a Thing from.
|
770 | * @param thing The Thing to remove from `litDataset`.
|
771 | * @returns A new [[LitDataset]] equal to the input LitDataset, excluding the given Thing.
|
772 | */
|
773 | function removeThing(litDataset, thing) {
|
774 | const newLitDataset = withChangeLog(cloneLitStructs(litDataset));
|
775 | const resourceIri = hasDatasetInfo(newLitDataset)
|
776 | ? newLitDataset.datasetInfo.fetchedFrom
|
777 | : undefined;
|
778 | const thingSubject = toNode(thing);
|
779 | for (const quad of litDataset) {
|
780 | if (!isNamedNode(quad.subject) && !isLocalNode(quad.subject)) {
|
781 | // This data is unexpected, and hence unlikely to be added by us. Thus, leave it intact:
|
782 | newLitDataset.add(quad);
|
783 | }
|
784 | else if (!isEqual(thingSubject, quad.subject, { resourceIri: resourceIri })) {
|
785 | newLitDataset.add(quad);
|
786 | }
|
787 | else {
|
788 | newLitDataset.changeLog.deletions.push(quad);
|
789 | }
|
790 | }
|
791 | return newLitDataset;
|
792 | }
|
793 | function withChangeLog(litDataset) {
|
794 | const newLitDataset = hasChangelog(litDataset)
|
795 | ? litDataset
|
796 | : Object.assign(litDataset, {
|
797 | changeLog: { additions: [], deletions: [] },
|
798 | });
|
799 | return newLitDataset;
|
800 | }
|
801 | function cloneLitStructs(litDataset) {
|
802 | const freshDataset = dataset.dataset();
|
803 | if (hasChangelog(litDataset)) {
|
804 | freshDataset.changeLog = {
|
805 | additions: [...litDataset.changeLog.additions],
|
806 | deletions: [...litDataset.changeLog.deletions],
|
807 | };
|
808 | }
|
809 | if (hasDatasetInfo(litDataset)) {
|
810 | freshDataset.datasetInfo = Object.assign({}, litDataset.datasetInfo);
|
811 | }
|
812 | return freshDataset;
|
813 | }
|
814 | function createThing(options = {}) {
|
815 | var _a;
|
816 | if (typeof options.url !== "undefined") {
|
817 | const url = options.url;
|
818 | /* istanbul ignore else [URL is defined is the testing environment, so we cannot test this] */
|
819 | if (typeof URL !== "undefined") {
|
820 | // Throws an error if the IRI is invalid:
|
821 | new URL(url);
|
822 | }
|
823 | const thing = Object.assign(dataset.dataset(), { url: url });
|
824 | return thing;
|
825 | }
|
826 | const name = (_a = options.name) !== null && _a !== void 0 ? _a : generateName();
|
827 | const thing = Object.assign(dataset.dataset(), { name: name });
|
828 | return thing;
|
829 | }
|
830 | function asUrl(thing, baseUrl) {
|
831 | if (isThingLocal(thing)) {
|
832 | if (typeof baseUrl === "undefined") {
|
833 | throw new Error("The URL of a Thing that has not been persisted cannot be determined without a base URL.");
|
834 | }
|
835 | return resolveLocalIri(thing.name, baseUrl);
|
836 | }
|
837 | return thing.url;
|
838 | }
|
839 | /** @hidden Alias of [[asUrl]] for those who prefer IRI terminology. */
|
840 | const asIri = asUrl;
|
841 | /**
|
842 | * @param thing The [[Thing]] of which a URL might or might not be known.
|
843 | * @return Whether `thing` has no known URL yet.
|
844 | */
|
845 | function isThingLocal(thing) {
|
846 | return (typeof thing.name === "string" &&
|
847 | typeof thing.url === "undefined");
|
848 | }
|
849 | /**
|
850 | * @internal
|
851 | * @param thing The Thing whose Subject Node you're interested in.
|
852 | * @returns A Node that can be used as the Subject for this Thing's Quads.
|
853 | */
|
854 | function toNode(thing) {
|
855 | if (isNamedNode(thing) || isLocalNode(thing)) {
|
856 | return thing;
|
857 | }
|
858 | if (typeof thing === "string") {
|
859 | return asNamedNode(thing);
|
860 | }
|
861 | if (isThingLocal(thing)) {
|
862 | return getLocalNode(thing.name);
|
863 | }
|
864 | return asNamedNode(asUrl(thing));
|
865 | }
|
866 | function cloneThing(thing) {
|
867 | const cloned = clone(thing);
|
868 | if (isThingLocal(thing)) {
|
869 | cloned.name = thing.name;
|
870 | return cloned;
|
871 | }
|
872 | cloned.url = thing.url;
|
873 | return cloned;
|
874 | }
|
875 | function filterThing(thing, callback) {
|
876 | const filtered = filter(thing, callback);
|
877 | if (isThingLocal(thing)) {
|
878 | filtered.name = thing.name;
|
879 | return filtered;
|
880 | }
|
881 | filtered.url = thing.url;
|
882 | return filtered;
|
883 | }
|
884 | /**
|
885 | * Generate a string that can be used as the unique identifier for a Thing
|
886 | *
|
887 | * This function works by starting with a date string (so that Things can be
|
888 | * sorted chronologically), followed by a random number generated by taking a
|
889 | * random number between 0 and 1, and cutting off the `0.`.
|
890 | *
|
891 | * @internal
|
892 | * @returns An string that's likely to be unique
|
893 | */
|
894 | const generateName = () => {
|
895 | return (Date.now().toString() + Math.random().toString().substring("0.".length));
|
896 | };
|
897 |
|
898 | /**
|
899 | * Copyright 2020 Inrupt Inc.
|
900 | *
|
901 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
902 | * of this software and associated documentation files (the "Software"), to deal in
|
903 | * the Software without restriction, including without limitation the rights to use,
|
904 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
905 | * Software, and to permit persons to whom the Software is furnished to do so,
|
906 | * subject to the following conditions:
|
907 | *
|
908 | * The above copyright notice and this permission notice shall be included in
|
909 | * all copies or substantial portions of the Software.
|
910 | *
|
911 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
912 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
913 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
914 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
915 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
916 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
917 | */
|
918 | /**
|
919 | * @param thing The [[Thing]] to read a URL value from.
|
920 | * @param predicate The given Predicate for which you want the URL value.
|
921 | * @returns A URL value for the given Predicate, if present, or null otherwise.
|
922 | */
|
923 | function getUrlOne(thing, predicate) {
|
924 | const namedNodeMatcher = getNamedNodeMatcher(predicate);
|
925 | const matchingQuad = findOne(thing, namedNodeMatcher);
|
926 | if (matchingQuad === null) {
|
927 | return null;
|
928 | }
|
929 | return matchingQuad.object.value;
|
930 | }
|
931 | /** @hidden Alias of [[getUrlOne]] for those who prefer IRI terminology. */
|
932 | const getIriOne = getUrlOne;
|
933 | /**
|
934 | * @param thing The [[Thing]] to read the URL values from.
|
935 | * @param predicate The given Predicate for which you want the URL values.
|
936 | * @returns The URL values for the given Predicate.
|
937 | */
|
938 | function getUrlAll(thing, predicate) {
|
939 | const iriMatcher = getNamedNodeMatcher(predicate);
|
940 | const matchingQuads = findAll(thing, iriMatcher);
|
941 | return matchingQuads.map((quad) => quad.object.value);
|
942 | }
|
943 | /** @hidden Alias of [[getUrlAll]] for those who prefer IRI terminology. */
|
944 | const getIriAll = getUrlAll;
|
945 | /**
|
946 | * @param thing The [[Thing]] to read a boolean value from.
|
947 | * @param predicate The given Predicate for which you want the boolean value.
|
948 | * @returns A boolean value for the given Predicate, if present, or null otherwise.
|
949 | */
|
950 | function getBooleanOne(thing, predicate) {
|
951 | const literalString = getLiteralOneOfType(thing, predicate, xmlSchemaTypes.boolean);
|
952 | if (literalString === null) {
|
953 | return null;
|
954 | }
|
955 | return deserializeBoolean(literalString);
|
956 | }
|
957 | /**
|
958 | * @param thing The [[Thing]] to read the boolean values from.
|
959 | * @param predicate The given Predicate for which you want the boolean values.
|
960 | * @returns The boolean values for the given Predicate.
|
961 | */
|
962 | function getBooleanAll(thing, predicate) {
|
963 | const literalStrings = getLiteralAllOfType(thing, predicate, xmlSchemaTypes.boolean);
|
964 | return literalStrings
|
965 | .map(deserializeBoolean)
|
966 | .filter((possibleBoolean) => possibleBoolean !== null);
|
967 | }
|
968 | /**
|
969 | * @param thing The [[Thing]] to read a datetime value from.
|
970 | * @param predicate The given Predicate for which you want the datetime value.
|
971 | * @returns A datetime value for the given Predicate, if present, or null otherwise.
|
972 | */
|
973 | function getDatetimeOne(thing, predicate) {
|
974 | const literalString = getLiteralOneOfType(thing, predicate, xmlSchemaTypes.dateTime);
|
975 | if (literalString === null) {
|
976 | return null;
|
977 | }
|
978 | return deserializeDatetime(literalString);
|
979 | }
|
980 | /**
|
981 | * @param thing The [[Thing]] to read the datetime values from.
|
982 | * @param predicate The given Predicate for which you want the datetime values.
|
983 | * @returns The datetime values for the given Predicate.
|
984 | */
|
985 | function getDatetimeAll(thing, predicate) {
|
986 | const literalStrings = getLiteralAllOfType(thing, predicate, xmlSchemaTypes.dateTime);
|
987 | return literalStrings
|
988 | .map(deserializeDatetime)
|
989 | .filter((potentialDatetime) => potentialDatetime !== null);
|
990 | }
|
991 | /**
|
992 | * @param thing The [[Thing]] to read a decimal value from.
|
993 | * @param predicate The given Predicate for which you want the decimal value.
|
994 | * @returns A decimal value for the given Predicate, if present, or null otherwise.
|
995 | */
|
996 | function getDecimalOne(thing, predicate) {
|
997 | const literalString = getLiteralOneOfType(thing, predicate, xmlSchemaTypes.decimal);
|
998 | if (literalString === null) {
|
999 | return null;
|
1000 | }
|
1001 | return deserializeDecimal(literalString);
|
1002 | }
|
1003 | /**
|
1004 | * @param thing The [[Thing]] to read the decimal values from.
|
1005 | * @param predicate The given Predicate for which you want the decimal values.
|
1006 | * @returns The decimal values for the given Predicate.
|
1007 | */
|
1008 | function getDecimalAll(thing, predicate) {
|
1009 | const literalStrings = getLiteralAllOfType(thing, predicate, xmlSchemaTypes.decimal);
|
1010 | return literalStrings
|
1011 | .map((literalString) => deserializeDecimal(literalString))
|
1012 | .filter((potentialDecimal) => potentialDecimal !== null);
|
1013 | }
|
1014 | /**
|
1015 | * @param thing The [[Thing]] to read an integer value from.
|
1016 | * @param predicate The given Predicate for which you want the integer value.
|
1017 | * @returns An integer value for the given Predicate, if present, or null otherwise.
|
1018 | */
|
1019 | function getIntegerOne(thing, predicate) {
|
1020 | const literalString = getLiteralOneOfType(thing, predicate, xmlSchemaTypes.integer);
|
1021 | if (literalString === null) {
|
1022 | return null;
|
1023 | }
|
1024 | return deserializeInteger(literalString);
|
1025 | }
|
1026 | /**
|
1027 | * @param thing The [[Thing]] to read the integer values from.
|
1028 | * @param predicate The given Predicate for which you want the integer values.
|
1029 | * @returns The integer values for the given Predicate.
|
1030 | */
|
1031 | function getIntegerAll(thing, predicate) {
|
1032 | const literalStrings = getLiteralAllOfType(thing, predicate, xmlSchemaTypes.integer);
|
1033 | return literalStrings
|
1034 | .map((literalString) => deserializeInteger(literalString))
|
1035 | .filter((potentialInteger) => potentialInteger !== null);
|
1036 | }
|
1037 | /**
|
1038 | * @param thing The [[Thing]] to read a localised string value from.
|
1039 | * @param predicate The given Predicate for which you want the localised string value.
|
1040 | * @param locale The desired locale for the string value.
|
1041 | * @returns A localised string value for the given Predicate, if present in `locale`, or null otherwise.
|
1042 | */
|
1043 | function getStringInLocaleOne(thing, predicate, locale) {
|
1044 | const localeStringMatcher = getLocaleStringMatcher(predicate, locale);
|
1045 | const matchingQuad = findOne(thing, localeStringMatcher);
|
1046 | if (matchingQuad === null) {
|
1047 | return null;
|
1048 | }
|
1049 | return matchingQuad.object.value;
|
1050 | }
|
1051 | /**
|
1052 | * @param thing The [[Thing]] to read the localised string values from.
|
1053 | * @param predicate The given Predicate for which you want the localised string values.
|
1054 | * @param locale The desired locale for the string values.
|
1055 | * @returns The localised string values for the given Predicate.
|
1056 | */
|
1057 | function getStringInLocaleAll(thing, predicate, locale) {
|
1058 | const localeStringMatcher = getLocaleStringMatcher(predicate, locale);
|
1059 | const matchingQuads = findAll(thing, localeStringMatcher);
|
1060 | return matchingQuads.map((quad) => quad.object.value);
|
1061 | }
|
1062 | /**
|
1063 | * @param thing The [[Thing]] to read a string value from.
|
1064 | * @param predicate The given Predicate for which you want the string value.
|
1065 | * @returns A string value for the given Predicate, if present, or null otherwise.
|
1066 | */
|
1067 | function getStringUnlocalizedOne(thing, predicate) {
|
1068 | const literalString = getLiteralOneOfType(thing, predicate, xmlSchemaTypes.string);
|
1069 | return literalString;
|
1070 | }
|
1071 | /**
|
1072 | * @param thing The [[Thing]] to read the string values from.
|
1073 | * @param predicate The given Predicate for which you want the string values.
|
1074 | * @returns The string values for the given Predicate.
|
1075 | */
|
1076 | function getStringUnlocalizedAll(thing, predicate) {
|
1077 | const literalStrings = getLiteralAllOfType(thing, predicate, xmlSchemaTypes.string);
|
1078 | return literalStrings;
|
1079 | }
|
1080 | /**
|
1081 | * @param thing The [[Thing]] to read a NamedNode value from.
|
1082 | * @param predicate The given Predicate for which you want the NamedNode value.
|
1083 | * @returns A NamedNode value for the given Predicate, if present, or null otherwise.
|
1084 | * @ignore This should not be needed due to the other get*One() functions. If you do find yourself needing it, please file a feature request for your use case.
|
1085 | */
|
1086 | function getNamedNodeOne(thing, predicate) {
|
1087 | const namedNodeMatcher = getNamedNodeMatcher(predicate);
|
1088 | const matchingQuad = findOne(thing, namedNodeMatcher);
|
1089 | if (matchingQuad === null) {
|
1090 | return null;
|
1091 | }
|
1092 | return matchingQuad.object;
|
1093 | }
|
1094 | /**
|
1095 | * @param thing The [[Thing]] to read the NamedNode values from.
|
1096 | * @param predicate The given Predicate for which you want the NamedNode values.
|
1097 | * @returns The NamedNode values for the given Predicate.
|
1098 | * @ignore This should not be needed due to the other get*One() functions. If you do find yourself needing it, please file a feature request for your use case.
|
1099 | */
|
1100 | function getNamedNodeAll(thing, predicate) {
|
1101 | const namedNodeMatcher = getNamedNodeMatcher(predicate);
|
1102 | const matchingQuads = findAll(thing, namedNodeMatcher);
|
1103 | return matchingQuads.map((quad) => quad.object);
|
1104 | }
|
1105 | /**
|
1106 | * @param thing The [[Thing]] to read a Literal value from.
|
1107 | * @param predicate The given Predicate for which you want the Literal value.
|
1108 | * @returns A Literal value for the given Predicate, if present, or null otherwise.
|
1109 | * @ignore This should not be needed due to the other get*One() functions. If you do find yourself needing it, please file a feature request for your use case.
|
1110 | */
|
1111 | function getLiteralOne(thing, predicate) {
|
1112 | const literalMatcher = getLiteralMatcher(predicate);
|
1113 | const matchingQuad = findOne(thing, literalMatcher);
|
1114 | if (matchingQuad === null) {
|
1115 | return null;
|
1116 | }
|
1117 | return matchingQuad.object;
|
1118 | }
|
1119 | /**
|
1120 | * @param thing The [[Thing]] to read the Literal values from.
|
1121 | * @param predicate The given Predicate for which you want the Literal values.
|
1122 | * @returns The Literal values for the given Predicate.
|
1123 | * @ignore This should not be needed due to the other get*All() functions. If you do find yourself needing it, please file a feature request for your use case.
|
1124 | */
|
1125 | function getLiteralAll(thing, predicate) {
|
1126 | const literalMatcher = getLiteralMatcher(predicate);
|
1127 | const matchingQuads = findAll(thing, literalMatcher);
|
1128 | return matchingQuads.map((quad) => quad.object);
|
1129 | }
|
1130 | /**
|
1131 | * @param thing The [[Thing]] to extract a Quad from.
|
1132 | * @param matcher Callback function that returns a boolean indicating whether a given Quad should be included.
|
1133 | * @returns First Quad in `thing` for which `matcher` returned true.
|
1134 | */
|
1135 | function findOne(thing, matcher) {
|
1136 | for (const quad of thing) {
|
1137 | if (matcher(quad)) {
|
1138 | return quad;
|
1139 | }
|
1140 | }
|
1141 | return null;
|
1142 | }
|
1143 | /**
|
1144 | * @param thing The [[Thing]] to extract Quads from.
|
1145 | * @param matcher Callback function that returns a boolean indicating whether a given Quad should be included.
|
1146 | * @returns All Quads in `thing` for which `matcher` returned true.
|
1147 | */
|
1148 | function findAll(thing, matcher) {
|
1149 | const matched = [];
|
1150 | for (const quad of thing) {
|
1151 | if (matcher(quad)) {
|
1152 | matched.push(quad);
|
1153 | }
|
1154 | }
|
1155 | return matched;
|
1156 | }
|
1157 | function getNamedNodeMatcher(predicate) {
|
1158 | const predicateNode = asNamedNode(predicate);
|
1159 | const matcher = function matcher(quad) {
|
1160 | return predicateNode.equals(quad.predicate) && isNamedNode(quad.object);
|
1161 | };
|
1162 | return matcher;
|
1163 | }
|
1164 | function getLiteralMatcher(predicate) {
|
1165 | const predicateNode = asNamedNode(predicate);
|
1166 | const matcher = function matcher(quad) {
|
1167 | return predicateNode.equals(quad.predicate) && isLiteral(quad.object);
|
1168 | };
|
1169 | return matcher;
|
1170 | }
|
1171 | function getLiteralOfTypeMatcher(predicate, datatype) {
|
1172 | const predicateNode = asNamedNode(predicate);
|
1173 | const matcher = function matcher(quad) {
|
1174 | return (predicateNode.equals(quad.predicate) &&
|
1175 | isLiteral(quad.object) &&
|
1176 | quad.object.datatype.value === datatype);
|
1177 | };
|
1178 | return matcher;
|
1179 | }
|
1180 | function getLocaleStringMatcher(predicate, locale) {
|
1181 | const predicateNode = asNamedNode(predicate);
|
1182 | const matcher = function matcher(quad) {
|
1183 | return (predicateNode.equals(quad.predicate) &&
|
1184 | isLiteral(quad.object) &&
|
1185 | quad.object.datatype.value === xmlSchemaTypes.langString &&
|
1186 | quad.object.language.toLowerCase() === locale.toLowerCase());
|
1187 | };
|
1188 | return matcher;
|
1189 | }
|
1190 | /**
|
1191 | * @param thing The [Thing]] to read a Literal of the given type from.
|
1192 | * @param predicate The given Predicate for which you want the Literal value.
|
1193 | * @param literalType Set type of the Literal data.
|
1194 | * @returns The stringified value for the given Predicate and type, if present, or null otherwise.
|
1195 | */
|
1196 | function getLiteralOneOfType(thing, predicate, literalType) {
|
1197 | const literalOfTypeMatcher = getLiteralOfTypeMatcher(predicate, literalType);
|
1198 | const matchingQuad = findOne(thing, literalOfTypeMatcher);
|
1199 | if (matchingQuad === null) {
|
1200 | return null;
|
1201 | }
|
1202 | return matchingQuad.object.value;
|
1203 | }
|
1204 | /**
|
1205 | * @param thing The [Thing]] to read the Literals of the given type from.
|
1206 | * @param predicate The given Predicate for which you want the Literal values.
|
1207 | * @param literalType Set type of the Literal data.
|
1208 | * @returns The stringified values for the given Predicate and type.
|
1209 | */
|
1210 | function getLiteralAllOfType(thing, predicate, literalType) {
|
1211 | const literalOfTypeMatcher = getLiteralOfTypeMatcher(predicate, literalType);
|
1212 | const matchingQuads = findAll(thing, literalOfTypeMatcher);
|
1213 | return matchingQuads.map((quad) => quad.object.value);
|
1214 | }
|
1215 |
|
1216 | /**
|
1217 | * Copyright 2020 Inrupt Inc.
|
1218 | *
|
1219 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
1220 | * of this software and associated documentation files (the "Software"), to deal in
|
1221 | * the Software without restriction, including without limitation the rights to use,
|
1222 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
1223 | * Software, and to permit persons to whom the Software is furnished to do so,
|
1224 | * subject to the following conditions:
|
1225 | *
|
1226 | * The above copyright notice and this permission notice shall be included in
|
1227 | * all copies or substantial portions of the Software.
|
1228 | *
|
1229 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
1230 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
1231 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
1232 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
1233 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
1234 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1235 | */
|
1236 | /** @internal */
|
1237 | function internal_fetchResourceAcl(dataset, options = defaultFetchOptions) {
|
1238 | return __awaiter(this, void 0, void 0, function* () {
|
1239 | if (!unstable_hasAccessibleAcl(dataset)) {
|
1240 | return null;
|
1241 | }
|
1242 | try {
|
1243 | const aclLitDataset = yield fetchLitDataset(dataset.datasetInfo.unstable_aclUrl, options);
|
1244 | return Object.assign(aclLitDataset, {
|
1245 | accessTo: dataset.datasetInfo.fetchedFrom,
|
1246 | });
|
1247 | }
|
1248 | catch (e) {
|
1249 | // Since a Solid server adds a `Link` header to an ACL even if that ACL does not exist,
|
1250 | // failure to fetch the ACL is expected to happen - we just return `null` and let callers deal
|
1251 | // with it.
|
1252 | return null;
|
1253 | }
|
1254 | });
|
1255 | }
|
1256 | /** @internal */
|
1257 | function internal_fetchFallbackAcl(dataset, options = defaultFetchOptions) {
|
1258 | return __awaiter(this, void 0, void 0, function* () {
|
1259 | const resourceUrl = new URL(dataset.datasetInfo.fetchedFrom);
|
1260 | const resourcePath = resourceUrl.pathname;
|
1261 | // Note: we're currently assuming that the Origin is the root of the Pod. However, it is not yet
|
1262 | // set in stone that that will always be the case. We might need to check the Container's
|
1263 | // metadata at some point in time to check whether it is actually the root of the Pod.
|
1264 | // See: https://github.com/solid/specification/issues/153#issuecomment-624630022
|
1265 | if (resourcePath === "/") {
|
1266 | // We're already at the root, so there's no Container we can retrieve:
|
1267 | return null;
|
1268 | }
|
1269 | const containerPath = getContainerPath(resourcePath);
|
1270 | const containerIri = new URL(containerPath, resourceUrl.origin).href;
|
1271 | const containerInfo = yield internal_fetchLitDatasetInfo(containerIri, options);
|
1272 | if (!unstable_hasAccessibleAcl(containerInfo)) {
|
1273 | // If the current user does not have access to this Container's ACL,
|
1274 | // we cannot determine whether its ACL is the one that applies. Thus, return null:
|
1275 | return null;
|
1276 | }
|
1277 | const containerAcl = yield internal_fetchResourceAcl(containerInfo, options);
|
1278 | if (containerAcl === null) {
|
1279 | return internal_fetchFallbackAcl(containerInfo, options);
|
1280 | }
|
1281 | return containerAcl;
|
1282 | });
|
1283 | }
|
1284 | function getContainerPath(resourcePath) {
|
1285 | const resourcePathWithoutTrailingSlash = resourcePath.substring(resourcePath.length - 1) === "/"
|
1286 | ? resourcePath.substring(0, resourcePath.length - 1)
|
1287 | : resourcePath;
|
1288 | const containerPath = resourcePath.substring(0, resourcePathWithoutTrailingSlash.lastIndexOf("/")) + "/";
|
1289 | return containerPath;
|
1290 | }
|
1291 | /**
|
1292 | * Verify whether an ACL was found for the given LitDataset.
|
1293 | *
|
1294 | * A LitDataset fetched with [[unstable_fetchLitDatasetWithAcl]] _might_ have an ACL attached, but
|
1295 | * we cannot be sure: it might be that none exists for this specific Resource (in which case the
|
1296 | * fallback ACL applies), or the currently authenticated user (if any) might not have Control access
|
1297 | * to the fetched Resource.
|
1298 | *
|
1299 | * This function verifies that the LitDataset's ACL is accessible.
|
1300 | *
|
1301 | * @param dataset A [[LitDataset]] that might have an ACL attached.
|
1302 | * @returns Whether `dataset` has an ACL attached.
|
1303 | */
|
1304 | function unstable_hasResourceAcl(dataset) {
|
1305 | return typeof dataset.acl.resourceAcl !== "undefined";
|
1306 | }
|
1307 | function unstable_getResourceAcl(dataset) {
|
1308 | if (!unstable_hasResourceAcl(dataset)) {
|
1309 | return null;
|
1310 | }
|
1311 | return dataset.acl.resourceAcl;
|
1312 | }
|
1313 | /**
|
1314 | * Verify whether a fallback ACL was found for the given LitDataset.
|
1315 | *
|
1316 | * A LitDataset fetched with [[unstable_fetchLitDatasetWithAcl]] _might_ have a fallback ACL
|
1317 | * attached, but we cannot be sure: the currently authenticated user (if any) might not have Control
|
1318 | * access to one of the fetched Resource's Containers.
|
1319 | *
|
1320 | * This function verifies that the fallback ACL is accessible.
|
1321 | *
|
1322 | * @param dataset A [[LitDataset]] that might have a fallback ACL attached.
|
1323 | * @returns Whether `dataset` has a fallback ACL attached.
|
1324 | */
|
1325 | function unstable_hasFallbackAcl(dataset) {
|
1326 | return dataset.acl.fallbackAcl !== null;
|
1327 | }
|
1328 | function unstable_getFallbackAcl(dataset) {
|
1329 | if (!unstable_hasFallbackAcl(dataset)) {
|
1330 | return null;
|
1331 | }
|
1332 | return dataset.acl.fallbackAcl;
|
1333 | }
|
1334 | /** @internal */
|
1335 | function internal_getAclRules(aclDataset) {
|
1336 | const things = getThingAll(aclDataset);
|
1337 | return things.filter(isAclRule);
|
1338 | }
|
1339 | function isAclRule(thing) {
|
1340 | return getIriAll(thing, rdf.type).includes(acl.Authorization);
|
1341 | }
|
1342 | /** @internal */
|
1343 | function internal_getResourceAclRulesForResource(aclRules, resource) {
|
1344 | return aclRules.filter((rule) => appliesToResource(rule, resource));
|
1345 | }
|
1346 | function appliesToResource(aclRule, resource) {
|
1347 | return getIriAll(aclRule, acl.accessTo).includes(resource);
|
1348 | }
|
1349 | /** @internal */
|
1350 | function internal_getDefaultAclRulesForResource(aclRules, resource) {
|
1351 | return aclRules.filter((rule) => isDefaultForResource(rule, resource));
|
1352 | }
|
1353 | function isDefaultForResource(aclRule, resource) {
|
1354 | return getIriAll(aclRule, acl.default).includes(resource);
|
1355 | }
|
1356 | /** @internal */
|
1357 | function internal_getAccessModes(rule) {
|
1358 | const ruleAccessModes = getIriAll(rule, acl.mode);
|
1359 | const writeAccess = ruleAccessModes.includes(accessModeIriStrings.write);
|
1360 | return writeAccess
|
1361 | ? {
|
1362 | read: ruleAccessModes.includes(accessModeIriStrings.read),
|
1363 | append: true,
|
1364 | write: true,
|
1365 | control: ruleAccessModes.includes(accessModeIriStrings.control),
|
1366 | }
|
1367 | : {
|
1368 | read: ruleAccessModes.includes(accessModeIriStrings.read),
|
1369 | append: ruleAccessModes.includes(accessModeIriStrings.append),
|
1370 | write: false,
|
1371 | control: ruleAccessModes.includes(accessModeIriStrings.control),
|
1372 | };
|
1373 | }
|
1374 | /** @internal */
|
1375 | function internal_combineAccessModes(modes) {
|
1376 | return modes.reduce((accumulator, current) => {
|
1377 | const writeAccess = accumulator.write || current.write;
|
1378 | return writeAccess
|
1379 | ? {
|
1380 | read: accumulator.read || current.read,
|
1381 | append: true,
|
1382 | write: true,
|
1383 | control: accumulator.control || current.control,
|
1384 | }
|
1385 | : {
|
1386 | read: accumulator.read || current.read,
|
1387 | append: accumulator.append || current.append,
|
1388 | write: false,
|
1389 | control: accumulator.control || current.control,
|
1390 | };
|
1391 | }, { read: false, append: false, write: false, control: false });
|
1392 | }
|
1393 | /**
|
1394 | * IRIs of potential Access Modes
|
1395 | * @internal
|
1396 | */
|
1397 | const accessModeIriStrings = {
|
1398 | read: "http://www.w3.org/ns/auth/acl#Read",
|
1399 | append: "http://www.w3.org/ns/auth/acl#Append",
|
1400 | write: "http://www.w3.org/ns/auth/acl#Write",
|
1401 | control: "http://www.w3.org/ns/auth/acl#Control",
|
1402 | };
|
1403 |
|
1404 | /**
|
1405 | * Copyright 2020 Inrupt Inc.
|
1406 | *
|
1407 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
1408 | * of this software and associated documentation files (the "Software"), to deal in
|
1409 | * the Software without restriction, including without limitation the rights to use,
|
1410 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
1411 | * Software, and to permit persons to whom the Software is furnished to do so,
|
1412 | * subject to the following conditions:
|
1413 | *
|
1414 | * The above copyright notice and this permission notice shall be included in
|
1415 | * all copies or substantial portions of the Software.
|
1416 | *
|
1417 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
1418 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
1419 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
1420 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
1421 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
1422 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1423 | */
|
1424 | /**
|
1425 | * Initialise a new [[LitDataset]] in memory.
|
1426 | *
|
1427 | * @returns An empty [[LitDataset]].
|
1428 | */
|
1429 | function createLitDataset() {
|
1430 | return dataset.dataset();
|
1431 | }
|
1432 | /**
|
1433 | * @internal
|
1434 | */
|
1435 | const defaultFetchOptions = {
|
1436 | fetch: fetch,
|
1437 | };
|
1438 | /**
|
1439 | * Fetch a LitDataset from the given URL. Currently requires the LitDataset to be available as [Turtle](https://www.w3.org/TR/turtle/).
|
1440 | *
|
1441 | * @param url URL to fetch a [[LitDataset]] from.
|
1442 | * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).
|
1443 | * @returns Promise resolving to a [[LitDataset]] containing the data at the given Resource, or rejecting if fetching it failed.
|
1444 | */
|
1445 | function fetchLitDataset(url, options = defaultFetchOptions) {
|
1446 | return __awaiter(this, void 0, void 0, function* () {
|
1447 | const config = Object.assign(Object.assign({}, defaultFetchOptions), options);
|
1448 | const response = yield config.fetch(url);
|
1449 | if (!response.ok) {
|
1450 | throw new Error(`Fetching the Resource failed: ${response.status} ${response.statusText}.`);
|
1451 | }
|
1452 | const data = yield response.text();
|
1453 | const triples = yield turtleToTriples(data, url);
|
1454 | const resource = dataset.dataset();
|
1455 | triples.forEach((triple) => resource.add(triple));
|
1456 | const datasetInfo = parseDatasetInfo(response);
|
1457 | const resourceWithDatasetInfo = Object.assign(resource, { datasetInfo: datasetInfo });
|
1458 | return resourceWithDatasetInfo;
|
1459 | });
|
1460 | }
|
1461 | /**
|
1462 | * @internal
|
1463 | */
|
1464 | function internal_fetchLitDatasetInfo(url, options = defaultFetchOptions) {
|
1465 | return __awaiter(this, void 0, void 0, function* () {
|
1466 | const config = Object.assign(Object.assign({}, defaultFetchOptions), options);
|
1467 | const response = yield config.fetch(url, { method: "HEAD" });
|
1468 | if (!response.ok) {
|
1469 | throw new Error(`Fetching the Resource metadata failed: ${response.status} ${response.statusText}.`);
|
1470 | }
|
1471 | const datasetInfo = parseDatasetInfo(response);
|
1472 | return { datasetInfo: datasetInfo };
|
1473 | });
|
1474 | }
|
1475 | function parseDatasetInfo(response) {
|
1476 | const datasetInfo = {
|
1477 | fetchedFrom: response.url,
|
1478 | };
|
1479 | const linkHeader = response.headers.get("Link");
|
1480 | if (linkHeader) {
|
1481 | const parsedLinks = LinkHeader.parse(linkHeader);
|
1482 | const aclLinks = parsedLinks.get("rel", "acl");
|
1483 | if (aclLinks.length === 1) {
|
1484 | datasetInfo.unstable_aclUrl = new URL(aclLinks[0].uri, datasetInfo.fetchedFrom).href;
|
1485 | }
|
1486 | }
|
1487 | const wacAllowHeader = response.headers.get("WAC-Allow");
|
1488 | if (wacAllowHeader) {
|
1489 | datasetInfo.unstable_permissions = parseWacAllowHeader(wacAllowHeader);
|
1490 | }
|
1491 | return datasetInfo;
|
1492 | }
|
1493 | /**
|
1494 | * Experimental: fetch a LitDataset and its associated Access Control List.
|
1495 | *
|
1496 | * This is an experimental function that fetches both a Resource, the linked ACL Resource (if
|
1497 | * available), and the ACL that applies to it if the linked ACL Resource is not available. This can
|
1498 | * result in many HTTP requests being executed, in lieu of the Solid spec mandating servers to
|
1499 | * provide this info in a single request. Therefore, and because this function is still
|
1500 | * experimental, prefer [[fetchLitDataset]] instead.
|
1501 | *
|
1502 | * If the Resource does not advertise the ACL Resource (because the authenticated user does not have
|
1503 | * access to it), the `acl` property in the returned value will be null. `acl.resourceAcl` will be
|
1504 | * undefined if the Resource's linked ACL Resource could not be fetched (because it does not exist),
|
1505 | * and `acl.fallbackAcl` will be null if the applicable Container's ACL is not accessible to the
|
1506 | * authenticated user.
|
1507 | *
|
1508 | * @param url URL of the LitDataset to fetch.
|
1509 | * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).
|
1510 | * @returns A LitDataset and the ACLs that apply to it, if available to the authenticated user.
|
1511 | */
|
1512 | function unstable_fetchLitDatasetWithAcl(url, options = defaultFetchOptions) {
|
1513 | return __awaiter(this, void 0, void 0, function* () {
|
1514 | const litDataset = yield fetchLitDataset(url, options);
|
1515 | if (!unstable_hasAccessibleAcl(litDataset)) {
|
1516 | return Object.assign(litDataset, { acl: null });
|
1517 | }
|
1518 | const [resourceAcl, fallbackAcl] = yield Promise.all([
|
1519 | internal_fetchResourceAcl(litDataset, options),
|
1520 | internal_fetchFallbackAcl(litDataset, options),
|
1521 | ]);
|
1522 | const acl = {
|
1523 | fallbackAcl: fallbackAcl,
|
1524 | resourceAcl: resourceAcl !== null ? resourceAcl : undefined,
|
1525 | };
|
1526 | return Object.assign(litDataset, { acl: acl });
|
1527 | });
|
1528 | }
|
1529 | const defaultSaveOptions = {
|
1530 | fetch: fetch,
|
1531 | };
|
1532 | /**
|
1533 | * Given a LitDataset, store it in a Solid Pod (overwriting the existing data at the given URL).
|
1534 | *
|
1535 | * @param url URL to save `litDataset` to.
|
1536 | * @param litDataset The [[LitDataset]] to save.
|
1537 | * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).
|
1538 | * @returns A Promise resolving to a [[LitDataset]] containing the stored data, or rejecting if saving it failed.
|
1539 | */
|
1540 | function saveLitDatasetAt(url, litDataset, options = defaultSaveOptions) {
|
1541 | return __awaiter(this, void 0, void 0, function* () {
|
1542 | const config = Object.assign(Object.assign({}, defaultSaveOptions), options);
|
1543 | let requestInit;
|
1544 | if (isUpdate(litDataset, url)) {
|
1545 | const deleteStatement = litDataset.changeLog.deletions.length > 0
|
1546 | ? `DELETE DATA {${(yield triplesToTurtle(litDataset.changeLog.deletions.map(getNamedNodesForLocalNodes))).trim()}};`
|
1547 | : "";
|
1548 | const insertStatement = litDataset.changeLog.additions.length > 0
|
1549 | ? `INSERT DATA {${(yield triplesToTurtle(litDataset.changeLog.additions.map(getNamedNodesForLocalNodes))).trim()}};`
|
1550 | : "";
|
1551 | requestInit = {
|
1552 | method: "PATCH",
|
1553 | body: `${deleteStatement} ${insertStatement}`,
|
1554 | headers: {
|
1555 | "Content-Type": "application/sparql-update",
|
1556 | },
|
1557 | };
|
1558 | }
|
1559 | else {
|
1560 | requestInit = {
|
1561 | method: "PUT",
|
1562 | body: yield triplesToTurtle(Array.from(litDataset).map(getNamedNodesForLocalNodes)),
|
1563 | headers: {
|
1564 | "Content-Type": "text/turtle",
|
1565 | "If-None-Match": "*",
|
1566 | Link: '<http://www.w3.org/ns/ldp#Resource>; rel="type"',
|
1567 | },
|
1568 | };
|
1569 | }
|
1570 | const response = yield config.fetch(url, requestInit);
|
1571 | if (!response.ok) {
|
1572 | throw new Error(`Storing the Resource failed: ${response.status} ${response.statusText}.`);
|
1573 | }
|
1574 | const datasetInfo = hasDatasetInfo(litDataset)
|
1575 | ? Object.assign(Object.assign({}, litDataset.datasetInfo), { fetchedFrom: url }) : { fetchedFrom: url };
|
1576 | const storedDataset = Object.assign(litDataset, {
|
1577 | changeLog: { additions: [], deletions: [] },
|
1578 | datasetInfo: datasetInfo,
|
1579 | });
|
1580 | const storedDatasetWithResolvedIris = resolveLocalIrisInLitDataset(storedDataset);
|
1581 | return storedDatasetWithResolvedIris;
|
1582 | });
|
1583 | }
|
1584 | function isUpdate(litDataset, url) {
|
1585 | return (hasChangelog(litDataset) &&
|
1586 | hasDatasetInfo(litDataset) &&
|
1587 | typeof litDataset.datasetInfo.fetchedFrom === "string" &&
|
1588 | litDataset.datasetInfo.fetchedFrom === url);
|
1589 | }
|
1590 | const defaultSaveInContainerOptions = {
|
1591 | fetch: fetch,
|
1592 | };
|
1593 | /**
|
1594 | * Given a LitDataset, store it in a Solid Pod in a new Resource inside a Container.
|
1595 | *
|
1596 | * @param containerUrl URL of the Container in which to create a new Resource.
|
1597 | * @param litDataset The [[LitDataset]] to save to a new Resource in the given Container.
|
1598 | * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).
|
1599 | * @returns A Promise resolving to a [[LitDataset]] containing the stored data linked to the new Resource, or rejecting if saving it failed.
|
1600 | */
|
1601 | function saveLitDatasetInContainer(containerUrl, litDataset, options = defaultSaveInContainerOptions) {
|
1602 | return __awaiter(this, void 0, void 0, function* () {
|
1603 | const config = Object.assign(Object.assign({}, defaultSaveOptions), options);
|
1604 | const rawTurtle = yield triplesToTurtle(Array.from(litDataset).map(getNamedNodesForLocalNodes));
|
1605 | const headers = {
|
1606 | "Content-Type": "text/turtle",
|
1607 | Link: '<http://www.w3.org/ns/ldp#Resource>; rel="type"',
|
1608 | };
|
1609 | if (options.slugSuggestion) {
|
1610 | headers.slug = options.slugSuggestion;
|
1611 | }
|
1612 | const response = yield config.fetch(containerUrl, {
|
1613 | method: "POST",
|
1614 | body: rawTurtle,
|
1615 | headers: headers,
|
1616 | });
|
1617 | if (!response.ok) {
|
1618 | throw new Error(`Storing the Resource in the Container failed: ${response.status} ${response.statusText}.`);
|
1619 | }
|
1620 | const locationHeader = response.headers.get("Location");
|
1621 | if (locationHeader === null) {
|
1622 | throw new Error("Could not determine the location for the newly saved LitDataset.");
|
1623 | }
|
1624 | const resourceIri = new URL(locationHeader, new URL(containerUrl).origin)
|
1625 | .href;
|
1626 | const datasetInfo = {
|
1627 | fetchedFrom: resourceIri,
|
1628 | };
|
1629 | const resourceWithDatasetInfo = Object.assign(litDataset, { datasetInfo: datasetInfo });
|
1630 | const resourceWithResolvedIris = resolveLocalIrisInLitDataset(resourceWithDatasetInfo);
|
1631 | return resourceWithResolvedIris;
|
1632 | });
|
1633 | }
|
1634 | function getNamedNodesForLocalNodes(quad) {
|
1635 | const subject = isLocalNode(quad.subject)
|
1636 | ? getNamedNodeFromLocalNode(quad.subject)
|
1637 | : quad.subject;
|
1638 | const object = isLocalNode(quad.object)
|
1639 | ? getNamedNodeFromLocalNode(quad.object)
|
1640 | : quad.object;
|
1641 | return Object.assign(Object.assign({}, quad), { subject: subject, object: object });
|
1642 | }
|
1643 | function getNamedNodeFromLocalNode(localNode) {
|
1644 | return DataFactory.namedNode("#" + localNode.name);
|
1645 | }
|
1646 | function resolveLocalIrisInLitDataset(litDataset) {
|
1647 | const resourceIri = litDataset.datasetInfo.fetchedFrom;
|
1648 | const unresolvedQuads = Array.from(litDataset);
|
1649 | unresolvedQuads.forEach((unresolvedQuad) => {
|
1650 | const resolvedQuad = resolveIriForLocalNodes(unresolvedQuad, resourceIri);
|
1651 | litDataset.delete(unresolvedQuad);
|
1652 | litDataset.add(resolvedQuad);
|
1653 | });
|
1654 | return litDataset;
|
1655 | }
|
1656 | /**
|
1657 | * Parse a WAC-Allow header into user and public access booleans.
|
1658 | *
|
1659 | * @param wacAllowHeader A WAC-Allow header in the format `user="read append write control",public="read"`
|
1660 | * @see https://github.com/solid/solid-spec/blob/cb1373a369398d561b909009bd0e5a8c3fec953b/api-rest.md#wac-allow-headers
|
1661 | */
|
1662 | function parseWacAllowHeader(wacAllowHeader) {
|
1663 | function parsePermissionStatement(permissionStatement) {
|
1664 | const permissions = permissionStatement.split(" ");
|
1665 | const writePermission = permissions.includes("write");
|
1666 | return writePermission
|
1667 | ? {
|
1668 | read: permissions.includes("read"),
|
1669 | append: true,
|
1670 | write: true,
|
1671 | control: permissions.includes("control"),
|
1672 | }
|
1673 | : {
|
1674 | read: permissions.includes("read"),
|
1675 | append: permissions.includes("append"),
|
1676 | write: false,
|
1677 | control: permissions.includes("control"),
|
1678 | };
|
1679 | }
|
1680 | function getStatementFor(header, scope) {
|
1681 | const relevantEntries = header
|
1682 | .split(",")
|
1683 | .map((rawEntry) => rawEntry.split("="))
|
1684 | .filter((parts) => parts.length === 2 && parts[0].trim() === scope);
|
1685 | // There should only be one statement with the given scope:
|
1686 | if (relevantEntries.length !== 1) {
|
1687 | return "";
|
1688 | }
|
1689 | const relevantStatement = relevantEntries[0][1].trim();
|
1690 | // The given statement should be wrapped in double quotes to be valid:
|
1691 | if (relevantStatement.charAt(0) !== '"' ||
|
1692 | relevantStatement.charAt(relevantStatement.length - 1) !== '"') {
|
1693 | return "";
|
1694 | }
|
1695 | // Return the statment without the wrapping quotes, e.g.: read append write control
|
1696 | return relevantStatement.substring(1, relevantStatement.length - 1);
|
1697 | }
|
1698 | return {
|
1699 | user: parsePermissionStatement(getStatementFor(wacAllowHeader, "user")),
|
1700 | public: parsePermissionStatement(getStatementFor(wacAllowHeader, "public")),
|
1701 | };
|
1702 | }
|
1703 |
|
1704 | /**
|
1705 | * Copyright 2020 Inrupt Inc.
|
1706 | *
|
1707 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
1708 | * of this software and associated documentation files (the "Software"), to deal in
|
1709 | * the Software without restriction, including without limitation the rights to use,
|
1710 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
1711 | * Software, and to permit persons to whom the Software is furnished to do so,
|
1712 | * subject to the following conditions:
|
1713 | *
|
1714 | * The above copyright notice and this permission notice shall be included in
|
1715 | * all copies or substantial portions of the Software.
|
1716 | *
|
1717 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
1718 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
1719 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
1720 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
1721 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
1722 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1723 | */
|
1724 | /**
|
1725 | * Create a new Thing with a URL added for a Predicate.
|
1726 | *
|
1727 | * This preserves existing values for the given Predicate. To replace them, see [[setUrl]].
|
1728 | *
|
1729 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
1730 | *
|
1731 | * @param thing Thing to add a URL value to.
|
1732 | * @param predicate Predicate for which to add the given URL value.
|
1733 | * @param url URL to add to `thing` for the given `predicate`.
|
1734 | * @returns A new Thing equal to the input Thing with the given value added for the given Predicate.
|
1735 | */
|
1736 | const addUrl = (thing, predicate, url) => {
|
1737 | const predicateNode = asNamedNode(predicate);
|
1738 | const newThing = cloneThing(thing);
|
1739 | newThing.add(DataFactory.quad(toNode(newThing), predicateNode, toNode(url)));
|
1740 | return newThing;
|
1741 | };
|
1742 | /** @hidden Alias for [[addUrl]] for those who prefer IRI terminology. */
|
1743 | const addIri = addUrl;
|
1744 | /**
|
1745 | * Create a new Thing with a boolean added for a Predicate.
|
1746 | *
|
1747 | * This preserves existing values for the given Predicate. To replace them, see [[setBoolean]].
|
1748 | *
|
1749 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
1750 | *
|
1751 | * @param thing Thing to add a boolean value to.
|
1752 | * @param predicate Predicate for which to add the given boolean value.
|
1753 | * @param value Boolean to add to `thing` for the given `predicate`.
|
1754 | * @returns A new Thing equal to the input Thing with the given value added for the given Predicate.
|
1755 | */
|
1756 | const addBoolean = (thing, predicate, value) => {
|
1757 | return addLiteralOfType(thing, predicate, serializeBoolean(value), xmlSchemaTypes.boolean);
|
1758 | };
|
1759 | /**
|
1760 | * Create a new Thing with a datetime added for a Predicate.
|
1761 | *
|
1762 | * This preserves existing values for the given Predicate. To replace them, see [[setDatetime]].
|
1763 | *
|
1764 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
1765 | *
|
1766 | * @param thing Thing to add a datetime value to.
|
1767 | * @param predicate Predicate for which to add the given datetime value.
|
1768 | * @param value Datetime to add to `thing` for the given `predicate`.
|
1769 | * @returns A new Thing equal to the input Thing with the given value added for the given Predicate.
|
1770 | */
|
1771 | const addDatetime = (thing, predicate, value) => {
|
1772 | return addLiteralOfType(thing, predicate, serializeDatetime(value), xmlSchemaTypes.dateTime);
|
1773 | };
|
1774 | /**
|
1775 | * Create a new Thing with a decimal added for a Predicate.
|
1776 | *
|
1777 | * This preserves existing values for the given Predicate. To replace them, see [[setDecimal]].
|
1778 | *
|
1779 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
1780 | *
|
1781 | * @param thing Thing to add a decimal value to.
|
1782 | * @param predicate Predicate for which to add the given decimal value.
|
1783 | * @param value Decimal to add to `thing` for the given `predicate`.
|
1784 | * @returns A new Thing equal to the input Thing with the given value added for the given Predicate.
|
1785 | */
|
1786 | const addDecimal = (thing, predicate, value) => {
|
1787 | return addLiteralOfType(thing, predicate, serializeDecimal(value), xmlSchemaTypes.decimal);
|
1788 | };
|
1789 | /**
|
1790 | * Create a new Thing with an integer added for a Predicate.
|
1791 | *
|
1792 | * This preserves existing values for the given Predicate. To replace them, see [[setInteger]].
|
1793 | *
|
1794 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
1795 | *
|
1796 | * @param thing Thing to add an integer value to.
|
1797 | * @param predicate Predicate for which to add the given integer value.
|
1798 | * @param value Integer to add to `thing` for the given `predicate`.
|
1799 | * @returns A new Thing equal to the input Thing with the given value added for the given Predicate.
|
1800 | */
|
1801 | const addInteger = (thing, predicate, value) => {
|
1802 | return addLiteralOfType(thing, predicate, serializeInteger(value), xmlSchemaTypes.integer);
|
1803 | };
|
1804 | function addStringInLocale(thing, predicate, value, locale) {
|
1805 | const literal = DataFactory.literal(value, normalizeLocale(locale));
|
1806 | return addLiteral(thing, predicate, literal);
|
1807 | }
|
1808 | /**
|
1809 | * Create a new Thing with an unlocalised string added for a Predicate.
|
1810 | *
|
1811 | * This preserves existing values for the given Predicate. To replace them, see [[setStringUnlocalized]].
|
1812 | *
|
1813 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
1814 | *
|
1815 | * @param thing Thing to add an unlocalised string value to.
|
1816 | * @param predicate Predicate for which to add the given string value.
|
1817 | * @param value String to add to `thing` for the given `predicate`.
|
1818 | * @returns A new Thing equal to the input Thing with the given value added for the given Predicate.
|
1819 | */
|
1820 | const addStringUnlocalized = (thing, predicate, value) => {
|
1821 | return addLiteralOfType(thing, predicate, value, xmlSchemaTypes.string);
|
1822 | };
|
1823 | function addNamedNode(thing, predicate, value) {
|
1824 | const predicateNode = asNamedNode(predicate);
|
1825 | const newThing = cloneThing(thing);
|
1826 | newThing.add(DataFactory.quad(toNode(newThing), predicateNode, value));
|
1827 | return newThing;
|
1828 | }
|
1829 | function addLiteral(thing, predicate, value) {
|
1830 | const predicateNode = asNamedNode(predicate);
|
1831 | const newThing = cloneThing(thing);
|
1832 | newThing.add(DataFactory.quad(toNode(newThing), predicateNode, value));
|
1833 | return newThing;
|
1834 | }
|
1835 | function addLiteralOfType(thing, predicate, value, type) {
|
1836 | const literal = DataFactory.literal(value, type);
|
1837 | return addLiteral(thing, predicate, literal);
|
1838 | }
|
1839 |
|
1840 | /**
|
1841 | * Copyright 2020 Inrupt Inc.
|
1842 | *
|
1843 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
1844 | * of this software and associated documentation files (the "Software"), to deal in
|
1845 | * the Software without restriction, including without limitation the rights to use,
|
1846 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
1847 | * Software, and to permit persons to whom the Software is furnished to do so,
|
1848 | * subject to the following conditions:
|
1849 | *
|
1850 | * The above copyright notice and this permission notice shall be included in
|
1851 | * all copies or substantial portions of the Software.
|
1852 | *
|
1853 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
1854 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
1855 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
1856 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
1857 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
1858 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1859 | */
|
1860 | function removeAll(thing, predicate) {
|
1861 | const predicateNode = asNamedNode(predicate);
|
1862 | const updatedThing = filterThing(thing, (quad) => !quad.predicate.equals(predicateNode));
|
1863 | return updatedThing;
|
1864 | }
|
1865 | /**
|
1866 | * Create a new Thing with the given URL removed for the given Predicate.
|
1867 | *
|
1868 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
1869 | *
|
1870 | * @param thing Thing to remove a URL value from.
|
1871 | * @param predicate Predicate for which to remove the given URL value.
|
1872 | * @param value URL to remove from `thing` for the given `predicate`.
|
1873 | * @returns A new Thing equal to the input Thing with the given value removed for the given Predicate.
|
1874 | */
|
1875 | const removeUrl = (thing, predicate, value) => {
|
1876 | const predicateNode = asNamedNode(predicate);
|
1877 | const iriNode = isNamedNode(value)
|
1878 | ? value
|
1879 | : typeof value === "string"
|
1880 | ? asNamedNode(value)
|
1881 | : asNamedNode(asIri(value));
|
1882 | const updatedThing = filterThing(thing, (quad) => {
|
1883 | return (!quad.predicate.equals(predicateNode) ||
|
1884 | !isNamedNode(quad.object) ||
|
1885 | !quad.object.equals(iriNode));
|
1886 | });
|
1887 | return updatedThing;
|
1888 | };
|
1889 | /** @hidden Alias of [[removeUrl]] for those who prefer IRI terminology. */
|
1890 | const removeIri = removeUrl;
|
1891 | /**
|
1892 | * Create a new Thing with the given boolean removed for the given Predicate.
|
1893 | *
|
1894 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
1895 | *
|
1896 | * @param thing Thing to remove a boolean value from.
|
1897 | * @param predicate Predicate for which to remove the given boolean value.
|
1898 | * @param value Boolean to remove from `thing` for the given `predicate`.
|
1899 | * @returns A new Thing equal to the input Thing with the given value removed for the given Predicate.
|
1900 | */
|
1901 | const removeBoolean = (thing, predicate, value) => {
|
1902 | return removeLiteralOfType(thing, predicate, serializeBoolean(value), xmlSchemaTypes.boolean);
|
1903 | };
|
1904 | /**
|
1905 | * Create a new Thing with the given datetime removed for the given Predicate.
|
1906 | *
|
1907 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
1908 | *
|
1909 | * @param thing Thing to remove a datetime value from.
|
1910 | * @param predicate Predicate for which to remove the given datetime value.
|
1911 | * @param value Datetime to remove from `thing` for the given `predicate`.
|
1912 | * @returns A new Thing equal to the input Thing with the given value removed for the given Predicate.
|
1913 | */
|
1914 | const removeDatetime = (thing, predicate, value) => {
|
1915 | return removeLiteralOfType(thing, predicate, serializeDatetime(value), xmlSchemaTypes.dateTime);
|
1916 | };
|
1917 | /**
|
1918 | * Create a new Thing with the given decimal removed for the given Predicate.
|
1919 | *
|
1920 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
1921 | *
|
1922 | * @param thing Thing to remove a decimal value from.
|
1923 | * @param predicate Predicate for which to remove the given decimal value.
|
1924 | * @param value Decimal to remove from `thing` for the given `predicate`.
|
1925 | * @returns A new Thing equal to the input Thing with the given value removed for the given Predicate.
|
1926 | */
|
1927 | const removeDecimal = (thing, predicate, value) => {
|
1928 | return removeLiteralOfType(thing, predicate, serializeDecimal(value), xmlSchemaTypes.decimal);
|
1929 | };
|
1930 | /**
|
1931 | * Create a new Thing with the given integer removed for the given Predicate.
|
1932 | *
|
1933 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
1934 | *
|
1935 | * @param thing Thing to remove an integer value from.
|
1936 | * @param predicate Predicate for which to remove the given integer value.
|
1937 | * @param value Integer to remove from `thing` for the given `predicate`.
|
1938 | * @returns A new Thing equal to the input Thing with the given value removed for the given Predicate.
|
1939 | */
|
1940 | const removeInteger = (thing, predicate, value) => {
|
1941 | return removeLiteralOfType(thing, predicate, serializeInteger(value), xmlSchemaTypes.integer);
|
1942 | };
|
1943 | function removeStringInLocale(thing, predicate, value, locale) {
|
1944 | // Note: Due to how the `DataFactory.literal` constructor behaves, this function
|
1945 | // must call directly `removeLiteral` directly, with the locale as the data
|
1946 | // type of the Literal (which is not a valid NamedNode).
|
1947 | return removeLiteral(thing, predicate, DataFactory.literal(value, normalizeLocale(locale)));
|
1948 | }
|
1949 | /**
|
1950 | * Create a new Thing with the given unlocalised string removed for the given Predicate.
|
1951 | *
|
1952 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
1953 | *
|
1954 | * @param thing Thing to remove an unlocalised string value from.
|
1955 | * @param predicate Predicate for which to remove the given string value.
|
1956 | * @param value String to remove from `thing` for the given `predicate`.
|
1957 | * @returns A new Thing equal to the input Thing with the given value removed for the given Predicate.
|
1958 | */
|
1959 | const removeStringUnlocalized = (thing, predicate, value) => {
|
1960 | return removeLiteralOfType(thing, predicate, value, xmlSchemaTypes.string);
|
1961 | };
|
1962 | function removeNamedNode(thing, predicate, value) {
|
1963 | const predicateNode = asNamedNode(predicate);
|
1964 | const updatedThing = filterThing(thing, (quad) => {
|
1965 | return (!quad.predicate.equals(predicateNode) ||
|
1966 | !isNamedNode(quad.object) ||
|
1967 | !quad.object.equals(value));
|
1968 | });
|
1969 | return updatedThing;
|
1970 | }
|
1971 | function removeLiteral(thing, predicate, value) {
|
1972 | const predicateNode = asNamedNode(predicate);
|
1973 | const updatedThing = filterThing(thing, (quad) => {
|
1974 | return (!quad.predicate.equals(predicateNode) ||
|
1975 | !isLiteral(quad.object) ||
|
1976 | !quad.object.equals(value));
|
1977 | });
|
1978 | return updatedThing;
|
1979 | }
|
1980 | function removeLiteralOfType(thing, predicate, value, type) {
|
1981 | const updatedThing = removeLiteral(thing, predicate, DataFactory.literal(value, DataFactory.namedNode(type)));
|
1982 | return updatedThing;
|
1983 | }
|
1984 |
|
1985 | /**
|
1986 | * Copyright 2020 Inrupt Inc.
|
1987 | *
|
1988 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
1989 | * of this software and associated documentation files (the "Software"), to deal in
|
1990 | * the Software without restriction, including without limitation the rights to use,
|
1991 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
1992 | * Software, and to permit persons to whom the Software is furnished to do so,
|
1993 | * subject to the following conditions:
|
1994 | *
|
1995 | * The above copyright notice and this permission notice shall be included in
|
1996 | * all copies or substantial portions of the Software.
|
1997 | *
|
1998 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
1999 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
2000 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
2001 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
2002 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
2003 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
2004 | */
|
2005 | /**
|
2006 | * Create a new Thing with existing values replaced by the given URL for the given Predicate.
|
2007 | *
|
2008 | * To preserve existing values, see [[addUrl]].
|
2009 | *
|
2010 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
2011 | *
|
2012 | * @param thing Thing to set a URL value on.
|
2013 | * @param predicate Predicate for which to set the given URL value.
|
2014 | * @param url URL to set on `thing` for the given `predicate`.
|
2015 | * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Predicate.
|
2016 | */
|
2017 | const setUrl = (thing, predicate, url) => {
|
2018 | const newThing = removeAll(thing, predicate);
|
2019 | const predicateNode = asNamedNode(predicate);
|
2020 | newThing.add(DataFactory.quad(toNode(newThing), predicateNode, toNode(url)));
|
2021 | return newThing;
|
2022 | };
|
2023 | /** @hidden Alias of [[setUrl]] for those who prefer IRI terminology. */
|
2024 | const setIri = setUrl;
|
2025 | /**
|
2026 | * Create a new Thing with existing values replaced by the given boolean for the given Predicate.
|
2027 | *
|
2028 | * To preserve existing values, see [[addBoolean]].
|
2029 | *
|
2030 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
2031 | *
|
2032 | * @param thing Thing to set a boolean value on.
|
2033 | * @param predicate Predicate for which to set the given boolean value.
|
2034 | * @param value Boolean to set on `thing` for the given `predicate`.
|
2035 | * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Predicate.
|
2036 | */
|
2037 | const setBoolean = (thing, predicate, value) => {
|
2038 | return setLiteralOfType(thing, predicate, serializeBoolean(value), xmlSchemaTypes.boolean);
|
2039 | };
|
2040 | /**
|
2041 | * Create a new Thing with existing values replaced by the given datetime for the given Predicate.
|
2042 | *
|
2043 | * To preserve existing values, see [[addDatetime]].
|
2044 | *
|
2045 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
2046 | *
|
2047 | * @param thing Thing to set an datetime value on.
|
2048 | * @param predicate Predicate for which to set the given datetime value.
|
2049 | * @param value Datetime to set on `thing` for the given `predicate`.
|
2050 | * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Predicate.
|
2051 | */
|
2052 | const setDatetime = (thing, predicate, value) => {
|
2053 | return setLiteralOfType(thing, predicate, serializeDatetime(value), xmlSchemaTypes.dateTime);
|
2054 | };
|
2055 | /**
|
2056 | * Create a new Thing with existing values replaced by the given decimal for the given Predicate.
|
2057 | *
|
2058 | * To preserve existing values, see [[addDecimal]].
|
2059 | *
|
2060 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
2061 | *
|
2062 | * @param thing Thing to set a decimal value on.
|
2063 | * @param predicate Predicate for which to set the given decimal value.
|
2064 | * @param value Decimal to set on `thing` for the given `predicate`.
|
2065 | * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Predicate.
|
2066 | */
|
2067 | const setDecimal = (thing, predicate, value) => {
|
2068 | return setLiteralOfType(thing, predicate, serializeDecimal(value), xmlSchemaTypes.decimal);
|
2069 | };
|
2070 | /**
|
2071 | * Create a new Thing with existing values replaced by the given integer for the given Predicate.
|
2072 | *
|
2073 | * To preserve existing values, see [[addInteger]].
|
2074 | *
|
2075 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
2076 | *
|
2077 | * @param thing Thing to set an integer value on.
|
2078 | * @param predicate Predicate for which to set the given integer value.
|
2079 | * @param value Integer to set on `thing` for the given `predicate`.
|
2080 | * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Predicate.
|
2081 | */
|
2082 | const setInteger = (thing, predicate, value) => {
|
2083 | return setLiteralOfType(thing, predicate, serializeInteger(value), xmlSchemaTypes.integer);
|
2084 | };
|
2085 | function setStringInLocale(thing, predicate, value, locale) {
|
2086 | const literal = DataFactory.literal(value, normalizeLocale(locale));
|
2087 | return setLiteral(thing, predicate, literal);
|
2088 | }
|
2089 | /**
|
2090 | * Create a new Thing with existing values replaced by the given unlocalised string for the given Predicate.
|
2091 | *
|
2092 | * To preserve existing values, see [[addStringUnlocalized]].
|
2093 | *
|
2094 | * The original `thing` is not modified; this function returns a cloned Thing with updated values.
|
2095 | *
|
2096 | * @param thing Thing to set an unlocalised string value on.
|
2097 | * @param predicate Predicate for which to set the given unlocalised string value.
|
2098 | * @param value Unlocalised string to set on `thing` for the given `predicate`.
|
2099 | * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Predicate.
|
2100 | */
|
2101 | const setStringUnlocalized = (thing, predicate, value) => {
|
2102 | return setLiteralOfType(thing, predicate, value, xmlSchemaTypes.string);
|
2103 | };
|
2104 | function setNamedNode(thing, predicate, value) {
|
2105 | const newThing = removeAll(thing, predicate);
|
2106 | const predicateNode = asNamedNode(predicate);
|
2107 | newThing.add(DataFactory.quad(toNode(newThing), predicateNode, value));
|
2108 | return newThing;
|
2109 | }
|
2110 | function setLiteral(thing, predicate, value) {
|
2111 | const newThing = removeAll(thing, predicate);
|
2112 | const predicateNode = asNamedNode(predicate);
|
2113 | newThing.add(DataFactory.quad(toNode(newThing), predicateNode, value));
|
2114 | return newThing;
|
2115 | }
|
2116 | function setLiteralOfType(thing, predicate, value, type) {
|
2117 | const literal = DataFactory.literal(value, type);
|
2118 | return setLiteral(thing, predicate, literal);
|
2119 | }
|
2120 |
|
2121 | /**
|
2122 | * Copyright 2020 Inrupt Inc.
|
2123 | *
|
2124 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
2125 | * of this software and associated documentation files (the "Software"), to deal in
|
2126 | * the Software without restriction, including without limitation the rights to use,
|
2127 | * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
2128 | * Software, and to permit persons to whom the Software is furnished to do so,
|
2129 | * subject to the following conditions:
|
2130 | *
|
2131 | * The above copyright notice and this permission notice shall be included in
|
2132 | * all copies or substantial portions of the Software.
|
2133 | *
|
2134 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
2135 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
2136 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
2137 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
2138 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
2139 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
2140 | */
|
2141 | /**
|
2142 | * Find out what Access Modes have been granted to a given Agent specifically for a given LitDataset.
|
2143 | *
|
2144 | * Keep in mind that this function will not tell you what access the given Agent has through other ACL rules, e.g. public or group-specific permissions.
|
2145 | *
|
2146 | * Also, please note that this function is still experimental: its API can change in non-major releases.
|
2147 | *
|
2148 | * @param dataset The LitDataset to which the given Agent may have been granted access.
|
2149 | * @param agent WebID of the Agent for which to retrieve what access it has to the Resource.
|
2150 | * @returns Which Access Modes have been granted to the Agent specifically for the given LitDataset, or `null` if it could not be determined (e.g. because the current user does not have Control Access to a given Resource or its Container).
|
2151 | */
|
2152 | function unstable_getAgentAccessModesOne(dataset, agent) {
|
2153 | if (unstable_hasResourceAcl(dataset)) {
|
2154 | const resourceAcl = unstable_getResourceAcl(dataset);
|
2155 | return unstable_getAgentResourceAccessModesOne(resourceAcl, agent);
|
2156 | }
|
2157 | if (unstable_hasFallbackAcl(dataset)) {
|
2158 | const fallbackAcl = unstable_getFallbackAcl(dataset);
|
2159 | return unstable_getAgentDefaultAccessModesOne(fallbackAcl, agent);
|
2160 | }
|
2161 | return null;
|
2162 | }
|
2163 | /**
|
2164 | * Find out what Access Modes have been granted to specific Agents for a given LitDataset.
|
2165 | *
|
2166 | * Keep in mind that this function will not tell you what access arbitrary Agents might have through other ACL rules, e.g. public or group-specific permissions.
|
2167 | *
|
2168 | * Also, please note that this function is still experimental: its API can change in non-major releases.
|
2169 | *
|
2170 | * @param dataset The LitDataset to which Agents may have been granted access.
|
2171 | * @returns Which Access Modes have been granted to which Agents specifically for the given LitDataset, or `null` if it could not be determined (e.g. because the current user does not have Control Access to a given Resource or its Container).
|
2172 | */
|
2173 | function unstable_getAgentAccessModesAll(dataset) {
|
2174 | if (unstable_hasResourceAcl(dataset)) {
|
2175 | const resourceAcl = unstable_getResourceAcl(dataset);
|
2176 | return unstable_getAgentResourceAccessModesAll(resourceAcl);
|
2177 | }
|
2178 | if (unstable_hasFallbackAcl(dataset)) {
|
2179 | const fallbackAcl = unstable_getFallbackAcl(dataset);
|
2180 | return unstable_getAgentDefaultAccessModesAll(fallbackAcl);
|
2181 | }
|
2182 | return null;
|
2183 | }
|
2184 | /**
|
2185 | * Given an ACL LitDataset, find out which access modes it provides to an Agent for its associated Resource.
|
2186 | *
|
2187 | * Keep in mind that this function will not tell you:
|
2188 | * - what access the given Agent has through other ACL rules, e.g. public or group-specific permissions.
|
2189 | * - what access the given Agent has to child Resources, in case the associated Resource is a Container.
|
2190 | *
|
2191 | * Also, please note that this function is still experimental: its API can change in non-major releases.
|
2192 | *
|
2193 | * @param aclDataset The LitDataset that contains Access-Control List rules.
|
2194 | * @param agent WebID of the Agent for which to retrieve what access it has to the Resource.
|
2195 | * @returns Which Access Modes have been granted to the Agent specifically for the Resource the given ACL LitDataset is associated with.
|
2196 | */
|
2197 | function unstable_getAgentResourceAccessModesOne(aclDataset, agent) {
|
2198 | const allRules = internal_getAclRules(aclDataset);
|
2199 | const resourceRules = internal_getResourceAclRulesForResource(allRules, aclDataset.accessTo);
|
2200 | const agentResourceRules = getAgentAclRulesForAgent(resourceRules, agent);
|
2201 | const agentAccessModes = agentResourceRules.map(internal_getAccessModes);
|
2202 | return internal_combineAccessModes(agentAccessModes);
|
2203 | }
|
2204 | /**
|
2205 | * Given an ACL LitDataset, find out which access modes it provides to specific Agents for the associated Resource.
|
2206 | *
|
2207 | * Keep in mind that this function will not tell you:
|
2208 | * - what access arbitrary Agents might have been given through other ACL rules, e.g. public or group-specific permissions.
|
2209 | * - what access arbitrary Agents have to child Resources, in case the associated Resource is a Container.
|
2210 | *
|
2211 | * Also, please note that this function is still experimental: its API can change in non-major releases.
|
2212 | *
|
2213 | * @param aclDataset The LitDataset that contains Access-Control List rules.
|
2214 | * @returns Which Access Modes have been granted to which Agents specifically for the Resource the given ACL LitDataset is associated with.
|
2215 | */
|
2216 | function unstable_getAgentResourceAccessModesAll(aclDataset) {
|
2217 | const allRules = internal_getAclRules(aclDataset);
|
2218 | const resourceRules = internal_getResourceAclRulesForResource(allRules, aclDataset.accessTo);
|
2219 | const agentResourceRules = getAgentAclRules(resourceRules);
|
2220 | return getAccessModesByAgent(agentResourceRules);
|
2221 | }
|
2222 | /**
|
2223 | * Given an ACL LitDataset, find out which access modes it provides to an Agent for the associated Container Resource's child Resources.
|
2224 | *
|
2225 | * Keep in mind that this function will not tell you:
|
2226 | * - what access the given Agent has through other ACL rules, e.g. public or group-specific permissions.
|
2227 | * - what access the given Agent has to Container Resource itself (see [[unstable_getAgentResourceAccessModesOne]] for that).
|
2228 | *
|
2229 | * Also, please note that this function is still experimental: its API can change in non-major releases.
|
2230 | *
|
2231 | * @param aclDataset The LitDataset that contains Access-Control List rules for a certain Container.
|
2232 | * @param agent WebID of the Agent for which to retrieve what access it has to the Container's children.
|
2233 | * @returns Which Access Modes have been granted to the Agent specifically for the children of the Container associated with the given ACL LitDataset.
|
2234 | */
|
2235 | function unstable_getAgentDefaultAccessModesOne(aclDataset, agent) {
|
2236 | const allRules = internal_getAclRules(aclDataset);
|
2237 | const resourceRules = internal_getDefaultAclRulesForResource(allRules, aclDataset.accessTo);
|
2238 | const agentResourceRules = getAgentAclRulesForAgent(resourceRules, agent);
|
2239 | const agentAccessModes = agentResourceRules.map(internal_getAccessModes);
|
2240 | return internal_combineAccessModes(agentAccessModes);
|
2241 | }
|
2242 | /**
|
2243 | * Given an ACL LitDataset, find out which access modes it provides to specific Agents for the associated Container Resource's child Resources.
|
2244 | *
|
2245 | * Keep in mind that this function will not tell you:
|
2246 | * - what access arbitrary Agents might have been given through other ACL rules, e.g. public or group-specific permissions.
|
2247 | * - what access arbitrary Agents have to the Container Resource itself (see [[unstable_getAgentResourceAccessModesAll]] for that).
|
2248 | *
|
2249 | * Also, please note that this function is still experimental: its API can change in non-major releases.
|
2250 | *
|
2251 | * @param aclDataset The LitDataset that contains Access-Control List rules.
|
2252 | * @returns Which Access Modes have been granted to which Agents specifically for the children of the Container associated with the given ACL LitDataset.
|
2253 | */
|
2254 | function unstable_getAgentDefaultAccessModesAll(aclDataset) {
|
2255 | const allRules = internal_getAclRules(aclDataset);
|
2256 | const resourceRules = internal_getDefaultAclRulesForResource(allRules, aclDataset.accessTo);
|
2257 | const agentResourceRules = getAgentAclRules(resourceRules);
|
2258 | return getAccessModesByAgent(agentResourceRules);
|
2259 | }
|
2260 | function getAgentAclRulesForAgent(aclRules, agent) {
|
2261 | return aclRules.filter((rule) => appliesToAgent(rule, agent));
|
2262 | }
|
2263 | function appliesToAgent(aclRule, agent) {
|
2264 | return getIriAll(aclRule, acl.agent).includes(agent);
|
2265 | }
|
2266 | function getAgentAclRules(aclRules) {
|
2267 | return aclRules.filter(isAgentAclRule);
|
2268 | }
|
2269 | function isAgentAclRule(aclRule) {
|
2270 | return getIriOne(aclRule, acl.agent) !== null;
|
2271 | }
|
2272 | function getAccessModesByAgent(aclRules) {
|
2273 | const agentAccess = {};
|
2274 | aclRules.forEach((rule) => {
|
2275 | const ruleAgents = getIriAll(rule, acl.agent);
|
2276 | const accessModes = internal_getAccessModes(rule);
|
2277 | // A rule might apply to multiple agents. If multiple rules apply to the same agent, the Access
|
2278 | // Modes granted by those rules should be combined:
|
2279 | ruleAgents.forEach((agent) => {
|
2280 | agentAccess[agent] =
|
2281 | typeof agentAccess[agent] === "undefined"
|
2282 | ? accessModes
|
2283 | : internal_combineAccessModes([agentAccess[agent], accessModes]);
|
2284 | });
|
2285 | });
|
2286 | return agentAccess;
|
2287 | }
|
2288 |
|
2289 | exports.addBoolean = addBoolean;
|
2290 | exports.addDatetime = addDatetime;
|
2291 | exports.addDecimal = addDecimal;
|
2292 | exports.addInteger = addInteger;
|
2293 | exports.addIri = addIri;
|
2294 | exports.addLiteral = addLiteral;
|
2295 | exports.addNamedNode = addNamedNode;
|
2296 | exports.addStringInLocale = addStringInLocale;
|
2297 | exports.addStringUnlocalized = addStringUnlocalized;
|
2298 | exports.addUrl = addUrl;
|
2299 | exports.asIri = asIri;
|
2300 | exports.asUrl = asUrl;
|
2301 | exports.createLitDataset = createLitDataset;
|
2302 | exports.createThing = createThing;
|
2303 | exports.fetchLitDataset = fetchLitDataset;
|
2304 | exports.getBooleanAll = getBooleanAll;
|
2305 | exports.getBooleanOne = getBooleanOne;
|
2306 | exports.getDatetimeAll = getDatetimeAll;
|
2307 | exports.getDatetimeOne = getDatetimeOne;
|
2308 | exports.getDecimalAll = getDecimalAll;
|
2309 | exports.getDecimalOne = getDecimalOne;
|
2310 | exports.getIntegerAll = getIntegerAll;
|
2311 | exports.getIntegerOne = getIntegerOne;
|
2312 | exports.getIriAll = getIriAll;
|
2313 | exports.getIriOne = getIriOne;
|
2314 | exports.getLiteralAll = getLiteralAll;
|
2315 | exports.getLiteralOne = getLiteralOne;
|
2316 | exports.getNamedNodeAll = getNamedNodeAll;
|
2317 | exports.getNamedNodeOne = getNamedNodeOne;
|
2318 | exports.getStringInLocaleAll = getStringInLocaleAll;
|
2319 | exports.getStringInLocaleOne = getStringInLocaleOne;
|
2320 | exports.getStringUnlocalizedAll = getStringUnlocalizedAll;
|
2321 | exports.getStringUnlocalizedOne = getStringUnlocalizedOne;
|
2322 | exports.getThingAll = getThingAll;
|
2323 | exports.getThingOne = getThingOne;
|
2324 | exports.getUrlAll = getUrlAll;
|
2325 | exports.getUrlOne = getUrlOne;
|
2326 | exports.removeAll = removeAll;
|
2327 | exports.removeBoolean = removeBoolean;
|
2328 | exports.removeDatetime = removeDatetime;
|
2329 | exports.removeDecimal = removeDecimal;
|
2330 | exports.removeInteger = removeInteger;
|
2331 | exports.removeIri = removeIri;
|
2332 | exports.removeLiteral = removeLiteral;
|
2333 | exports.removeNamedNode = removeNamedNode;
|
2334 | exports.removeStringInLocale = removeStringInLocale;
|
2335 | exports.removeStringUnlocalized = removeStringUnlocalized;
|
2336 | exports.removeThing = removeThing;
|
2337 | exports.removeUrl = removeUrl;
|
2338 | exports.saveLitDatasetAt = saveLitDatasetAt;
|
2339 | exports.saveLitDatasetInContainer = saveLitDatasetInContainer;
|
2340 | exports.setBoolean = setBoolean;
|
2341 | exports.setDatetime = setDatetime;
|
2342 | exports.setDecimal = setDecimal;
|
2343 | exports.setInteger = setInteger;
|
2344 | exports.setIri = setIri;
|
2345 | exports.setLiteral = setLiteral;
|
2346 | exports.setNamedNode = setNamedNode;
|
2347 | exports.setStringInLocale = setStringInLocale;
|
2348 | exports.setStringUnlocalized = setStringUnlocalized;
|
2349 | exports.setThing = setThing;
|
2350 | exports.setUrl = setUrl;
|
2351 | exports.unstable_deleteFile = unstable_deleteFile;
|
2352 | exports.unstable_fetchFile = unstable_fetchFile;
|
2353 | exports.unstable_fetchLitDatasetWithAcl = unstable_fetchLitDatasetWithAcl;
|
2354 | exports.unstable_getAgentAccessModesAll = unstable_getAgentAccessModesAll;
|
2355 | exports.unstable_getAgentAccessModesOne = unstable_getAgentAccessModesOne;
|
2356 | exports.unstable_getAgentDefaultAccessModesAll = unstable_getAgentDefaultAccessModesAll;
|
2357 | exports.unstable_getAgentDefaultAccessModesOne = unstable_getAgentDefaultAccessModesOne;
|
2358 | exports.unstable_getAgentResourceAccessModesAll = unstable_getAgentResourceAccessModesAll;
|
2359 | exports.unstable_getAgentResourceAccessModesOne = unstable_getAgentResourceAccessModesOne;
|
2360 | exports.unstable_getFallbackAcl = unstable_getFallbackAcl;
|
2361 | exports.unstable_getResourceAcl = unstable_getResourceAcl;
|
2362 | exports.unstable_hasFallbackAcl = unstable_hasFallbackAcl;
|
2363 | exports.unstable_hasResourceAcl = unstable_hasResourceAcl;
|
2364 | exports.unstable_overwriteFile = unstable_overwriteFile;
|
2365 | exports.unstable_saveFileInContainer = unstable_saveFileInContainer;
|