diff --git a/package-lock.json b/package-lock.json index da0f3f9f..017da32c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1291,6 +1291,16 @@ "type-detect": "4.0.8" } }, + "@tpluscode/rdf-ns-builders": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@tpluscode/rdf-ns-builders/-/rdf-ns-builders-0.1.0.tgz", + "integrity": "sha512-HxcNaUSZZOIBS8pdYiyRodFejLCcrleCMc/b8qdHA8bw830u5JOomSBZKRgylEAaps69G7PQPWtwvAEFSPRcKQ==", + "requires": { + "@rdfjs/namespace": "^1.1.0", + "@types/rdf-js": "^2.0.11", + "@types/rdfjs__namespace": "^1.1.1" + } + }, "@types/accepts": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", @@ -1628,7 +1638,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/rdfjs__namespace/-/rdfjs__namespace-1.1.1.tgz", "integrity": "sha512-IgPTKBbKC4Hm5j7kO9XpJMtWMXCRc9x308VD/e/ibdDiaSc27c7dzwPtgQeWUK0q1IQ5hobOAuHZVvlhIH8eMg==", - "dev": true, "requires": { "@types/rdf-js": "*" } diff --git a/package.json b/package.json index 61a71f29..7d2c0124 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,9 @@ "@koa/cors": "^3.0.0", "@koa/router": "^8.0.8", "@rdfjs/data-model": "^1.1.2", - "@rdfjs/namespace": "^1.1.0", "@rdfjs/parser-jsonld": "^1.2.0", "@rdfjs/serializer-jsonld-ext": "^2.0.0", + "@tpluscode/rdf-ns-builders": "^0.1.0", "clownface": "^0.12.1", "content-type": "^1.0.4", "format-link-header": "^3.0.0", @@ -45,7 +45,6 @@ "@types/rdf-dataset-ext": "^1.0.0", "@types/rdf-dataset-indexed": "^0.4.3", "@types/rdf-js": "^2.0.11", - "@types/rdfjs__namespace": "^1.1.1", "@types/rdfjs__parser-jsonld": "^1.2.2", "@types/rdfjs__serializer-jsonld-ext": "^2.0.2", "@types/supertest": "^2.0.8", diff --git a/src/adaptors/in-memory-articles.ts b/src/adaptors/in-memory-articles.ts index 140384f7..05041076 100644 --- a/src/adaptors/in-memory-articles.ts +++ b/src/adaptors/in-memory-articles.ts @@ -1,10 +1,10 @@ +import { rdf, schema } from '@tpluscode/rdf-ns-builders'; import { DatasetCore, NamedNode, Quad, Quad_Object as QuadObject, } from 'rdf-js'; import Articles from '../articles'; import ArticleNotFound from '../errors/article-not-found'; import NotAnArticle from '../errors/not-an-article'; -import { rdf, schema } from '../namespaces'; export default class InMemoryArticles implements Articles { private articles: { [id: string]: [NamedNode, DatasetCore] } = {}; diff --git a/src/adaptors/postgres-articles.ts b/src/adaptors/postgres-articles.ts index 31504dab..9d5b025e 100644 --- a/src/adaptors/postgres-articles.ts +++ b/src/adaptors/postgres-articles.ts @@ -1,5 +1,6 @@ import ParserJsonld from '@rdfjs/parser-jsonld'; import SerializerJsonld from '@rdfjs/serializer-jsonld-ext'; +import { rdf, schema } from '@tpluscode/rdf-ns-builders'; import { JsonLdObj } from 'jsonld/jsonld-spec'; import pEvent from 'p-event'; import { @@ -15,7 +16,6 @@ import Articles from '../articles'; import ArticleNotFound from '../errors/article-not-found'; import NotAnArticle from '../errors/not-an-article'; import { ExtendedDataFactory } from '../middleware/dataset'; -import { rdf, schema } from '../namespaces'; const { QueryResultError, queryResultErrorCode: { noData } } = errors; diff --git a/src/app.ts b/src/app.ts index f2f9845b..64b3f493 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,5 +1,8 @@ import cors from '@koa/cors'; import Router, { RouterContext } from '@koa/router'; +import { + hydra, owl, rdf, schema, +} from '@tpluscode/rdf-ns-builders'; import Koa, { DefaultState, Middleware } from 'koa'; import logger from 'koa-logger'; import Articles from './articles'; @@ -10,7 +13,6 @@ import emptyResponse from './middleware/empty-response'; import errorHandler from './middleware/error-handler'; import jsonld from './middleware/jsonld'; import routing from './middleware/routing'; -import namespaces from './namespaces'; export type AppState = DefaultState; @@ -44,7 +46,10 @@ export default ( app.use(addDatasets()); app.use(jsonld({ '@language': 'en', - ...namespaces, + hydra: hydra().value, + owl: owl().value, + rdf: rdf().value, + schema: schema().value, })); app.use(apiDocumentationLink(apiDocumentationPath)); app.use(errorHandler()); diff --git a/src/errors/not-an-article.ts b/src/errors/not-an-article.ts index fbd6de24..3c69d42f 100644 --- a/src/errors/not-an-article.ts +++ b/src/errors/not-an-article.ts @@ -1,6 +1,6 @@ +import { schema } from '@tpluscode/rdf-ns-builders'; import { Quad_Object as QuadObject } from 'rdf-js'; import { termToString } from 'rdf-string'; -import { schema } from '../namespaces'; export default class NotAnArticle extends Error { readonly types: Array; diff --git a/src/middleware/error-handler.ts b/src/middleware/error-handler.ts index eacf477f..6f61dcd9 100644 --- a/src/middleware/error-handler.ts +++ b/src/middleware/error-handler.ts @@ -1,7 +1,7 @@ +import { hydra, rdf } from '@tpluscode/rdf-ns-builders'; import createHttpError, { HttpError } from 'http-errors'; import { ExtendableContext, Next } from 'koa'; import { Middleware } from 'koa-compose'; -import { hydra, rdf } from '../namespaces'; import { DatasetContext } from './dataset'; const handleHttpError = ( diff --git a/src/namespaces.ts b/src/namespaces.ts deleted file mode 100644 index 34c10de3..00000000 --- a/src/namespaces.ts +++ /dev/null @@ -1,15 +0,0 @@ -import namespace from '@rdfjs/namespace'; - -const namespaces = { - hydra: 'http://www.w3.org/ns/hydra/core#', - owl: 'http://www.w3.org/2002/07/owl#', - rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', - schema: 'http://schema.org/', -} as const; - -export const hydra = namespace(namespaces.hydra); -export const owl = namespace(namespaces.owl); -export const rdf = namespace(namespaces.rdf); -export const schema = namespace(namespaces.schema); - -export default namespaces; diff --git a/src/routes/add-article.ts b/src/routes/add-article.ts index 18901032..f8760d42 100644 --- a/src/routes/add-article.ts +++ b/src/routes/add-article.ts @@ -1,3 +1,4 @@ +import { rdf, schema } from '@tpluscode/rdf-ns-builders'; import clownface from 'clownface'; import createHttpError from 'http-errors'; import { CREATED } from 'http-status-codes'; @@ -7,7 +8,6 @@ import { termToString } from 'rdf-string'; import uniqueString from 'unique-string'; import url from 'url'; import { AppContext, AppMiddleware } from '../app'; -import { rdf, schema } from '../namespaces'; import Routes from './index'; export default (): AppMiddleware => ( @@ -24,8 +24,8 @@ export default (): AppMiddleware => ( throw new createHttpError.BadRequest(`Article must have a blank node identifier (${termToString(id)} given)`); } - if (request.dataset.match(id, schema('name')).size === 0) { - throw new createHttpError.BadRequest(`Article must have at least one ${termToString(schema('name'))}`); + if (request.dataset.match(id, schema.name).size === 0) { + throw new createHttpError.BadRequest(`Article must have at least one ${termToString(schema.name)}`); } const newId = namedNode(url.resolve(request.origin, router.url(Routes.Article, uniqueString()))); diff --git a/src/routes/api-documentation.ts b/src/routes/api-documentation.ts index 85ed08e7..337796c6 100644 --- a/src/routes/api-documentation.ts +++ b/src/routes/api-documentation.ts @@ -1,3 +1,6 @@ +import { + hydra, owl, rdf, schema, +} from '@tpluscode/rdf-ns-builders'; import clownface, { Clownface } from 'clownface'; import { CREATED, OK } from 'http-status-codes'; import { Next } from 'koa'; @@ -5,9 +8,6 @@ import { NamedNode } from 'rdf-js'; import { toRdf } from 'rdf-literal'; import url from 'url'; import { AppContext, AppMiddleware } from '../app'; -import { - hydra, owl, rdf, schema, -} from '../namespaces'; import Routes from './index'; export default (): AppMiddleware => ( @@ -40,7 +40,7 @@ export default (): AppMiddleware => ( entryPoint.addOut(hydra.supportedProperty, (name: Clownface): void => { name.addOut(rdf.type, hydra.SupportedProperty); name.addOut(hydra.title, literal('Name', 'en')); - name.addOut(hydra.property, schema('name'), (property: Clownface): void => { + name.addOut(hydra.property, schema.name, (property: Clownface): void => { property.addOut(rdf.type, rdf.Property); }); name.addOut(hydra.required, true); @@ -56,7 +56,7 @@ export default (): AppMiddleware => ( article.addOut(hydra.supportedProperty, (name: Clownface): void => { name.addOut(rdf.type, hydra.SupportedProperty); name.addOut(hydra.title, literal('Name', 'en')); - name.addOut(hydra.property, schema('name'), (property: Clownface): void => { + name.addOut(hydra.property, schema.name, (property: Clownface): void => { property.addOut(rdf.type, rdf.Property); }); name.addOut(hydra.required, true); diff --git a/src/routes/article-list.ts b/src/routes/article-list.ts index c0ef2314..03b36956 100644 --- a/src/routes/article-list.ts +++ b/src/routes/article-list.ts @@ -1,3 +1,4 @@ +import { hydra, rdf, schema } from '@tpluscode/rdf-ns-builders'; import clownface, { Clownface } from 'clownface'; import { OK } from 'http-status-codes'; import all from 'it-all'; @@ -7,7 +8,6 @@ import { DatasetCore, NamedNode } from 'rdf-js'; import { toRdf } from 'rdf-literal'; import url from 'url'; import { AppContext, AppMiddleware } from '../app'; -import { hydra, rdf, schema } from '../namespaces'; import Routes from './index'; export default (): AppMiddleware => ( diff --git a/src/routes/entry-point.ts b/src/routes/entry-point.ts index 01f6ea53..692bc4a5 100644 --- a/src/routes/entry-point.ts +++ b/src/routes/entry-point.ts @@ -1,10 +1,10 @@ +import { hydra, rdf, schema } from '@tpluscode/rdf-ns-builders'; import clownface, { Clownface } from 'clownface'; import { OK } from 'http-status-codes'; import { Next } from 'koa'; import { NamedNode } from 'rdf-js'; import url from 'url'; import { AppContext, AppMiddleware } from '../app'; -import { hydra, rdf, schema } from '../namespaces'; import Routes from './index'; export default (): AppMiddleware => ( @@ -19,7 +19,7 @@ export default (): AppMiddleware => ( }); graph.addOut(rdf.type, schema.EntryPoint); - graph.addOut(schema('name'), literal('Article Store', 'en')); + graph.addOut(schema.name, literal('Article Store', 'en')); graph.addOut(hydra.collection, createNamedNode(Routes.ArticleList), (list: Clownface): void => { list.addOut(rdf.type, hydra.Collection); }); diff --git a/test/adaptors/in-memory-articles.test.ts b/test/adaptors/in-memory-articles.test.ts index 16f18438..e12bd12d 100644 --- a/test/adaptors/in-memory-articles.test.ts +++ b/test/adaptors/in-memory-articles.test.ts @@ -2,10 +2,10 @@ import { literal, namedNode, quad } from '@rdfjs/data-model'; import all from 'it-all'; import 'jest-rdf'; import { DatasetCore, NamedNode } from 'rdf-js'; +import { schema } from '@tpluscode/rdf-ns-builders'; import InMemoryArticles from '../../src/adaptors/in-memory-articles'; import ArticleNotFound from '../../src/errors/article-not-found'; import NotAnArticle from '../../src/errors/not-an-article'; -import { schema } from '../../src/namespaces'; import createArticle from '../create-article'; describe('in-memory articles', (): void => { @@ -37,7 +37,7 @@ describe('in-memory articles', (): void => { await articles.set(id, createArticle({ id, name: literal('Original') })); await articles.set(id, createArticle({ id, name: literal('Updated') })); - expect(await articles.get(id)).toBeRdfDatasetContaining(quad(id, schema('name'), literal('Updated'))); + expect(await articles.get(id)).toBeRdfDatasetContaining(quad(id, schema.name, literal('Updated'))); }); it('throws an error if it is not an article', async (): Promise => { diff --git a/test/adaptors/postgres-articles.test.ts b/test/adaptors/postgres-articles.test.ts index 8342092c..1a240387 100644 --- a/test/adaptors/postgres-articles.test.ts +++ b/test/adaptors/postgres-articles.test.ts @@ -3,12 +3,12 @@ import all from 'it-all'; import 'jest-rdf'; import pgPromise, { IBaseProtocol, IMain } from 'pg-promise'; import { DatasetCore, NamedNode } from 'rdf-js'; +import { schema } from '@tpluscode/rdf-ns-builders'; import PostgresArticles from '../../src/adaptors/postgres-articles'; import dataFactory from '../../src/data-factory'; import db from '../../src/db'; import ArticleNotFound from '../../src/errors/article-not-found'; import NotAnArticle from '../../src/errors/not-an-article'; -import { schema } from '../../src/namespaces'; import createArticle from '../create-article'; let postgresPromise: IMain; @@ -59,7 +59,7 @@ describe('postgres articles', (): void => { await articles.set(id, createArticle({ id, name: literal('Original') })); await articles.set(id, createArticle({ id, name: literal('Updated') })); - expect(await articles.get(id)).toBeRdfDatasetContaining(quad(id, schema('name'), literal('Updated'))); + expect(await articles.get(id)).toBeRdfDatasetContaining(quad(id, schema.name, literal('Updated'))); }); it('throws an error if it is not an article', async (): Promise => { diff --git a/test/create-article.ts b/test/create-article.ts index 15343f9d..41a13ec4 100644 --- a/test/create-article.ts +++ b/test/create-article.ts @@ -1,10 +1,10 @@ import { DatasetCore, Literal, NamedNode, Quad_Subject as QuadSubject, } from 'rdf-js'; +import { rdf, schema } from '@tpluscode/rdf-ns-builders'; import { blankNode, dataset, literal, quad, } from '../src/data-factory'; -import { rdf, schema } from '../src/namespaces'; type Options = { id?: QuadSubject; @@ -24,7 +24,7 @@ export default ({ }); if (name) { - article.add(quad(id, schema('name'), name)); + article.add(quad(id, schema.name, name)); } return article; diff --git a/test/errors/not-an-article.test.ts b/test/errors/not-an-article.test.ts index 5d941395..5bf0e101 100644 --- a/test/errors/not-an-article.test.ts +++ b/test/errors/not-an-article.test.ts @@ -1,6 +1,6 @@ import { literal } from '@rdfjs/data-model'; +import { schema } from '@tpluscode/rdf-ns-builders'; import NotAnArticle from '../../src/errors/not-an-article'; -import { schema } from '../../src/namespaces'; describe('not an article error', (): void => { it('should be an error', async (): Promise => { diff --git a/test/middleware/error-handler.test.ts b/test/middleware/error-handler.test.ts index b1011250..ff9720e7 100644 --- a/test/middleware/error-handler.test.ts +++ b/test/middleware/error-handler.test.ts @@ -3,9 +3,9 @@ import createHttpError from 'http-errors'; import { INTERNAL_SERVER_ERROR, SERVICE_UNAVAILABLE } from 'http-status-codes'; import 'jest-rdf'; import { Response } from 'koa'; +import { hydra, rdf } from '@tpluscode/rdf-ns-builders'; import { WithDataset } from '../../src/middleware/dataset'; import errorHandler from '../../src/middleware/error-handler'; -import { hydra, rdf } from '../../src/namespaces'; import createContext, { ErrorListener } from '../context'; import runMiddleware, { NextMiddleware, throwingNext } from '../middleware'; diff --git a/test/middleware/jsonld.test.ts b/test/middleware/jsonld.test.ts index 86e03172..751d1603 100644 --- a/test/middleware/jsonld.test.ts +++ b/test/middleware/jsonld.test.ts @@ -6,9 +6,9 @@ import 'jest-rdf'; import { Context as JsonLdContext } from 'jsonld/jsonld-spec'; import { addAll } from 'rdf-dataset-ext'; import { Quad } from 'rdf-js'; +import { rdf, schema } from '@tpluscode/rdf-ns-builders'; import { AppContext } from '../../src/app'; import jsonld from '../../src/middleware/jsonld'; -import { rdf, schema } from '../../src/namespaces'; import createContext, { Headers } from '../context'; import { NextMiddleware } from '../middleware'; @@ -44,7 +44,7 @@ const dc = namespace('http://purl.org/dc/elements/1.1/'); const id = namedNode('http://example.com/object'); const quads = [ quad(id, rdf.type, schema.Article), - quad(id, schema('name'), literal('English Name', 'en')), + quad(id, schema.name, literal('English Name', 'en')), quad(id, dc.title, literal('English Title', 'en')), quad(id, dc.title, literal('French Title', 'fr')), ]; diff --git a/test/routes/add-article.test.ts b/test/routes/add-article.test.ts index 2152cb6a..357aced2 100644 --- a/test/routes/add-article.test.ts +++ b/test/routes/add-article.test.ts @@ -5,9 +5,9 @@ import all from 'it-all'; import 'jest-rdf'; import { Response } from 'koa'; import { DatasetCore } from 'rdf-js'; +import { schema } from '@tpluscode/rdf-ns-builders'; import InMemoryArticles from '../../src/adaptors/in-memory-articles'; import Articles from '../../src/articles'; -import { schema } from '../../src/namespaces'; import addArticle from '../../src/routes/add-article'; import createContext from '../context'; import createArticle from '../create-article'; diff --git a/test/routes/api-documentation.test.ts b/test/routes/api-documentation.test.ts index 82d621e2..a102fb75 100644 --- a/test/routes/api-documentation.test.ts +++ b/test/routes/api-documentation.test.ts @@ -2,8 +2,8 @@ import { namedNode, quad } from '@rdfjs/data-model'; import { OK } from 'http-status-codes'; import 'jest-rdf'; import { Response } from 'koa'; +import { hydra, rdf } from '@tpluscode/rdf-ns-builders'; import { WithDataset } from '../../src/middleware/dataset'; -import { hydra, rdf } from '../../src/namespaces'; import apiDocumentation from '../../src/routes/api-documentation'; import createContext from '../context'; import runMiddleware, { NextMiddleware } from '../middleware'; diff --git a/test/routes/article-list.test.ts b/test/routes/article-list.test.ts index 0ee02b1b..f8469221 100644 --- a/test/routes/article-list.test.ts +++ b/test/routes/article-list.test.ts @@ -3,10 +3,10 @@ import { OK } from 'http-status-codes'; import 'jest-rdf'; import { Response } from 'koa'; import { toRdf } from 'rdf-literal'; +import { hydra, rdf } from '@tpluscode/rdf-ns-builders'; import InMemoryArticles from '../../src/adaptors/in-memory-articles'; import Articles from '../../src/articles'; import { WithDataset } from '../../src/middleware/dataset'; -import { hydra, rdf } from '../../src/namespaces'; import articleList from '../../src/routes/article-list'; import createContext from '../context'; import createArticle from '../create-article'; diff --git a/test/routes/entry-point.test.ts b/test/routes/entry-point.test.ts index 597db606..10e9291e 100644 --- a/test/routes/entry-point.test.ts +++ b/test/routes/entry-point.test.ts @@ -2,8 +2,8 @@ import { namedNode, quad } from '@rdfjs/data-model'; import { OK } from 'http-status-codes'; import 'jest-rdf'; import { Response } from 'koa'; +import { hydra, rdf, schema } from '@tpluscode/rdf-ns-builders'; import { WithDataset } from '../../src/middleware/dataset'; -import { hydra, rdf, schema } from '../../src/namespaces'; import entryPoint from '../../src/routes/entry-point'; import createContext from '../context'; import runMiddleware, { NextMiddleware } from '../middleware'; @@ -24,7 +24,7 @@ describe('entry-point', (): void => { const id = namedNode('http://example.com/path-to/entry-point'); expect(dataset).toBeRdfDatasetContaining(quad(id, rdf.type, schema.EntryPoint)); - expect(dataset).toBeRdfDatasetMatching({ subject: id, predicate: schema('name') }); + expect(dataset).toBeRdfDatasetMatching({ subject: id, predicate: schema.name }); expect(dataset).toBeRdfDatasetMatching({ subject: id, predicate: hydra.collection }); });