Skip to content

Commit a09876b

Browse files
committed
Use 'types' property to detect index.d.ts file
Closes LinkedSoftwareDependencies/Components.js#19
1 parent 7c14d2a commit a09876b

5 files changed

Lines changed: 62 additions & 12 deletions

File tree

lib/generate/Generator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export class Generator {
3434
const classIndexer = new ClassIndexer({ classLoader, classFinder });
3535

3636
// Find all relevant classes
37-
const packageExports = await classFinder.getPackageExports(this.pathDestination.packageRootDirectory);
37+
const packageExports = await classFinder.getPackageExports(packageMetadata.typesPath);
3838
const classIndex = await classIndexer.createIndex(packageExports);
3939

4040
// Load constructor data

lib/parse/ClassFinder.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import * as Path from 'path';
21
import { ClassIndex, ClassReference } from './ClassIndex';
32
import { ClassLoader } from './ClassLoader';
43

@@ -14,15 +13,14 @@ export class ClassFinder {
1413
}
1514

1615
/**
17-
* From a given package directory, find all named exports.
18-
* It is assumed that the given package contains an index.d.ts file.
19-
* @param packageRootDirectory The path of a package.
16+
* From a given types index, find all named exports.
17+
* @param typesPath The path to the index typings file.
2018
*/
21-
public async getPackageExports(packageRootDirectory: string): Promise<ClassIndex<ClassReference>> {
19+
public async getPackageExports(typesPath: string): Promise<ClassIndex<ClassReference>> {
2220
let exports: ClassIndex<ClassReference> = {};
2321

2422
// Start from the package index, and collect all named exports.
25-
const paths = [ Path.join(packageRootDirectory, 'index') ];
23+
const paths = [ typesPath ];
2624
for (const path of paths) {
2725
const { named, unnamed } = await this.getFileExports(path);
2826
exports = { ...exports, ...named };

lib/parse/PackageMetadataLoader.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ export class PackageMetadataLoader {
4545
throw new Error(`Invalid package: Missing 'lsd:importPaths' in ${packageJsonPath}`);
4646
}
4747
const importPaths = packageJson['lsd:importPaths'];
48+
if (!('types' in packageJson)) {
49+
throw new Error(`Invalid package: Missing 'types' in ${packageJsonPath}`);
50+
}
51+
let typesPath = Path.join(packageRootDirectory, packageJson.types);
52+
if (!typesPath.endsWith('.d.ts')) {
53+
throw new Error(`Invalid package: 'types' entry does not have '.d.ts' suffix in ${packageJsonPath}`);
54+
} else {
55+
typesPath = typesPath.slice(0, -5);
56+
}
4857

4958
// Construct metadata hash
5059
return {
@@ -54,6 +63,7 @@ export class PackageMetadataLoader {
5463
componentsPath,
5564
contexts,
5665
importPaths,
66+
typesPath,
5767
};
5868
}
5969
}
@@ -69,4 +79,5 @@ export interface PackageMetadata {
6979
componentsPath: string;
7080
contexts: {[iri: string]: string};
7181
importPaths: {[iri: string]: string};
82+
typesPath: string;
7283
}

test/parse/ClassFinder.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ export {A};
221221
[Path.normalize('package-simple-named/index.d.ts')]: `export {A as B} from './lib/A';`,
222222
[Path.normalize('package-simple-named/lib/A.d.ts')]: 'export class A {}',
223223
};
224-
expect(await parser.getPackageExports('package-simple-named'))
224+
expect(await parser.getPackageExports('package-simple-named/index'))
225225
.toEqual({
226226
B: {
227227
fileName: Path.normalize('package-simple-named/lib/A'),
@@ -235,7 +235,7 @@ export {A};
235235
[Path.normalize('package-simple-unnamed/index.d.ts')]: `export * from './lib/A';`,
236236
[Path.normalize('package-simple-unnamed/lib/A.d.ts')]: 'export class A {}',
237237
};
238-
expect(await parser.getPackageExports('package-simple-unnamed'))
238+
expect(await parser.getPackageExports('package-simple-unnamed/index'))
239239
.toEqual({
240240
A: {
241241
fileName: Path.normalize('package-simple-unnamed/lib/A'),
@@ -253,7 +253,7 @@ export * from './lib/C';
253253
[Path.normalize('package-multiple/lib/A.d.ts')]: 'export class A {}',
254254
[Path.normalize('package-multiple/lib/C.d.ts')]: 'export class C {}',
255255
};
256-
expect(await parser.getPackageExports('package-multiple'))
256+
expect(await parser.getPackageExports('package-multiple/index'))
257257
.toEqual({
258258
B: {
259259
fileName: Path.normalize('package-multiple/lib/A'),
@@ -276,7 +276,7 @@ export * from './sub2/C'
276276
[Path.normalize('package-nested/lib/sub1/B.d.ts')]: 'export class B {}',
277277
[Path.normalize('package-nested/lib/sub2/C.d.ts')]: 'export class C {}',
278278
};
279-
expect(await parser.getPackageExports('package-nested'))
279+
expect(await parser.getPackageExports('package-nested/index'))
280280
.toEqual({
281281
B: {
282282
fileName: Path.normalize('package-nested/lib/sub1/B'),

test/parse/PackageMetadataLoader.test.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ describe('PackageMetadataLoader', () => {
3030
"lsd:importPaths": {
3131
"https://example.org/bundles/npm/@solid/community-server/^1.0.0/components/": "components/",
3232
"https://example.org/bundles/npm/@solid/community-server/^1.0.0/config/": "config/"
33-
}
33+
},
34+
"types": "./index.d.ts"
3435
}`,
3536
};
3637
expect(await loader.load('/')).toEqual({
@@ -46,6 +47,7 @@ describe('PackageMetadataLoader', () => {
4647
moduleIri: 'https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server',
4748
name: '@solid/community-server',
4849
version: '1.2.3',
50+
typesPath: Path.normalize('/index'),
4951
});
5052
});
5153

@@ -114,5 +116,44 @@ describe('PackageMetadataLoader', () => {
114116
await expect(loader.load('/')).rejects
115117
.toThrow(new Error(`Invalid package: Missing 'lsd:importPaths' in ${Path.normalize('/package.json')}`));
116118
});
119+
120+
it('should error when types is missing', async() => {
121+
resolutionContext.contentsOverrides = {
122+
[Path.normalize('/package.json')]: `{
123+
"name": "@solid/community-server",
124+
"lsd:module": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server",
125+
"lsd:components": "components/components.jsonld",
126+
"lsd:contexts": {
127+
"https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^1.0.0/components/context.jsonld": "components/context.jsonld"
128+
},
129+
"lsd:importPaths": {
130+
"https://example.org/bundles/npm/@solid/community-server/^1.0.0/components/": "components/",
131+
"https://example.org/bundles/npm/@solid/community-server/^1.0.0/config/": "config/"
132+
}
133+
}`,
134+
};
135+
await expect(loader.load('/')).rejects
136+
.toThrow(new Error(`Invalid package: Missing 'types' in ${Path.normalize('/package.json')}`));
137+
});
138+
139+
it('should error when types does not end with .d.ts', async() => {
140+
resolutionContext.contentsOverrides = {
141+
[Path.normalize('/package.json')]: `{
142+
"name": "@solid/community-server",
143+
"lsd:module": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server",
144+
"lsd:components": "components/components.jsonld",
145+
"lsd:contexts": {
146+
"https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^1.0.0/components/context.jsonld": "components/context.jsonld"
147+
},
148+
"lsd:importPaths": {
149+
"https://example.org/bundles/npm/@solid/community-server/^1.0.0/components/": "components/",
150+
"https://example.org/bundles/npm/@solid/community-server/^1.0.0/config/": "config/"
151+
},
152+
"types": "index.ts"
153+
}`,
154+
};
155+
await expect(loader.load('/')).rejects
156+
.toThrow(new Error(`Invalid package: 'types' entry does not have '.d.ts' suffix in ${Path.normalize('/package.json')}`));
157+
});
117158
});
118159
});

0 commit comments

Comments
 (0)