Skip to content

Commit 3249687

Browse files
authored
Fix type-scoped contexts breaking when aliasing @type
Closes #115
1 parent 10c21b2 commit 3249687

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

lib/JsonLdParser.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export class JsonLdParser extends Transform implements RDF.Sink<EventEmitter, RD
5454
// Jobs that are not started yet that process a @type (only used if streamingProfile is false)
5555
private readonly typeJobs: { job: () => Promise<void>, keys: string[] }[];
5656
// Jobs that are not started yet because of a missing @context or @type (only used if streamingProfile is false)
57-
private readonly contextAwaitingJobs: { job: () => Promise<void>, keys: string[] }[];
57+
private readonly contextAwaitingJobs: { job: () => Promise<void>, keys: string[]; depth: number }[];
5858

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

511-
// Handle non-context jobs
507+
const contextAwaitingJobs: { job: () => Promise<void>, keys: string[]; depth: number }[] = [];
508+
512509
for (const job of this.contextAwaitingJobs) {
510+
if ((await this.util.unaliasKeyword(job.keys[job.depth], job.keys, job.depth, true)) === '@type'
511+
|| 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
512+
// Remove @type from keys, because we want it to apply to parent later on
513+
this.typeJobs.push({ job: job.job, keys: job.keys.slice(0, job.keys.length - 1) })
514+
} else {
515+
contextAwaitingJobs.push(job)
516+
}
517+
}
518+
519+
// Handle non-context jobs
520+
for (const job of contextAwaitingJobs) {
513521
// Check if we have a type (with possible type-scoped context) that should be handled before.
514522
// We check all possible parent nodes for the current job, from root to leaves.
515523
if (this.typeJobs.length > 0) {

test/JsonLdParser-test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13523,4 +13523,30 @@ describe('JsonLdParser', () => {
1352313523
return expect(arrayifyStream(result)).rejects.toThrow(new Error('my error'));
1352413524
});
1352513525
});
13526+
13527+
it('should parse a VC with minified context', async () => {
13528+
const parser = new JsonLdParser();
13529+
const stream = streamifyString(JSON.stringify({
13530+
"@context": {
13531+
"ty": "@type",
13532+
"VerifiableCredential": {
13533+
"@id": "https://www.w3.org/2018/credentials#VerifiableCredential",
13534+
"@context": {
13535+
"credentialSubject": {"@id": "https://www.w3.org/2018/credentials#credentialSubject", "@type": "@id"},
13536+
}
13537+
},
13538+
},
13539+
"@id": "https://some.credential",
13540+
"credentialSubject": {
13541+
"@id": "https://some.requestor",
13542+
},
13543+
"ty":
13544+
"VerifiableCredential"
13545+
13546+
}));
13547+
return expect(await arrayifyStream(stream.pipe(parser))).toBeRdfIsomorphic([
13548+
DF.quad(DF.namedNode("https://some.credential"), DF.namedNode('https://www.w3.org/2018/credentials#credentialSubject'), DF.namedNode('https://some.requestor')),
13549+
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')),
13550+
]);
13551+
});
1352613552
});

0 commit comments

Comments
 (0)