Skip to content

Commit 9e181fc

Browse files
committed
Add experimental typeScopedContexts flag
1 parent 379d9aa commit 9e181fc

6 files changed

Lines changed: 102 additions & 13 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ Usage:
101101
-e jsonld Extension for components files (without .), defaults to 'jsonld'
102102
-i ignore-classes.json Relative path to an optional file with class names to ignore
103103
--help Show information about this command
104+
105+
Experimental options:
106+
--typeScopedContexts If a type-scoped context for each component is to be generated with parameter name aliases
104107
```
105108

106109
**Note:** This generator will read `.d.ts` files,

bin/componentsjs-generator.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ Usage:
1717
-i ignore-classes.json Relative path to an optional file with class names to ignore
1818
-l info The logger level
1919
--help Show information about this command
20+
21+
Experimental options:
22+
--typeScopedContexts If a type-scoped context for each component is to be generated with parameter name aliases
2023
`);
2124
process.exit(1);
2225
}
@@ -34,6 +37,7 @@ if (args.help) {
3437
replacementPath: Path.posix.join(packageRootDirectory, args.c || 'components'),
3538
},
3639
fileExtension: args.e || 'jsonld',
40+
typeScopedContexts: args.typeScopedContexts,
3741
logLevel: args.l || 'info',
3842
ignoreClasses: args.i ?
3943
// eslint-disable-next-line no-sync

lib/generate/Generator.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@ export class Generator {
2222
private readonly pathDestination: PathDestinationDefinition;
2323
private readonly fileExtension: string;
2424
private readonly ignoreClasses: Record<string, boolean>;
25+
private readonly typeScopedContexts: boolean;
2526
private readonly logLevel: LogLevel;
2627

2728
public constructor(args: GeneratorArgs) {
2829
this.resolutionContext = args.resolutionContext;
2930
this.pathDestination = args.pathDestination;
3031
this.fileExtension = args.fileExtension;
3132
this.ignoreClasses = args.ignoreClasses;
33+
this.typeScopedContexts = args.typeScopedContexts;
3234
this.logLevel = args.logLevel;
3335
}
3436

@@ -51,7 +53,10 @@ export class Generator {
5153
.resolveAllConstructorParameters(constructorsUnresolved, classIndex);
5254

5355
// Create components
54-
const contextConstructor = new ContextConstructor({ packageMetadata });
56+
const contextConstructor = new ContextConstructor({
57+
packageMetadata,
58+
typeScopedContexts: this.typeScopedContexts,
59+
});
5560
const componentConstructor = new ComponentConstructor({
5661
packageMetadata,
5762
contextConstructor,
@@ -89,5 +94,6 @@ export interface GeneratorArgs {
8994
pathDestination: PathDestinationDefinition;
9095
fileExtension: string;
9196
ignoreClasses: Record<string, boolean>;
97+
typeScopedContexts: boolean;
9298
logLevel: LogLevel;
9399
}

lib/serialize/ContextConstructor.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ import type { ComponentDefinitions } from './ComponentDefinitions';
88
*/
99
export class ContextConstructor {
1010
private readonly packageMetadata: PackageMetadata;
11+
private readonly typeScopedContexts: boolean;
1112

12-
public constructor(args: ContextSerializerArgs) {
13+
public constructor(args: ContextConstructorArgs) {
1314
this.packageMetadata = args.packageMetadata;
15+
this.typeScopedContexts = args.typeScopedContexts;
1416
}
1517

1618
/**
@@ -65,14 +67,24 @@ export class ContextConstructor {
6567
'@id': component['@id'],
6668
'@prefix': true,
6769
};
70+
71+
// Generate type-scoped context when enabled
72+
if (this.typeScopedContexts) {
73+
const typeScopedContext: Record<string, string> = {};
74+
for (const parameter of component.parameters) {
75+
typeScopedContext[parameter['@id'].slice(Math.max(0, component['@id'].length + 1))] = parameter['@id'];
76+
}
77+
(<any> shortcuts[match[0]])['@context'] = typeScopedContext;
78+
}
6879
}
6980
}
7081
return shortcuts;
7182
}
7283
}
7384

74-
export interface ContextSerializerArgs {
85+
export interface ContextConstructorArgs {
7586
packageMetadata: PackageMetadata;
87+
typeScopedContexts: boolean;
7688
}
7789

7890
export interface ContextRaw {

test/serialize/ComponentConstructor.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ describe('ComponentConstructor', () => {
3333
},
3434
typesPath: '',
3535
};
36-
const contextConstructor = new ContextConstructorMocked({ packageMetadata });
36+
const contextConstructor = new ContextConstructorMocked({ packageMetadata, typeScopedContexts: false });
3737
ctor = new ComponentConstructor({
3838
packageMetadata,
3939
contextConstructor,

test/serialize/ContextConstructor.test.ts

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
1+
import type { PackageMetadata } from '../../lib/parse/PackageMetadataLoader';
12
import { ContextConstructor } from '../../lib/serialize/ContextConstructor';
23

34
describe('ContextConstructor', () => {
45
let ctor: ContextConstructor;
6+
let packageMetadata: PackageMetadata;
57

68
beforeEach(async() => {
9+
packageMetadata = {
10+
name: 'my-package',
11+
version: '2.3.4',
12+
moduleIri: 'https://linkedsoftwaredependencies.org/bundles/npm/my-package/',
13+
componentsPath: 'components',
14+
contexts: {},
15+
importPaths: {},
16+
typesPath: '',
17+
};
718
ctor = new ContextConstructor({
8-
packageMetadata: {
9-
name: 'my-package',
10-
version: '2.3.4',
11-
moduleIri: 'https://linkedsoftwaredependencies.org/bundles/npm/my-package/',
12-
componentsPath: 'components',
13-
contexts: {},
14-
importPaths: {},
15-
typesPath: '',
16-
},
19+
packageMetadata,
20+
typeScopedContexts: false,
1721
});
1822
});
1923

@@ -150,5 +154,65 @@ describe('ContextConstructor', () => {
150154
},
151155
});
152156
});
157+
158+
it('should handle non-empty component definitions when typeScopedContexts is true', () => {
159+
ctor = new ContextConstructor({
160+
packageMetadata,
161+
typeScopedContexts: true,
162+
});
163+
expect(ctor.constructComponentShortcuts({
164+
'/docs/package/components/file1': {
165+
'@context': [
166+
'https://linkedsoftwaredependencies.org/bundles/npm/my-package/context.jsonld',
167+
],
168+
'@id': 'npmd:my-package',
169+
components: [
170+
{
171+
'@id': 'mp:file1#MyClass1',
172+
'@type': 'Class',
173+
constructorArguments: [],
174+
parameters: [
175+
{
176+
'@id': 'mp:file1#MyClass1_param1',
177+
},
178+
{
179+
'@id': 'mp:file1#MyClass1_param2',
180+
},
181+
],
182+
requireElement: 'MyClass1',
183+
},
184+
],
185+
},
186+
'/docs/package/components/b/file2': {
187+
'@context': [
188+
'https://linkedsoftwaredependencies.org/bundles/npm/my-package/context.jsonld',
189+
],
190+
'@id': 'npmd:my-package',
191+
components: [
192+
{
193+
'@id': 'mp:b/file2#MyClass2',
194+
'@type': 'Class',
195+
requireElement: 'MyClass2',
196+
constructorArguments: [],
197+
parameters: [],
198+
},
199+
],
200+
},
201+
})).toEqual({
202+
MyClass1: {
203+
'@id': 'mp:file1#MyClass1',
204+
'@prefix': true,
205+
'@context': {
206+
param1: 'mp:file1#MyClass1_param1',
207+
param2: 'mp:file1#MyClass1_param2',
208+
},
209+
},
210+
MyClass2: {
211+
'@id': 'mp:b/file2#MyClass2',
212+
'@prefix': true,
213+
'@context': {},
214+
},
215+
});
216+
});
153217
});
154218
});

0 commit comments

Comments
 (0)