Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: allow custom context parser as a parameter to the parser & fix …
…context mutations
  • Loading branch information
jeswr committed Oct 27, 2023
commit 476344e51168ee249c82972f9fddc4c6e3f1a5fb
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