UNPKG

@inrupt/solid-client

Version:
224 lines (221 loc) • 11.6 kB
import { internal_isValidUrl, asNamedNode, isNamedNode, normalizeLocale, isLiteral, deserializeBoolean, xmlSchemaTypes, deserializeDatetime, deserializeDecimal, deserializeInteger } from '../datatypes.mjs'; import { DataFactory } from '../rdfjs.mjs'; import { internal_throwIfNotThing, internal_filterThing } from './thing.internal.mjs'; import { ValidPropertyUrlExpectedError, isThing, ValidValueUrlExpectedError, asIri } from './thing.mjs'; /** * Copyright 2020 Inrupt Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the * Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ function removeAll(thing, property) { internal_throwIfNotThing(thing); if (!internal_isValidUrl(property)) { throw new ValidPropertyUrlExpectedError(property); } const predicateNode = asNamedNode(property); const updatedThing = internal_filterThing(thing, (quad) => !quad.predicate.equals(predicateNode)); return updatedThing; } /** * Create a new Thing with the given URL removed for the given Property. * * The original `thing` is not modified; this function returns a cloned Thing with updated values. * * @param thing Thing to remove a URL value from. * @param property Property for which to remove the given URL value. * @param value URL to remove from `thing` for the given `Property`. * @returns A new Thing equal to the input Thing with the given value removed for the given Property. */ const removeUrl = (thing, property, value) => { internal_throwIfNotThing(thing); if (!internal_isValidUrl(property)) { throw new ValidPropertyUrlExpectedError(property); } const predicateNode = asNamedNode(property); if (!isThing(value) && !internal_isValidUrl(value)) { throw new ValidValueUrlExpectedError(value); } const iriNode = isNamedNode(value) ? value : typeof value === "string" ? asNamedNode(value) : asNamedNode(asIri(value)); const updatedThing = internal_filterThing(thing, (quad) => { return (!quad.predicate.equals(predicateNode) || !isNamedNode(quad.object) || !quad.object.equals(iriNode)); }); return updatedThing; }; /** @hidden Alias of [[removeUrl]] for those who prefer IRI terminology. */ const removeIri = removeUrl; /** * Create a new Thing with the given boolean removed for the given Property. * * The original `thing` is not modified; this function returns a cloned Thing with updated values. * * @param thing Thing to remove a boolean value from. * @param property Property for which to remove the given boolean value. * @param value Boolean to remove from `thing` for the given `property`. * @returns A new Thing equal to the input Thing with the given value removed for the given Property. */ const removeBoolean = (thing, property, value) => { internal_throwIfNotThing(thing); return removeLiteralMatching(thing, property, xmlSchemaTypes.boolean, (foundBoolean) => deserializeBoolean(foundBoolean) === value); }; /** * Create a new Thing with the given datetime removed for the given Property. * * The original `thing` is not modified; this function returns a cloned Thing with updated values. * * @param thing Thing to remove a datetime value from. * @param property Property for which to remove the given datetime value. * @param value Datetime to remove from `thing` for the given `property`. * @returns A new Thing equal to the input Thing with the given value removed for the given Property. */ const removeDatetime = (thing, property, value) => { internal_throwIfNotThing(thing); return removeLiteralMatching(thing, property, xmlSchemaTypes.dateTime, (foundDatetime) => { var _a; return ((_a = deserializeDatetime(foundDatetime)) === null || _a === void 0 ? void 0 : _a.getTime()) === value.getTime(); }); }; /** * Create a new Thing with the given decimal removed for the given Property. * * The original `thing` is not modified; this function returns a cloned Thing with updated values. * * @param thing Thing to remove a decimal value from. * @param property Property for which to remove the given decimal value. * @param value Decimal to remove from `thing` for the given `property`. * @returns A new Thing equal to the input Thing with the given value removed for the given Property. */ const removeDecimal = (thing, property, value) => { internal_throwIfNotThing(thing); return removeLiteralMatching(thing, property, xmlSchemaTypes.decimal, (foundDecimal) => deserializeDecimal(foundDecimal) === value); }; /** * Create a new Thing with the given integer removed for the given Property. * * The original `thing` is not modified; this function returns a cloned Thing with updated values. * * @param thing Thing to remove an integer value from. * @param property Property for which to remove the given integer value. * @param value Integer to remove from `thing` for the given `property`. * @returns A new Thing equal to the input Thing with the given value removed for the given Property. */ const removeInteger = (thing, property, value) => { internal_throwIfNotThing(thing); return removeLiteralMatching(thing, property, xmlSchemaTypes.integer, (foundInteger) => deserializeInteger(foundInteger) === value); }; /** * Create a new Thing with the given localised string removed for the given Property. * * The original `thing` is not modified; this function returns a cloned Thing with updated values. * * @param thing Thing to remove a localised string value from. * @param property Property for which to remove the given localised string value. * @param value String to remove from `thing` for the given `property`. * @param locale Locale of the string to remove. * @returns A new Thing equal to the input Thing with the given value removed for the given Property. */ function removeStringWithLocale(thing, property, value, locale) { internal_throwIfNotThing(thing); // Note: Due to how the `DataFactory.literal` constructor behaves, this function // must call directly `removeLiteral` directly, with the locale as the data // type of the Literal (which is not a valid NamedNode). return removeLiteral(thing, property, DataFactory.literal(value, normalizeLocale(locale))); } /** * Create a new Thing with the given unlocalised string removed for the given Property. * * The original `thing` is not modified; this function returns a cloned Thing with updated values. * * @param thing Thing to remove an unlocalised string value from. * @param property Property for which to remove the given string value. * @param value String to remove from `thing` for the given `property`. * @returns A new Thing equal to the input Thing with the given value removed for the given Property. */ const removeStringNoLocale = (thing, property, value) => { internal_throwIfNotThing(thing); return removeLiteralMatching(thing, property, xmlSchemaTypes.string, (foundString) => foundString === value); }; /** * @ignore This should not be needed due to the other remove*() functions. If you do find yourself needing it, please file a feature request for your use case. * @param thing Thing to remove a NamedNode value from. * @param property Property for which to remove the given NamedNode value. * @param value NamedNode to remove from `thing` for the given `property`. * @returns A new Thing equal to the input Thing with the given value removed for the given Property. */ function removeNamedNode(thing, property, value) { internal_throwIfNotThing(thing); if (!internal_isValidUrl(property)) { throw new ValidPropertyUrlExpectedError(property); } const predicateNode = asNamedNode(property); const updatedThing = internal_filterThing(thing, (quad) => { return (!quad.predicate.equals(predicateNode) || !isNamedNode(quad.object) || !quad.object.equals(value)); }); return updatedThing; } /** * @ignore This should not be needed due to the other remove*() functions. If you do find yourself needing it, please file a feature request for your use case. * @param thing Thing to remove a Literal value from. * @param property Property for which to remove the given Literal value. * @param value Literal to remove from `thing` for the given `property`. * @returns A new Thing equal to the input Thing with the given value removed for the given Property. */ function removeLiteral(thing, property, value) { internal_throwIfNotThing(thing); if (!internal_isValidUrl(property)) { throw new ValidPropertyUrlExpectedError(property); } const predicateNode = asNamedNode(property); const updatedThing = internal_filterThing(thing, (quad) => { return (!quad.predicate.equals(predicateNode) || !isLiteral(quad.object) || !quad.object.equals(value)); }); return updatedThing; } /** * @param thing Thing to remove a Literal value from. * @param property Property for which to remove the given Literal value. * @param type Data type that the Literal should be stored as. * @param matcher Function that returns true if the given value is an equivalent serialisation of the value to remove. For example, when removing a `false` boolean, the matcher should return true for both "0" and "false". */ function removeLiteralMatching(thing, property, type, matcher) { if (!internal_isValidUrl(property)) { throw new ValidPropertyUrlExpectedError(property); } const predicateNode = asNamedNode(property); const updatedThing = internal_filterThing(thing, (quad) => { // Copy every value from the old thing into the new thing, unless it: return !( // has the predicate of the value-to-be-removed, (quad.predicate.equals(predicateNode) && // also is a literal isLiteral(quad.object) && // of the same type as the value-to-be-removed, quad.object.datatype.equals(DataFactory.namedNode(type)) && // and has a value determined to be equal to the value-to-be-removed // by the given matcher (i.e. because their serialisations are equal): matcher(quad.object.value))); }); return updatedThing; } export { removeAll, removeBoolean, removeDatetime, removeDecimal, removeInteger, removeIri, removeLiteral, removeNamedNode, removeStringNoLocale, removeStringWithLocale, removeUrl };