just-scripts
Version:
Just Stack Scripts
131 lines • 6.64 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.fixApiFileNewlines = exports.apiExtractorUpdateTask = exports.apiExtractorVerifyTask = void 0;
const just_task_1 = require("just-task");
const fs = require("fs-extra");
const path = require("path");
const tryRequire_1 = require("../tryRequire");
function apiExtractorVerifyTask(configJsonFilePathOrOption = {}, extractorOptions = {}) {
const options = typeof configJsonFilePathOrOption === 'string'
? { ...extractorOptions, configJsonFilePath: configJsonFilePathOrOption }
: { ...configJsonFilePathOrOption };
return function apiExtractorVerify() {
const context = initApiExtractor(options);
if (context) {
const apiExtractorResult = apiExtractorWrapper(context);
if (apiExtractorResult && !apiExtractorResult.succeeded) {
throw new Error('The public API file is out of date. Please run the API snapshot and commit the updated API file.');
}
}
};
}
exports.apiExtractorVerifyTask = apiExtractorVerifyTask;
function apiExtractorUpdateTask(configJsonFilePathOrOption = {}, extractorOptions = {}) {
const options = typeof configJsonFilePathOrOption === 'string'
? { ...extractorOptions, configJsonFilePath: configJsonFilePathOrOption }
: { ...configJsonFilePathOrOption };
return function apiExtractorUpdate() {
const context = initApiExtractor(options);
if (context) {
let apiExtractorResult = apiExtractorWrapper(context);
if (apiExtractorResult) {
if (!apiExtractorResult.succeeded) {
just_task_1.logger.warn(`- Update API: API file is out of date, updating...`);
fs.mkdirpSync(path.dirname(context.config.reportFilePath)); // ensure destination exists
fs.copyFileSync(context.config.reportTempFilePath, context.config.reportFilePath);
just_task_1.logger.info(`- Update API: successfully updated API file, verifying the updates...`);
apiExtractorResult = apiExtractorWrapper(context);
if (!apiExtractorResult || !apiExtractorResult.succeeded) {
throw new Error(`- Update API: failed to verify API updates.`);
}
else {
just_task_1.logger.info(`- Update API: successully verified API file. Please commit API file as part of your changes.`);
}
}
else {
just_task_1.logger.info(`- Update API: API file is already up to date, no update needed.`);
}
}
}
};
}
exports.apiExtractorUpdateTask = apiExtractorUpdateTask;
/**
* Load the api-extractor module (if available) and the config file.
* Returns undefined if api-extractor or the config file couldn't be found.
*/
function initApiExtractor(options) {
var _a;
const apiExtractorModule = (0, tryRequire_1.tryRequire)('@microsoft/api-extractor');
if (!apiExtractorModule) {
just_task_1.logger.warn('@microsoft/api-extractor package not detected. This task will have no effect.');
return;
}
if (!apiExtractorModule.Extractor.invoke) {
just_task_1.logger.warn('Please update your @microsoft/api-extractor package. This task will have no effect.');
return;
}
const { ExtractorConfig } = apiExtractorModule;
const { configJsonFilePath = ExtractorConfig.FILENAME, fixNewlines, onResult, ...extractorOptions } = options;
if (!fs.existsSync(configJsonFilePath)) {
const defaultConfig = path.resolve(__dirname, '../../config/apiExtractor/api-extractor.json');
just_task_1.logger.warn(`Config file not found for api-extractor! Please copy ${defaultConfig} to project root folder to try again`);
return;
}
const rawConfig = ExtractorConfig.loadFile(configJsonFilePath);
// Allow modification of the config
(_a = options.onConfigLoaded) === null || _a === void 0 ? void 0 : _a.call(options, rawConfig);
// This follows the logic from ExtractorConfig.loadFileAndPrepare
// https://github.com/microsoft/rushstack/blob/1eb3d8ccf2a87b90a1038bf464b0b73fb3c7fd78/apps/api-extractor/src/api/ExtractorConfig.ts#L455
const prepareConfig = {
configObject: rawConfig,
configObjectFullPath: path.resolve(configJsonFilePath),
packageJsonFullPath: path.resolve('package.json'),
};
// Respect projectFolder if provided.
if (options.projectFolder) {
prepareConfig.configObject.projectFolder = options.projectFolder;
}
const config = ExtractorConfig.prepare(prepareConfig);
return { apiExtractorModule, config, extractorOptions, options };
}
function apiExtractorWrapper({ apiExtractorModule, config, extractorOptions, options, }) {
const { Extractor } = apiExtractorModule;
just_task_1.logger.info(`Extracting Public API surface from '${config.mainEntryPointFilePath}'`);
const result = Extractor.invoke(config, extractorOptions);
if (options.onResult) {
options.onResult(result, extractorOptions);
}
if (options.fixNewlines) {
fixApiFileNewlines(options.localBuild ? config.reportFilePath : config.reportTempFilePath, {
sampleFilePath: config.apiJsonFilePath,
});
}
return result;
}
/**
* Update the newlines of the API report file to be consistent with other files in the repo,
* and remove trailing spaces.
* @param apiFilePath - Path to the API report file
* @param newlineOptions - Provide either `newline` to specify the type of newlines to use,
* or `sampleFilePath` to infer the newline type from a file.
*/
function fixApiFileNewlines(apiFilePath, newlineOptions) {
let newline;
if (newlineOptions.newline) {
newline = newlineOptions.newline;
}
else if (newlineOptions.sampleFilePath) {
const sampleFile = fs.readFileSync(newlineOptions.sampleFilePath).toString();
newline = sampleFile.match(/\r?\n/)[0];
}
else {
throw new Error('fixApiFileNewlines: you must provide either newlineOptions.sampleFilePath or newlineOptions.newline');
}
const contents = fs.readFileSync(apiFilePath).toString();
// Replace newlines. Also remove trailing spaces (second regex gets a trailing space on the
// last line of the file).
fs.writeFileSync(apiFilePath, contents.replace(/ ?\r?\n/g, newline).replace(/ $/, ''));
}
exports.fixApiFileNewlines = fixApiFileNewlines;
//# sourceMappingURL=apiExtractorTask.js.map