Skip to content

Commit

Permalink
Add ActorExtractLinksHeaders for following auxiliary resources in Solid
Browse files Browse the repository at this point in the history
  • Loading branch information
wdantuma authored Apr 11, 2024
1 parent ffb72b3 commit 66181c0
Show file tree
Hide file tree
Showing 10 changed files with 207 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"ccqslt:config/config-solid-base.json",
"ccqslt:config/extract-links/actors/predicates-common.json",
"ccqslt:config/extract-links/actors/predicates-ldp.json",
"ccqslt:config/extract-links/actors/links-describedby.json",
"ccqslt:config/extract-links/actors/predicates-solidstorage.json",
"ccqslt:config/extract-links/actors/quad-pattern-query.json",
"ccqslt:config/extract-links/actors/solid-type-index-noinference.json"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"@context": [
"https://linkedsoftwaredependencies.org/bundles/npm/@comunica/runner/^3.0.0/components/context.jsonld",

"https://linkedsoftwaredependencies.org/bundles/npm/@comunica/actor-extract-links-headers/^0.0.0/components/context.jsonld"
],
"@id": "urn:comunica:default:Runner",
"@type": "Runner",
"actors": [
{
"@id": "urn:comunica:default:extract-links/actors#links-describedby",
"@type": "ActorExtractLinksHeaders",
"headersRegexes": [
"rel=\"describedby\""
]
}
]
}
1 change: 1 addition & 0 deletions engines/query-sparql-link-traversal-solid/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"@comunica/actor-context-preprocess-set-defaults-link-traversal": "^0.3.0",
"@comunica/actor-extract-links-all": "^0.3.0",
"@comunica/actor-extract-links-content-policies": "^0.3.0",
"@comunica/actor-extract-links-headers": "^0.3.0",
"@comunica/actor-extract-links-predicates": "^0.3.0",
"@comunica/actor-extract-links-quad-pattern": "^0.3.0",
"@comunica/actor-extract-links-quad-pattern-query": "^0.3.0",
Expand Down
1 change: 1 addition & 0 deletions engines/query-sparql-link-traversal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"@comunica/actor-context-preprocess-set-defaults-link-traversal": "^0.3.0",
"@comunica/actor-extract-links-all": "^0.3.0",
"@comunica/actor-extract-links-content-policies": "^0.3.0",
"@comunica/actor-extract-links-headers": "^0.3.0",
"@comunica/actor-extract-links-predicates": "^0.3.0",
"@comunica/actor-extract-links-quad-pattern": "^0.3.0",
"@comunica/actor-extract-links-quad-pattern-query": "^0.3.0",
Expand Down
Empty file.
43 changes: 43 additions & 0 deletions packages/actor-extract-links-headers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Comunica Headers Extract Links Actor

[![npm version](https://badge.fury.io/js/%40comunica%2Factor-extract-links-headers.svg)](https://www.npmjs.com/package/@comunica/actor-extract-links-headers)

An [RDF Metadata Extract](https://github.com/comunica/comunica/tree/master/packages/bus-extract-links) actor that
collects all links headers that match with any of the configured regular expressions.

This module is part of the [Comunica framework](https://github.com/comunica/comunica),
and should only be used by [developers that want to build their own query engine](https://comunica.dev/docs/modify/).

[Click here if you just want to query with Comunica](https://comunica.dev/docs/query/).

## Install

```bash
$ yarn add @comunica/actor-extract-links-headers
```

## Configure

After installing, this package can be added to your engine's configuration as follows:
```text
{
"@context": [
...
"https://linkedsoftwaredependencies.org/bundles/npm/@comunica/actor-extract-links-headers/^1.0.0/components/context.jsonld"
],
"actors": [
...
{
"@id": "urn:comunica:default:extract-links/actors#headers",
"@type": "ActorExtractLinksHeaders"
"headersRegexes": [
"rel=\"describedby\""
]
}
]
}
```

### Config Parameters

* `headersRegexes`: An array of regular expressions that will be matched with incoming link headers.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { IActionExtractLinks, IActorExtractLinksOutput } from '@comunica/bus-extract-links';
import { ActorExtractLinks } from '@comunica/bus-extract-links';
import type { ILink } from '@comunica/bus-rdf-resolve-hypermedia-links';
import type { IActorArgs, IActorTest } from '@comunica/core';

/**
* A comunica Traverse Predicates RDF Link Header Actor.
*/
export class ActorExtractLinksHeaders extends ActorExtractLinks {
private readonly headers: RegExp[];
private readonly linkRegEx = /<(.*)>/u;

public constructor(args: IActorExtractLinksTraverseHeadersArgs) {
super(args);
this.headers = args.headersRegexes.map(stringRegex => new RegExp(stringRegex, 'u'));
}

public async test(_action: IActionExtractLinks): Promise<IActorTest> {
return true;
}

public async run(action: IActionExtractLinks): Promise<IActorExtractLinksOutput> {
return new Promise((resolve, _reject) => {
const headers = action.headers;
const links: ILink[] = [];

for (const regex of this.headers) {
const linkHeaders = headers?.get('link')?.split(',');
if (linkHeaders) {
for (const header of linkHeaders) {
if (regex.test(header)) {
const match = this.linkRegEx.exec(header);
if (match) {
links.push({ url: new URL(match[1], action.url).href });
}
}
}
}
}
resolve({ links });
});
}
}

export interface IActorExtractLinksTraverseHeadersArgs
extends IActorArgs<IActionExtractLinks, IActorTest, IActorExtractLinksOutput> {
headersRegexes: string[];
}
1 change: 1 addition & 0 deletions packages/actor-extract-links-headers/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ActorExtractLinksHeaders';
44 changes: 44 additions & 0 deletions packages/actor-extract-links-headers/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "@comunica/actor-extract-links-headers",
"version": "0.3.0",
"description": "A headers extract-links actor",
"lsd:module": true,
"license": "MIT",
"homepage": "https://comunica.dev/",
"repository": {
"type": "git",
"url": "https://github.com/comunica/comunica.git",
"directory": "packages/actor-extract-links-headers"
},
"publishConfig": {
"access": "public"
},
"bugs": {
"url": "https://github.com/comunica/comunica/issues"
},
"keywords": [
"comunica",
"actor",
"extract-links",
"headers"
],
"sideEffects": false,
"main": "lib/index.js",
"typings": "lib/index",
"files": [
"components",
"lib/**/*.d.ts",
"lib/**/*.js",
"lib/**/*.js.map"
],
"scripts": {
"build": "npm run build:ts && npm run build:components",
"build:ts": "node \"../../node_modules/typescript/bin/tsc\"",
"build:components": "componentsjs-generator"
},
"dependencies": {
"@comunica/bus-extract-links": "^0.3.0",
"@comunica/bus-rdf-resolve-hypermedia-links": "^3.0.1",
"@comunica/core": "^3.0.1"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type { Readable } from 'node:stream';
import { ActionContext, Bus } from '@comunica/core';
import { ActorExtractLinksHeaders } from '../lib/ActorExtractLinksHeaders';

const quad = require('rdf-quad');
const stream = require('streamify-array');

describe('ActorExtractLinksHeaders', () => {
let bus: any;

beforeEach(() => {
bus = new Bus({ name: 'bus' });
});

describe('An ActorExtractLinksHeaders instance with check subject', () => {
let actor: ActorExtractLinksHeaders;
let inputMetadata: Readable;
let input: Headers;

beforeEach(() => {
actor = new ActorExtractLinksHeaders({
name: 'actor',
bus,
headersRegexes: [
'rel="describedby"',
],
});
inputMetadata = stream([]);
input = new Headers();
input.append('Content-Type', 'text-turtle');
input.append('Location', '/storage/resource');
input.append('Content-Length', '1024');
input.append('Link', '</storage/resource.meta>;rel="describedby"');
});

it('should test ', async() => {
await expect(actor.test({ url: 'http://pod.example.com/storage/resource', metadata: inputMetadata, headers: input, requestTime: 0, context: new ActionContext() }))
.resolves.toBe(true);
});

it('should run on headers and return all describedby values', async() => {
await expect(actor.run({ url: 'http://pod.example.com/storage/resource', metadata: inputMetadata, headers: input, requestTime: 0, context: new ActionContext() })).resolves
.toEqual({
links: [
{ url: 'http://pod.example.com/storage/resource.meta' },
],
});
});
});
});

0 comments on commit 66181c0

Please sign in to comment.