Skip to content

Commit

Permalink
Fix type-scoped contexts breaking when aliasing @type
Browse files Browse the repository at this point in the history
Closes #115
  • Loading branch information
jeswr committed Sep 19, 2023
1 parent 10c21b2 commit 3249687
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 7 deletions.
22 changes: 15 additions & 7 deletions lib/JsonLdParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export class JsonLdParser extends Transform implements RDF.Sink<EventEmitter, RD
// Jobs that are not started yet that process a @type (only used if streamingProfile is false)
private readonly typeJobs: { job: () => Promise<void>, keys: string[] }[];
// Jobs that are not started yet because of a missing @context or @type (only used if streamingProfile is false)
private readonly contextAwaitingJobs: { job: () => Promise<void>, keys: string[] }[];
private readonly contextAwaitingJobs: { job: () => Promise<void>, keys: string[]; depth: number }[];

// The last depth that was processed.
private lastDepth: number;
Expand Down Expand Up @@ -453,12 +453,8 @@ export class JsonLdParser extends Transform implements RDF.Sink<EventEmitter, RD
jobs = this.contextJobs[depth] = [];
}
jobs.push(valueJobCb);
} else if (keys[depth] === '@type'
|| typeof keys[depth] === 'number' && keys[depth - 1] === '@type') { // Also capture @type with array values
// Remove @type from keys, because we want it to apply to parent later on
this.typeJobs.push({ job: valueJobCb, keys: keys.slice(0, keys.length - 1) });
} else {
this.contextAwaitingJobs.push({ job: valueJobCb, keys });
this.contextAwaitingJobs.push({ job: valueJobCb, keys, depth });
}
} else {
// Make sure that our value jobs are chained synchronously
Expand Down Expand Up @@ -508,8 +504,20 @@ export class JsonLdParser extends Transform implements RDF.Sink<EventEmitter, RD
// Clear the keyword cache.
this.parsingContext.unaliasedKeywordCacheStack.splice(0);

// Handle non-context jobs
const contextAwaitingJobs: { job: () => Promise<void>, keys: string[]; depth: number }[] = [];

for (const job of this.contextAwaitingJobs) {
if ((await this.util.unaliasKeyword(job.keys[job.depth], job.keys, job.depth, true)) === '@type'
|| typeof job.keys[job.depth] === 'number' && (await this.util.unaliasKeyword(job.keys[job.depth - 1], job.keys, job.depth - 1, true)) === '@type') { // Also capture @type with array values
// Remove @type from keys, because we want it to apply to parent later on
this.typeJobs.push({ job: job.job, keys: job.keys.slice(0, job.keys.length - 1) })
} else {
contextAwaitingJobs.push(job)
}
}

// Handle non-context jobs
for (const job of contextAwaitingJobs) {
// Check if we have a type (with possible type-scoped context) that should be handled before.
// We check all possible parent nodes for the current job, from root to leaves.
if (this.typeJobs.length > 0) {
Expand Down
26 changes: 26 additions & 0 deletions test/JsonLdParser-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13523,4 +13523,30 @@ describe('JsonLdParser', () => {
return expect(arrayifyStream(result)).rejects.toThrow(new Error('my error'));
});
});

it('should parse a VC with minified context', async () => {
const parser = new JsonLdParser();
const stream = streamifyString(JSON.stringify({
"@context": {
"ty": "@type",
"VerifiableCredential": {
"@id": "https://www.w3.org/2018/credentials#VerifiableCredential",
"@context": {
"credentialSubject": {"@id": "https://www.w3.org/2018/credentials#credentialSubject", "@type": "@id"},
}
},
},
"@id": "https://some.credential",
"credentialSubject": {
"@id": "https://some.requestor",
},
"ty":
"VerifiableCredential"

}));
return expect(await arrayifyStream(stream.pipe(parser))).toBeRdfIsomorphic([
DF.quad(DF.namedNode("https://some.credential"), DF.namedNode('https://www.w3.org/2018/credentials#credentialSubject'), DF.namedNode('https://some.requestor')),
DF.quad(DF.namedNode("https://some.credential"), DF.namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), DF.namedNode('https://www.w3.org/2018/credentials#VerifiableCredential')),
]);
});
});

0 comments on commit 3249687

Please sign in to comment.