build: enable npm package publication from master branch (#878)

* build: make dist/build ready for direct publishing

* build: prevent unintentional npm publish from root

* docs: update release steps for npm package publish
This commit is contained in:
Andrii Dieiev 2019-07-29 12:34:57 +03:00 коммит произвёл GitHub
Родитель 8f86920e4f
Коммит bfc28e95dd
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
9 изменённых файлов: 522 добавлений и 27 удалений

Просмотреть файл

@ -9,3 +9,6 @@ dist/
# Test files
test-data/NoUnnecessarySemicolonsTestInput.ts
# Files from package for backward compatibility
build-tasks/back-compat

Просмотреть файл

@ -0,0 +1,275 @@
/**
* These rule settings are a broad, general recommendation for a good default configuration.
* This file is exported in the npm/nuget package as ./tslint.json.
*/
module.exports = {
'rules': {
/**
* Security Rules. The following rules should be turned on because they find security issues
* or are recommended in the Microsoft Secure Development Lifecycle (SDL)
*/
'insecure-random': true,
'no-banned-terms': true,
'no-cookies': true,
'no-delete-expression': true,
'no-disable-auto-sanitization': true,
'no-document-domain': true,
'no-document-write': true,
'no-eval': true,
'no-exec-script': true,
'no-function-constructor-with-string-args': true,
'no-http-string': [true, 'http://www.example.com/?.*', 'http://localhost:?.*'],
'no-inner-html': true,
'no-octal-literal': true,
'no-reserved-keywords': true,
'no-string-based-set-immediate': true,
'no-string-based-set-interval': true,
'no-string-based-set-timeout': true,
'non-literal-fs-path': true,
'non-literal-require': true,
'possible-timing-attack': true,
'react-anchor-blank-noopener': true,
'react-iframe-missing-sandbox': true,
'react-no-dangerous-html': true,
/**
* Common Bugs and Correctness. The following rules should be turned on because they find
* common bug patterns in the code or enforce type safety.
*/
'await-promise': true,
'forin': true,
'jquery-deferred-must-complete': true,
'label-position': true,
'match-default-export-name': true,
'mocha-avoid-only': true,
'mocha-no-side-effect-code': true,
'no-any': true,
'no-arg': true,
'no-backbone-get-set-outside-model': true,
'no-bitwise': true,
'no-conditional-assignment': true,
'no-console': [true, 'debug', 'info', 'error', 'log', 'time', 'timeEnd', 'trace'],
'no-constant-condition': true,
'no-control-regex': true,
'no-debugger': true,
'no-duplicate-super': true,
'no-duplicate-switch-case': true,
'no-duplicate-variable': true,
'no-empty': true,
'no-floating-promises': true,
'no-for-in-array': true,
'no-implicit-dependencies': true,
'no-import-side-effect': true,
'no-increment-decrement': true,
'no-invalid-regexp': true,
'no-invalid-template-strings': true,
'no-invalid-this': true,
'no-jquery-raw-elements': true,
'no-misused-new': true,
'no-non-null-assertion': true,
'no-object-literal-type-assertion': true,
'no-parameter-reassignment': true,
'no-reference-import': true,
'no-regex-spaces': true,
'no-sparse-arrays': true,
'no-string-literal': true,
'no-string-throw': true,
'no-submodule-imports': true,
'no-unnecessary-bind': true,
'no-unnecessary-callback-wrapper': true,
'no-unnecessary-initializer': true,
'no-unnecessary-override': true,
'no-unsafe-any': true,
'no-unsafe-finally': true,
'no-unused-expression': true,
'no-use-before-declare': true,
'no-with-statement': true,
'promise-function-async': true,
'promise-must-complete': true,
'radix': true,
'react-this-binding-issue': true,
'react-unused-props-and-state': true,
'restrict-plus-operands': true, // the plus operand should really only be used for strings and numbers
'strict-boolean-expressions': true,
'switch-default': true,
'switch-final-break': true,
'triple-equals': [true, 'allow-null-check'],
'use-isnan': true,
'use-named-parameter': true,
'use-simple-attributes': true,
/**
* Code Clarity. The following rules should be turned on because they make the code
* generally more clear to the reader.
*/
'adjacent-overload-signatures': true,
'array-type': [true, 'array'],
'arrow-parens': false, // for simple functions the parens on arrow functions are not needed
'ban-comma-operator': true, // possibly controversial
'binary-expression-operand-order': true,
'callable-types': true,
'chai-prefer-contains-to-index-of': true,
'chai-vague-errors': true,
'class-name': true,
'comment-format': true,
'completed-docs': [true, 'classes'],
'export-name': true,
'file-name-casing': true,
'function-name': true,
'import-name': true,
'informative-docs': true,
'interface-name': true,
'jsdoc-format': true,
'max-classes-per-file': [true, 3], // we generally recommend making one public class per file
'max-file-line-count': true,
'max-func-body-length': [true, 100, { 'ignore-parameters-to-function-regex': '^describe$' }],
'max-line-length': [true, 140],
'member-access': true,
'member-ordering': [true, { 'order': 'fields-first' }],
'mocha-unneeded-done': true,
'new-parens': true,
'newline-per-chained-call': true,
'no-construct': true,
'no-default-export': true,
'no-duplicate-imports': true,
'no-dynamic-delete': true,
'no-empty-interface': true,
'no-for-in': true,
'no-function-expression': true,
'no-inferrable-types': false, // turn no-inferrable-types off in order to make the code consistent in its use of type decorations
'no-multiline-string': false,
'no-null-keyword': true,
'no-parameter-properties': true,
'no-redundant-jsdoc': true,
'no-relative-imports': true,
'no-require-imports': true,
'no-return-await': true,
'no-shadowed-variable': true,
'no-suspicious-comment': true,
'no-this-assignment': true,
'no-typeof-undefined': true,
'no-unnecessary-field-initialization': true,
'no-unnecessary-local-variable': true,
'no-unnecessary-qualifier': true,
'no-unnecessary-type-assertion': true,
'no-unsupported-browser-code': true,
'no-useless-files': true,
'no-var-keyword': true,
'no-var-requires': true,
'no-void-expression': true,
'number-literal-format': true,
'object-literal-sort-keys': false, // turn object-literal-sort-keys off and sort keys in a meaningful manner
'one-variable-per-declaration': true,
'only-arrow-functions': false, // there are many valid reasons to declare a function
'ordered-imports': true,
'prefer-array-literal': true,
'prefer-const': true,
'prefer-for-of': true,
'prefer-method-signature': true,
'prefer-object-spread': true,
'prefer-readonly': true,
'prefer-template': true,
'prefer-while': true,
'type-literal-delimiter': true,
'typedef': [true, 'call-signature', 'arrow-call-signature', 'parameter', 'arrow-parameter', 'property-declaration', 'variable-declaration', 'member-variable-declaration'],
'underscore-consistent-invocation': true,
'unified-signatures': true,
'use-default-type-parameter': true,
'variable-name': true,
/**
* Accessibility. The following rules should be turned on to guarantee the best user
* experience for keyboard and screen reader users.
*/
'react-a11y-anchors': true,
'react-a11y-aria-unsupported-elements': true,
'react-a11y-event-has-role': true,
'react-a11y-image-button-has-alt': true,
'react-a11y-img-has-alt': true,
'react-a11y-input-elements': true,
'react-a11y-lang': true,
'react-a11y-meta': true,
'react-a11y-no-onchange': true,
'react-a11y-props': true,
'react-a11y-proptypes': true,
'react-a11y-required': true,
'react-a11y-role': true,
'react-a11y-role-has-required-aria-props': true,
'react-a11y-role-supports-aria-props': true,
'react-a11y-tabindex-no-positive': true,
'react-a11y-titles': true,
/**
* Whitespace related rules. The only recommended whitespace strategy is to pick a single format and
* be consistent.
*/
'align': [true, 'parameters', 'arguments', 'statements'],
'curly': true,
'encoding': true,
'eofline': true,
'import-spacing': true,
'indent': [true, 'spaces'],
'linebreak-style': true,
'newline-before-return': true,
'no-consecutive-blank-lines': true,
'no-empty-line-after-opening-brace': false,
'no-irregular-whitespace': true,
'no-single-line-block-comment': true,
'no-trailing-whitespace': true,
'no-unnecessary-semicolons': true,
'object-literal-key-quotes': [true, 'as-needed'],
'one-line': [true, 'check-open-brace', 'check-catch', 'check-else', 'check-whitespace'],
'quotemark': [true, 'single'],
'semicolon': [true, 'always'],
'space-within-parens': true,
'trailing-comma': [true, { 'singleline': 'never', 'multiline': 'never' }], // forcing trailing commas for multi-line
// lists results in lists that are easier to reorder and version control diffs that are more clear.
// Many teams like to have multiline be 'always'. There is no clear consensus on this rule but the
// internal MS JavaScript coding standard does discourage it.
'typedef-whitespace': false,
'whitespace': [true, 'check-branch', 'check-decl', 'check-operator', 'check-separator', 'check-type'],
/**
* Controversial/Configurable rules.
*/
'ban': false, // only enable this if you have some code pattern that you want to ban
'ban-types': true,
'cyclomatic-complexity': true,
'deprecation': false, // deprecated APIs are sometimes unavoidable
'file-header': false, // enable this rule only if you are legally required to add a file header
'import-blacklist': false, // enable and configure this as you desire
'interface-over-type-literal': false, // there are plenty of reasons to prefer interfaces
'no-angle-bracket-type-assertion': false, // pick either type-cast format and use it consistently
'no-inferred-empty-object-type': false, // if the compiler is satisfied then this is probably not an issue
'no-internal-module': false, // only enable this if you are not using internal modules
'no-magic-numbers': false, // by default it will find too many false positives
'no-mergeable-namespace': false, // your project may require mergeable namespaces
'no-namespace': false, // only enable this if you are not using modules/namespaces
'no-reference': true, // in general you should use a module system and not /// reference imports
'no-unexternalized-strings': false, // the VS Code team has a specific localization process that this rule enforces
'object-literal-shorthand': false, // object-literal-shorthand offers an abbreviation not an abstraction
'prefer-conditional-expression': false, // unnecessarily strict
'prefer-switch': false, // more of a style preference
'prefer-type-cast': true, // pick either type-cast format and use it consistently
'return-undefined': false, // this actually affects the readability of the code
'space-before-function-paren': false, // turn this on if this is really your coding standard
/**
* Deprecated rules. The following rules are deprecated for various reasons.
*/
'missing-jsdoc': false,
'missing-optional-annotation': false, // now supported by TypeScript compiler
'no-duplicate-case': false,
'no-duplicate-parameter-names': false, // now supported by TypeScript compiler
'no-empty-interfaces': false, // use tslint no-empty-interface rule instead
'no-missing-visibility-modifiers': false, // use tslint member-access rule instead
'no-multiple-var-decl': false, // use tslint one-variable-per-declaration rule instead
'no-stateless-class': false,
'no-switch-case-fall-through': false, // now supported by TypeScript compiler
'no-unnecessary-class': true,
'no-var-self': false,
'react-tsx-curly-spacing': false,
'typeof-compare': false, // the valid-typeof rule is currently superior to this version
'valid-typeof': false,
}
};

Просмотреть файл

@ -0,0 +1,61 @@
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ScopedSymbolTrackingWalker_1 = require("./ScopedSymbolTrackingWalker");
var AstUtils_1 = require("./AstUtils");
var NoStringParameterToFunctionCallWalker = (function (_super) {
__extends(NoStringParameterToFunctionCallWalker, _super);
function NoStringParameterToFunctionCallWalker(sourceFile, targetFunctionName, options, program) {
var _this = _super.call(this, sourceFile, options, program) || this;
_this.targetFunctionName = targetFunctionName;
_this.failureString = 'Forbidden ' + targetFunctionName + ' string parameter: ';
return _this;
}
NoStringParameterToFunctionCallWalker.prototype.visitCallExpression = function (node) {
this.validateExpression(node);
_super.prototype.visitCallExpression.call(this, node);
};
NoStringParameterToFunctionCallWalker.prototype.validateExpression = function (node) {
var functionName = AstUtils_1.AstUtils.getFunctionName(node);
var functionTarget = AstUtils_1.AstUtils.getFunctionTarget(node);
var functionTargetType = this.getFunctionTargetType(node);
var firstArg = node.arguments[0];
if (functionName === this.targetFunctionName && firstArg !== undefined) {
if (functionTarget) {
if (functionTargetType) {
if (!functionTargetType.match(/^(any|Window|Worker)$/)) {
return;
}
}
else {
if (!functionTarget.match(/^(this|window)$/)) {
return;
}
}
}
if (!this.isExpressionEvaluatingToFunction(firstArg)) {
var msg = this.failureString +
firstArg
.getFullText()
.trim()
.substring(0, 40);
this.addFailureAt(node.getStart(), node.getWidth(), msg);
}
}
};
return NoStringParameterToFunctionCallWalker;
}(ScopedSymbolTrackingWalker_1.ScopedSymbolTrackingWalker));
exports.NoStringParameterToFunctionCallWalker = NoStringParameterToFunctionCallWalker;
//# sourceMappingURL=NoStringParameterToFunctionCallWalker.js.map

Просмотреть файл

@ -0,0 +1,172 @@
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var AstUtils_1 = require("./AstUtils");
var Scope_1 = require("./Scope");
var TypeGuard_1 = require("./TypeGuard");
var ScopedSymbolTrackingWalker = (function (_super) {
__extends(ScopedSymbolTrackingWalker, _super);
function ScopedSymbolTrackingWalker(sourceFile, options, program) {
var _this = _super.call(this, sourceFile, options) || this;
if (program) {
_this.typeChecker = program.getTypeChecker();
}
return _this;
}
ScopedSymbolTrackingWalker.prototype.getFunctionTargetType = function (expression) {
if (expression.expression.kind === ts.SyntaxKind.PropertyAccessExpression && this.typeChecker) {
var propExp = expression.expression;
var targetType = this.typeChecker.getTypeAtLocation(propExp.expression);
return this.typeChecker.typeToString(targetType);
}
return undefined;
};
ScopedSymbolTrackingWalker.prototype.isExpressionEvaluatingToFunction = function (expression) {
if (expression.kind === ts.SyntaxKind.ArrowFunction || expression.kind === ts.SyntaxKind.FunctionExpression) {
return true;
}
if (expression.kind === ts.SyntaxKind.StringLiteral ||
expression.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral ||
expression.kind === ts.SyntaxKind.TemplateExpression ||
expression.kind === ts.SyntaxKind.TaggedTemplateExpression ||
expression.kind === ts.SyntaxKind.BinaryExpression) {
return false;
}
if (this.scope !== undefined && this.scope.isFunctionSymbol(expression.getText())) {
return true;
}
if (expression.kind === ts.SyntaxKind.Identifier && this.typeChecker) {
var tsSymbol = this.typeChecker.getSymbolAtLocation(expression);
if (tsSymbol && tsSymbol.flags === ts.SymbolFlags.Function) {
return true;
}
return false;
}
if (ts.isCallExpression(expression)) {
if (TypeGuard_1.isNamed(expression.expression) && expression.expression.name.getText() === 'bind') {
return true;
}
try {
if (!this.typeChecker) {
return true;
}
var signature = this.typeChecker.getResolvedSignature(expression);
if (signature !== undefined) {
var expressionType = this.typeChecker.getReturnTypeOfSignature(signature);
return this.isFunctionType(expressionType, this.typeChecker);
}
}
catch (e) {
return false;
}
}
if (!this.typeChecker) {
return true;
}
return this.isFunctionType(this.typeChecker.getTypeAtLocation(expression), this.typeChecker);
};
ScopedSymbolTrackingWalker.prototype.isFunctionType = function (expressionType, typeChecker) {
var signatures = typeChecker.getSignaturesOfType(expressionType, ts.SignatureKind.Call);
if (signatures !== undefined && signatures.length > 0) {
var signatureDeclaration = signatures[0].declaration;
if (signatureDeclaration !== undefined && signatureDeclaration.kind === ts.SyntaxKind.FunctionType) {
return true;
}
}
return false;
};
ScopedSymbolTrackingWalker.prototype.visitSourceFile = function (node) {
this.scope = new Scope_1.Scope(undefined);
this.scope.addGlobalScope(node, node, this.getOptions());
_super.prototype.visitSourceFile.call(this, node);
this.scope = undefined;
};
ScopedSymbolTrackingWalker.prototype.visitModuleDeclaration = function (node) {
this.scope = new Scope_1.Scope(this.scope);
this.scope.addGlobalScope(node.body, this.getSourceFile(), this.getOptions());
_super.prototype.visitModuleDeclaration.call(this, node);
this.scope = this.scope.parent;
};
ScopedSymbolTrackingWalker.prototype.visitClassDeclaration = function (node) {
var scope = (this.scope = new Scope_1.Scope(this.scope));
node.members.forEach(function (element) {
var prefix = AstUtils_1.AstUtils.isStatic(element) && node.name !== undefined ? node.name.getText() + '.' : 'this.';
if (element.kind === ts.SyntaxKind.MethodDeclaration) {
scope.addFunctionSymbol(prefix + element.name.getText());
}
else if (element.kind === ts.SyntaxKind.PropertyDeclaration) {
var prop = element;
if (AstUtils_1.AstUtils.isDeclarationFunctionType(prop)) {
scope.addFunctionSymbol(prefix + element.name.getText());
}
else {
scope.addNonFunctionSymbol(prefix + element.name.getText());
}
}
});
_super.prototype.visitClassDeclaration.call(this, node);
this.scope = this.scope.parent;
};
ScopedSymbolTrackingWalker.prototype.visitFunctionDeclaration = function (node) {
this.scope = new Scope_1.Scope(this.scope);
this.scope.addParameters(node.parameters);
_super.prototype.visitFunctionDeclaration.call(this, node);
this.scope = this.scope.parent;
};
ScopedSymbolTrackingWalker.prototype.visitConstructorDeclaration = function (node) {
this.scope = new Scope_1.Scope(this.scope);
this.scope.addParameters(node.parameters);
_super.prototype.visitConstructorDeclaration.call(this, node);
this.scope = this.scope.parent;
};
ScopedSymbolTrackingWalker.prototype.visitMethodDeclaration = function (node) {
this.scope = new Scope_1.Scope(this.scope);
this.scope.addParameters(node.parameters);
_super.prototype.visitMethodDeclaration.call(this, node);
this.scope = this.scope.parent;
};
ScopedSymbolTrackingWalker.prototype.visitArrowFunction = function (node) {
this.scope = new Scope_1.Scope(this.scope);
this.scope.addParameters(node.parameters);
_super.prototype.visitArrowFunction.call(this, node);
this.scope = this.scope.parent;
};
ScopedSymbolTrackingWalker.prototype.visitFunctionExpression = function (node) {
this.scope = new Scope_1.Scope(this.scope);
this.scope.addParameters(node.parameters);
_super.prototype.visitFunctionExpression.call(this, node);
this.scope = this.scope.parent;
};
ScopedSymbolTrackingWalker.prototype.visitSetAccessor = function (node) {
this.scope = new Scope_1.Scope(this.scope);
this.scope.addParameters(node.parameters);
_super.prototype.visitSetAccessor.call(this, node);
this.scope = this.scope.parent;
};
ScopedSymbolTrackingWalker.prototype.visitVariableDeclaration = function (node) {
if (AstUtils_1.AstUtils.isDeclarationFunctionType(node)) {
this.scope.addFunctionSymbol(node.name.getText());
}
else {
this.scope.addNonFunctionSymbol(node.name.getText());
}
_super.prototype.visitVariableDeclaration.call(this, node);
};
return ScopedSymbolTrackingWalker;
}(Lint.RuleWalker));
exports.ScopedSymbolTrackingWalker = ScopedSymbolTrackingWalker;
//# sourceMappingURL=ScopedSymbolTrackingWalker.js.map

Просмотреть файл

@ -19,3 +19,5 @@ mkdirp.sync('./dist/build');
for (const configFileName of readDirectory('./configs')) {
copyConfigFile(`./configs/${configFileName}`, `./dist/build/${configFileName}`);
}
copyConfigFile('./configs/legacy.json', './dist/build/tslint.json');

Просмотреть файл

@ -6,5 +6,6 @@ const { readJSON, writeFile } = require('./common/files');
const basePackageJson = readJSON('package.json');
delete basePackageJson.devDependencies;
delete basePackageJson.scripts;
writeFile('dist/build/package.json', JSON.stringify(basePackageJson, undefined, 4));

Просмотреть файл

@ -184,13 +184,11 @@
"unified-signatures": true,
"use-default-type-parameter": true,
"variable-name": true,
"void-zero": true,
/**
* Accessibility. The following rules should be turned on to guarantee the best user
* experience for keyboard and screen reader users.
*/
"react-a11y-accessible-headings": true,
"react-a11y-anchors": true,
"react-a11y-aria-unsupported-elements": true,
"react-a11y-event-has-role": true,

Просмотреть файл

@ -29,31 +29,12 @@ git push --tags
- Create [release](https://github.com/Microsoft/tslint-microsoft-contrib/releases) for newly pushed tag
- Increase the version number in package.json and README.md to the next minor version and push
## Prepare the tslint-microsoft-contrib releases branch
## Publish the npm package
- Clone the repo again to a new folder:
Package should be published only from `dist/build` folder.
```shell
git clone https://github.com/Microsoft/tslint-microsoft-contrib tslint-microsoft-contrib-releases
```
- For beta release run `npm publish --tag beta`
- Checkout branch `releases`
- For stable release run `npm publish`
```shell
git checkout releases
```
- Replace all files with the contents of `/dist/build` directory created from `master`
- Commit and push to remote
- tag the releases branch with the format `npm-[version]`
```shell
git tag npm-2.0.10
git push --tags
```
## Publish the Package with the Microsoft npmjs Account
- Follow the steps at https://docs.opensource.microsoft.com/releasing/build-your-project.html#npm
- Basically just send the email they want and wait a little while
- Include the npmjs.org user ids of all contributors: brndkfr, hamletdrc, dmanesku, joshuakgoldberg
If you need to promote package from beta to stable use `npm dist-tag add tslint-microsoft-contrib@<version> latest`

Просмотреть файл

@ -49,6 +49,7 @@
},
"scripts": {
"clean": "rimraf dist",
"copy:back-compat": "cpy \"**/*.js\" ../../dist/build --cwd=\"build-tasks/back-compat\" --parents",
"copy:config-json": "node build-tasks/copy-config-json.js",
"copy:json": "cpy \"src/**/*.json\" dist --parents",
"copy:meta": "cpy README.md dist/build --parents",
@ -60,11 +61,12 @@
"generate:package-json-for-npm": "node build-tasks/generate-package-json-for-npm.js",
"lint:rules": "tslint -p tsconfig.json -t stylish -c tslint.json -e \"src/tests/**\" \"src/**/*.ts\"",
"lint:tests": "tslint -p tsconfig.json -t stylish -c src/tests/tslint.json -e src/tests/references.ts \"src/tests/**/*.ts\"",
"prepublishOnly": "node -e \"throw 'You should not publish package from root directory. Publish from `dist/build` instead'\"",
"prettier": "prettier --write \"**/*.{js,ts,tsx,json,md}\"",
"start": "npm-run-all clean copy:json watch:src",
"test:mocha": "mocha \"dist/src/tests/**/*.js\" --timeout 5000",
"test:rules": "tslint -r dist/src --test \"tests/**\"",
"test": "npm-run-all clean copy:json tsc:src test:* tslint:check lint:* validate:* copy:package generate:* copy:meta copy:config-json",
"test": "npm-run-all clean copy:json tsc:src test:* tslint:check lint:* validate:* copy:package generate:* copy:meta copy:config-json copy:back-compat",
"tsc:src": "tsc",
"tslint:check": "tslint-config-prettier-check ./tslint.json",
"validate:documentation": "node build-tasks/validate-documentation.js",