Skip to content

Commit 4e71b24

Browse files
committed
Redesign API based on recent discussion
1 parent 1563118 commit 4e71b24

28 files changed

+185
-249
lines changed

tsdoc-config/src/ConfigLoader.ts

Lines changed: 0 additions & 111 deletions
This file was deleted.

tsdoc-config/src/TSDocConfigFile.ts

Lines changed: 78 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@ import {
44
TSDocConfiguration
55
} from '@microsoft/tsdoc';
66
import * as fs from 'fs';
7+
import * as resolve from 'resolve';
78
import * as path from 'path';
89
import * as Ajv from 'ajv';
910

1011
const ajv: Ajv.Ajv = new Ajv({ verbose: true });
1112

1213
function initializeSchemaValidator(): Ajv.ValidateFunction {
13-
const jsonSchemaContent: string = fs.readFileSync(path.join(__dirname, 'schemas/tsdoc-config.schema.json'))
14-
.toString();
14+
const jsonSchemaPath: string = resolve.sync('@microsoft/tsdoc/schemas/tsdocconfig.schema.json', { basedir: __dirname });
15+
const jsonSchemaContent: string = fs.readFileSync(jsonSchemaPath).toString();
1516
const jsonSchema: object = JSON.parse(jsonSchemaContent);
16-
1717
return ajv.compile(jsonSchema);
1818
}
1919

@@ -36,25 +36,30 @@ interface IConfigJson {
3636
}
3737

3838
/**
39-
* Represents an individual `tsdoc-config.json` file.
39+
* Represents an individual `tsdocconfig.json` file.
4040
*
4141
* @public
4242
*/
4343
export class TSDocConfigFile {
44+
public static readonly FILENAME: string = 'tsdocconfig.json';
45+
public static readonly CURRENT_SCHEMA_URL: string = 'https://developer.microsoft.com/json-schemas/tsdoc/v1/tsdocconfig.schema.json';
46+
4447
private readonly _extendsFiles: TSDocConfigFile[] = [];
4548

4649
/**
47-
* The full path of the file.
50+
* The full path of the file that was attempted to load.
4851
*/
4952
public readonly filePath: string;
5053

54+
public readonly fileNotFound: boolean = false;
55+
5156
/**
52-
* The `$schema` field from the `tsdoc-config.json` file.
57+
* The `$schema` field from the `tsdocconfig.json` file.
5358
*/
5459
public readonly tsdocSchema: string;
5560

5661
/**
57-
* The `extends` field from the `tsdoc-config.json` file. For the parsed file contents,
62+
* The `extends` field from the `tsdocconfig.json` file. For the parsed file contents,
5863
* use the `extendsFiles` property instead.
5964
*/
6065
public readonly extendsPaths: ReadonlyArray<string>;
@@ -99,11 +104,11 @@ export class TSDocConfigFile {
99104
*
100105
* @remarks
101106
*
102-
* This method does not process the `extends` field of `tsdoc-config.json`.
103-
* For full functionality, including discovery of the file path, use the {@link ConfigLoader}
107+
* This method does not process the `extends` field of `tsdocconfig.json`.
108+
* For full functionality, including discovery of the file path, use the {@link TSDocConfigFileSet}
104109
* API instead.
105110
*/
106-
public static loadFromFile(jsonFilePath: string): TSDocConfigFile {
111+
private static _loadSingleFile(jsonFilePath: string): TSDocConfigFile {
107112
const fullJsonFilePath: string = path.resolve(jsonFilePath);
108113

109114
const configJsonContent: string = fs.readFileSync(fullJsonFilePath).toString();
@@ -117,9 +122,70 @@ export class TSDocConfigFile {
117122
+ '\nError in file: ' + jsonFilePath);
118123
}
119124

125+
if (configJson.$schema !== TSDocConfigFile.CURRENT_SCHEMA_URL) {
126+
throw new Error('Expecting JSON "$schema" field to be ' + TSDocConfigFile.CURRENT_SCHEMA_URL
127+
+ '\nError in file: ' + jsonFilePath);
128+
}
129+
120130
return new TSDocConfigFile(fullJsonFilePath, configJson);
121131
}
122132

133+
private static _findConfigPathForFolder(folderPath: string): string {
134+
if (folderPath) {
135+
let foundFolder: string = folderPath;
136+
for (;;) {
137+
const tsconfigFilePath: string = path.join(foundFolder, 'tsconfig.json');
138+
if (fs.existsSync(tsconfigFilePath)) {
139+
// Success
140+
return path.join(foundFolder, TSDocConfigFile.FILENAME);
141+
}
142+
143+
const previousFolder: string = foundFolder;
144+
foundFolder = path.dirname(foundFolder);
145+
146+
if (!foundFolder || foundFolder === previousFolder) {
147+
// Failed
148+
break;
149+
}
150+
}
151+
}
152+
return '';
153+
}
154+
155+
private static _loadWithExtends(configFilePath: string, alreadyVisitedPaths: Set<string>): TSDocConfigFile {
156+
const hashKey: string = fs.realpathSync(configFilePath);
157+
if (alreadyVisitedPaths.has(hashKey)) {
158+
throw new Error('Circular reference encountered for "extends" field of ' + configFilePath);
159+
}
160+
alreadyVisitedPaths.add(hashKey);
161+
162+
const configFile: TSDocConfigFile = TSDocConfigFile._loadSingleFile(configFilePath);
163+
164+
const configFileFolder: string = path.dirname(configFile.filePath);
165+
166+
for (const extendsField of configFile.extendsPaths) {
167+
const resolvedExtendsPath: string = resolve.sync(extendsField, { basedir: configFileFolder });
168+
if (!fs.existsSync(resolvedExtendsPath)) {
169+
throw new Error('Unable to resolve "extends" field of ' + configFilePath);
170+
}
171+
172+
const baseConfigFile: TSDocConfigFile = TSDocConfigFile._loadWithExtends(resolvedExtendsPath, alreadyVisitedPaths);
173+
configFile.addExtendsFile(baseConfigFile);
174+
}
175+
176+
return configFile;
177+
}
178+
179+
/**
180+
* For the given folder, discover the relevant tsdocconfig.json files (if any), and load them.
181+
* @param folderPath - the path to a folder where the search should start
182+
*/
183+
public static loadForFolder(folderPath: string): TSDocConfigFile {
184+
const rootConfigPath: string = TSDocConfigFile._findConfigPathForFolder(folderPath);
185+
const alreadyVisitedPaths: Set<string> = new Set<string>();
186+
return TSDocConfigFile._loadWithExtends(rootConfigPath, alreadyVisitedPaths);
187+
}
188+
123189
/**
124190
* Adds an item to `TSDocConfigFile.extendsFiles`.
125191
*/
@@ -131,10 +197,10 @@ export class TSDocConfigFile {
131197
* Applies the settings from this config file to a TSDoc parser configuration.
132198
* Any `extendsFile` settings will also applied.
133199
*/
134-
public applyToParserConfiguration(configuration: TSDocConfiguration): void {
200+
public configureParser(configuration: TSDocConfiguration): void {
135201
// First apply the base config files
136202
for (const extendsFile of this.extendsFiles) {
137-
extendsFile.applyToParserConfiguration(configuration);
203+
extendsFile.configureParser(configuration);
138204
}
139205

140206
// The apply this one

0 commit comments

Comments
 (0)