11import type { Quad } from '@rdfjs/types' ;
2- import { Store , Writer } from 'n3' ;
2+ import { Parser , Store , Writer } from 'n3' ;
33import { randomUUID } from 'node:crypto' ;
4- import path from 'node:path' ;
5- import { storeToString , turtleStringToStore } from '../util/Conversion' ;
64import { extractQuadsRecursive } from '../util/Util' ;
75import { UCRulesStorage } from './UCRulesStorage' ;
86
@@ -15,16 +13,19 @@ export class ContainerUCRulesStorage implements UCRulesStorage {
1513 protected readonly extraDataUrl : string ;
1614
1715 /**
18- *
19- * @param containerURL The URL to an LDP container
16+ * @param containerURL - The URL to an LDP container
17+ * @param customFetch - Fetch function to use for requests. Default to builtin fetch.
2018 */
2119 public constructor (
2220 containerURL : string ,
2321 customFetch ?: ( input : RequestInfo , init ?: RequestInit | undefined ) => Promise < Response >
2422 ) {
2523 this . containerURL = containerURL ;
2624 this . fetch = customFetch ?? fetch ;
27- this . extraDataUrl = path . posix . join ( containerURL , randomUUID ( ) ) ;
25+ if ( ! containerURL . endsWith ( '/' ) ) {
26+ throw new Error ( `Invalid container URL ${ containerURL } : URL does not end with a slash` ) ;
27+ }
28+ this . extraDataUrl = containerURL + randomUUID ( ) ;
2829 }
2930
3031 public async getStore ( ) : Promise < Store > {
@@ -41,9 +42,9 @@ export class ContainerUCRulesStorage implements UCRulesStorage {
4142 if ( rule . size === 0 ) {
4243 return ;
4344 }
44- const ruleString = storeToString ( rule ) ;
45+ const ruleString = new Writer ( ) . quadsToString ( rule . getQuads ( null , null , null , null ) ) ;
4546
46- let response = await fetch ( this . extraDataUrl , {
47+ let response = await this . fetch ( this . extraDataUrl , {
4748 method : 'PATCH' ,
4849 headers : { 'content-type' : 'text/n3' } ,
4950 body : `
@@ -55,15 +56,14 @@ export class ContainerUCRulesStorage implements UCRulesStorage {
5556 }.` ,
5657 } ) ;
5758 if ( response . status >= 400 ) {
58- throw Error ( `Could not add rule to the storage ${ response . status } ${ await response . text ( ) } ` ) ;
59+ throw Error ( `Could not add rule to the storage: ${ response . status } - ${ await response . text ( ) } ` ) ;
5960 }
6061 }
6162
6263 public async getRule ( identifier : string ) : Promise < Store > {
6364 // would be better if there was a cache <ruleID, ldp:resource>
6465 const allRules = await this . getStore ( )
65- const rule = extractQuadsRecursive ( allRules , identifier ) ;
66- return rule
66+ return extractQuadsRecursive ( allRules , identifier ) ;
6767 }
6868
6969 public async deleteRule ( identifier : string ) : Promise < void > {
@@ -86,7 +86,7 @@ export class ContainerUCRulesStorage implements UCRulesStorage {
8686 }
8787 if ( matches . length > 0 ) {
8888 const response = await this . fetch ( url , {
89- method : 'PUT ' ,
89+ method : 'PATCH ' ,
9090 headers : { 'content-type' : 'text/n3' } ,
9191 body : `
9292 @prefix solid: <http://www.w3.org/ns/solid/terms#>.
@@ -122,23 +122,23 @@ export class ContainerUCRulesStorage implements UCRulesStorage {
122122 }
123123
124124 protected async readLdpRDFResource ( resourceURL : string ) : Promise < Store > {
125- const containerResponse = await this . fetch ( resourceURL , { headers : { 'accept' : 'text/turtle' } } ) ;
125+ const response = await this . fetch ( resourceURL , { headers : { 'accept' : 'text/turtle' } } ) ;
126126
127- if ( containerResponse . status === 404 ) {
127+ if ( response . status === 404 ) {
128128 return new Store ( ) ;
129129 }
130130
131- if ( containerResponse . status !== 200 ) {
132- throw new Error ( `Unable to acces policy container ${ resourceURL } : ${
133- containerResponse . status } - ${ await containerResponse . text ( ) } `) ;
131+ if ( response . status !== 200 ) {
132+ throw new Error ( `Unable to access policy resource ${ resourceURL } : ${
133+ response . status } - ${ await response . text ( ) } `) ;
134134 }
135135
136- const contentType = containerResponse . headers . get ( 'content-type' ) ;
136+ const contentType = response . headers . get ( 'content-type' ) ;
137137 // TODO: support non-turtle formats
138138 if ( contentType !== 'text/turtle' ) {
139139 throw new Error ( `Only turtle serialization is supported, received ${ contentType } ` ) ;
140140 }
141- const text = await containerResponse . text ( ) ;
142- return await turtleStringToStore ( text , resourceURL ) ;
141+ const text = await response . text ( ) ;
142+ return new Store ( new Parser ( { baseIRI : resourceURL } ) . parse ( text ) ) ;
143143 }
144144}
0 commit comments