зеркало из https://github.com/microsoft/just.git
Merge branch 'master' into master
This commit is contained in:
Коммит
6cbae043a7
|
@ -1,20 +0,0 @@
|
||||||
name: 'Close stale issues'
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 0 * * *'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
stale:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/stale@v1
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
stale-issue-message: 'Issue seems to have gone stale.'
|
|
||||||
stale-pr-message: 'This PR seems to have gone stale.'
|
|
||||||
days-before-stale: 21
|
|
||||||
days-before-close: 3
|
|
||||||
stale-issue-label: 'stale-issue'
|
|
||||||
exempt-issue-label: 'awaiting-approval'
|
|
||||||
stale-pr-label: 'stale-pr'
|
|
||||||
exempt-pr-label: 'awaiting-approval'
|
|
|
@ -16,11 +16,11 @@
|
||||||
"@types/jest": "^23.3.13",
|
"@types/jest": "^23.3.13",
|
||||||
"@types/fs-extra": "^5.0.5",
|
"@types/fs-extra": "^5.0.5",
|
||||||
"create-just": "1.2.3",
|
"create-just": "1.2.3",
|
||||||
"just-scripts": ">=0.36.1 <1.0.0",
|
"just-scripts": ">=0.38.0 <1.0.0",
|
||||||
"just-stack-monorepo": "1.0.6",
|
"just-stack-monorepo": "1.0.6",
|
||||||
"just-stack-single-lib": "1.0.4",
|
"just-stack-single-lib": "1.0.4",
|
||||||
"just-stack-uifabric": "1.0.2",
|
"just-stack-uifabric": "1.0.2",
|
||||||
"just-scripts-utils": ">=0.8.4 <1.0.0",
|
"just-scripts-utils": ">=0.9.0 <1.0.0",
|
||||||
"fs-extra": "^7.0.1",
|
"fs-extra": "^7.0.1",
|
||||||
"ts-jest": "^24.0.1",
|
"ts-jest": "^24.0.1",
|
||||||
"jest": "^24.0.0"
|
"jest": "^24.0.0"
|
||||||
|
|
|
@ -1,6 +1,20 @@
|
||||||
{
|
{
|
||||||
"name": "create-just",
|
"name": "create-just",
|
||||||
"entries": [
|
"entries": [
|
||||||
|
{
|
||||||
|
"date": "Fri, 10 Apr 2020 20:34:02 GMT",
|
||||||
|
"tag": "create-just_v1.2.3",
|
||||||
|
"version": "1.2.3",
|
||||||
|
"comments": {
|
||||||
|
"none": [
|
||||||
|
{
|
||||||
|
"comment": "fix up initCommand with new yargs types",
|
||||||
|
"author": "kchau@microsoft.com",
|
||||||
|
"commit": "565e98494de5bae050cdc04365dee0a0aef638d8"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"date": "Mon, 04 Nov 2019 20:25:32 GMT",
|
"date": "Mon, 04 Nov 2019 20:25:32 GMT",
|
||||||
"tag": "create-just_v1.2.3",
|
"tag": "create-just_v1.2.3",
|
||||||
|
|
|
@ -28,6 +28,6 @@
|
||||||
"yargs-parser": "^13.1.1",
|
"yargs-parser": "^13.1.1",
|
||||||
"just-plop-helpers": "^1.1.2",
|
"just-plop-helpers": "^1.1.2",
|
||||||
"node-plop": "^0.20.0",
|
"node-plop": "^0.20.0",
|
||||||
"just-scripts-utils": ">=0.8.4 <1.0.0"
|
"just-scripts-utils": ">=0.9.0 <1.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ async function getStackPath(pathName: string, registry?: string) {
|
||||||
* 4. git init and commit
|
* 4. git init and commit
|
||||||
* 5. yarn install
|
* 5. yarn install
|
||||||
*/
|
*/
|
||||||
export async function initCommand(argv: yargs.Arguments) {
|
export async function initCommand(argv: yargs.Arguments<{ [key: string]: string }>) {
|
||||||
// TODO: autosuggest just-stack-* packages from npmjs.org
|
// TODO: autosuggest just-stack-* packages from npmjs.org
|
||||||
if (!argv.stack) {
|
if (!argv.stack) {
|
||||||
const { stack } = await prompts({
|
const { stack } = await prompts({
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"just-scripts": ">=0.36.1 <1.0.0",
|
"just-scripts": ">=0.38.0 <1.0.0",
|
||||||
"typescript": "~3.4.4"
|
"typescript": "~3.4.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,20 @@
|
||||||
{
|
{
|
||||||
"name": "just-scripts-utils",
|
"name": "just-scripts-utils",
|
||||||
"entries": [
|
"entries": [
|
||||||
|
{
|
||||||
|
"date": "Mon, 13 Apr 2020 15:57:30 GMT",
|
||||||
|
"tag": "just-scripts-utils_v0.9.0",
|
||||||
|
"version": "0.9.0",
|
||||||
|
"comments": {
|
||||||
|
"minor": [
|
||||||
|
{
|
||||||
|
"comment": "Add execSync utility",
|
||||||
|
"author": "elcraig@microsoft.com",
|
||||||
|
"commit": "91c6179993b4cc25076b8511b4d5d4726cd402d4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"date": "Tue, 13 Aug 2019 21:00:51 GMT",
|
"date": "Tue, 13 Aug 2019 21:00:51 GMT",
|
||||||
"tag": "just-scripts-utils_v0.8.4",
|
"tag": "just-scripts-utils_v0.8.4",
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
# Change Log - just-scripts-utils
|
# Change Log - just-scripts-utils
|
||||||
|
|
||||||
This log was last generated on Tue, 13 Aug 2019 21:00:51 GMT and should not be manually modified.
|
This log was last generated on Mon, 13 Apr 2020 15:57:30 GMT and should not be manually modified.
|
||||||
|
|
||||||
|
## 0.9.0
|
||||||
|
Mon, 13 Apr 2020 15:57:30 GMT
|
||||||
|
|
||||||
|
### Minor changes
|
||||||
|
|
||||||
|
- Add execSync utility (elcraig@microsoft.com)
|
||||||
## 0.8.4
|
## 0.8.4
|
||||||
Tue, 13 Aug 2019 21:00:51 GMT
|
Tue, 13 Aug 2019 21:00:51 GMT
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "just-scripts-utils",
|
"name": "just-scripts-utils",
|
||||||
"version": "0.8.4",
|
"version": "0.9.0",
|
||||||
"description": "Utilities for Just stack scripts",
|
"description": "Utilities for Just stack scripts",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import cp from 'child_process';
|
import cp from 'child_process';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
export interface ExecError extends cp.ExecException {
|
export interface ExecError extends cp.ExecException {
|
||||||
stdout?: string;
|
stdout?: string;
|
||||||
stderr?: string;
|
stderr?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SEPARATOR = process.platform === 'win32' ? ';' : ':';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a command.
|
* Execute a command.
|
||||||
*
|
*
|
||||||
|
@ -60,6 +63,29 @@ export function encodeArgs(cmdArgs: string[]) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a command synchronously.
|
||||||
|
*
|
||||||
|
* @param cmd Command to execute
|
||||||
|
* @param cwd Working directory in which to run the command (default: `process.cwd()`)
|
||||||
|
* @param returnOutput If true, return the command's output. If false/unspecified,
|
||||||
|
* inherit stdio from the parent process (so the child's output goes to the console).
|
||||||
|
* @returns If `returnOutput` is true, returns the command's output. Otherwise returns undefined.
|
||||||
|
*/
|
||||||
|
export function execSync(cmd: string, cwd?: string, returnOutput?: boolean): string | undefined {
|
||||||
|
cwd = cwd || process.cwd();
|
||||||
|
|
||||||
|
const env = { ...process.env };
|
||||||
|
env.PATH = path.resolve('./node_modules/.bin') + SEPARATOR + env.PATH;
|
||||||
|
|
||||||
|
const output = cp.execSync(cmd, {
|
||||||
|
cwd,
|
||||||
|
env,
|
||||||
|
stdio: returnOutput ? undefined : 'inherit'
|
||||||
|
});
|
||||||
|
return returnOutput ? (output || '').toString('utf8') : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a command in a new process.
|
* Execute a command in a new process.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,62 @@
|
||||||
{
|
{
|
||||||
"name": "just-scripts",
|
"name": "just-scripts",
|
||||||
"entries": [
|
"entries": [
|
||||||
|
{
|
||||||
|
"date": "Mon, 13 Apr 2020 15:57:30 GMT",
|
||||||
|
"tag": "just-scripts_v0.38.0",
|
||||||
|
"version": "0.38.0",
|
||||||
|
"comments": {
|
||||||
|
"minor": [
|
||||||
|
{
|
||||||
|
"comment": "Make API Extractor task accept all API Extractor options, and deprecate fixNewlines. Add shared Jest reporter.",
|
||||||
|
"author": "elcraig@microsoft.com",
|
||||||
|
"commit": "91c6179993b4cc25076b8511b4d5d4726cd402d4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "Fri, 10 Apr 2020 20:34:02 GMT",
|
||||||
|
"tag": "just-scripts_v0.37.2",
|
||||||
|
"version": "0.37.2",
|
||||||
|
"comments": {
|
||||||
|
"patch": [
|
||||||
|
{
|
||||||
|
"comment": "Jest now can take a positional arg to run a certain test pattern",
|
||||||
|
"author": "kchau@microsoft.com",
|
||||||
|
"commit": "565e98494de5bae050cdc04365dee0a0aef638d8"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "Tue, 07 Apr 2020 17:35:38 GMT",
|
||||||
|
"tag": "just-scripts_v0.37.1",
|
||||||
|
"version": "0.37.1",
|
||||||
|
"comments": {
|
||||||
|
"patch": [
|
||||||
|
{
|
||||||
|
"comment": "another take on tar task using tar-fs instead because it can actually handle large amounts of data",
|
||||||
|
"author": "kchau@microsoft.com",
|
||||||
|
"commit": "b5c1b57062e97a6780c5c30d27f81e9c5298bedf"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "Mon, 06 Apr 2020 21:43:56 GMT",
|
||||||
|
"tag": "just-scripts_v0.37.0",
|
||||||
|
"version": "0.37.0",
|
||||||
|
"comments": {
|
||||||
|
"minor": [
|
||||||
|
{
|
||||||
|
"comment": "Adds a new set of tar create and extract tasks",
|
||||||
|
"author": "kchau@microsoft.com",
|
||||||
|
"commit": "d8c91d78ed4337dbb8a592f388e382a8dd3628a2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"date": "Wed, 13 Nov 2019 19:42:46 GMT",
|
"date": "Wed, 13 Nov 2019 19:42:46 GMT",
|
||||||
"tag": "just-scripts_v0.36.1",
|
"tag": "just-scripts_v0.36.1",
|
||||||
|
|
|
@ -1,7 +1,31 @@
|
||||||
# Change Log - just-scripts
|
# Change Log - just-scripts
|
||||||
|
|
||||||
This log was last generated on Wed, 13 Nov 2019 19:42:46 GMT and should not be manually modified.
|
This log was last generated on Mon, 13 Apr 2020 15:57:30 GMT and should not be manually modified.
|
||||||
|
|
||||||
|
## 0.38.0
|
||||||
|
Mon, 13 Apr 2020 15:57:30 GMT
|
||||||
|
|
||||||
|
### Minor changes
|
||||||
|
|
||||||
|
- Make API Extractor task accept all API Extractor options, and deprecate fixNewlines. Add shared Jest reporter. (elcraig@microsoft.com)
|
||||||
|
## 0.37.2
|
||||||
|
Fri, 10 Apr 2020 20:34:02 GMT
|
||||||
|
|
||||||
|
### Patches
|
||||||
|
|
||||||
|
- Jest now can take a positional arg to run a certain test pattern (kchau@microsoft.com)
|
||||||
|
## 0.37.1
|
||||||
|
Tue, 07 Apr 2020 17:35:38 GMT
|
||||||
|
|
||||||
|
### Patches
|
||||||
|
|
||||||
|
- another take on tar task using tar-fs instead because it can actually handle large amounts of data (kchau@microsoft.com)
|
||||||
|
## 0.37.0
|
||||||
|
Mon, 06 Apr 2020 21:43:56 GMT
|
||||||
|
|
||||||
|
### Minor changes
|
||||||
|
|
||||||
|
- Adds a new set of tar create and extract tasks (kchau@microsoft.com)
|
||||||
## 0.36.1
|
## 0.36.1
|
||||||
Wed, 13 Nov 2019 19:42:46 GMT
|
Wed, 13 Nov 2019 19:42:46 GMT
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,32 @@
|
||||||
{
|
{
|
||||||
"name": "just-scripts",
|
"name": "just-scripts",
|
||||||
"version": "0.36.1",
|
"version": "0.38.0",
|
||||||
"description": "Just Stack Scripts",
|
"description": "Just Stack Scripts",
|
||||||
|
"keywords": [],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/microsoft/just"
|
"url": "https://github.com/microsoft/just"
|
||||||
},
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"author": "",
|
||||||
|
"main": "./lib/index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
"just-scripts": "bin/just-scripts.js"
|
"just-scripts": "bin/just-scripts.js"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"scripts": {
|
||||||
"author": "",
|
"build": "tsc",
|
||||||
"license": "MIT",
|
"start": "tsc -w --preserveWatchOutput",
|
||||||
"main": "./lib/index.js",
|
"test": "jest",
|
||||||
|
"test:update": "jest --updateSnapshot"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "^10.12.18",
|
"@types/node": "^10.12.18",
|
||||||
"chalk": "^2.4.1",
|
"chalk": "^2.4.1",
|
||||||
"diff-match-patch": "1.0.4",
|
"diff-match-patch": "1.0.4",
|
||||||
"fs-extra": "^7.0.1",
|
"fs-extra": "^7.0.1",
|
||||||
"glob": "^7.1.3",
|
"glob": "^7.1.3",
|
||||||
"just-scripts-utils": ">=0.8.4 <1.0.0",
|
"just-scripts-utils": ">=0.9.0 <1.0.0",
|
||||||
"just-task": ">=0.14.3 <1.0.0",
|
"just-task": ">=0.15.0 <1.0.0",
|
||||||
"npm-registry-fetch": "^3.9.0",
|
"npm-registry-fetch": "^3.9.0",
|
||||||
"prompts": "^2.0.1",
|
"prompts": "^2.0.1",
|
||||||
"run-parallel-limit": "^1.0.5",
|
"run-parallel-limit": "^1.0.5",
|
||||||
|
@ -28,24 +34,19 @@
|
||||||
"webpack-merge": "^4.2.1"
|
"webpack-merge": "^4.2.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/supports-color": "5.3.0",
|
|
||||||
"@types/diff-match-patch": "1.0.32",
|
"@types/diff-match-patch": "1.0.32",
|
||||||
"@types/fs-extra": "^5.0.4",
|
"@types/fs-extra": "^5.0.4",
|
||||||
"@types/glob": "^7.1.1",
|
"@types/glob": "^7.1.1",
|
||||||
"@types/jest": "^24.0.13",
|
"@types/jest": "^24.0.13",
|
||||||
"@types/prompts": "^1.2.0",
|
"@types/prompts": "^1.2.0",
|
||||||
"@types/run-parallel-limit": "^1.0.0",
|
"@types/run-parallel-limit": "^1.0.0",
|
||||||
|
"@types/supports-color": "5.3.0",
|
||||||
|
"@types/tar": "^4.0.3",
|
||||||
"@types/webpack-merge": "^4.1.3",
|
"@types/webpack-merge": "^4.1.3",
|
||||||
"async-done": "^1.3.2",
|
"async-done": "^1.3.2",
|
||||||
"jest": "^24.0.0",
|
"jest": "^24.0.0",
|
||||||
"jest-cli": "^24.8.0",
|
"jest-cli": "^24.8.0",
|
||||||
"mock-fs": "^4.8.0",
|
"mock-fs": "^4.8.0",
|
||||||
"typescript": "~3.4.4"
|
"typescript": "~3.8.3"
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"build": "tsc",
|
|
||||||
"start": "tsc -w --preserveWatchOutput",
|
|
||||||
"test": "jest",
|
|
||||||
"test:update": "jest --updateSnapshot"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,6 @@ function executeSingleCopyInstruction(copyInstruction: CopyInstruction) {
|
||||||
|
|
||||||
// perform text merge operation.
|
// perform text merge operation.
|
||||||
return Promise.all(sourceFileNames.map(fileName => readFile(fileName))).then(fileContents => {
|
return Promise.all(sourceFileNames.map(fileName => readFile(fileName))).then(fileContents => {
|
||||||
writeFile(copyInstruction.destinationFilePath, fileContents.join('\n'));
|
return writeFile(copyInstruction.destinationFilePath, fileContents.join('\n'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
// This doesn't have types for some reason
|
||||||
|
const { DefaultReporter } = require('@jest/reporters');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The purpose of this custom reporter is to prevent Jest from logging to stderr
|
||||||
|
* when there are no errors.
|
||||||
|
*/
|
||||||
|
class JestReporter extends DefaultReporter {
|
||||||
|
private _isLoggingError = false;
|
||||||
|
|
||||||
|
public log(message: string) {
|
||||||
|
if (this._isLoggingError) {
|
||||||
|
process.stderr.write(message + '\n');
|
||||||
|
} else {
|
||||||
|
process.stdout.write(message + '\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public printTestFileFailureMessage(...args: any[]) {
|
||||||
|
this._isLoggingError = true;
|
||||||
|
super.printTestFileFailureMessage(...args);
|
||||||
|
this._isLoggingError = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// jest needs this format
|
||||||
|
module.exports = JestReporter;
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -2,46 +2,22 @@ import { logger, TaskFunction } from 'just-task';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { tryRequire } from '../tryRequire';
|
import { tryRequire } from '../tryRequire';
|
||||||
// This is a TYPING ONLY import from <root>/typings/api-extractor.d.ts
|
import * as ApiExtractorTypes from './api-extractor.d';
|
||||||
import * as ApiExtractorTypes from '@microsoft/api-extractor';
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subset of the options from `IExtractorConfigOptions` that are exposed via this just task,
|
* Options from `IExtractorConfigOptions` plus additional options specific to the task.
|
||||||
* plus additional options specific to the task.
|
|
||||||
*/
|
*/
|
||||||
export interface ApiExtractorOptions {
|
export interface ApiExtractorOptions extends ApiExtractorTypes.IExtractorInvokeOptions {
|
||||||
/**
|
/** @deprecated Does not appear to be used */
|
||||||
* Indicates that API Extractor is running as part of a local build, e.g. on developer's
|
|
||||||
* machine. This disables certain validation that would normally be performed
|
|
||||||
* for a ship/production build. For example, the *.api.md report file is
|
|
||||||
* automatically updated in a local build.
|
|
||||||
*
|
|
||||||
* The default value is false.
|
|
||||||
*/
|
|
||||||
localBuild?: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If true, API Extractor will include {@link ExtractorLogLevel.Verbose} messages in its output.
|
|
||||||
*/
|
|
||||||
showVerboseMessages?: boolean;
|
|
||||||
|
|
||||||
projectFolder?: string;
|
projectFolder?: string;
|
||||||
|
|
||||||
/**
|
|
||||||
* By default API Extractor uses its own TypeScript compiler version to analyze your project.
|
|
||||||
* This can often cause compiler errors due to incompatibilities between different TS versions.
|
|
||||||
* Use this option to specify the folder path for your compiler version.
|
|
||||||
*/
|
|
||||||
typescriptCompilerFolder?: string;
|
|
||||||
|
|
||||||
/** The config file path */
|
/** The config file path */
|
||||||
configJsonFilePath?: string;
|
configJsonFilePath?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API Extractor uses CRLF newlines by default and adds trailing spaces after empty comment lines,
|
* @deprecated Update API Extractor and use option `newlineKind: 'os'`.
|
||||||
* both of which can add excessive noise to diffs. Set this option to true to post-process the
|
|
||||||
* API Extractor .md file to fix these issues (newline type will be inferred from the type used in
|
|
||||||
* the config file). It will also remove trailing spaces.
|
|
||||||
*/
|
*/
|
||||||
fixNewlines?: boolean;
|
fixNewlines?: boolean;
|
||||||
|
|
||||||
|
@ -131,7 +107,7 @@ export function apiExtractorUpdateTask(
|
||||||
return function apiExtractorUpdate() {
|
return function apiExtractorUpdate() {
|
||||||
const context = initApiExtractor(options);
|
const context = initApiExtractor(options);
|
||||||
if (context) {
|
if (context) {
|
||||||
const apiExtractorResult = apiExtractorWrapper(context);
|
let apiExtractorResult = apiExtractorWrapper(context);
|
||||||
|
|
||||||
if (apiExtractorResult) {
|
if (apiExtractorResult) {
|
||||||
if (!apiExtractorResult.succeeded) {
|
if (!apiExtractorResult.succeeded) {
|
||||||
|
@ -140,7 +116,8 @@ export function apiExtractorUpdateTask(
|
||||||
|
|
||||||
logger.info(`- Update API: successfully updated API file, verifying the updates...`);
|
logger.info(`- Update API: successfully updated API file, verifying the updates...`);
|
||||||
|
|
||||||
if (!apiExtractorWrapper(context)!.succeeded) {
|
apiExtractorResult = apiExtractorWrapper(context);
|
||||||
|
if (!apiExtractorResult || !apiExtractorResult.succeeded) {
|
||||||
throw new Error(`- Update API: failed to verify API updates.`);
|
throw new Error(`- Update API: failed to verify API updates.`);
|
||||||
} else {
|
} else {
|
||||||
logger.info(`- Update API: successully verified API file. Please commit API file as part of your changes.`);
|
logger.info(`- Update API: successully verified API file. Please commit API file as part of your changes.`);
|
||||||
|
@ -155,6 +132,7 @@ export function apiExtractorUpdateTask(
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the api-extractor module (if available) and the config file.
|
* 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: ApiExtractorOptions): ApiExtractorContext | undefined {
|
function initApiExtractor(options: ApiExtractorOptions): ApiExtractorContext | undefined {
|
||||||
const apiExtractorModule: typeof ApiExtractorTypes = tryRequire('@microsoft/api-extractor');
|
const apiExtractorModule: typeof ApiExtractorTypes = tryRequire('@microsoft/api-extractor');
|
||||||
|
|
|
@ -14,3 +14,4 @@ export * from './prettierTask';
|
||||||
export * from './eslintTask';
|
export * from './eslintTask';
|
||||||
export * from './webpackCliInitTask';
|
export * from './webpackCliInitTask';
|
||||||
export * from './webpackCliTask';
|
export * from './webpackCliTask';
|
||||||
|
export * from './tarTask';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { resolve, logger, resolveCwd, TaskFunction } from 'just-task';
|
import { resolve, logger, resolveCwd, TaskFunction, argv } from 'just-task';
|
||||||
import { spawn, encodeArgs } from 'just-scripts-utils';
|
import { spawn, encodeArgs } from 'just-scripts-utils';
|
||||||
import { existsSync } from 'fs';
|
import { existsSync } from 'fs';
|
||||||
import supportsColor from 'supports-color';
|
import supportsColor from 'supports-color';
|
||||||
|
@ -11,6 +11,8 @@ export interface JestTaskOptions {
|
||||||
watch?: boolean;
|
watch?: boolean;
|
||||||
colors?: boolean;
|
colors?: boolean;
|
||||||
passWithNoTests?: boolean;
|
passWithNoTests?: boolean;
|
||||||
|
testPathPattern?: string;
|
||||||
|
testNamePattern?: string;
|
||||||
u?: boolean;
|
u?: boolean;
|
||||||
_?: string[];
|
_?: string[];
|
||||||
|
|
||||||
|
@ -35,6 +37,10 @@ export function jestTask(options: JestTaskOptions = {}): TaskFunction {
|
||||||
if (configFile && jestCmd && existsSync(configFile)) {
|
if (configFile && jestCmd && existsSync(configFile)) {
|
||||||
logger.info(`Running Jest`);
|
logger.info(`Running Jest`);
|
||||||
const cmd = process.execPath;
|
const cmd = process.execPath;
|
||||||
|
|
||||||
|
const positional = argv()._.slice(1);
|
||||||
|
options = { ...options, ...{ ...argv(), _: positional } };
|
||||||
|
|
||||||
const args = [
|
const args = [
|
||||||
...(options.nodeArgs || []),
|
...(options.nodeArgs || []),
|
||||||
jestCmd,
|
jestCmd,
|
||||||
|
@ -45,6 +51,8 @@ export function jestTask(options: JestTaskOptions = {}): TaskFunction {
|
||||||
...(options.runInBand ? ['--runInBand'] : []),
|
...(options.runInBand ? ['--runInBand'] : []),
|
||||||
...(options.coverage ? ['--coverage'] : []),
|
...(options.coverage ? ['--coverage'] : []),
|
||||||
...(options.watch ? ['--watch'] : []),
|
...(options.watch ? ['--watch'] : []),
|
||||||
|
...(options.testPathPattern ? ['--testPathPattern', options.testPathPattern] : []),
|
||||||
|
...(options.testNamePattern ? ['--testNamePattern', options.testNamePattern] : []),
|
||||||
...(options.u || options.updateSnapshot ? ['--updateSnapshot'] : ['']),
|
...(options.u || options.updateSnapshot ? ['--updateSnapshot'] : ['']),
|
||||||
...(options._ || [])
|
...(options._ || [])
|
||||||
].filter(arg => !!arg) as Array<string>;
|
].filter(arg => !!arg) as Array<string>;
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
import { resolve, logger, TaskFunction } from 'just-task';
|
||||||
|
import { createWriteStream, createReadStream } from 'fs';
|
||||||
|
import { createGzip, createGunzip } from 'zlib';
|
||||||
|
import { Stream } from 'stream';
|
||||||
|
|
||||||
|
export interface EntryHeader {
|
||||||
|
name: string;
|
||||||
|
size: number;
|
||||||
|
|
||||||
|
/** entry mode. defaults to to 0755 for dirs and 0644 otherwise */
|
||||||
|
mode: number; //
|
||||||
|
|
||||||
|
/** last modified date for entry. defaults to now. */
|
||||||
|
mtime: Date;
|
||||||
|
|
||||||
|
/** type of entry. defaults to "file". */
|
||||||
|
type: 'file' | 'link' | 'symlink' | 'directory' | 'block-device' | 'character-device' | 'fifo' | 'contiguous-file';
|
||||||
|
|
||||||
|
/** linked file name */
|
||||||
|
linkname: string;
|
||||||
|
|
||||||
|
uid: number;
|
||||||
|
gid: number;
|
||||||
|
uname: string;
|
||||||
|
gname: string;
|
||||||
|
devmajor: number;
|
||||||
|
devminor: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreateOptions {
|
||||||
|
/** output file */
|
||||||
|
file: string;
|
||||||
|
|
||||||
|
/** whether to gzip or not, either a boolean or uses the `zlib.Gzip` options like level, memLevel */
|
||||||
|
gzip?:
|
||||||
|
| boolean
|
||||||
|
| {
|
||||||
|
level?: number;
|
||||||
|
memLevel?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** the context path of the tar pack */
|
||||||
|
cwd?: string;
|
||||||
|
|
||||||
|
/** filter (ignore) entries */
|
||||||
|
filter?: (path: string, header: EntryHeader) => boolean;
|
||||||
|
|
||||||
|
/** change the header in the entry (e.g. to replace prefix) */
|
||||||
|
map?: (header: EntryHeader) => EntryHeader;
|
||||||
|
|
||||||
|
/** whether to dereference links */
|
||||||
|
dereference?: boolean;
|
||||||
|
|
||||||
|
/** specify a set of entries to be packed */
|
||||||
|
entries?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an tar (optionally gzipped) archive
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
export function createTarTask(options: CreateOptions = { file: 'archive.tar.gz' }): TaskFunction {
|
||||||
|
const resolvedTar = resolve('tar-fs');
|
||||||
|
|
||||||
|
// Inject default options
|
||||||
|
options = { cwd: process.cwd(), gzip: true, ...options };
|
||||||
|
|
||||||
|
// Validate whether tar-fs is installed
|
||||||
|
if (!resolvedTar) {
|
||||||
|
logger.error('Please make sure to have "tar-fs" as a dependency in your package.json');
|
||||||
|
throw new Error('Required dependency "tar-fs" is not installed!');
|
||||||
|
}
|
||||||
|
|
||||||
|
const tar = require(resolvedTar);
|
||||||
|
|
||||||
|
let { entries, file, cwd, ...restOptions } = options;
|
||||||
|
|
||||||
|
return function archive(done) {
|
||||||
|
let tarStream = tar.pack(cwd, {
|
||||||
|
entries,
|
||||||
|
finalize: true,
|
||||||
|
finish: () => {
|
||||||
|
done();
|
||||||
|
},
|
||||||
|
...restOptions
|
||||||
|
});
|
||||||
|
|
||||||
|
if (options.gzip) {
|
||||||
|
const gzip = typeof options.gzip === 'boolean' ? createGzip() : createGzip(options.gzip as any);
|
||||||
|
tarStream = tarStream.pipe(gzip);
|
||||||
|
}
|
||||||
|
|
||||||
|
tarStream.pipe(createWriteStream(options.file));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ExtractOptions {
|
||||||
|
/** output file */
|
||||||
|
file: string;
|
||||||
|
|
||||||
|
/** whether to gzip or not, either a boolean or uses the `zlib.Gzip` options like level, memLevel */
|
||||||
|
gzip?: boolean;
|
||||||
|
|
||||||
|
/** the context path of the tar pack */
|
||||||
|
cwd?: string;
|
||||||
|
|
||||||
|
/** filter (ignore) entries */
|
||||||
|
filter?: (path: string, header: EntryHeader) => boolean;
|
||||||
|
|
||||||
|
/** change the header in the entry (e.g. to replace prefix) */
|
||||||
|
map?: (header: EntryHeader) => EntryHeader;
|
||||||
|
|
||||||
|
/** mode for files (e.g. `parseInt(755, 8)`)*/
|
||||||
|
fmode?: number;
|
||||||
|
|
||||||
|
/** mode for directories (e.g. `parseInt(755, 8)`) */
|
||||||
|
dmode?: number;
|
||||||
|
|
||||||
|
/** set whether all files and dirs are readable */
|
||||||
|
readable?: boolean;
|
||||||
|
|
||||||
|
/** set whether all files and dirs are writable */
|
||||||
|
writable?: boolean;
|
||||||
|
|
||||||
|
/** whether to dereference links */
|
||||||
|
dereference?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an tar (optionally gzipped) archive
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
export function extractTarTask(options: ExtractOptions = { file: 'archive.tar.gz' }): TaskFunction {
|
||||||
|
const resolvedTar = resolve('tar-fs');
|
||||||
|
|
||||||
|
// Inject default options
|
||||||
|
options = { cwd: process.cwd(), gzip: true, ...options };
|
||||||
|
|
||||||
|
// Validate whether tar-fs is installed
|
||||||
|
if (!resolvedTar) {
|
||||||
|
logger.error('Please make sure to have "tar-fs" as a dependency in your package.json');
|
||||||
|
throw new Error('Required dependency "tar-fs" is not installed!');
|
||||||
|
}
|
||||||
|
|
||||||
|
const tar = require(resolvedTar);
|
||||||
|
|
||||||
|
const { cwd, file, ...restOptions } = options;
|
||||||
|
|
||||||
|
return function extract(done) {
|
||||||
|
let tarStream: Stream = createReadStream(file);
|
||||||
|
|
||||||
|
if (options.gzip) {
|
||||||
|
const gunzip = createGunzip();
|
||||||
|
tarStream = tarStream.pipe(gunzip);
|
||||||
|
}
|
||||||
|
|
||||||
|
tarStream = tarStream.pipe(
|
||||||
|
tar.extract(cwd, {
|
||||||
|
finalize: true,
|
||||||
|
finish: () => {
|
||||||
|
done();
|
||||||
|
},
|
||||||
|
...restOptions
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,918 +0,0 @@
|
||||||
//
|
|
||||||
// Types copied from api-extractor, so we can use some version of the types without a dependency.
|
|
||||||
// Copied from version 7.3.7.
|
|
||||||
//
|
|
||||||
|
|
||||||
declare module '@microsoft/api-extractor' {
|
|
||||||
/**
|
|
||||||
* This class represents the TypeScript compiler state. This allows an optimization where multiple invocations
|
|
||||||
* of API Extractor can reuse the same TypeScript compiler analysis.
|
|
||||||
*/
|
|
||||||
export class CompilerState {
|
|
||||||
/**
|
|
||||||
* The TypeScript compiler's `Program` object, which represents a complete scope of analysis.
|
|
||||||
* Actual type is `ts.Program`.
|
|
||||||
*/
|
|
||||||
readonly program: any;
|
|
||||||
private constructor();
|
|
||||||
/**
|
|
||||||
* Create a compiler state for use with the specified `IExtractorInvokeOptions`.
|
|
||||||
*/
|
|
||||||
static create(extractorConfig: ExtractorConfig, options?: ICompilerStateCreateOptions): CompilerState;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unique identifiers for console messages reported by API Extractor.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
*
|
|
||||||
* These strings are possible values for the {@link ExtractorMessage.messageId} property
|
|
||||||
* when the `ExtractorMessage.category` is {@link ExtractorMessageCategory.Console}.
|
|
||||||
*/
|
|
||||||
export const enum ConsoleMessageId {
|
|
||||||
/**
|
|
||||||
* "Found metadata in ___"
|
|
||||||
*/
|
|
||||||
FoundTSDocMetadata = 'console-found-tsdoc-metadata',
|
|
||||||
/**
|
|
||||||
* "Writing: ___"
|
|
||||||
*/
|
|
||||||
WritingDocModelFile = 'console-writing-doc-model-file',
|
|
||||||
/**
|
|
||||||
* "Writing package typings: ___"
|
|
||||||
*/
|
|
||||||
WritingDtsRollup = 'console-writing-dts-rollup',
|
|
||||||
/**
|
|
||||||
* "You have changed the public API signature for this project.
|
|
||||||
* Please copy the file ___ to ___, or perform a local build (which does this automatically).
|
|
||||||
* See the Git repo documentation for more info."
|
|
||||||
*
|
|
||||||
* OR
|
|
||||||
*
|
|
||||||
* "The API report file is missing.
|
|
||||||
* Please copy the file ___ to ___, or perform a local build (which does this automatically).
|
|
||||||
* See the Git repo documentation for more info."
|
|
||||||
*/
|
|
||||||
ApiReportNotCopied = 'console-api-report-not-copied',
|
|
||||||
/**
|
|
||||||
* "You have changed the public API signature for this project. Updating ___"
|
|
||||||
*/
|
|
||||||
ApiReportCopied = 'console-api-report-copied',
|
|
||||||
/**
|
|
||||||
* "The API report is up to date: ___"
|
|
||||||
*/
|
|
||||||
ApiReportUnchanged = 'console-api-report-unchanged',
|
|
||||||
/**
|
|
||||||
* "The API report file was missing, so a new file was created. Please add this file to Git: ___"
|
|
||||||
*/
|
|
||||||
ApiReportCreated = 'console-api-report-created',
|
|
||||||
/**
|
|
||||||
* "Unable to create the API report file. Please make sure the target folder exists: ___"
|
|
||||||
*/
|
|
||||||
ApiReportFolderMissing = 'console-api-report-folder-missing',
|
|
||||||
/**
|
|
||||||
* Used for the information printed when the "--diagnostics" flag is enabled.
|
|
||||||
*/
|
|
||||||
Diagnostics = 'console-diagnostics'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The starting point for invoking the API Extractor tool.
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
export class Extractor {
|
|
||||||
/**
|
|
||||||
* Returns the version number of the API Extractor NPM package.
|
|
||||||
*/
|
|
||||||
static readonly version: string;
|
|
||||||
/**
|
|
||||||
* Returns the package name of the API Extractor NPM package.
|
|
||||||
*/
|
|
||||||
static readonly packageName: string;
|
|
||||||
/**
|
|
||||||
* Load the api-extractor.json config file from the specified path, and then invoke API Extractor.
|
|
||||||
*/
|
|
||||||
static loadConfigAndInvoke(configFilePath: string, options?: IExtractorInvokeOptions): ExtractorResult;
|
|
||||||
/**
|
|
||||||
* Invoke API Extractor using an already prepared `ExtractorConfig` object.
|
|
||||||
*/
|
|
||||||
static invoke(extractorConfig: ExtractorConfig, options?: IExtractorInvokeOptions): ExtractorResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `ExtractorConfig` class loads, validates, interprets, and represents the api-extractor.json config file.
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
export class ExtractorConfig {
|
|
||||||
/**
|
|
||||||
* The JSON Schema for API Extractor config file (api-extractor.schema.json).
|
|
||||||
*/
|
|
||||||
static readonly jsonSchema: object;
|
|
||||||
/**
|
|
||||||
* The config file name "api-extractor.json".
|
|
||||||
*/
|
|
||||||
static readonly FILENAME: string;
|
|
||||||
/** {@inheritDoc IConfigFile.projectFolder} */
|
|
||||||
readonly projectFolder: string;
|
|
||||||
/**
|
|
||||||
* The parsed package.json file for the working package, or undefined if API Extractor was invoked without
|
|
||||||
* a package.json file.
|
|
||||||
*/
|
|
||||||
readonly packageJson: object | undefined;
|
|
||||||
/**
|
|
||||||
* The absolute path of the folder containing the package.json file for the working package, or undefined
|
|
||||||
* if API Extractor was invoked without a package.json file.
|
|
||||||
*/
|
|
||||||
readonly packageFolder: string | undefined;
|
|
||||||
/** {@inheritDoc IConfigFile.mainEntryPointFilePath} */
|
|
||||||
readonly mainEntryPointFilePath: string;
|
|
||||||
/** {@inheritDoc IConfigCompiler.tsconfigFilePath} */
|
|
||||||
readonly tsconfigFilePath: string;
|
|
||||||
/** {@inheritDoc IConfigCompiler.overrideTsconfig} */
|
|
||||||
readonly overrideTsconfig: {} | undefined;
|
|
||||||
/** {@inheritDoc IConfigCompiler.skipLibCheck} */
|
|
||||||
readonly skipLibCheck: boolean;
|
|
||||||
/** {@inheritDoc IConfigApiReport.enabled} */
|
|
||||||
readonly apiReportEnabled: boolean;
|
|
||||||
/** The `reportFolder` path combined with the `reportFileName`. */
|
|
||||||
readonly reportFilePath: string;
|
|
||||||
/** The `reportTempFolder` path combined with the `reportFileName`. */
|
|
||||||
readonly reportTempFilePath: string;
|
|
||||||
/** {@inheritDoc IConfigDocModel.enabled} */
|
|
||||||
readonly docModelEnabled: boolean;
|
|
||||||
/** {@inheritDoc IConfigDocModel.apiJsonFilePath} */
|
|
||||||
readonly apiJsonFilePath: string;
|
|
||||||
/** {@inheritDoc IConfigDtsRollup.enabled} */
|
|
||||||
readonly rollupEnabled: boolean;
|
|
||||||
/** {@inheritDoc IConfigDtsRollup.untrimmedFilePath} */
|
|
||||||
readonly untrimmedFilePath: string;
|
|
||||||
/** {@inheritDoc IConfigDtsRollup.betaTrimmedFilePath} */
|
|
||||||
readonly betaTrimmedFilePath: string;
|
|
||||||
/** {@inheritDoc IConfigDtsRollup.publicTrimmedFilePath} */
|
|
||||||
readonly publicTrimmedFilePath: string;
|
|
||||||
/** {@inheritDoc IConfigDtsRollup.omitTrimmingComments} */
|
|
||||||
readonly omitTrimmingComments: boolean;
|
|
||||||
/** {@inheritDoc IConfigTsdocMetadata.enabled} */
|
|
||||||
readonly tsdocMetadataEnabled: boolean;
|
|
||||||
/** {@inheritDoc IConfigTsdocMetadata.tsdocMetadataFilePath} */
|
|
||||||
readonly tsdocMetadataFilePath: string;
|
|
||||||
/** {@inheritDoc IConfigFile.messages} */
|
|
||||||
readonly messages: IExtractorMessagesConfig;
|
|
||||||
/** {@inheritDoc IConfigFile.testMode} */
|
|
||||||
readonly testMode: boolean;
|
|
||||||
private constructor();
|
|
||||||
/**
|
|
||||||
* Returns a JSON-like string representing the `ExtractorConfig` state, which can be printed to a console
|
|
||||||
* for diagnostic purposes.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This is used by the "--diagnostics" command-line option. The string is not intended to be deserialized;
|
|
||||||
* its format may be changed at any time.
|
|
||||||
*/
|
|
||||||
getDiagnosticDump(): string;
|
|
||||||
/**
|
|
||||||
* Returns a simplified file path for use in error messages.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_getShortFilePath(absolutePath: string): string;
|
|
||||||
/**
|
|
||||||
* Loads the api-extractor.json config file from the specified file path, and prepares an `ExtractorConfig` object.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* Loads the api-extractor.json config file from the specified file path. If the "extends" field is present,
|
|
||||||
* the referenced file(s) will be merged. For any omitted fields, the API Extractor default values are merged.
|
|
||||||
*
|
|
||||||
* The result is prepared using `ExtractorConfig.prepare()`.
|
|
||||||
*/
|
|
||||||
static loadFileAndPrepare(configJsonFilePath: string): ExtractorConfig;
|
|
||||||
/**
|
|
||||||
* Performs only the first half of {@link ExtractorConfig.loadFileAndPrepare}, providing an opportunity to
|
|
||||||
* modify the object before it is passed to {@link ExtractorConfig.prepare}.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* Loads the api-extractor.json config file from the specified file path. If the "extends" field is present,
|
|
||||||
* the referenced file(s) will be merged. For any omitted fields, the API Extractor default values are merged.
|
|
||||||
*/
|
|
||||||
static loadFile(jsonFilePath: string): IConfigFile;
|
|
||||||
/**
|
|
||||||
* Prepares an `ExtractorConfig` object using a configuration that is provided as a runtime object,
|
|
||||||
* rather than reading it from disk. This allows configurations to be constructed programmatically,
|
|
||||||
* loaded from an alternate source, and/or customized after loading.
|
|
||||||
*/
|
|
||||||
static prepare(options: IExtractorConfigPrepareOptions): ExtractorConfig;
|
|
||||||
/**
|
|
||||||
* Returns true if the specified file path has the ".d.ts" file extension.
|
|
||||||
*/
|
|
||||||
static hasDtsFileExtension(filePath: string): boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used with {@link IConfigMessageReportingRule.logLevel} and {@link IExtractorInvokeOptions.messageCallback}.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This is part of the {@link IConfigFile} structure.
|
|
||||||
*/
|
|
||||||
export const enum ExtractorLogLevel {
|
|
||||||
/**
|
|
||||||
* The message will be displayed as an error.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* Errors typically cause the build to fail and return a nonzero exit code.
|
|
||||||
*/
|
|
||||||
Error = 'error',
|
|
||||||
/**
|
|
||||||
* The message will be displayed as an warning.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* Warnings typically cause a production build fail and return a nonzero exit code. For a non-production build
|
|
||||||
* (e.g. using the `--local` option with `api-extractor run`), the warning is displayed but the build will not fail.
|
|
||||||
*/
|
|
||||||
Warning = 'warning',
|
|
||||||
/**
|
|
||||||
* The message will be displayed as an informational message.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* Informational messages may contain newlines to ensure nice formatting of the output,
|
|
||||||
* however word-wrapping is the responsibility of the message handler.
|
|
||||||
*/
|
|
||||||
Info = 'info',
|
|
||||||
/**
|
|
||||||
* The message will be displayed only when "verbose" output is requested, e.g. using the `--verbose`
|
|
||||||
* command line option.
|
|
||||||
*/
|
|
||||||
Verbose = 'verbose',
|
|
||||||
/**
|
|
||||||
* The message will be discarded entirely.
|
|
||||||
*/
|
|
||||||
None = 'none'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This object is used to report an error or warning that occurred during API Extractor's analysis.
|
|
||||||
*/
|
|
||||||
export class ExtractorMessage {
|
|
||||||
/**
|
|
||||||
* The category of issue.
|
|
||||||
*/
|
|
||||||
readonly category: ExtractorMessageCategory;
|
|
||||||
/**
|
|
||||||
* A text string that uniquely identifies the issue type. This identifier can be used to suppress
|
|
||||||
* or configure the reporting of issues, and also to search for help about an issue.
|
|
||||||
*/
|
|
||||||
readonly messageId: /*tsdoc.TSDocMessageId |*/ ExtractorMessageId | ConsoleMessageId | string;
|
|
||||||
/**
|
|
||||||
* The text description of this issue.
|
|
||||||
*/
|
|
||||||
readonly text: string;
|
|
||||||
/**
|
|
||||||
* The absolute path to the affected input source file, if there is one.
|
|
||||||
*/
|
|
||||||
readonly sourceFilePath: string | undefined;
|
|
||||||
/**
|
|
||||||
* The line number where the issue occurred in the input source file. This is not used if `sourceFilePath`
|
|
||||||
* is undefined. The first line number is 1.
|
|
||||||
*/
|
|
||||||
readonly sourceFileLine: number | undefined;
|
|
||||||
/**
|
|
||||||
* The column number where the issue occurred in the input source file. This is not used if `sourceFilePath`
|
|
||||||
* is undefined. The first column number is 1.
|
|
||||||
*/
|
|
||||||
readonly sourceFileColumn: number | undefined;
|
|
||||||
/**
|
|
||||||
* Additional contextual information about the message that may be useful when reporting errors.
|
|
||||||
* All properties are optional.
|
|
||||||
*/
|
|
||||||
readonly properties: IExtractorMessageProperties;
|
|
||||||
/**
|
|
||||||
* If the {@link IExtractorInvokeOptions.messageCallback} sets this property to true, it will prevent the message
|
|
||||||
* from being displayed by API Extractor.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* If the `messageCallback` routes the message to a custom handler (e.g. a toolchain logger), it should
|
|
||||||
* assign `handled = true` to prevent API Extractor from displaying it. Assigning `handled = true` for all messages
|
|
||||||
* would effectively disable all console output from the `Extractor` API.
|
|
||||||
*
|
|
||||||
* If `handled` is set to true, the message will still be included in the count of errors/warnings;
|
|
||||||
* to discard a message entirely, instead assign `logLevel = none`.
|
|
||||||
*/
|
|
||||||
handled: boolean;
|
|
||||||
/**
|
|
||||||
* Specifies how the message should be reported.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* If the {@link IExtractorInvokeOptions.messageCallback} handles the message (i.e. sets `handled = true`),
|
|
||||||
* it can use the `logLevel` to determine how to display the message.
|
|
||||||
*
|
|
||||||
* Alternatively, if API Extractor is handling the message, the `messageCallback` could assign `logLevel` to change
|
|
||||||
* how it will be processed. However, in general the recommended practice is to configure message routing
|
|
||||||
* using the `messages` section in api-extractor.json.
|
|
||||||
*
|
|
||||||
* To discard a message entirely, assign `logLevel = none`.
|
|
||||||
*/
|
|
||||||
logLevel: ExtractorLogLevel;
|
|
||||||
/**
|
|
||||||
* Returns the message formatted with its identifier and file position.
|
|
||||||
* @remarks
|
|
||||||
* Example:
|
|
||||||
* ```
|
|
||||||
* src/folder/File.ts:123:4 - (ae-extra-release-tag) The doc comment should not contain more than one release tag.
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
formatMessageWithLocation(workingPackageFolderPath: string | undefined): string;
|
|
||||||
formatMessageWithoutLocation(): string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies a category of messages for use with {@link ExtractorMessage}.
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
export const enum ExtractorMessageCategory {
|
|
||||||
/**
|
|
||||||
* Messages originating from the TypeScript compiler.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* These strings begin with the prefix "TS" and have a numeric error code.
|
|
||||||
* Example: `TS2551`
|
|
||||||
*/
|
|
||||||
Compiler = 'Compiler',
|
|
||||||
/**
|
|
||||||
* Messages related to parsing of TSDoc comments.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* These strings begin with the prefix "tsdoc-".
|
|
||||||
* Example: `tsdoc-link-tag-unescaped-text`
|
|
||||||
*/
|
|
||||||
TSDoc = 'TSDoc',
|
|
||||||
/**
|
|
||||||
* Messages related to API Extractor's analysis.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* These strings begin with the prefix "ae-".
|
|
||||||
* Example: `ae-extra-release-tag`
|
|
||||||
*/
|
|
||||||
Extractor = 'Extractor',
|
|
||||||
/**
|
|
||||||
* Console messages communicate the progress of the overall operation. They may include newlines to ensure
|
|
||||||
* nice formatting. They are output in real time, and cannot be routed to the API Report file.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* These strings begin with the prefix "console-".
|
|
||||||
* Example: `console-writing-typings-file`
|
|
||||||
*/
|
|
||||||
Console = 'console'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unique identifiers for messages reported by API Extractor during its analysis.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
*
|
|
||||||
* These strings are possible values for the {@link ExtractorMessage.messageId} property
|
|
||||||
* when the `ExtractorMessage.category` is {@link ExtractorMessageCategory.Extractor}.
|
|
||||||
*/
|
|
||||||
export const enum ExtractorMessageId {
|
|
||||||
/**
|
|
||||||
* "The doc comment should not contain more than one release tag."
|
|
||||||
*/
|
|
||||||
ExtraReleaseTag = 'ae-extra-release-tag',
|
|
||||||
/**
|
|
||||||
* "This symbol has another declaration with a different release tag."
|
|
||||||
*/
|
|
||||||
DifferentReleaseTags = 'ae-different-release-tags',
|
|
||||||
/**
|
|
||||||
* "The symbol ___ is marked as ___, but its signature references ___ which is marked as ___."
|
|
||||||
*/
|
|
||||||
IncompatibleReleaseTags = 'ae-incompatible-release-tags',
|
|
||||||
/**
|
|
||||||
* "___ is exported by the package, but it is missing a release tag (`@alpha`, `@beta`, `@public`, or `@internal`)."
|
|
||||||
*/
|
|
||||||
MissingReleaseTag = 'ae-missing-release-tag',
|
|
||||||
/**
|
|
||||||
* "The `@packageDocumentation` comment must appear at the top of entry point *.d.ts file."
|
|
||||||
*/
|
|
||||||
MisplacedPackageTag = 'ae-misplaced-package-tag',
|
|
||||||
/**
|
|
||||||
* "The symbol ___ needs to be exported by the entry point ___."
|
|
||||||
*/
|
|
||||||
ForgottenExport = 'ae-forgotten-export',
|
|
||||||
/**
|
|
||||||
* "The name ___ should be prefixed with an underscore because the declaration is marked as `@internal`."
|
|
||||||
*/
|
|
||||||
InternalMissingUnderscore = 'ae-internal-missing-underscore',
|
|
||||||
/**
|
|
||||||
* "The `@preapproved` tag cannot be applied to ___ because it is not a supported declaration type."
|
|
||||||
*/
|
|
||||||
PreapprovedUnsupportedType = 'ae-preapproved-unsupported-type',
|
|
||||||
/**
|
|
||||||
* "The `@preapproved` tag cannot be applied to ___ without an `@internal` release tag."
|
|
||||||
*/
|
|
||||||
PreapprovedBadReleaseTag = 'ae-preapproved-bad-release-tag',
|
|
||||||
/**
|
|
||||||
* "The `@inheritDoc` reference could not be resolved".
|
|
||||||
*/
|
|
||||||
UnresolvedInheritDocReference = 'ae-unresolved-inheritdoc-reference',
|
|
||||||
/**
|
|
||||||
* "The `@inheritDoc` tag needs a TSDoc declaration reference; signature matching is not supported yet".
|
|
||||||
*
|
|
||||||
* @privateRemarks
|
|
||||||
* In the future, we will implement signature matching so that you can write `{@inheritDoc}` and API Extractor
|
|
||||||
* will find a corresponding member from a base class (or implemented interface). Until then, the tag
|
|
||||||
* always needs an explicit declaration reference such as `{@inhertDoc MyBaseClass.sameMethod}`.
|
|
||||||
*/
|
|
||||||
UnresolvedInheritDocBase = 'ae-unresolved-inheritdoc-base',
|
|
||||||
/**
|
|
||||||
* "The `@inheritDoc` tag for ___ refers to its own declaration".
|
|
||||||
*/
|
|
||||||
CyclicInheritDoc = 'ae-cyclic-inherit-doc',
|
|
||||||
/**
|
|
||||||
* "The `@link` reference could not be resolved".
|
|
||||||
*/
|
|
||||||
UnresolvedLink = 'ae-unresolved-link'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This object represents the outcome of an invocation of API Extractor.
|
|
||||||
*/
|
|
||||||
export class ExtractorResult {
|
|
||||||
/**
|
|
||||||
* The TypeScript compiler state that was used.
|
|
||||||
*/
|
|
||||||
readonly compilerState: CompilerState;
|
|
||||||
/**
|
|
||||||
* The API Extractor configuration that was used.
|
|
||||||
*/
|
|
||||||
readonly extractorConfig: ExtractorConfig;
|
|
||||||
/**
|
|
||||||
* Whether the invocation of API Extractor was successful. For example, if `succeeded` is false, then the build task
|
|
||||||
* would normally return a nonzero process exit code, indicating that the operation failed.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
*
|
|
||||||
* Normally the operation "succeeds" if `errorCount` and `warningCount` are both zero. However if
|
|
||||||
* {@link IExtractorInvokeOptions.localBuild} is `true`, then the operation "succeeds" if `errorCount` is zero
|
|
||||||
* (i.e. warnings are ignored).
|
|
||||||
*/
|
|
||||||
readonly succeeded: boolean;
|
|
||||||
/**
|
|
||||||
* Returns true if the API report was found to have changed.
|
|
||||||
*/
|
|
||||||
readonly apiReportChanged: boolean;
|
|
||||||
/**
|
|
||||||
* Reports the number of errors encountered during analysis.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This does not count exceptions, where unexpected issues prematurely abort the operation.
|
|
||||||
*/
|
|
||||||
readonly errorCount: number;
|
|
||||||
/**
|
|
||||||
* Reports the number of warnings encountered during analysis.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This does not count warnings that are emitted in the API report file.
|
|
||||||
*/
|
|
||||||
readonly warningCount: number;
|
|
||||||
/** @internal */
|
|
||||||
constructor(properties: ExtractorResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Options for {@link CompilerState.create}
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
export interface ICompilerStateCreateOptions {
|
|
||||||
/** {@inheritDoc IExtractorInvokeOptions.typescriptCompilerFolder} */
|
|
||||||
typescriptCompilerFolder?: string;
|
|
||||||
/**
|
|
||||||
* Additional .d.ts files to include in the analysis.
|
|
||||||
*/
|
|
||||||
additionalEntryPoints?: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures how the API report files (*.api.md) will be generated.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This is part of the {@link IConfigFile} structure.
|
|
||||||
*/
|
|
||||||
export interface IConfigApiReport {
|
|
||||||
/**
|
|
||||||
* Whether to generate an API report.
|
|
||||||
*/
|
|
||||||
enabled: boolean;
|
|
||||||
/**
|
|
||||||
* The filename for the API report files. It will be combined with `reportFolder` or `reportTempFolder` to produce
|
|
||||||
* a full output filename.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* The file extension should be ".api.md", and the string should not contain a path separator such as `\` or `/`.
|
|
||||||
*/
|
|
||||||
reportFileName?: string;
|
|
||||||
/**
|
|
||||||
* Specifies the folder where the API report file is written. The file name portion is determined by
|
|
||||||
* the `reportFileName` setting.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* The API report file is normally tracked by Git. Changes to it can be used to trigger a branch policy,
|
|
||||||
* e.g. for an API review.
|
|
||||||
*
|
|
||||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
|
||||||
* prepend a folder token such as `<projectFolder>`.
|
|
||||||
*/
|
|
||||||
reportFolder?: string;
|
|
||||||
/**
|
|
||||||
* Specifies the folder where the temporary report file is written. The file name portion is determined by
|
|
||||||
* the `reportFileName` setting.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* After the temporary file is written to disk, it is compared with the file in the `reportFolder`.
|
|
||||||
* If they are different, a production build will fail.
|
|
||||||
*
|
|
||||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
|
||||||
* prepend a folder token such as `<projectFolder>`.
|
|
||||||
*/
|
|
||||||
reportTempFolder?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines how the TypeScript compiler engine will be invoked by API Extractor.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This is part of the {@link IConfigFile} structure.
|
|
||||||
*/
|
|
||||||
export interface IConfigCompiler {
|
|
||||||
/**
|
|
||||||
* Specifies the path to the tsconfig.json file to be used by API Extractor when analyzing the project.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
|
||||||
* prepend a folder token such as `<projectFolder>`.
|
|
||||||
*
|
|
||||||
* Note: This setting will be ignored if `overrideTsconfig` is used.
|
|
||||||
*/
|
|
||||||
tsconfigFilePath?: string;
|
|
||||||
/**
|
|
||||||
* Provides a compiler configuration that will be used instead of reading the tsconfig.json file from disk.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* The value must conform to the TypeScript tsconfig schema:
|
|
||||||
*
|
|
||||||
* http://json.schemastore.org/tsconfig
|
|
||||||
*
|
|
||||||
* If omitted, then the tsconfig.json file will instead be read from the projectFolder.
|
|
||||||
*/
|
|
||||||
overrideTsconfig?: {};
|
|
||||||
/**
|
|
||||||
* This option causes the compiler to be invoked with the `--skipLibCheck` option.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This option is not recommended and may cause API Extractor to produce incomplete or incorrect declarations,
|
|
||||||
* but it may be required when dependencies contain declarations that are incompatible with the TypeScript engine
|
|
||||||
* that API Extractor uses for its analysis. Where possible, the underlying issue should be fixed rather than
|
|
||||||
* relying on skipLibCheck.
|
|
||||||
*/
|
|
||||||
skipLibCheck?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures how the doc model file (*.api.json) will be generated.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This is part of the {@link IConfigFile} structure.
|
|
||||||
*/
|
|
||||||
export interface IConfigDocModel {
|
|
||||||
/**
|
|
||||||
* Whether to generate a doc model file.
|
|
||||||
*/
|
|
||||||
enabled: boolean;
|
|
||||||
/**
|
|
||||||
* The output path for the doc model file. The file extension should be ".api.json".
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
|
||||||
* prepend a folder token such as `<projectFolder>`.
|
|
||||||
*/
|
|
||||||
apiJsonFilePath?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures how the .d.ts rollup file will be generated.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This is part of the {@link IConfigFile} structure.
|
|
||||||
*/
|
|
||||||
export interface IConfigDtsRollup {
|
|
||||||
/**
|
|
||||||
* Whether to generate the .d.ts rollup file.
|
|
||||||
*/
|
|
||||||
enabled: boolean;
|
|
||||||
/**
|
|
||||||
* Specifies the output path for a .d.ts rollup file to be generated without any trimming.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This file will include all declarations that are exported by the main entry point.
|
|
||||||
*
|
|
||||||
* If the path is an empty string, then this file will not be written.
|
|
||||||
*
|
|
||||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
|
||||||
* prepend a folder token such as `<projectFolder>`.
|
|
||||||
*/
|
|
||||||
untrimmedFilePath?: string;
|
|
||||||
/**
|
|
||||||
* Specifies the output path for a .d.ts rollup file to be generated with trimming for a "beta" release.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This file will include only declarations that are marked as `@public` or `@beta`.
|
|
||||||
*
|
|
||||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
|
||||||
* prepend a folder token such as `<projectFolder>`.
|
|
||||||
*/
|
|
||||||
betaTrimmedFilePath?: string;
|
|
||||||
/**
|
|
||||||
* Specifies the output path for a .d.ts rollup file to be generated with trimming for a "public" release.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This file will include only declarations that are marked as `@public`.
|
|
||||||
*
|
|
||||||
* If the path is an empty string, then this file will not be written.
|
|
||||||
*
|
|
||||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
|
||||||
* prepend a folder token such as `<projectFolder>`.
|
|
||||||
*/
|
|
||||||
publicTrimmedFilePath?: string;
|
|
||||||
/**
|
|
||||||
* When a declaration is trimmed, by default it will be replaced by a code comment such as
|
|
||||||
* "Excluded from this release type: exampleMember". Set "omitTrimmingComments" to true to remove the
|
|
||||||
* declaration completely.
|
|
||||||
*/
|
|
||||||
omitTrimmingComments?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration options for the API Extractor tool. These options can be constructed programmatically
|
|
||||||
* or loaded from the api-extractor.json config file using the {@link ExtractorConfig} class.
|
|
||||||
*/
|
|
||||||
export interface IConfigFile {
|
|
||||||
/**
|
|
||||||
* Optionally specifies another JSON config file that this file extends from. This provides a way for
|
|
||||||
* standard settings to be shared across multiple projects.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* If the path starts with `./` or `../`, the path is resolved relative to the folder of the file that contains
|
|
||||||
* the `extends` field. Otherwise, the first path segment is interpreted as an NPM package name, and will be
|
|
||||||
* resolved using NodeJS `require()`.
|
|
||||||
*/
|
|
||||||
extends?: string;
|
|
||||||
/**
|
|
||||||
* Determines the `<projectFolder>` token that can be used with other config file settings. The project folder
|
|
||||||
* typically contains the tsconfig.json and package.json config files, but the path is user-defined.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
*
|
|
||||||
* The path is resolved relative to the folder of the config file that contains the setting.
|
|
||||||
*
|
|
||||||
* The default value for `projectFolder` is the token `<lookup>`, which means the folder is determined by traversing
|
|
||||||
* parent folders, starting from the folder containing api-extractor.json, and stopping at the first folder
|
|
||||||
* that contains a tsconfig.json file. If a tsconfig.json file cannot be found in this way, then an error
|
|
||||||
* will be reported.
|
|
||||||
*/
|
|
||||||
projectFolder?: string;
|
|
||||||
/**
|
|
||||||
* Specifies the .d.ts file to be used as the starting point for analysis. API Extractor
|
|
||||||
* analyzes the symbols exported by this module.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
*
|
|
||||||
* The file extension must be ".d.ts" and not ".ts".
|
|
||||||
* The path is resolved relative to the "projectFolder" location.
|
|
||||||
*/
|
|
||||||
mainEntryPointFilePath: string;
|
|
||||||
/**
|
|
||||||
* {@inheritDoc IConfigCompiler}
|
|
||||||
*/
|
|
||||||
compiler?: IConfigCompiler;
|
|
||||||
/**
|
|
||||||
* {@inheritDoc IConfigApiReport}
|
|
||||||
*/
|
|
||||||
apiReport?: IConfigApiReport;
|
|
||||||
/**
|
|
||||||
* {@inheritDoc IConfigDocModel}
|
|
||||||
*/
|
|
||||||
docModel?: IConfigDocModel;
|
|
||||||
/**
|
|
||||||
* {@inheritDoc IConfigDtsRollup}
|
|
||||||
* @beta
|
|
||||||
*/
|
|
||||||
dtsRollup?: IConfigDtsRollup;
|
|
||||||
/**
|
|
||||||
* {@inheritDoc IConfigTsdocMetadata}
|
|
||||||
* @beta
|
|
||||||
*/
|
|
||||||
tsdocMetadata?: IConfigTsdocMetadata;
|
|
||||||
/**
|
|
||||||
* {@inheritDoc IExtractorMessagesConfig}
|
|
||||||
*/
|
|
||||||
messages?: IExtractorMessagesConfig;
|
|
||||||
/**
|
|
||||||
* Set to true when invoking API Extractor's test harness.
|
|
||||||
* @remarks
|
|
||||||
* When `testMode` is true, the `toolVersion` field in the .api.json file is assigned an empty string
|
|
||||||
* to prevent spurious diffs in output files tracked for tests.
|
|
||||||
*/
|
|
||||||
testMode?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures reporting for a given message identifier.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This is part of the {@link IConfigFile} structure.
|
|
||||||
*/
|
|
||||||
export interface IConfigMessageReportingRule {
|
|
||||||
/**
|
|
||||||
* Specifies whether the message should be written to the the tool's output log.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* Note that the `addToApiReportFile` property may supersede this option.
|
|
||||||
*/
|
|
||||||
logLevel: ExtractorLogLevel;
|
|
||||||
/**
|
|
||||||
* When `addToApiReportFile` is true: If API Extractor is configured to write an API report file (.api.md),
|
|
||||||
* then the message will be written inside that file; otherwise, the message is instead logged according to
|
|
||||||
* the `logLevel` option.
|
|
||||||
*/
|
|
||||||
addToApiReportFile?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies a table of reporting rules for different message identifiers, and also the default rule used for
|
|
||||||
* identifiers that do not appear in the table.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This is part of the {@link IConfigFile} structure.
|
|
||||||
*/
|
|
||||||
export interface IConfigMessageReportingTable {
|
|
||||||
/**
|
|
||||||
* The key is a message identifier for the associated type of message, or "default" to specify the default policy.
|
|
||||||
* For example, the key might be `TS2551` (a compiler message), `tsdoc-link-tag-unescaped-text` (a TSDOc message),
|
|
||||||
* or `ae-extra-release-tag` (a message related to the API Extractor analysis).
|
|
||||||
*/
|
|
||||||
[messageId: string]: IConfigMessageReportingRule;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures how the tsdoc-metadata.json file will be generated.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This is part of the {@link IConfigFile} structure.
|
|
||||||
*/
|
|
||||||
export interface IConfigTsdocMetadata {
|
|
||||||
/**
|
|
||||||
* Whether to generate the tsdoc-metadata.json file.
|
|
||||||
*/
|
|
||||||
enabled: boolean;
|
|
||||||
/**
|
|
||||||
* Specifies where the TSDoc metadata file should be written.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
|
||||||
* prepend a folder token such as `<projectFolder>`.
|
|
||||||
*
|
|
||||||
* The default value is `<lookup>`, which causes the path to be automatically inferred from the `tsdocMetadata`,
|
|
||||||
* `typings` or `main` fields of the project's package.json. If none of these fields are set, the lookup
|
|
||||||
* falls back to `tsdoc-metadata.json` in the package folder.
|
|
||||||
*/
|
|
||||||
tsdocMetadataFilePath?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Options for {@link ExtractorConfig.prepare}.
|
|
||||||
*/
|
|
||||||
export interface IExtractorConfigPrepareOptions {
|
|
||||||
/**
|
|
||||||
* A configuration object as returned by {@link ExtractorConfig.loadFile}.
|
|
||||||
*/
|
|
||||||
configObject: IConfigFile;
|
|
||||||
/**
|
|
||||||
* The absolute path of the file that the `configObject` object was loaded from. This is used for error messages
|
|
||||||
* and when probing for `tsconfig.json`.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
*
|
|
||||||
* If this is omitted, then the `projectFolder` must not be specified using the `<lookup>` token.
|
|
||||||
*/
|
|
||||||
configObjectFullPath: string | undefined;
|
|
||||||
/**
|
|
||||||
* The parsed package.json file for the working package, or undefined if API Extractor was invoked without
|
|
||||||
* a package.json file.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
*
|
|
||||||
* If omitted, then the `<unscopedPackageName>` and `<packageName>` tokens will have default values.
|
|
||||||
*/
|
|
||||||
packageJson?: object | undefined;
|
|
||||||
/**
|
|
||||||
* The absolute path of the file that the `packageJson` object was loaded from, or undefined if API Extractor
|
|
||||||
* was invoked without a package.json file.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
*
|
|
||||||
* This is used for error messages and when resolving paths found in package.json.
|
|
||||||
*
|
|
||||||
* If `packageJsonFullPath` is specified but `packageJson` is omitted, the file will be loaded automatically.
|
|
||||||
*/
|
|
||||||
packageJsonFullPath: string | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runtime options for Extractor.
|
|
||||||
*/
|
|
||||||
export interface IExtractorInvokeOptions {
|
|
||||||
/**
|
|
||||||
* An optional TypeScript compiler state. This allows an optimization where multiple invocations of API Extractor
|
|
||||||
* can reuse the same TypeScript compiler analysis.
|
|
||||||
*/
|
|
||||||
compilerState?: CompilerState;
|
|
||||||
/**
|
|
||||||
* Indicates that API Extractor is running as part of a local build, e.g. on developer's
|
|
||||||
* machine.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This disables certain validation that would normally be performed for a ship/production build. For example,
|
|
||||||
* the *.api.md report file is automatically updated in a local build.
|
|
||||||
*
|
|
||||||
* The default value is false.
|
|
||||||
*/
|
|
||||||
localBuild?: boolean;
|
|
||||||
/**
|
|
||||||
* If true, API Extractor will include {@link ExtractorLogLevel.Verbose} messages in its output.
|
|
||||||
*/
|
|
||||||
showVerboseMessages?: boolean;
|
|
||||||
/**
|
|
||||||
* If true, API Extractor will print diagnostic information used for troubleshooting problems.
|
|
||||||
* These messages will be included as {@link ExtractorLogLevel.Verbose} output.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* Setting `showDiagnostics=true` forces `showVerboseMessages=true`.
|
|
||||||
*/
|
|
||||||
showDiagnostics?: boolean;
|
|
||||||
/**
|
|
||||||
* Specifies an alternate folder path to be used when loading the TypeScript system typings.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* API Extractor uses its own TypeScript compiler engine to analyze your project. If your project
|
|
||||||
* is built with a significantly different TypeScript version, sometimes API Extractor may report compilation
|
|
||||||
* errors due to differences in the system typings (e.g. lib.dom.d.ts). You can use the "--typescriptCompilerFolder"
|
|
||||||
* option to specify the folder path where you installed the TypeScript package, and API Extractor's compiler will
|
|
||||||
* use those system typings instead.
|
|
||||||
*/
|
|
||||||
typescriptCompilerFolder?: string;
|
|
||||||
/**
|
|
||||||
* An optional callback function that will be called for each `ExtractorMessage` before it is displayed by
|
|
||||||
* API Extractor. The callback can customize the message, handle it, or discard it.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* If a `messageCallback` is not provided, then by default API Extractor will print the messages to
|
|
||||||
* the STDERR/STDOUT console.
|
|
||||||
*/
|
|
||||||
messageCallback?: (message: ExtractorMessage) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by {@link ExtractorMessage.properties}.
|
|
||||||
*/
|
|
||||||
export interface IExtractorMessageProperties {
|
|
||||||
/**
|
|
||||||
* A declaration can have multiple names if it is exported more than once.
|
|
||||||
* If an `ExtractorMessage` applies to a specific export name, this property can indicate that.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
*
|
|
||||||
* Used by {@link ExtractorMessageId.InternalMissingUnderscore}.
|
|
||||||
*/
|
|
||||||
readonly exportName?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures how API Extractor reports error and warning messages produced during analysis.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This is part of the {@link IConfigFile} structure.
|
|
||||||
*/
|
|
||||||
export interface IExtractorMessagesConfig {
|
|
||||||
/**
|
|
||||||
* Configures handling of diagnostic messages generating the TypeScript compiler while analyzing the
|
|
||||||
* input .d.ts files.
|
|
||||||
*/
|
|
||||||
compilerMessageReporting?: IConfigMessageReportingTable;
|
|
||||||
/**
|
|
||||||
* Configures handling of messages reported by API Extractor during its analysis.
|
|
||||||
*/
|
|
||||||
extractorMessageReporting?: IConfigMessageReportingTable;
|
|
||||||
/**
|
|
||||||
* Configures handling of messages reported by the TSDoc parser when analyzing code comments.
|
|
||||||
*/
|
|
||||||
tsdocMessageReporting?: IConfigMessageReportingTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
export {};
|
|
||||||
}
|
|
|
@ -13,7 +13,7 @@
|
||||||
"beachball": "^1.11.5",
|
"beachball": "^1.11.5",
|
||||||
"jest": "^24.8.0",
|
"jest": "^24.8.0",
|
||||||
"just-plop-helpers": "^1.1.2",
|
"just-plop-helpers": "^1.1.2",
|
||||||
"just-scripts": "^0.36.1",
|
"just-scripts": "^0.38.0",
|
||||||
"plop": "^2.5.0",
|
"plop": "^2.5.0",
|
||||||
"typescript": "^3.5.3"
|
"typescript": "^3.5.3"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,20 @@
|
||||||
{
|
{
|
||||||
"name": "just-task",
|
"name": "just-task",
|
||||||
"entries": [
|
"entries": [
|
||||||
|
{
|
||||||
|
"date": "Fri, 10 Apr 2020 20:34:02 GMT",
|
||||||
|
"tag": "just-task_v0.15.0",
|
||||||
|
"version": "0.15.0",
|
||||||
|
"comments": {
|
||||||
|
"minor": [
|
||||||
|
{
|
||||||
|
"comment": "Replace yargs with yargs-parser, taking over the command parsing",
|
||||||
|
"author": "kchau@microsoft.com",
|
||||||
|
"commit": "565e98494de5bae050cdc04365dee0a0aef638d8"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"date": "Fri, 06 Mar 2020 19:44:20 GMT",
|
"date": "Fri, 06 Mar 2020 19:44:20 GMT",
|
||||||
"tag": "just-task_v0.14.3",
|
"tag": "just-task_v0.14.3",
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
# Change Log - just-task
|
# Change Log - just-task
|
||||||
|
|
||||||
This log was last generated on Mon, 11 Nov 2019 21:09:42 GMT and should not be manually modified.
|
This log was last generated on Fri, 10 Apr 2020 20:34:02 GMT and should not be manually modified.
|
||||||
|
|
||||||
|
## 0.15.0
|
||||||
|
Fri, 10 Apr 2020 20:34:02 GMT
|
||||||
|
|
||||||
|
### Minor changes
|
||||||
|
|
||||||
|
- Replace yargs with yargs-parser, taking over the command parsing (kchau@microsoft.com)
|
||||||
## 0.14.3
|
## 0.14.3
|
||||||
Mon, 11 Nov 2019 21:09:42 GMT
|
Mon, 11 Nov 2019 21:09:42 GMT
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "just-task",
|
"name": "just-task",
|
||||||
"version": "0.14.3",
|
"version": "0.15.0",
|
||||||
"description": "Build task definition library",
|
"description": "Build task definition library",
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -15,19 +15,20 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"dev": "tsc -w --preserveWatchOutput",
|
"start": "tsc -w --preserveWatchOutput",
|
||||||
"start-test": "jest --watch",
|
"start-test": "jest --watch",
|
||||||
"test": "jest"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@microsoft/package-deps-hash": "^2.2.153",
|
"@microsoft/package-deps-hash": "^2.2.153",
|
||||||
|
"bach": "^1.2.0",
|
||||||
"chalk": "^2.4.1",
|
"chalk": "^2.4.1",
|
||||||
"fs-extra": "^7.0.1",
|
"fs-extra": "^7.0.1",
|
||||||
"just-task-logger": ">=0.3.0 <1.0.0",
|
"just-task-logger": ">=0.3.0 <1.0.0",
|
||||||
"resolve": "^1.8.1",
|
"resolve": "^1.8.1",
|
||||||
"undertaker": "^1.2.0",
|
"undertaker": "^1.2.1",
|
||||||
"undertaker-registry": "^1.0.1",
|
"undertaker-registry": "^1.0.1",
|
||||||
"yargs": "^12.0.5"
|
"yargs-parser": "^18.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/fs-extra": "^5.0.4",
|
"@types/fs-extra": "^5.0.4",
|
||||||
|
@ -37,7 +38,7 @@
|
||||||
"@types/resolve": "^0.0.8",
|
"@types/resolve": "^0.0.8",
|
||||||
"@types/undertaker": "^1.2.0",
|
"@types/undertaker": "^1.2.0",
|
||||||
"@types/undertaker-registry": "^1.0.1",
|
"@types/undertaker-registry": "^1.0.1",
|
||||||
"@types/yargs": "12.0.1",
|
"@types/yargs-parser": "^15.0.0",
|
||||||
"jest": "^24.0.0",
|
"jest": "^24.0.0",
|
||||||
"mock-fs": "^4.8.0",
|
"mock-fs": "^4.8.0",
|
||||||
"ts-jest": "^24.0.1",
|
"ts-jest": "^24.0.1",
|
||||||
|
|
|
@ -1,115 +0,0 @@
|
||||||
import yargs from 'yargs';
|
|
||||||
import fs from 'fs';
|
|
||||||
import path from 'path';
|
|
||||||
import { logger, mark } from './logger';
|
|
||||||
|
|
||||||
import UndertakerRegistry from 'undertaker-registry';
|
|
||||||
import Undertaker from 'undertaker';
|
|
||||||
import { resolve } from './resolve';
|
|
||||||
import { enableTypeScript } from './enableTypeScript';
|
|
||||||
|
|
||||||
export class JustTaskRegistry extends UndertakerRegistry {
|
|
||||||
private hasDefault: boolean = false;
|
|
||||||
|
|
||||||
public init(taker: Undertaker) {
|
|
||||||
super.init(taker);
|
|
||||||
|
|
||||||
// uses a separate instance of yargs to first parse the config (without the --help in the way) so we can parse the configFile first regardless
|
|
||||||
const configFile = [yargs.argv.config, './just.config.js', './just-task.js', './just.config.ts'].reduce(
|
|
||||||
(value, entry) => value || resolve(entry)
|
|
||||||
);
|
|
||||||
|
|
||||||
mark('registry:configModule');
|
|
||||||
|
|
||||||
if (configFile && fs.existsSync(configFile)) {
|
|
||||||
const ext = path.extname(configFile);
|
|
||||||
if (ext === '.ts' || ext === '.tsx') {
|
|
||||||
// TODO: add option to do typechecking as well
|
|
||||||
enableTypeScript({ transpileOnly: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const configModule = require(configFile);
|
|
||||||
if (typeof configModule === 'function') {
|
|
||||||
configModule();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
logger.error(`Invalid configuration file: ${configFile}`);
|
|
||||||
logger.error(`Error: ${e.stack || e.message || e}`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.error(
|
|
||||||
`Cannot find config file "${configFile}".`,
|
|
||||||
`Please create a file called "just.config.js" in the root of the project next to "package.json".`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.perf('registry:configModule');
|
|
||||||
|
|
||||||
if (!validateCommands(yargs)) {
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.hasDefault) {
|
|
||||||
yargs.demandCommand(1, 'No default tasks are defined.').help();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public set<TTaskFunction>(taskName: string, fn: TTaskFunction): TTaskFunction {
|
|
||||||
super.set(taskName, fn);
|
|
||||||
|
|
||||||
if (taskName === 'default') {
|
|
||||||
this.hasDefault = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateCommands(yargs: any) {
|
|
||||||
const commandKeys = yargs.getCommandInstance().getCommands();
|
|
||||||
const argv = yargs.argv;
|
|
||||||
const unknown: string[] = [];
|
|
||||||
const currentContext = yargs.getContext();
|
|
||||||
|
|
||||||
if (commandKeys.length > 0) {
|
|
||||||
argv._.slice(currentContext.commands.length).forEach((key: string) => {
|
|
||||||
if (commandKeys.indexOf(key) === -1) {
|
|
||||||
unknown.push(key);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unknown.length > 0) {
|
|
||||||
logger.error(`Unknown command: ${unknown.join(', ')}`);
|
|
||||||
|
|
||||||
const recommended = recommendCommands(unknown[0], commandKeys);
|
|
||||||
|
|
||||||
if (recommended) {
|
|
||||||
logger.info(`Did you mean this task name: ${recommended}?`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function recommendCommands(cmd: string, potentialCommands: string[]) {
|
|
||||||
const distance = require('yargs/lib/levenshtein');
|
|
||||||
const threshold = 3; // if it takes more than three edits, let's move on.
|
|
||||||
potentialCommands = potentialCommands.sort((a, b) => b.length - a.length);
|
|
||||||
|
|
||||||
let recommended = null;
|
|
||||||
let bestDistance = Infinity;
|
|
||||||
for (let i = 0, candidate; (candidate = potentialCommands[i]) !== undefined; i++) {
|
|
||||||
const d = distance(cmd, candidate);
|
|
||||||
if (d <= threshold && d < bestDistance) {
|
|
||||||
bestDistance = d;
|
|
||||||
recommended = candidate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return recommended;
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
import * as yargs from './yargs/yargs';
|
|
||||||
export default yargs;
|
|
|
@ -1,21 +0,0 @@
|
||||||
const yargs = () => yargs;
|
|
||||||
|
|
||||||
yargs.argv = {
|
|
||||||
config: undefined
|
|
||||||
} as { config: string | undefined };
|
|
||||||
|
|
||||||
yargs.command = () => yargs;
|
|
||||||
|
|
||||||
yargs.demandCommand = () => yargs;
|
|
||||||
|
|
||||||
yargs.help = () => yargs;
|
|
||||||
|
|
||||||
yargs.getCommandInstance = () => ({
|
|
||||||
getCommands: () => []
|
|
||||||
});
|
|
||||||
|
|
||||||
yargs.getContext = () => ({
|
|
||||||
commands: []
|
|
||||||
});
|
|
||||||
|
|
||||||
export = yargs;
|
|
|
@ -1,14 +1,8 @@
|
||||||
import mockfs from 'mock-fs';
|
import mockfs from 'mock-fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import yargsMock from './__mocks__/yargs/yargs';
|
import { _isFileNameLike, _tryResolve, resetResolvePaths, resolveCwd, addResolvePath, resolve } from '../resolve';
|
||||||
import {
|
|
||||||
_isFileNameLike,
|
import * as option from '../option';
|
||||||
_tryResolve,
|
|
||||||
resetResolvePaths,
|
|
||||||
resolveCwd,
|
|
||||||
addResolvePath,
|
|
||||||
resolve
|
|
||||||
} from '../resolve';
|
|
||||||
|
|
||||||
describe('_isFileNameLike', () => {
|
describe('_isFileNameLike', () => {
|
||||||
it('returns false for empty input', () => {
|
it('returns false for empty input', () => {
|
||||||
|
@ -83,6 +77,10 @@ describe('_tryResolve', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('resolveCwd', () => {
|
describe('resolveCwd', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.spyOn(option, 'argv').mockImplementation(() => ({ config: undefined } as any));
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
mockfs.restore();
|
mockfs.restore();
|
||||||
resetResolvePaths();
|
resetResolvePaths();
|
||||||
|
@ -117,9 +115,10 @@ describe('resolveCwd', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('resolve', () => {
|
describe('resolve', () => {
|
||||||
|
jest.spyOn(option, 'argv').mockImplementation(() => ({ config: undefined } as any));
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
mockfs.restore();
|
mockfs.restore();
|
||||||
yargsMock.argv.config = undefined;
|
|
||||||
resetResolvePaths();
|
resetResolvePaths();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -145,7 +144,9 @@ describe('resolve', () => {
|
||||||
mockfs({
|
mockfs({
|
||||||
a: { 'b.txt': '' }
|
a: { 'b.txt': '' }
|
||||||
});
|
});
|
||||||
yargsMock.argv.config = 'a/just-task.js';
|
|
||||||
|
jest.spyOn(option, 'argv').mockImplementation(() => ({ config: 'a/just-task.js' } as any));
|
||||||
|
|
||||||
expect(resolve('b.txt')).toContain(path.join('a', 'b.txt'));
|
expect(resolve('b.txt')).toContain(path.join('a', 'b.txt'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -166,7 +167,9 @@ describe('resolve', () => {
|
||||||
d: { 'b.txt': '' }, // wrong
|
d: { 'b.txt': '' }, // wrong
|
||||||
'b.txt': '' // wrong
|
'b.txt': '' // wrong
|
||||||
});
|
});
|
||||||
yargsMock.argv.config = 'a/just-task.js';
|
|
||||||
|
jest.spyOn(option, 'argv').mockImplementation(() => ({ config: 'a/just-task.js' } as any));
|
||||||
|
|
||||||
addResolvePath('c');
|
addResolvePath('c');
|
||||||
expect(resolve('b.txt', 'd')).toContain(path.join('d', 'b.txt'));
|
expect(resolve('b.txt', 'd')).toContain(path.join('d', 'b.txt'));
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,22 +1,24 @@
|
||||||
import { task } from '../task';
|
import { task } from '../task';
|
||||||
import { parallel, undertaker } from '../undertaker';
|
import { parallel, undertaker } from '../undertaker';
|
||||||
import { JustTaskRegistry } from '../JustTaskRegistry';
|
import UndertakerRegistry from 'undertaker-registry';
|
||||||
|
|
||||||
import { logger } from '../logger';
|
import { logger } from '../logger';
|
||||||
import yargsMock from './__mocks__/yargs';
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
|
import * as option from '../option';
|
||||||
|
|
||||||
describe('task', () => {
|
describe('task', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
yargsMock.argv.config = path.resolve(__dirname, '__mocks__/just-task.js');
|
jest.spyOn(option, 'argv').mockImplementation(() => ({ config: path.resolve(__dirname, '__mocks__/just-task.js') } as any));
|
||||||
jest.spyOn(logger, 'info').mockImplementation(() => undefined);
|
jest.spyOn(logger, 'info').mockImplementation(() => undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
undertaker.registry(new JustTaskRegistry());
|
undertaker.registry(new UndertakerRegistry());
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
yargsMock.argv.config = undefined;
|
jest.spyOn(option, 'argv').mockImplementation(() => ({ config: 'a/just-task.js' } as any));
|
||||||
jest.restoreAllMocks();
|
jest.restoreAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import { undertaker } from './undertaker';
|
import { undertaker } from './undertaker';
|
||||||
import { JustTaskRegistry } from './JustTaskRegistry';
|
import { option, parseCommand } from './option';
|
||||||
import yargs from 'yargs';
|
import { logger } from 'just-task-logger';
|
||||||
|
import { TaskFunction } from './interfaces';
|
||||||
|
import { readConfig } from './config';
|
||||||
|
|
||||||
const originalEmitWarning = process.emitWarning;
|
const originalEmitWarning = process.emitWarning;
|
||||||
|
|
||||||
|
@ -17,15 +19,33 @@ const originalEmitWarning = process.emitWarning;
|
||||||
return originalEmitWarning.apply(this, arguments);
|
return originalEmitWarning.apply(this, arguments);
|
||||||
};
|
};
|
||||||
|
|
||||||
yargs
|
function showHelp() {
|
||||||
.option({ config: { describe: 'path to a just-task.js file (includes the file name)' } })
|
const tasks = undertaker.registry().tasks();
|
||||||
.usage('$0 <cmd> [options]')
|
|
||||||
.updateStrings({
|
|
||||||
'Commands:': 'Tasks:\n'
|
|
||||||
});
|
|
||||||
|
|
||||||
const registry = new JustTaskRegistry();
|
console.log('All the tasks that are available to just:');
|
||||||
|
|
||||||
undertaker.registry(registry);
|
for (const [name, wrappedTask] of Object.entries(tasks)) {
|
||||||
|
const unwrapped = (wrappedTask as any).unwrap ? (wrappedTask as any).unwrap() : (wrappedTask as TaskFunction);
|
||||||
|
const description = (unwrapped as TaskFunction).description;
|
||||||
|
console.log(` ${name}${description ? `: ${description}` : ''}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
yargs.parse();
|
// Define a built-in option of "config" so users can specify which path to choose for configurations
|
||||||
|
option('config', { describe: 'path to a just configuration file (includes the file name, e.g. /path/to/just.config.ts)' });
|
||||||
|
|
||||||
|
readConfig();
|
||||||
|
|
||||||
|
const registry = undertaker.registry();
|
||||||
|
|
||||||
|
const command = parseCommand();
|
||||||
|
|
||||||
|
if (command) {
|
||||||
|
if (registry.get(command)) {
|
||||||
|
undertaker.series(registry.get(command))(() => {});
|
||||||
|
} else {
|
||||||
|
logger.error(`Command not defined: ${command}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showHelp();
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
import { argv } from './option';
|
||||||
|
import { resolve } from './resolve';
|
||||||
|
import { mark, logger } from 'just-task-logger';
|
||||||
|
import { enableTypeScript } from './enableTypeScript';
|
||||||
|
|
||||||
|
export function readConfig() {
|
||||||
|
// uses a separate instance of yargs to first parse the config (without the --help in the way) so we can parse the configFile first regardless
|
||||||
|
let configFile: string | null = null;
|
||||||
|
for (const entry of [argv().config, './just.config.js', './just-task.js', './just.config.ts']) {
|
||||||
|
configFile = resolve(entry);
|
||||||
|
if (configFile) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mark('registry:configModule');
|
||||||
|
|
||||||
|
if (configFile && fs.existsSync(configFile)) {
|
||||||
|
const ext = path.extname(configFile);
|
||||||
|
if (ext === '.ts' || ext === '.tsx') {
|
||||||
|
// TODO: add option to do typechecking as well
|
||||||
|
enableTypeScript({ transpileOnly: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const configModule = require(configFile);
|
||||||
|
if (typeof configModule === 'function') {
|
||||||
|
configModule();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
logger.error(`Invalid configuration file: ${configFile}`);
|
||||||
|
logger.error(`Error: ${e.stack || e.message || e}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.error(
|
||||||
|
`Cannot find config file "${configFile}".`,
|
||||||
|
`Please create a file called "just.config.js" in the root of the project next to "package.json".`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.perf('registry:configModule');
|
||||||
|
}
|
|
@ -13,4 +13,5 @@ export interface TaskContext {
|
||||||
export interface TaskFunction extends Undertaker.TaskFunctionParams {
|
export interface TaskFunction extends Undertaker.TaskFunctionParams {
|
||||||
(this: TaskContext, done: (error?: any) => void): void | Duplex | NodeJS.Process | Promise<never> | any;
|
(this: TaskContext, done: (error?: any) => void): void | Duplex | NodeJS.Process | Promise<never> | any;
|
||||||
cached?: () => void;
|
cached?: () => void;
|
||||||
|
description?: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,90 @@
|
||||||
import yargs from 'yargs';
|
import parser, { Options, Arguments } from 'yargs-parser';
|
||||||
|
|
||||||
export function option(key: string, options: yargs.Options = {}): yargs.Argv {
|
export interface OptionConfig {
|
||||||
return yargs.option.apply(yargs, [key, options]);
|
/** Aliases for the argument, can be a string or array */
|
||||||
|
alias?: string | string[];
|
||||||
|
|
||||||
|
/** Argument should be an array */
|
||||||
|
array?: boolean;
|
||||||
|
|
||||||
|
/** Argument should be parsed as booleans: `{ boolean: ['x', 'y'] }`. */
|
||||||
|
boolean?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide a custom synchronous function that returns a coerced value from the argument provided (or throws an error), e.g.
|
||||||
|
* `{ coerce: function (arg) { return modifiedArg } }`.
|
||||||
|
*/
|
||||||
|
coerce?: (arg: any) => any;
|
||||||
|
|
||||||
|
/** Indicate a key that should be used as a counter, e.g., `-vvv = {v: 3}`. */
|
||||||
|
count?: boolean;
|
||||||
|
|
||||||
|
/** Provide default values for keys: `{ default: { x: 33, y: 'hello world!' } }`. */
|
||||||
|
default?: { [key: string]: any };
|
||||||
|
|
||||||
|
/** Specify that a key requires n arguments: `{ narg: {x: 2} }`. */
|
||||||
|
narg?: number;
|
||||||
|
|
||||||
|
/** `path.normalize()` will be applied to values set to this key. */
|
||||||
|
normalize?: boolean;
|
||||||
|
|
||||||
|
/** Keys should be treated as strings (even if they resemble a number `-x 33`). */
|
||||||
|
string?: boolean;
|
||||||
|
|
||||||
|
/** Keys should be treated as numbers. */
|
||||||
|
number?: boolean;
|
||||||
|
|
||||||
|
/** A description of the option */
|
||||||
|
describe?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function argv(): yargs.Arguments {
|
let argOptions: Options = {};
|
||||||
return yargs.argv;
|
const descriptions: { [key: string]: string } = {};
|
||||||
|
const processArgs = process.argv.slice(2);
|
||||||
|
|
||||||
|
export function option(key: string, options: OptionConfig = {}) {
|
||||||
|
const booleanArgs = ['array', 'boolean', 'count', 'normalize', 'string', 'number'] as const;
|
||||||
|
const assignArgs = ['alias', 'coerce', 'default'] as const;
|
||||||
|
|
||||||
|
for (const argName of booleanArgs) {
|
||||||
|
if (options[argName]) {
|
||||||
|
if (!argOptions[argName]) {
|
||||||
|
argOptions[argName] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const argOpts = argOptions[argName]! as string[];
|
||||||
|
|
||||||
|
if (argOpts.indexOf(key) === -1) {
|
||||||
|
argOpts.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const argName of assignArgs) {
|
||||||
|
if (options[argName]) {
|
||||||
|
if (!argOptions[argName]) {
|
||||||
|
argOptions[argName] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
argOptions[argName]![key] = options[argName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.describe) {
|
||||||
|
descriptions[key] = options.describe;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function argv(): Arguments {
|
||||||
|
return parser(processArgs, argOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseCommand(): string | null {
|
||||||
|
const positionals = argv()._;
|
||||||
|
|
||||||
|
if (positionals.length > 0) {
|
||||||
|
return positionals[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
import { sync as resolveSync } from 'resolve';
|
import { sync as resolveSync } from 'resolve';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
import { argv } from './option';
|
||||||
// It is important to keep this line like this:
|
|
||||||
// 1. it cannot be an import because TS will try to do type checks which isn't available in @types/yargs
|
|
||||||
// 2. this breaks a require.cache, which is needed because we need a new instance of yargs to check the config
|
|
||||||
// - this is because of the timing of when tasks are defined vs when this resolve is called the first time
|
|
||||||
// to figure out config path)
|
|
||||||
const yargsFn = require('yargs/yargs');
|
|
||||||
|
|
||||||
let resolvePaths: string[] = [__dirname];
|
let resolvePaths: string[] = [__dirname];
|
||||||
|
|
||||||
|
@ -62,7 +56,8 @@ export function resolve(moduleName: string, cwd?: string): string | null {
|
||||||
if (!cwd) {
|
if (!cwd) {
|
||||||
cwd = process.cwd();
|
cwd = process.cwd();
|
||||||
}
|
}
|
||||||
const configArg = yargsFn(process.argv.slice(1).filter(a => a !== '--help')).argv.config;
|
|
||||||
|
const configArg = argv().config;
|
||||||
const configFilePath = configArg ? path.resolve(path.dirname(configArg)) : undefined;
|
const configFilePath = configArg ? path.resolve(path.dirname(configArg)) : undefined;
|
||||||
|
|
||||||
const allResolvePaths = [cwd, ...(configFilePath ? [configFilePath] : []), ...resolvePaths];
|
const allResolvePaths = [cwd, ...(configFilePath ? [configFilePath] : []), ...resolvePaths];
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
import yargs from 'yargs';
|
|
||||||
import { undertaker } from './undertaker';
|
import { undertaker } from './undertaker';
|
||||||
import { wrapTask } from './wrapTask';
|
import { wrapTask } from './wrapTask';
|
||||||
import { TaskFunction } from './interfaces';
|
import { TaskFunction } from './interfaces';
|
||||||
import { logger } from 'just-task-logger';
|
import { registerCachedTask } from './cache';
|
||||||
import { registerCachedTask, isCached, saveCache } from './cache';
|
|
||||||
|
|
||||||
export function task(firstParam: string | TaskFunction, secondParam?: string | TaskFunction, thirdParam?: TaskFunction): TaskFunction {
|
export function task(firstParam: string | TaskFunction, secondParam?: string | TaskFunction, thirdParam?: TaskFunction): TaskFunction {
|
||||||
const argCount = arguments.length;
|
const argCount = arguments.length;
|
||||||
|
@ -19,7 +17,6 @@ export function task(firstParam: string | TaskFunction, secondParam?: string | T
|
||||||
};
|
};
|
||||||
|
|
||||||
undertaker.task(firstParam, wrapped);
|
undertaker.task(firstParam, wrapped);
|
||||||
yargs.command(getCommandModule(firstParam, ''));
|
|
||||||
|
|
||||||
return wrapped;
|
return wrapped;
|
||||||
} else if (argCount === 2 && isString(firstParam) && isTaskFunction(secondParam)) {
|
} else if (argCount === 2 && isString(firstParam) && isTaskFunction(secondParam)) {
|
||||||
|
@ -31,7 +28,6 @@ export function task(firstParam: string | TaskFunction, secondParam?: string | T
|
||||||
};
|
};
|
||||||
|
|
||||||
undertaker.task(firstParam, wrapped);
|
undertaker.task(firstParam, wrapped);
|
||||||
yargs.command(getCommandModule(firstParam, ''));
|
|
||||||
|
|
||||||
return wrapped;
|
return wrapped;
|
||||||
} else if (argCount === 3 && isString(firstParam) && isString(secondParam) && isTaskFunction(thirdParam)) {
|
} else if (argCount === 3 && isString(firstParam) && isString(secondParam) && isTaskFunction(thirdParam)) {
|
||||||
|
@ -41,8 +37,9 @@ export function task(firstParam: string | TaskFunction, secondParam?: string | T
|
||||||
registerCachedTask(firstParam);
|
registerCachedTask(firstParam);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
wrapped.description = secondParam;
|
||||||
|
|
||||||
undertaker.task(firstParam, wrapped);
|
undertaker.task(firstParam, wrapped);
|
||||||
yargs.command(getCommandModule(firstParam, secondParam));
|
|
||||||
|
|
||||||
return wrapped;
|
return wrapped;
|
||||||
} else {
|
} else {
|
||||||
|
@ -57,21 +54,3 @@ function isString(param: string | TaskFunction | undefined): param is string {
|
||||||
function isTaskFunction(param: string | TaskFunction | undefined): param is TaskFunction {
|
function isTaskFunction(param: string | TaskFunction | undefined): param is TaskFunction {
|
||||||
return typeof param === 'function';
|
return typeof param === 'function';
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCommandModule(taskName: string, describe?: string): yargs.CommandModule {
|
|
||||||
return {
|
|
||||||
command: taskName,
|
|
||||||
describe,
|
|
||||||
...(taskName === 'default' ? { aliases: ['*'] } : {}),
|
|
||||||
handler(_argvParam: any) {
|
|
||||||
if (isCached(taskName)) {
|
|
||||||
logger.info(`Skipped ${taskName} since it was cached`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return undertaker.parallel(taskName)(() => {
|
|
||||||
saveCache(taskName);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,5 +3,5 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "lib"
|
"outDir": "lib"
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"include": ["src", "types"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,23 @@ const DefaultReporter = require('@jest/reporters').DefaultReporter;
|
||||||
* when there are no errors.
|
* when there are no errors.
|
||||||
*/
|
*/
|
||||||
class JestReporter extends DefaultReporter {
|
class JestReporter extends DefaultReporter {
|
||||||
|
constructor(...args) {
|
||||||
|
super(...args);
|
||||||
|
this._isLoggingError = false;
|
||||||
|
}
|
||||||
|
|
||||||
log(message) {
|
log(message) {
|
||||||
process.stdout.write(message + '\n');
|
if (this._isLoggingError) {
|
||||||
|
process.stderr.write(message + '\n');
|
||||||
|
} else {
|
||||||
|
process.stdout.write(message + '\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printTestFileFailureMessage(...args) {
|
||||||
|
this._isLoggingError = true;
|
||||||
|
super.printTestFileFailureMessage(...args);
|
||||||
|
this._isLoggingError = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
24
yarn.lock
24
yarn.lock
|
@ -2271,7 +2271,7 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.4.tgz#b4ffc7dc97b498c969b360a41eee247f82616370"
|
resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.4.tgz#b4ffc7dc97b498c969b360a41eee247f82616370"
|
||||||
integrity sha512-78AdXtlhpCHT0K3EytMpn4JNxaf5tbqbLcbIRoQIHzpTIyjpxLQKRoxU55ujBXAtg3Nl2h/XWvfDa9dsMOd0pQ==
|
integrity sha512-78AdXtlhpCHT0K3EytMpn4JNxaf5tbqbLcbIRoQIHzpTIyjpxLQKRoxU55ujBXAtg3Nl2h/XWvfDa9dsMOd0pQ==
|
||||||
|
|
||||||
"@types/tar@^4.0.0":
|
"@types/tar@^4.0.0", "@types/tar@^4.0.3":
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@types/tar/-/tar-4.0.3.tgz#e2cce0b8ff4f285293243f5971bd7199176ac489"
|
resolved "https://registry.yarnpkg.com/@types/tar/-/tar-4.0.3.tgz#e2cce0b8ff4f285293243f5971bd7199176ac489"
|
||||||
integrity sha512-Z7AVMMlkI8NTWF0qGhC4QIX0zkV/+y0J8x7b/RsHrN0310+YNjoJd8UrApCiGBCWtKjxS9QhNqLi2UJNToh5hA==
|
integrity sha512-Z7AVMMlkI8NTWF0qGhC4QIX0zkV/+y0J8x7b/RsHrN0310+YNjoJd8UrApCiGBCWtKjxS9QhNqLi2UJNToh5hA==
|
||||||
|
@ -2328,6 +2328,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.0.0.tgz#453743c5bbf9f1bed61d959baab5b06be029b2d0"
|
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.0.0.tgz#453743c5bbf9f1bed61d959baab5b06be029b2d0"
|
||||||
integrity sha512-wBlsw+8n21e6eTd4yVv8YD/E3xq0O6nNnJIquutAsFGE7EyMKz7W6RNT6BRu1SmdgmlCZ9tb0X+j+D6HGr8pZw==
|
integrity sha512-wBlsw+8n21e6eTd4yVv8YD/E3xq0O6nNnJIquutAsFGE7EyMKz7W6RNT6BRu1SmdgmlCZ9tb0X+j+D6HGr8pZw==
|
||||||
|
|
||||||
|
"@types/yargs-parser@^15.0.0":
|
||||||
|
version "15.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d"
|
||||||
|
integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==
|
||||||
|
|
||||||
"@types/yargs@12.0.1":
|
"@types/yargs@12.0.1":
|
||||||
version "12.0.1"
|
version "12.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.1.tgz#c5ce4ad64499010ae4dc2acd9b14d49749a44233"
|
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.1.tgz#c5ce4ad64499010ae4dc2acd9b14d49749a44233"
|
||||||
|
@ -3248,7 +3253,7 @@ babylon@^6.17.4:
|
||||||
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
|
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
|
||||||
integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==
|
integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==
|
||||||
|
|
||||||
bach@^1.0.0:
|
bach@^1.0.0, bach@^1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880"
|
resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880"
|
||||||
integrity sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=
|
integrity sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=
|
||||||
|
@ -13310,6 +13315,11 @@ typescript@~3.4.4:
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.4.5.tgz#2d2618d10bb566572b8d7aad5180d84257d70a99"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.4.5.tgz#2d2618d10bb566572b8d7aad5180d84257d70a99"
|
||||||
integrity sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==
|
integrity sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==
|
||||||
|
|
||||||
|
typescript@~3.8.3:
|
||||||
|
version "3.8.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061"
|
||||||
|
integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==
|
||||||
|
|
||||||
uglify-js@3.4.x:
|
uglify-js@3.4.x:
|
||||||
version "3.4.10"
|
version "3.4.10"
|
||||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f"
|
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f"
|
||||||
|
@ -13359,7 +13369,7 @@ undertaker-registry@^1.0.0, undertaker-registry@^1.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50"
|
resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50"
|
||||||
integrity sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=
|
integrity sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=
|
||||||
|
|
||||||
undertaker@^1.2.0:
|
undertaker@^1.2.1:
|
||||||
version "1.2.1"
|
version "1.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/undertaker/-/undertaker-1.2.1.tgz#701662ff8ce358715324dfd492a4f036055dfe4b"
|
resolved "https://registry.yarnpkg.com/undertaker/-/undertaker-1.2.1.tgz#701662ff8ce358715324dfd492a4f036055dfe4b"
|
||||||
integrity sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==
|
integrity sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==
|
||||||
|
@ -14040,6 +14050,14 @@ yargs-parser@^13.1.0, yargs-parser@^13.1.1:
|
||||||
camelcase "^5.0.0"
|
camelcase "^5.0.0"
|
||||||
decamelize "^1.2.0"
|
decamelize "^1.2.0"
|
||||||
|
|
||||||
|
yargs-parser@^18.1.2:
|
||||||
|
version "18.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.2.tgz#2f482bea2136dbde0861683abea7756d30b504f1"
|
||||||
|
integrity sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ==
|
||||||
|
dependencies:
|
||||||
|
camelcase "^5.0.0"
|
||||||
|
decamelize "^1.2.0"
|
||||||
|
|
||||||
yargs-parser@^5.0.0:
|
yargs-parser@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a"
|
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a"
|
||||||
|
|
Загрузка…
Ссылка в новой задаче