Skip to content

Commit

Permalink
feat: allow custom context parser as a parameter to the parser & fix …
Browse files Browse the repository at this point in the history
…context mutations
  • Loading branch information
jeswr committed Oct 27, 2023
1 parent 5a23c1f commit 476344e
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 15 deletions.
6 changes: 5 additions & 1 deletion lib/JsonLdParser.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as RDF from "@rdfjs/types";
// tslint:disable-next-line:no-var-requires
const Parser = require('@bergos/jsonparse');
import {ERROR_CODES, ErrorCoded, IDocumentLoader, JsonLdContext, Util as ContextUtil} from "jsonld-context-parser";
import {ERROR_CODES, ErrorCoded, IDocumentLoader, JsonLdContext, Util as ContextUtil, ContextParser} from "jsonld-context-parser";
import {PassThrough, Transform, Readable} from "readable-stream";
import {EntryHandlerArrayValue} from "./entryhandler/EntryHandlerArrayValue";
import {EntryHandlerContainer} from "./entryhandler/EntryHandlerContainer";
Expand Down Expand Up @@ -672,4 +672,8 @@ export interface IJsonLdParserOptions {
* Defaults to false.
*/
rdfstarReverseInEmbedded?: boolean;
/**
* The the context parser to use.
*/
contextParser?: ContextParser;
}
6 changes: 3 additions & 3 deletions lib/ParsingContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export class ParsingContext {

constructor(options: IParsingContextOptions) {
// Initialize settings
this.contextParser = new ContextParser({ documentLoader: options.documentLoader, skipValidation: options.skipContextValidation });
this.contextParser = options.contextParser ?? new ContextParser({ documentLoader: options.documentLoader, skipValidation: options.skipContextValidation });
this.streamingProfile = !!options.streamingProfile;
this.baseIRI = options.baseIRI;
this.produceGeneralizedRdf = !!options.produceGeneralizedRdf;
Expand Down Expand Up @@ -207,11 +207,11 @@ export class ParsingContext {
|| scopedContext[key]['@context']['@propagate']; // Propagation is true by default

if (propagate !== false || i === keysOriginal.length - 1 - offset) {
contextRaw = scopedContext;
contextRaw = { ...scopedContext };

// Clean up final context
delete contextRaw['@propagate'];
contextRaw[key] = { ...contextRaw[key] };
contextRaw[key] = { ...contextRaw[key], };
if ('@id' in contextKeyEntry) {
contextRaw[key]['@id'] = contextKeyEntry['@id'];
}
Expand Down
13 changes: 4 additions & 9 deletions lib/entryhandler/keyword/EntryHandlerKeywordType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,13 @@ export class EntryHandlerKeywordType extends EntryHandlerKeyword {
if (hasTypedScopedContext) {
// Do not propagate by default
scopedContext = scopedContext.then((c) => {
if (!('@propagate' in c.getContextRaw())) {
c.getContextRaw()['@propagate'] = false;
}
let contextRaw = c.getContextRaw();

// Set the original context at this depth as a fallback
// This is needed when a context was already defined at the given depth,
// and this context needs to remain accessible from child nodes when propagation is disabled.
if (c.getContextRaw()['@propagate'] === false) {
c.getContextRaw()['@__propagateFallback'] = context.getContextRaw();
if (!('@propagate' in contextRaw) || contextRaw['@propagate'] === false) {
contextRaw = { ...contextRaw, '@propagate': false, '@__propagateFallback': context.getContextRaw() };
}

return c;
return new JsonLdContextNormalized(contextRaw);
});

// Set the new context in the context tree
Expand Down
25 changes: 23 additions & 2 deletions test/JsonLdParser-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,31 @@ import { EventEmitter } from 'events';
import {DataFactory} from "rdf-data-factory";
import each from 'jest-each';
import "jest-rdf";
import {ERROR_CODES, ErrorCoded, FetchDocumentLoader, JsonLdContextNormalized} from "jsonld-context-parser";
import {ContextParser, ERROR_CODES, ErrorCoded, FetchDocumentLoader, IParseOptions, JsonLdContext, JsonLdContextNormalized} from "jsonld-context-parser";
import {PassThrough} from "stream";
import {Util} from "../lib/Util";
import { ParsingContext } from '../lib/ParsingContext';
import contexts, { MockedDocumentLoader } from '../mocks/contexts';

const DF = new DataFactory<RDF.BaseQuad>();

const deepFreeze = obj => {
Object.keys(obj).forEach(prop => {
if (typeof obj[prop] === 'object' && !Object.isFrozen(obj[prop])) deepFreeze(obj[prop]);
});
return Object.freeze(obj);
};

class FrozenContextParser extends ContextParser {
constructor(options: ConstructorParameters<typeof ContextParser>[0]) {
super(options);
}

public parse(context: JsonLdContext, options?: IParseOptions): Promise<JsonLdContextNormalized> {
return super.parse(context, options)// .then(deepFreeze);
}
}

describe('JsonLdParser', () => {

describe('Parsing a Verifiable Credential', () => {
Expand All @@ -22,7 +39,11 @@ describe('JsonLdParser', () => {
beforeEach(() => {
parser = new JsonLdParser({
dataFactory: DF,
documentLoader: new MockedDocumentLoader(),
// Use the frozen context parser so we can detect if there are
// any attempts at mutations in the unit tests
contextParser: new FrozenContextParser({
documentLoader: new MockedDocumentLoader()
}),
})
});

Expand Down

0 comments on commit 476344e

Please sign in to comment.