Skip to content

Commit 1ffa92e

Browse files
committed
Implement ConfigLoader.tryLoadFromPackageFolder()
1 parent 3873045 commit 1ffa92e

File tree

16 files changed

+191
-1
lines changed

16 files changed

+191
-1
lines changed

tsdoc-config/.vscode/launch.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"type": "node",
9+
"request": "launch",
10+
"name": "Jest All",
11+
"program": "${workspaceFolder}/node_modules/jest/bin/jest",
12+
"args": ["--runInBand"],
13+
"console": "integratedTerminal",
14+
"internalConsoleOptions": "neverOpen"
15+
},
16+
{
17+
"type": "node",
18+
"request": "launch",
19+
"name": "Jest Current File",
20+
"program": "${workspaceFolder}/node_modules/jest/bin/jest",
21+
"args": ["${relativeFile}"],
22+
"console": "integratedTerminal",
23+
"internalConsoleOptions": "neverOpen"
24+
}
25+
]
26+
}

tsdoc-config/src/ConfigLoader.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import * as fs from 'fs';
2+
import * as path from 'path';
3+
import { TSDocConfigFile } from './TSDocConfigFile';
4+
5+
interface IPackageJson {
6+
name?: string;
7+
version?: string;
8+
main?: string;
9+
typings?: string;
10+
types?: string;
11+
tsdocConfig?: string;
12+
}
13+
14+
export class ConfigLoader {
15+
public static readonly JSON_FILE_NAME: string = 'tsdoc-config.json';
16+
17+
private static _getExpectedPathForPackage(packageJson: IPackageJson): string {
18+
// Rule 1: If package.json contains the field "tsdocConfig" then that takes precedence
19+
// then that takes precedence. This convention will be rarely needed, since the later
20+
// generally produce a good result.
21+
if (packageJson.tsdocConfig) {
22+
return packageJson.tsdocConfig;
23+
}
24+
25+
// Rule 2: If package.json contains a field such as "types" or "typings", then look
26+
// for the file in that folder
27+
//
28+
// Rule 3: If package.json contains a field such as "main", then we would look
29+
// for the file in that folder.
30+
//
31+
// Rule 4: Other wise look in the package.json folder, since the default entry point
32+
// is './index.js'
33+
34+
let entryPointPath: string = 'index.js';
35+
if (packageJson.types) {
36+
entryPointPath = packageJson.types;
37+
} else if (packageJson.typings) {
38+
entryPointPath = packageJson.typings;
39+
} else if (packageJson.main) {
40+
entryPointPath = packageJson.main;
41+
}
42+
const entryPointFolder: string = path.dirname(entryPointPath);
43+
44+
return path.join(entryPointFolder, ConfigLoader.JSON_FILE_NAME);
45+
}
46+
47+
/**
48+
* Given a `packageFolder` path, probe for tsdoc-config.json and return the
49+
* path to this file.
50+
* @returns the absolute path, or `undefined` if not found
51+
*/
52+
private static _tryGetValidPath(packageFolder: string): string | undefined {
53+
const packageJsonPath: string = path.join(packageFolder, 'package.json');
54+
if (!fs.existsSync(packageJsonPath)) {
55+
throw new Error('package.json was not found under the path: ' + packageFolder);
56+
}
57+
const packageJsonContent: string = fs.readFileSync(packageJsonPath).toString();
58+
const packageJson: IPackageJson = JSON.parse(packageJsonContent);
59+
const configFilePath: string = ConfigLoader._getExpectedPathForPackage(packageJson);
60+
const configFileAbsolutePath: string = path.resolve(packageFolder, configFilePath);
61+
62+
if (fs.existsSync(configFileAbsolutePath)) {
63+
return configFileAbsolutePath;
64+
}
65+
66+
return undefined;
67+
}
68+
69+
public static tryLoadFromPackageFolder(packageFolder: string): TSDocConfigFile | undefined {
70+
71+
const rootConfigFilePath: string | undefined = ConfigLoader._tryGetValidPath(packageFolder);
72+
73+
if (!rootConfigFilePath) {
74+
return undefined;
75+
}
76+
77+
return TSDocConfigFile.load(rootConfigFilePath);
78+
}
79+
}

tsdoc-config/src/TSDocConfigFile.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
interface ITSDocConfigFileData {
2+
filePath: string;
3+
}
4+
5+
export class TSDocConfigFile {
6+
public readonly filePath: string;
7+
8+
private constructor(data: ITSDocConfigFileData) {
9+
this.filePath = data.filePath;
10+
}
11+
12+
public static load(filePath: string): TSDocConfigFile {
13+
return new TSDocConfigFile({
14+
filePath
15+
});
16+
}
17+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import * as path from 'path';
2+
3+
import { TSDocConfigFile } from '../TSDocConfigFile';
4+
import { ConfigLoader } from '../ConfigLoader';
5+
6+
function getRelativePath(testPath: string): string {
7+
return path.relative(__dirname, testPath).split('\\').join('/');
8+
}
9+
10+
test('Resolve p1', () => {
11+
const configFile: TSDocConfigFile | undefined = ConfigLoader.tryLoadFromPackageFolder(
12+
path.join(__dirname, 'assets/p1'));
13+
expect(configFile).toBeDefined();
14+
expect(getRelativePath(configFile!.filePath)).toEqual('assets/p1/folder/tsdoc-config.json');
15+
});
16+
test('Resolve p2', () => {
17+
const configFile: TSDocConfigFile | undefined = ConfigLoader.tryLoadFromPackageFolder(
18+
path.join(__dirname, 'assets/p2'));
19+
expect(configFile).toBeDefined();
20+
expect(getRelativePath(configFile!.filePath)).toEqual('assets/p2/folder/tsdoc-config.json');
21+
});
22+
test('Resolve p3', () => {
23+
const configFile: TSDocConfigFile | undefined = ConfigLoader.tryLoadFromPackageFolder(
24+
path.join(__dirname, 'assets/p3'));
25+
expect(configFile).toBeDefined();
26+
expect(getRelativePath(configFile!.filePath)).toEqual('assets/p3/folder/tsdoc-config.json');
27+
});
28+
test('Resolve p4', () => {
29+
const configFile: TSDocConfigFile | undefined = ConfigLoader.tryLoadFromPackageFolder(
30+
path.join(__dirname, 'assets/p4'));
31+
expect(configFile).toBeDefined();
32+
expect(getRelativePath(configFile!.filePath)).toEqual('assets/p4/tsdoc-config.json');
33+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"tsdocVersion": "0.12"
3+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "p1",
3+
"version": "1.0.0",
4+
"tsdocConfig": "./folder/tsdoc-config.json"
5+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// empty
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"tsdocVersion": "0.12"
3+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "p2",
3+
"version": "1.0.0",
4+
"typings": "./folder/index.d.ts"
5+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// empty

0 commit comments

Comments
 (0)