diff --git a/bin/sync-dev-deps.js b/bin/sync-dev-deps.js new file mode 100755 index 000000000000..493b6b3a7a8a --- /dev/null +++ b/bin/sync-dev-deps.js @@ -0,0 +1,63 @@ +#!/usr/bin/env node +// Copyright IBM Corp. 2017,2018. All Rights Reserved. +// Node module: loopback-next +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +/** + * This is an internal script to synchronize versions of dev-dependencies + * from monorepo's package.json to individual example packages. + */ +'use strict'; + +const path = require('path'); +const fs = require('fs'); + +const Project = require('@lerna/project'); + +async function syncDevDeps() { + const project = new Project(process.cwd()); + const packages = await project.getPackages(); + + const rootPath = project.rootPath; + + // Load dependencies from `packages/build/package.json` + const buildDeps = require(path.join(rootPath, 'packages/build/package.json')) + .dependencies; + + const masterDeps = { + typescript: buildDeps.typescript, + tslint: buildDeps.tslint, + }; + + // Update typescript & tslint dependencies in individual packages + for (const pkg of packages) { + const data = readJsonFile(pkg.manifestLocation); + let modified = false; + for (const dep in masterDeps) { + if (data.devDependencies && dep in data.devDependencies) { + data.devDependencies[dep] = masterDeps[dep]; + modified = true; + } + } + if (!modified) continue; + writeJsonFile(pkg.manifestLocation, data); + } + + // Update dependencies in monorepo root + const rootPackage = path.join(rootPath, 'package.json'); + const data = readJsonFile(rootPackage); + Object.assign(data.devDependencies, masterDeps); + writeJsonFile(rootPackage, data); +} + +if (require.main === module) syncDevDeps(); + +function readJsonFile(filePath) { + return JSON.parse(fs.readFileSync(filePath, 'utf-8')); +} + +function writeJsonFile(filePath, data) { + fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\n', 'utf-8'); + console.log('%s has been updated.', filePath); +} diff --git a/bin/travis.sh b/bin/travis.sh index 4f4a46437b48..21c7da01fb0a 100755 --- a/bin/travis.sh +++ b/bin/travis.sh @@ -4,7 +4,7 @@ set -e # Running Code Linter -- Requires @loopback/build so it's bootstrapped if [ $TASK = "code-lint" ]; then echo "TASK => LINTING CODE" - lerna bootstrap --scope @loopback/build + lerna bootstrap --scope @loopback/build --scope @loopback/tslint-config npm run lint # Commit Message Linter diff --git a/docs/site/DEVELOPING.md b/docs/site/DEVELOPING.md index 8c462395d404..b633c91e0a04 100644 --- a/docs/site/DEVELOPING.md +++ b/docs/site/DEVELOPING.md @@ -22,6 +22,7 @@ See [Monorepo overview](./MONOREPO.md) for a list of all packages. - [Making breaking changes](#making-breaking-changes) - [Releasing new versions](#releasing-new-versions) - [Adding a new package](#adding-a-new-package) +- [Upgrading TypeScript/tslint](#upgrading-typescripttslint) - [How to test infrastructure changes](#how-to-test-infrastructure-changes) ## Setting up development environment @@ -437,6 +438,27 @@ Please register the new package in the following files: [@raymondfeng](https://github.com/raymondfeng) to enlist the new package on . +## Upgrading TypeScript/tslint + +In order to support tslint extensions with a peer dependency on tslint, we have +to specify `typescript` and `tslint` dependency in multiple places in our +monorepo. + +Steps to upgrade `typescript` or `tslint` to a newer version: + +1. Update the dependencies in `@loopback/build`, this is the source of truth for + the rest of the monorepo. + + ```shell + $ (cd packages/build && npm update typescript tslint) + ``` + +2. Propagate the change to other places to keep everything consistent. + + ```shell + $ node bin/sync-dev-deps + ``` + ## How to test infrastructure changes When making changes to project infrastructure, e.g. modifying `tsc` or `tslint` diff --git a/examples/hello-world/package.json b/examples/hello-world/package.json index e3400d24237e..6e7d386c379a 100644 --- a/examples/hello-world/package.json +++ b/examples/hello-world/package.json @@ -43,7 +43,9 @@ "@loopback/build": "^1.1.0", "@loopback/testlab": "^1.0.3", "@loopback/tslint-config": "^1.0.0", - "@types/node": "^10.11.2" + "@types/node": "^10.11.2", + "tslint": "^5.12.0", + "typescript": "^3.2.2" }, "keywords": [ "loopback", diff --git a/examples/log-extension/package.json b/examples/log-extension/package.json index 37ed01daa47d..d27120290132 100644 --- a/examples/log-extension/package.json +++ b/examples/log-extension/package.json @@ -45,7 +45,9 @@ "@loopback/testlab": "^1.0.3", "@loopback/tslint-config": "^1.0.0", "@types/debug": "0.0.30", - "@types/node": "^10.11.2" + "@types/node": "^10.11.2", + "tslint": "^5.12.0", + "typescript": "^3.2.2" }, "dependencies": { "@loopback/context": "^1.4.0", diff --git a/examples/rpc-server/package.json b/examples/rpc-server/package.json index 0a9fc0a81128..c1ca5db0a8e1 100644 --- a/examples/rpc-server/package.json +++ b/examples/rpc-server/package.json @@ -49,6 +49,8 @@ "@loopback/tslint-config": "^1.0.0", "@types/express": "^4.11.1", "@types/node": "^10.11.2", - "@types/p-event": "^1.3.0" + "@types/p-event": "^1.3.0", + "tslint": "^5.12.0", + "typescript": "^3.2.2" } } diff --git a/examples/soap-calculator/package.json b/examples/soap-calculator/package.json index 46c6b7f86f3c..72edf9ff5441 100644 --- a/examples/soap-calculator/package.json +++ b/examples/soap-calculator/package.json @@ -57,6 +57,8 @@ "@types/mocha": "^5.0.0", "@types/node": "^10.11.2", "mocha": "^5.1.1", - "source-map-support": "^0.5.5" + "source-map-support": "^0.5.5", + "tslint": "^5.12.0", + "typescript": "^3.2.2" } } diff --git a/examples/todo-list/package.json b/examples/todo-list/package.json index b8e8ca871caa..9fa795e25a4b 100644 --- a/examples/todo-list/package.json +++ b/examples/todo-list/package.json @@ -53,7 +53,9 @@ "@loopback/tslint-config": "^1.0.0", "@types/lodash": "^4.14.109", "@types/node": "^10.11.2", - "lodash": "^4.17.10" + "lodash": "^4.17.10", + "tslint": "^5.12.0", + "typescript": "^3.2.2" }, "keywords": [ "loopback", diff --git a/examples/todo/package.json b/examples/todo/package.json index d17332fa7451..b5868e212d46 100644 --- a/examples/todo/package.json +++ b/examples/todo/package.json @@ -53,7 +53,9 @@ "@loopback/tslint-config": "^1.0.0", "@types/lodash": "^4.14.109", "@types/node": "^10.11.2", - "lodash": "^4.17.10" + "lodash": "^4.17.10", + "tslint": "^5.12.0", + "typescript": "^3.2.2" }, "keywords": [ "loopback", diff --git a/package.json b/package.json index 8c915eab0e3a..fe89b0e1020d 100644 --- a/package.json +++ b/package.json @@ -17,13 +17,16 @@ "coveralls": "^3.0.0", "cz-conventional-changelog": "^2.1.0", "husky": "^1.2.0", - "lerna": "^3.5.1" + "lerna": "^3.5.1", + "tslint": "^5.12.0", + "typescript": "^3.2.2" }, "scripts": { "postinstall": "lerna bootstrap", "prerelease": "npm run build:full && npm run mocha && npm run lint", "release": "lerna version && lerna publish from-git --yes", "update-template-deps": "node bin/update-template-deps -f", + "sync-dev-deps": "node bin/sync-dev-deps", "version": "npm run update-template-deps && npm run apidocs", "outdated": "npm outdated --depth 0 && lerna exec --no-bail \"npm outdated --depth 0\"", "apidocs": "node bin/run-lerna run build:apidocs", diff --git a/packages/boot/test/fixtures/application.ts b/packages/boot/test/fixtures/application.ts index 6d129389c5c1..f1b2270285ff 100644 --- a/packages/boot/test/fixtures/application.ts +++ b/packages/boot/test/fixtures/application.ts @@ -10,7 +10,7 @@ import {ServiceMixin} from '@loopback/service-proxy'; import {BootMixin} from '../..'; // Force package.json to be copied to `dist` by `tsc` -//tslint:disable-next-line:no-unused-variable +//tslint:disable-next-line:no-unused import * as pkg from './package.json'; export class BooterApp extends BootMixin( diff --git a/packages/build/package.json b/packages/build/package.json index c9c7d1068f90..2424760629ec 100644 --- a/packages/build/package.json +++ b/packages/build/package.json @@ -26,8 +26,8 @@ "rimraf": "^2.6.2", "source-map-support": "^0.5.5", "strong-docs": "^4.0.0", - "tslint": "^5.9.1", - "typescript": "^3.2.1" + "tslint": "^5.12.0", + "typescript": "^3.2.2" }, "bin": { "lb-tsc": "./bin/compile-package.js", diff --git a/packages/cli/generators/project/templates/package.json.ejs b/packages/cli/generators/project/templates/package.json.ejs index a7ab4202122f..c30c45f0320a 100644 --- a/packages/cli/generators/project/templates/package.json.ejs +++ b/packages/cli/generators/project/templates/package.json.ejs @@ -93,6 +93,10 @@ "@loopback/build": "<%= project.dependencies['@loopback/build'] -%>", "@loopback/testlab": "<%= project.dependencies['@loopback/testlab'] -%>", "@loopback/tslint-config": "<%= project.dependencies['@loopback/tslint-config'] -%>", - "@types/node": "<%= project.dependencies['@types/node'] -%>" + "@types/node": "<%= project.dependencies['@types/node'] -%>", + <% if (project.tslint) { -%> + "tslint": "<%= project.dependencies['tslint'] -%>", + <% } -%> + "typescript": "<%= project.dependencies['typescript'] -%>" } } diff --git a/packages/cli/test/integration/lib/project-generator.js b/packages/cli/test/integration/lib/project-generator.js index b3570e2e2833..ca399e61de53 100644 --- a/packages/cli/test/integration/lib/project-generator.js +++ b/packages/cli/test/integration/lib/project-generator.js @@ -249,11 +249,12 @@ module.exports = function(projGenerator, props, projectType) { assert.jsonFileContent('package.json', props); assert.fileContent([ ['package.json', '@loopback/build'], + ['package.json', '"typescript"'], + ['package.json', '"tslint"'], ['tslint.json', '@loopback/tslint-config'], ['tsconfig.json', '@loopback/build'], ]); assert.noFileContent([ - ['package.json', '"typescript"'], ['tslint.json', '"rules"'], ['tsconfig.json', '"compilerOptions"'], ]); @@ -423,6 +424,7 @@ module.exports = function(projGenerator, props, projectType) { assert.noFile(['tslint.json', 'tslint.build.json']); assert.noFileContent([ ['package.json', '@loopback/build'], + ['package.json', '"tslint"'], ['tsconfig.json', '@loopback/build'], ]); assert.fileContent([ diff --git a/packages/context/src/binding-key.ts b/packages/context/src/binding-key.ts index c271af585829..02837d5a9a1d 100644 --- a/packages/context/src/binding-key.ts +++ b/packages/context/src/binding-key.ts @@ -5,7 +5,7 @@ export type BindingAddress = string | BindingKey; -// tslint:disable-next-line:no-unused-variable +// tslint:disable-next-line:no-unused export class BindingKey { static readonly PROPERTY_SEPARATOR = '#'; diff --git a/packages/context/src/resolution-session.ts b/packages/context/src/resolution-session.ts index e72b0151f53a..0a682c02f5b8 100644 --- a/packages/context/src/resolution-session.ts +++ b/packages/context/src/resolution-session.ts @@ -13,7 +13,7 @@ const debugSession = debugModule('loopback:context:resolver:session'); const getTargetName = DecoratorFactory.getTargetName; // NOTE(bajtos) The following import is required to satisfy TypeScript compiler -// tslint:disable-next-line:no-unused-variable +// tslint:disable-next-line:no-unused import {BindingKey} from './binding-key'; /** diff --git a/packages/context/test/unit/inject.unit.ts b/packages/context/test/unit/inject.unit.ts index acbd71151afd..75c4a3dd74d2 100644 --- a/packages/context/test/unit/inject.unit.ts +++ b/packages/context/test/unit/inject.unit.ts @@ -12,7 +12,7 @@ import { describe('function argument injection', () => { it('can decorate class constructor arguments', () => { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class TestClass { constructor(@inject('foo') foo: string) {} } @@ -29,7 +29,7 @@ describe('function argument injection', () => { }); it('can retrieve information about injected method arguments', () => { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class TestClass { test(@inject('foo') foo: string) {} } @@ -97,7 +97,7 @@ describe('function argument injection', () => { describe('property injection', () => { it('can decorate properties', () => { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class TestClass { @inject('foo') foo: string; @@ -126,7 +126,7 @@ describe('property injection', () => { it('cannot decorate static properties', () => { expect(() => { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class TestClass { @inject('foo') static foo: string; @@ -136,7 +136,7 @@ describe('property injection', () => { it('cannot decorate a method', () => { expect(() => { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class TestClass { @inject('bar') foo() {} diff --git a/packages/context/test/unit/resolution-session.unit.ts b/packages/context/test/unit/resolution-session.unit.ts index 02aad9f45942..73c248804666 100644 --- a/packages/context/test/unit/resolution-session.unit.ts +++ b/packages/context/test/unit/resolution-session.unit.ts @@ -8,7 +8,7 @@ import {ResolutionSession, Binding, Injection, inject} from '../..'; describe('ResolutionSession', () => { class MyController { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused constructor(@inject('b') private b: string) {} } function givenInjection(): Injection { diff --git a/packages/metadata/src/types.ts b/packages/metadata/src/types.ts index aa66d5f1235f..073e287830ed 100644 --- a/packages/metadata/src/types.ts +++ b/packages/metadata/src/types.ts @@ -17,6 +17,7 @@ export type DecoratorType = * @typeparam T Type of the metadata value * @typeparam D Type of the decorator */ +// tslint:disable-next-line:no-unused export class MetadataAccessor { private constructor(public readonly key: string) {} diff --git a/packages/metadata/test/unit/decorator-factory.unit.ts b/packages/metadata/test/unit/decorator-factory.unit.ts index b5a9cee90369..dc0755554c2a 100644 --- a/packages/metadata/test/unit/decorator-factory.unit.ts +++ b/packages/metadata/test/unit/decorator-factory.unit.ts @@ -113,7 +113,7 @@ describe('ClassDecoratorFactory', () => { expect(() => { @classDecorator({x: 1}) @classDecorator({y: 2}) - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class MyController {} }).to.throw( /Decorator cannot be applied more than once on class MyController/, @@ -352,7 +352,7 @@ describe('PropertyDecoratorFactory', () => { it('throws if applied more than once on the same property', () => { expect(() => { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class MyController { @propertyDecorator({x: 1}) @propertyDecorator({y: 2}) @@ -400,7 +400,7 @@ describe('PropertyDecoratorFactory for static properties', () => { it('throws if applied more than once on the same static property', () => { expect(() => { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class MyController { @propertyDecorator({x: 1}) @propertyDecorator({y: 2}) @@ -448,7 +448,7 @@ describe('MethodDecoratorFactory', () => { it('throws if applied more than once on the same method', () => { expect(() => { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class MyController { @methodDecorator({x: 1}) @methodDecorator({y: 2}) @@ -496,7 +496,7 @@ describe('MethodDecoratorFactory for static methods', () => { it('throws if applied more than once on the same static method', () => { expect(() => { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class MyController { @methodDecorator({x: 1}) @methodDecorator({y: 2}) @@ -545,7 +545,7 @@ describe('ParameterDecoratorFactory', () => { it('throws if applied more than once on the same parameter', () => { expect(() => { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class MyController { myMethod( @parameterDecorator({x: 1}) @@ -634,7 +634,7 @@ describe('ParameterDecoratorFactory for a static method', () => { it('throws if applied more than once on the same parameter', () => { expect(() => { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class MyController { static myMethod( @parameterDecorator({x: 1}) @@ -695,7 +695,7 @@ describe('MethodParameterDecoratorFactory with invalid decorations', () => { it('reports error if the # of decorations exceeeds the # of params', () => { expect(() => { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class MyController { @methodParameterDecorator({x: 1}) // Causing error @methodParameterDecorator({x: 2}) // For a diff --git a/packages/openapi-v3-types/test/unit/openapi-v3-spec-types.unit.ts b/packages/openapi-v3-types/test/unit/openapi-v3-spec-types.unit.ts index 73848d1461ef..32038995165d 100644 --- a/packages/openapi-v3-types/test/unit/openapi-v3-spec-types.unit.ts +++ b/packages/openapi-v3-types/test/unit/openapi-v3-spec-types.unit.ts @@ -57,7 +57,7 @@ describe('openapi-v3-types unit tests', () => { * original OAS 3 definition. (Though some interfaces allow for extensibility). */ - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class TestObject implements ExampleObject { summary: 'test object'; description: 'test object'; @@ -66,12 +66,12 @@ describe('openapi-v3-types unit tests', () => { randomProperty: 'extension value'; } - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class ReferenceTestObject implements ReferenceObject { $ref: '#def/reference-object'; } - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class DiscriminatorTestObject implements DiscriminatorObject { propertyName: 'test'; mapping: { @@ -79,7 +79,7 @@ describe('openapi-v3-types unit tests', () => { }; } - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class XMLTestObject implements XmlObject { name: 'test'; namespace: 'test'; @@ -88,13 +88,13 @@ describe('openapi-v3-types unit tests', () => { wrapped: false; } - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class TestExternalDocumentationObject implements ExternalDocumentationObject { url: 'https://test.com/test.html'; } - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class TestISpecificationExtension implements ISpecificationExtension { test: 'test'; } diff --git a/packages/openapi-v3/test/unit/decorators/param/param.decorator.unit.ts b/packages/openapi-v3/test/unit/decorators/param/param.decorator.unit.ts index 8d0a8e1aca43..0f273b4a6ea2 100644 --- a/packages/openapi-v3/test/unit/decorators/param/param.decorator.unit.ts +++ b/packages/openapi-v3/test/unit/decorators/param/param.decorator.unit.ts @@ -164,7 +164,7 @@ describe('Routing metadata for parameters', () => { it('reports error if an array parameter type is not Array', () => { expect.throws( () => { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class MyController { @get('/greet') greet( diff --git a/packages/repository-json-schema/test/unit/json-schema.unit.ts b/packages/repository-json-schema/test/unit/json-schema.unit.ts index 32bb1dcd823e..e4547d144603 100644 --- a/packages/repository-json-schema/test/unit/json-schema.unit.ts +++ b/packages/repository-json-schema/test/unit/json-schema.unit.ts @@ -15,7 +15,7 @@ describe('JSON Schema type', () => { * Inspired by https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/json-schema/json-schema-tests.ts */ - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused const testSchema: JsonSchema = { $id: 'test', $ref: 'test/sub', diff --git a/packages/repository/examples/controllers/customer-with-constructor-di.controller.ts b/packages/repository/examples/controllers/customer-with-constructor-di.controller.ts index 64d09d162b8a..2f60e0f677aa 100644 --- a/packages/repository/examples/controllers/customer-with-constructor-di.controller.ts +++ b/packages/repository/examples/controllers/customer-with-constructor-di.controller.ts @@ -3,7 +3,7 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -// tslint:disable:no-unused-variable +// tslint:disable:no-unused import {EntityCrudRepository, repository} from '../..'; import {Customer} from '../models/customer.model'; @@ -15,7 +15,7 @@ import {Customer} from '../models/customer.model'; export class CustomerController { constructor( // Use constructor dependency injection - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused @repository('Customer', 'mongodbDataSource') private _repository: EntityCrudRepository, ) {} diff --git a/packages/repository/examples/controllers/customer-with-property-di.controller.ts b/packages/repository/examples/controllers/customer-with-property-di.controller.ts index 7dc2f9f9431c..01067217a5bf 100644 --- a/packages/repository/examples/controllers/customer-with-property-di.controller.ts +++ b/packages/repository/examples/controllers/customer-with-property-di.controller.ts @@ -3,7 +3,7 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -// tslint:disable:no-unused-variable +// tslint:disable:no-unused import {EntityCrudRepository, repository} from '../..'; import {Customer} from '../models/customer.model'; diff --git a/packages/repository/examples/models/order.model.ts b/packages/repository/examples/models/order.model.ts index 47a72c71cba9..bf48dc85196c 100644 --- a/packages/repository/examples/models/order.model.ts +++ b/packages/repository/examples/models/order.model.ts @@ -6,7 +6,7 @@ import {belongsTo, Entity, model, property} from '../..'; import {Customer} from './customer.model'; -// tslint:disable:no-unused-variable +// tslint:disable:no-unused @model() class Order extends Entity { diff --git a/packages/repository/src/repositories/repository.ts b/packages/repository/src/repositories/repository.ts index 5077bf52145a..31a24a132c9b 100644 --- a/packages/repository/src/repositories/repository.ts +++ b/packages/repository/src/repositories/repository.ts @@ -18,7 +18,7 @@ import {CrudConnector} from '../connectors'; import {Filter, Where} from '../query'; import {EntityNotFoundError} from '../errors'; -// tslint:disable:no-unused-variable +// tslint:disable:no-unused export interface Repository {} @@ -333,7 +333,7 @@ export class CrudRepositoryImpl ); } else { // FIXME: populate inst with all properties - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused const inst = data; const where = this.entityClass.buildWhereForId(id); const result = await this.updateAll(data, where, options); diff --git a/packages/repository/test/acceptance/has-one.relation.acceptance.ts b/packages/repository/test/acceptance/has-one.relation.acceptance.ts index 18313c6d324e..0343a41443e4 100644 --- a/packages/repository/test/acceptance/has-one.relation.acceptance.ts +++ b/packages/repository/test/acceptance/has-one.relation.acceptance.ts @@ -5,7 +5,6 @@ import {Application} from '@loopback/core'; import {expect, toJSON} from '@loopback/testlab'; -import * as _ from 'lodash'; import { ApplicationWithRepositories, juggler, diff --git a/packages/repository/test/unit/decorator/model-and-relation.decorator.unit.ts b/packages/repository/test/unit/decorator/model-and-relation.decorator.unit.ts index 31dfe10f8ba7..ea6a2e678289 100644 --- a/packages/repository/test/unit/decorator/model-and-relation.decorator.unit.ts +++ b/packages/repository/test/unit/decorator/model-and-relation.decorator.unit.ts @@ -351,7 +351,7 @@ describe('model decorator', () => { it('throws when @property.array is used on a non-array property', () => { expect.throws( () => { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class Oops { @property.array(Product) product: Product; diff --git a/packages/repository/test/unit/decorator/relation.decorator.unit.ts b/packages/repository/test/unit/decorator/relation.decorator.unit.ts index e30f19e5fd2d..ec7cb9cf3a18 100644 --- a/packages/repository/test/unit/decorator/relation.decorator.unit.ts +++ b/packages/repository/test/unit/decorator/relation.decorator.unit.ts @@ -115,7 +115,7 @@ describe('relation decorator', () => { province: string; } - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class AddressBook extends Entity { id: number; @property.array(Entity) diff --git a/packages/repository/test/unit/decorator/repository.decorator.unit.ts b/packages/repository/test/unit/decorator/repository.decorator.unit.ts index 84d91949386e..fa05cb4c0ac1 100644 --- a/packages/repository/test/unit/decorator/repository.decorator.unit.ts +++ b/packages/repository/test/unit/decorator/repository.decorator.unit.ts @@ -80,7 +80,7 @@ describe('repository decorator', () => { it('throws not implemented for class-level @repository', () => { expect(() => { @repository('noteRepo') - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class Controller1 {} }).to.throw(/not implemented/); }); diff --git a/packages/repository/test/unit/model/model.unit.ts b/packages/repository/test/unit/model/model.unit.ts index 59f43be780bd..3680fbfe4125 100644 --- a/packages/repository/test/unit/model/model.unit.ts +++ b/packages/repository/test/unit/model/model.unit.ts @@ -96,7 +96,7 @@ describe('model', () => { } } - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused class User extends Entity { static definition = userDef; id: string; diff --git a/packages/repository/test/unit/repositories/relation.repository.unit.ts b/packages/repository/test/unit/repositories/relation.repository.unit.ts index 81a86610ee3f..ea242f63c22d 100644 --- a/packages/repository/test/unit/repositories/relation.repository.unit.ts +++ b/packages/repository/test/unit/repositories/relation.repository.unit.ts @@ -17,7 +17,6 @@ import { DefaultCrudRepository, DefaultHasManyRepository, Entity, - EntityCrudRepository, Filter, HasManyRepository, juggler, @@ -36,12 +35,9 @@ describe('relation repository', () => { * interface. The TS Compiler will complain if the interface changes. */ - // tslint:disable-next-line:no-unused-variable - class testHasManyEntityCrudRepository< - T extends Entity, - ID, - TargetRepository extends EntityCrudRepository - > implements HasManyRepository { + // tslint:disable-next-line:no-unused + class testHasManyEntityCrudRepository + implements HasManyRepository { create( targetModelData: DataObject, options?: AnyObject | undefined, diff --git a/packages/rest/test/acceptance/bootstrapping/rest.acceptance.ts b/packages/rest/test/acceptance/bootstrapping/rest.acceptance.ts index d5f71f2fa194..818f880586ab 100644 --- a/packages/rest/test/acceptance/bootstrapping/rest.acceptance.ts +++ b/packages/rest/test/acceptance/bootstrapping/rest.acceptance.ts @@ -76,7 +76,7 @@ async function startServerCheck(app: Application) { } function sequenceHandler( - {request, response}: RequestContext, + {response}: RequestContext, sequence: DefaultSequence, ) { sequence.send(response, 'hello world'); diff --git a/packages/rest/test/acceptance/routing/routing.acceptance.ts b/packages/rest/test/acceptance/routing/routing.acceptance.ts index dc75a3c6bd85..407bad662f12 100644 --- a/packages/rest/test/acceptance/routing/routing.acceptance.ts +++ b/packages/rest/test/acceptance/routing/routing.acceptance.ts @@ -692,7 +692,7 @@ describe('Routing', () => { it('provides httpHandler compatible with HTTP server API', async () => { const app = new RestApplication(); - app.handler(({request, response}, sequence) => response.end('hello')); + app.handler(({response}, sequence) => response.end('hello')); await createClientForHandler(app.requestHandler) .get('/') diff --git a/packages/rest/test/acceptance/sequence/sequence.acceptance.ts b/packages/rest/test/acceptance/sequence/sequence.acceptance.ts index bf74fe666992..ae94a70fddd2 100644 --- a/packages/rest/test/acceptance/sequence/sequence.acceptance.ts +++ b/packages/rest/test/acceptance/sequence/sequence.acceptance.ts @@ -44,7 +44,7 @@ describe('Sequence', () => { }); it('allows users to define a custom sequence as a function', () => { - server.handler(({request, response}, sequence) => { + server.handler(({response}, sequence) => { sequence.send(response, 'hello world'); }); return whenIRequest() @@ -98,7 +98,7 @@ describe('Sequence', () => { class MySequence implements SequenceHandler { constructor(@inject(SequenceActions.SEND) protected send: Send) {} - async handle({request, response}: RequestContext) { + async handle({response}: RequestContext) { this.send(response, 'MySequence was invoked.'); } } diff --git a/packages/rest/test/unit/re-export.unit.ts b/packages/rest/test/unit/re-export.unit.ts index 0a5395e7db1e..69da8f13fef3 100644 --- a/packages/rest/test/unit/re-export.unit.ts +++ b/packages/rest/test/unit/re-export.unit.ts @@ -6,7 +6,7 @@ import {get} from '../..'; describe('re-export controller decorators', () => { it('exports functions from @loopback/openapi-v3', async () => { - /* tslint:disable-next-line:no-unused-variable */ + /* tslint:disable-next-line:no-unused */ class Test { // Make sure the decorators are exported @get('/test') diff --git a/packages/rest/test/unit/rest.application/rest.application.unit.ts b/packages/rest/test/unit/rest.application/rest.application.unit.ts index 028387fdce80..b6789ec24a2f 100644 --- a/packages/rest/test/unit/rest.application/rest.application.unit.ts +++ b/packages/rest/test/unit/rest.application/rest.application.unit.ts @@ -14,7 +14,7 @@ import {expect} from '@loopback/testlab'; describe('RestApplication', () => { describe('throws', () => { it('when attempting to bind another server', () => { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused const app = new RestApplication(); expect.throws( () => { @@ -26,7 +26,7 @@ describe('RestApplication', () => { }); it('when attempting to bind an array of servers', () => { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused const app = new RestApplication(); expect.throws( () => { @@ -41,7 +41,7 @@ describe('RestApplication', () => { class OtherRestComponent extends RestComponent {} expect.throws( () => { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused const app = new RestApplication(); app.component(RestComponent); app.component(OtherRestComponent); diff --git a/packages/testlab/test/unit/to-json.test.ts b/packages/testlab/test/unit/to-json.test.ts index ab1e8d1838f9..726dd0ef6574 100644 --- a/packages/testlab/test/unit/to-json.test.ts +++ b/packages/testlab/test/unit/to-json.test.ts @@ -64,7 +64,7 @@ describe('toJSON', () => { it('handles classes with custom toJSON', () => { class Customer { - // tslint:disable-next-line:no-unused-variable + // tslint:disable-next-line:no-unused private __data: object; constructor(public id: string, public email: string) { diff --git a/packages/tslint-config/package.json b/packages/tslint-config/package.json index 114e0a9188e6..5b6f74a49d28 100644 --- a/packages/tslint-config/package.json +++ b/packages/tslint-config/package.json @@ -8,6 +8,9 @@ "author": "IBM", "copyright.owner": "IBM Corp.", "license": "MIT", + "dependencies": { + "tslint-consistent-codestyle": "^1.14.1" + }, "peerDependencies": { "tslint": ">=5.11.0" }, diff --git a/packages/tslint-config/tslint.build.json b/packages/tslint-config/tslint.build.json index 819a34736d9c..6906febfa0aa 100644 --- a/packages/tslint-config/tslint.build.json +++ b/packages/tslint-config/tslint.build.json @@ -17,7 +17,8 @@ // tell tslint that it's ok to `await` such promises. "await-promise": [true, "PromiseLike", "RequestPromise"], "no-floating-promises": [true, "PromiseLike", "RequestPromise"], - "no-unused-variable": true, + // Explicitly disable this rule, we are using "no-unused" rule instead + "no-unused-variable": false, "no-void-expression": [true, "ignore-arrow-function-shorthand"] } } diff --git a/packages/tslint-config/tslint.common.json b/packages/tslint-config/tslint.common.json index 78d35a3e62f3..ecd294e152b7 100644 --- a/packages/tslint-config/tslint.common.json +++ b/packages/tslint-config/tslint.common.json @@ -1,4 +1,8 @@ { + "$schema": "http://json.schemastore.org/tslint", + "rulesDirectory": [ + "tslint-consistent-codestyle" + ], // See https://palantir.github.io/tslint/rules/ "rules": { // These rules find errors related to TypeScript features. @@ -19,6 +23,7 @@ "no-misused-new": true, "no-shadowed-variable": true, "no-string-throw": true, + "no-unused": [true, "ignore-parameters"], "no-unused-expression": true, "no-var-keyword": true, "triple-equals": [true, "allow-null-check", "allow-undefined-check"]