import createDebug from "debug" ; import got from "got" ; import rdf from "@rdfjs/data-model" ; import { Term , Quad , Quad_Subject , Quad_Predicate , Quad_Object , Quad_Graph , } from "rdf-js" ; import jsonldFactory , { Term as PlainTerm , Quad as PlainQuad , IdentifierIssuer , ToRdfOptions , Processor , } from "jsonld" ; import { CacheService } from "./cache" ; import { TripleStore as PlainTripleStore } from "../util/rdf" ; import { JSON_ACCEPTS } from "../util/consts" ; import { checkPublicUrl } from "../util/misc" ; export interface JsonLdService { createStore ( ) : TripleStore ; } const debug = createDebug ( "chess:jsonld" ) ; const fromPlainTerm = ( plainTerm ) : Term => { switch ( plainTerm . termType ) { case "NamedNode" : return rdf . namedNode ( plainTerm . value ) ; case "BlankNode" : return rdf . blankNode ( plainTerm . value . substr ( 2 ) ) ; case "Literal" : return rdf . literal ( plainTerm . value , plainTerm . language || rdf . namedNode ( plainTerm . datatype . value ) ) ; case "DefaultGraph" : return rdf . defaultGraph ( ) ; } } ; const fromPlainQuad = ( plainQuad ) : Quad => rdf . quad ( < Quad_Subject > fromPlainTerm ( plainQuad . subject ) , < Quad_Predicate > fromPlainTerm ( plainQuad . predicate ) , < Quad_Object > fromPlainTerm ( plainQuad . object ) , < Quad_Graph > fromPlainTerm ( plainQuad . graph ) ) ; export class TripleStore extends PlainTripleStore { private jsonld : Processor ; private options : ToRdfOptions ; constructor ( jsonld ) { super ( ) ; this . jsonld = jsonld ; this . options = { issuer : new IdentifierIssuer ( "_:b" ) , } ; } async load ( input ) { if ( typeof input === "string" && this . spo [ input ] ) { return ; } const quads = await this . jsonld . toRDF ( input , this . options ) ; for ( const quad of quads ) { this . add ( fromPlainQuad ( quad ) ) ; } } } export default async ( { cache , env , origin , } ) : Promise < JsonLdService > => { const jsonld = jsonldFactory ( ) ; jsonld . documentLoader = async ( url ) => { if ( env === "production" && ! checkPublicUrl ( url ) ) { return null ; } debug ( `REQ: ${ url }` ) ; const document = await got ( url , { resolveBodyOnly : true , cache : cache . http , headers : { "user-agent" : `${ origin }/` , accept : JSON_ACCEPTS , } , } ) . json ( ) ; return { document } ; } ; const createStore = ( ) => new TripleStore ( jsonld ) ; return { createStore } ; } ;