Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The following changes are pending, and will be applied on the next major release

### Patch changes

- `getThing` now supports Blank Node identifiers in addition to IRIs and skolems to refer to a subject.
- `getThingAll(dataset, { allowacceptBlankNodes: true })` now returns all Blank Nodes
subjects in the Dataset, in particular including those part of a single chain of
predicates. For instance, given the following dataset:
Expand Down
21 changes: 20 additions & 1 deletion src/thing/thing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ import {
import type { WithAcl } from "../acl/acl";
import { mockSolidDatasetFrom } from "../resource/mock";
import { internal_setAcl } from "../acl/acl.internal";
import type { LocalNodeIri } from "../rdf.internal";
import type { BlankNodeId, LocalNodeIri } from "../rdf.internal";
import { localNodeSkolemPrefix } from "../rdf.internal";

describe("createThing", () => {
Expand Down Expand Up @@ -153,6 +153,16 @@ describe("getThing", () => {
},
},
};
const mockBlankNodeThingId: BlankNodeId = "_:0";
const mockBlankNodeThing: Thing = {
type: "Subject",
url: mockBlankNodeThingId,
predicates: {
"https://arbitrary.vocab/predicate": {
namedNodes: ["https://arbitrary.vocab/predicate"],
},
},
};
function getMockDataset(
things = [mockThing1, mockThing2],
otherGraphThings = [mockThing1],
Expand Down Expand Up @@ -286,6 +296,15 @@ describe("getThing", () => {

expect(thrownError).toBeInstanceOf(ValidThingUrlExpectedError);
});

it("accepts blank nodes identifiers", () => {
const thing = getThing(
getMockDataset([mockBlankNodeThing]),
mockBlankNodeThingId,
);

expect(thing).toStrictEqual(mockBlankNodeThing);
});
});

describe("getThingAll", () => {
Expand Down
12 changes: 7 additions & 5 deletions src/thing/thing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// There are multiple classes in this file for legacy reasons.
/* eslint-disable max-classes-per-file */
import { v4 as uuidv4 } from "uuid";
import {
isNamedNode,
Expand All @@ -42,7 +44,7 @@ import {
internal_addDeletionsToChangeLog,
internal_getReadableValue,
} from "./thing.internal";
import type { LocalNodeIri } from "../rdf.internal";
import type { BlankNodeId, LocalNodeIri } from "../rdf.internal";
import {
freeze,
getLocalNodeIri,
Expand Down Expand Up @@ -77,22 +79,22 @@ export function getThing(
): ThingLocal | null;
export function getThing(
solidDataset: SolidDataset,
thingUrl: UrlString | Url | LocalNodeIri,
thingUrl: UrlString | Url | LocalNodeIri | BlankNodeId,
options?: GetThingOptions,
): Thing | null;
/**
* Extract Quads with a given Subject from a [[SolidDataset]] into a [[Thing]].
*
* @param solidDataset The [[SolidDataset]] to extract the [[Thing]] from.
* @param thingUrl The URL of the desired [[Thing]].
* @param thingUrl The identifier of the desired [[Thing]] (URL or Blank Node identifier).
* @param options Not yet implemented.
*/
export function getThing(
solidDataset: SolidDataset,
thingUrl: UrlString | Url | LocalNodeIri,
thingUrl: UrlString | Url | LocalNodeIri | BlankNodeId,
options: GetThingOptions = {},
): Thing | null {
if (!internal_isValidUrl(thingUrl)) {
if (!internal_isValidUrl(thingUrl) && !thingUrl.match(/^_:/)) {
throw new ValidThingUrlExpectedError(thingUrl);
}

Expand Down