Skip to content

Commit

Permalink
fix: merge regression
Browse files Browse the repository at this point in the history
  • Loading branch information
tpluscode committed Nov 20, 2022
1 parent b36cda5 commit bf1280d
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .changeset/funny-dodos-applaud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hydrofoil/talos": patch
---

Regression: existing resources would have been merged instead of rewritten
20 changes: 9 additions & 11 deletions packages/talos/lib/bootstrap.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import { NamedNode } from 'rdf-js'
import StreamClient, { StreamClientOptions } from 'sparql-http-client'
import type DatasetExt from 'rdf-ext/lib/Dataset'
import clownface from 'clownface'
import { ResourcePerGraphStore } from '@hydrofoil/knossos/lib/store'
import type { ResourceStore } from '@hydrofoil/knossos/lib/store'
import { hydra } from '@tpluscode/rdf-ns-builders'
import { isNamedNode } from 'is-graph-pointer'
import $rdf from 'rdf-ext'
import { log } from './log'
import { talosNs } from './ns'

type Bootstrap = StreamClientOptions & {
type Bootstrap = {
store: ResourceStore
dataset: DatasetExt
apiUri: NamedNode
}

export async function bootstrap({ dataset, apiUri, ...options }: Bootstrap): Promise<void> {
const store = new ResourcePerGraphStore(new StreamClient(options))

export async function bootstrap({ dataset, apiUri, store }: Bootstrap): Promise<void> {
const graph = clownface({ dataset, graph: talosNs.resources })
const resources = graph.has(talosNs.action)
for (const resource of resources.toArray().filter(isNamedNode)) {
Expand All @@ -26,20 +24,20 @@ export async function bootstrap({ dataset, apiUri, ...options }: Bootstrap): Pro
.namedNode(resource)
.addOut(hydra.apiDocumentation, apiUri)

const action = resource.out(talosNs.action).value
const action = resource.out(talosNs.action).term
const exists = await store.exists(pointer.term)
if (exists && action === 'skip') {
if (exists && talosNs.skip.equals(action)) {
log(`Skipping resource ${resource}`)
continue
}

if (exists) {
if (action === 'overwrite') {
log(`Replacing resource ${resource}`)
} else {
if (talosNs.merge.equals(action)) {
log(`Merging existing resource ${resource}`)
const current = await store.load(pointer.term)
pointer.dataset.addAll(current.dataset)
} else {
log(`Replacing resource ${resource}`)
}
} else {
log(`Creating resource ${resource}`)
Expand Down
12 changes: 8 additions & 4 deletions packages/talos/lib/command/put.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import $rdf from 'rdf-ext'
import { ResourcePerGraphStore } from '@hydrofoil/knossos/lib/store'
import StreamClient from 'sparql-http-client'
import { bootstrap } from '../bootstrap'
import { deleteApi } from '../deleteApi'
import { fromDirectories } from '../resources'
Expand All @@ -17,10 +19,12 @@ export async function put(directories: string[], { token, api, endpoint, updateE
await bootstrap({
dataset,
apiUri,
endpointUrl: endpoint,
updateUrl: updateEndpoint || endpoint,
user,
password,
store: new ResourcePerGraphStore(new StreamClient({
endpointUrl: endpoint,
updateUrl: updateEndpoint || endpoint,
user,
password,
})),
})

await deleteApi({ apiUri, token })
Expand Down
15 changes: 13 additions & 2 deletions packages/talos/lib/resources.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from 'path'
import fs from 'fs'
import { NamedNode } from 'rdf-js'
import { NamedNode, DatasetCore } from 'rdf-js'
import walk from '@fcostarodrigo/walk'
import $rdf from 'rdf-ext'
import type DatasetExt from 'rdf-ext/lib/Dataset'
Expand All @@ -19,7 +19,18 @@ interface ResourceOptions {

export async function fromDirectories(directories: string[], api: string): Promise<DatasetExt> {
const validDirs = directories.filter(isValidDir)
return validDirs.reduce(toGraphs(api), Promise.resolve($rdf.dataset()))
const dataset = await validDirs.reduce(toGraphs(api), Promise.resolve($rdf.dataset()))

setDefaultAction(dataset)

return dataset
}

function setDefaultAction(dataset: DatasetCore) {
clownface({ dataset, graph: talosNs.resources })
.has(talosNs.action, talosNs.default)
.deleteOut(talosNs.action, talosNs.default)
.addOut(talosNs.action, talosNs.overwrite)
}

function toGraphs(api: string) {
Expand Down
1 change: 1 addition & 0 deletions packages/talos/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"sparql-http-client": "^2.4.1"
},
"devDependencies": {
"@labyrinth/testing": "*",
"@types/mime-types": "^2.1.1",
"@types/replacestream": "^4.0.1",
"@wikibus/vocabularies": "^0.2.2",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
exports["@hydrofoil/talos/lib/command/put --resources api http://example.com turtle replaces entire graph by default"] = "<http://example.com/project> <http://schema.org/parentItem> <http://example.com> .\n<http://example.com/project> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Thing> .\n<http://example.com/project> <http://www.w3.org/ns/hydra/core#apiDocumentation> <http://example.com/api> .\n";

exports["@hydrofoil/talos/lib/command/put --resources api http://example.com turtle merge existing graph when annotated"] = "<http://example.com/project/creta/user.group/admins> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2006/vcard/ns#Group> .\n<http://example.com/project/creta/user.group/admins> <http://www.w3.org/2006/vcard/ns#hasMember> <http://example.com/project/creta/user/tpluscode> .\n<http://example.com/project/creta/user.group/admins> <http://www.w3.org/2006/vcard/ns#n> \"Administrators\" .\n<http://example.com/project/creta/user.group/admins> <http://www.w3.org/ns/hydra/core#apiDocumentation> <http://example.com/api> .\n";

exports["@hydrofoil/talos/lib/command/put --resources api http://example.com/base turtle replaces entire graph by default"] = "<http://example.com/base/project> <http://schema.org/parentItem> <http://example.com/base> .\n<http://example.com/base/project> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Thing> .\n<http://example.com/base/project> <http://www.w3.org/ns/hydra/core#apiDocumentation> <http://example.com/base/api> .\n";

exports["@hydrofoil/talos/lib/command/put --resources api http://example.com/base turtle merge existing graph when annotated"] = "<http://example.com/base/project/creta/user.group/admins> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2006/vcard/ns#Group> .\n<http://example.com/base/project/creta/user.group/admins> <http://www.w3.org/2006/vcard/ns#hasMember> <http://example.com/base/project/creta/user/tpluscode> .\n<http://example.com/base/project/creta/user.group/admins> <http://www.w3.org/2006/vcard/ns#n> \"Administrators\" .\n<http://example.com/base/project/creta/user.group/admins> <http://www.w3.org/ns/hydra/core#apiDocumentation> <http://example.com/base/api> .\n";

29 changes: 26 additions & 3 deletions packages/talos/test/lib/command/put.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import * as path from 'path'
import { put, Put } from 'talos/lib/command/put'
import { ASK, DELETE, INSERT, SELECT } from '@tpluscode/sparql-builder'
import { ASK, CONSTRUCT, DELETE, SELECT } from '@tpluscode/sparql-builder'
import ParsingClient from 'sparql-http-client/ParsingClient'
import { expect } from 'chai'
import { dash, doap, hydra, schema, vcard, sh, foaf } from '@tpluscode/rdf-ns-builders/loose'
import namespace from '@rdfjs/namespace'
import * as NodeFetch from 'node-fetch'
import sinon from 'sinon'
import $rdf from 'rdf-ext'
import { testData } from '@labyrinth/testing/client'

const apis = [
'http://example.com',
Expand Down Expand Up @@ -36,11 +37,15 @@ for (const api of apis) {
before(async () => {
await DELETE`?s ?p ?o`.WHERE`?s ?p ?o`.execute(client.query)

await INSERT.DATA`
await testData`
GRAPH ${ns('project/creta/user.group/admins')} {
${ns('project/creta/user.group/admins')} ${vcard.hasMember} ${ns('project/creta/user/tpluscode')}
}
`.execute(client.query)
GRAPH ${ns('project')} {
${ns('project')} ${schema.name} "DELETE" .
}
`
})

it('ignores paths which do not exist', async () => {
Expand All @@ -57,6 +62,24 @@ for (const api of apis) {
})

context('turtle', () => {
it('replaces entire graph by default', async function () {
const dataset = $rdf.dataset().addAll(await CONSTRUCT`?s ?p ?o`
.FROM(ns('project'))
.WHERE`?s ?p ?o`
.execute(client.query))

expect(dataset.toCanonical()).to.matchSnapshot(this)
})

it('merge existing graph when annotated', async function () {
const dataset = $rdf.dataset().addAll(await CONSTRUCT`?s ?p ?o`
.FROM(ns('project/creta/user.group/admins'))
.WHERE`?s ?p ?o`
.execute(client.query))

expect(dataset.toCanonical()).to.matchSnapshot(this)
})

it('inserts into graph constructed from path', async () => {
const userCreated = ASK`${ns('project/creta/user/tpluscode')} a ${schema.Person}`
.FROM(ns('project/creta/user/tpluscode'))
Expand Down
4 changes: 2 additions & 2 deletions packages/talos/test/lib/resources.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ describe('@hydrofoil/talos/lib/resources', () => {
expect(toCanonical(resource)).to.matchSnapshot(this)
})

it('marks a resource for "default" by default', () => {
it('marks a resource for "overwrite" by default', () => {
const [{ object: action }, ...more] = dataset.match(ns(), talosNs.action, null, talosNs.resources)

expect(action).to.deep.eq(talosNs.default)
expect(action).to.deep.eq(talosNs.overwrite)
expect(more).to.be.empty
})

Expand Down

0 comments on commit bf1280d

Please sign in to comment.