move tslint ADF rules in principal repo (#3247)

* move tslint ADF rules in principal repo

* fix style issues

* change pacakge.json position

* update to angular cli 6.0.0

* reorganization package.json

* remove node modules2 folder

* exclude integration

* rollback alfresco-js-api

* solve types problems

* fix pdf test

* fix errors and exclude two tests

* fix e2e

* fix test

* copy all the new packages in node_modules

* fix test

* fix packaging script

* scss issue fix

* move test export in tools
This commit is contained in:
Eugenio Romano
2018-05-04 17:13:45 +01:00
committed by GitHub
parent 563af3bbfa
commit fe0ac0e474
89 changed files with 30455 additions and 1250 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,9 @@
{
"export-last-version": "export-new.json",
"export-versions": [
"export-2.0.0.json",
"export-2.1.0.json",
"export-2.2.0.json",
"export-2.3.0.json"
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,373 @@
import * as ts from "typescript";
import * as fs from "fs";
import chalk from "chalk";
var nconf = require('nconf');
var basePath = "./tools/export-check/";
nconf.add('config', { type: 'file', file: `${basePath}export-check-config.json` });
var newLibExports = basePath + nconf.get('export-last-version');
var exportFilesVersions = nconf.get('export-versions').map((currentFile) => {
return basePath + currentFile;
});
interface DocEntry {
position?: {
line: number,
character: number,
fileName: string
},
name?: string,
skipError?: boolean
};
let error_array = [];
let warning_array = [];
let exportedAllPath: Array<string> = [];
let classList: Array<any> = [];
let add_error = function (error: string, nameClass: string) {
let findErrorClass = false;
error_array.forEach((currentError) => {
if (currentError.nameClass === nameClass) {
findErrorClass = true;
return;
}
});
if (!findErrorClass) {
error_array.push({
error: error,
nameClass: nameClass
});
}
}
let count_error = 0;
let count_warning = 0;
let print_errors = function () {
error_array.forEach((current_error) => {
console.log(chalk.red(`[${++count_error}] ${current_error.error}\n`));
});
}
let add_warning = function (warning: string, nameClass: string, arrayCall: string[]) {
let findWarningClass = false;
warning_array.forEach((currentWarning) => {
if (currentWarning.nameClass === nameClass) {
findWarningClass = true;
return;
}
});
if (!findWarningClass) {
warning_array.push({
warning: warning,
nameClass: nameClass,
arrayCall: arrayCall
});
}
}
let print_warnings = function () {
warning_array.forEach((current_warning) => {
console.log(chalk.yellow(`[${++count_warning}] ${current_warning.warning} \n ${current_warning.arrayCall} \n`));
});
}
let currentErrorPostion = function (exportEntry) {
return ` ${exportEntry.position.fileName} (${exportEntry.position.line},${exportEntry.position.character})`
}
let check_export = function (exportLastMajor: any, exportNew: any) {
exportLastMajor.forEach((currentexportLastMajor) => {
let currentexportNew = exportNew.filter((currentexportNew) => {
return currentexportNew.name === currentexportLastMajor.name;
});
if (currentexportNew.length > 1) {
let arrayCall = [];
currentexportNew.forEach((error) => {
arrayCall.push(`${currentErrorPostion(error)}`);
})
add_warning(`Multiple export ${currentexportNew[0].name} times ${currentexportNew.length}`, currentexportNew[0].name, arrayCall);
} else if (currentexportNew.length === 0) {
if (!currentexportLastMajor.skipError) {
add_error(`Not find export ${currentexportLastMajor.name} , old path: [${currentErrorPostion(currentexportLastMajor)}]`, currentexportLastMajor.name);
}
}
});
};
let expandStarExport = function (node: ts.Node): ts.ExportDeclaration {
const ed = node as ts.Node as ts.ExportDeclaration;
const exports = [{ name: "x" }];
const exportSpecifiers = exports.map(e => ts.createExportSpecifier(e.name, e.name));
const exportClause = ts.createNamedExports(exportSpecifiers);
const newEd = ts.updateExportDeclaration(ed, ed.decorators, ed.modifiers, exportClause, ed.moduleSpecifier);
return newEd as ts.ExportDeclaration
};
/** Generate documentation for all classes in a set of .ts files */
function generatExportList(fileNames: string[], options: ts.CompilerOptions): void {
// Build a program using the set of root file names in fileNames
let program = ts.createProgram(fileNames, options);
// Get the checker, we will use it to find more about classes
let checker = program.getTypeChecker();
let exportCurrentVersion: DocEntry[] = [];
// Visit every sourceFile in the program
for (const sourceFile of program.getSourceFiles()) {
if (!sourceFile.isDeclarationFile) {
// Walk the tree to search for classes
ts.forEachChild(sourceFile, visit);
}
}
classList.forEach((classNode) => {
if (classNode.symbol.parent) {
let pathClass = classNode.symbol.parent.escapedName.replace(/"/g, "");
exportedAllPath.forEach((currenPath) => {
let pathNoExtension = currenPath.replace(/\.[^/.]+$/, "");
if (pathNoExtension === pathClass) {
// console.log('pathClass'+ pathClass);
// console.log('pathNoExtension '+ pathNoExtension);
extractExport(classNode);
return;
}
});
}
});
exportCurrentVersion.sort((nameA, nameB) => nameA.name.localeCompare(nameB.name));
console.log(chalk.green(`Saving new export in ${newLibExports}`));
fs.writeFileSync(newLibExports, JSON.stringify(exportCurrentVersion, undefined, 4));
var exportNewJSON = JSON.parse(JSON.stringify(exportCurrentVersion));
exportFilesVersions.forEach((currentExportVersionFile) => {
error_array = [];
warning_array = [];
try {
var currentExportVersionJSON = JSON.parse(fs.readFileSync(`${currentExportVersionFile}`, 'utf8'));
} catch (error) {
console.log(chalk.red(`${currentExportVersionFile} json not present`));
throw new Error(`Undetected export comapring file ${currentExportVersionFile}`);
}
console.log(chalk.green(`Comparing ${newLibExports} and ${currentExportVersionFile}`));
check_export(currentExportVersionJSON, exportNewJSON);
print_warnings();
print_errors();
if (error_array.length > 0) {
throw new Error('Export problems detected');
} else {
return;
}
})
function extractExport(node: ts.Node) {
//skip file with export-check: exclude comment
if (node.getFullText(node.getSourceFile()).indexOf('export-check: exclude') > 0) {
return;
}
let { line, character } = node.getSourceFile().getLineAndCharacterOfPosition(node.getStart());
//console.log(line + " " + character + " " + node.getSourceFile().fileName);
let symbol = checker.getSymbolAtLocation(node);
if (symbol) {
let arryCalls = recursiveStackSave(node);
let className: any = symbol.escapedName;
let filename = node.getSourceFile().fileName.substring(node.getSourceFile().fileName.indexOf('lib'), node.getSourceFile().fileName.length);
exportCurrentVersion.push(serializeClass(className, line, character, filename, arryCalls));
// if (className === "ContentMetadataService") {
// console.log(chalk.red("exportedAllPath" + exportedAllPath));
// console.log(chalk.red("ContentMetadataService"));
// recursiveStack(node);
// }
} else {
let arryCalls = recursiveStackSave(node);
let className: any = (node as ts.ClassDeclaration).name.escapedText;
let filename = node.getSourceFile().fileName.substring(node.getSourceFile().fileName.indexOf('lib'), node.getSourceFile().fileName.length);
exportCurrentVersion.push(serializeClass(className, line, character, filename, arryCalls));
// if (className === "ContentMetadataService") {
// console.log(chalk.greenBright("exportedAllPath" + exportedAllPath));
// console.log(chalk.greenBright("ContentMetadataService"));
// recursiveStack(node);
// }
}
}
function recursiveStackSave(node: ts.Node, arrayCalls?: string[]) {
if (!arrayCalls) {
arrayCalls = [];
}
let filename = node.getSourceFile().fileName.substring(node.getSourceFile().fileName.indexOf('lib'), node.getSourceFile().fileName.length);
let { line, character } = node.getSourceFile().getLineAndCharacterOfPosition(node.getStart());
arrayCalls.push(node.getSourceFile().fileName);
if (node.parent) {
recursiveStackSave(node.parent, arrayCalls)
}
return arrayCalls;
}
function recursiveStack(node: ts.Node) {
let filename = node.getSourceFile().fileName.substring(node.getSourceFile().fileName.indexOf('lib'), node.getSourceFile().fileName.length);
let { line, character } = node.getSourceFile().getLineAndCharacterOfPosition(node.getStart());
console.log(chalk.bgCyan(line + " " + character + " " + node.getSourceFile().fileName));
if (node.parent) {
recursiveStack(node.parent)
}
}
/** visit nodes finding exported classes */
function visit(node: ts.Node) {
// Only consider exported nodes
if (node.kind === ts.SyntaxKind.ClassDeclaration) {
if (node.decorators) {
node.decorators.forEach((decorator) => {
visit(decorator as ts.Node);
});
}
classList.push(node);
}
if (node.kind === ts.SyntaxKind.PropertyAssignment) {
const initializer = (node as ts.PropertyAssignment).initializer;
visit(initializer as ts.Node);
}
if (node.kind === ts.SyntaxKind.Identifier) {
extractExport(node);
}
if (node.kind === ts.SyntaxKind.ArrayLiteralExpression) {
(node as ts.ArrayLiteralExpression).elements.forEach((element) => {
visit(element as ts.Node);
});
}
if (node.kind === ts.SyntaxKind.Decorator &&
((node as ts.Decorator).expression as any).expression.text === "NgModule") {
((node as ts.Decorator).expression as any).arguments.forEach((argument) => {
argument.properties.forEach((property) => {
if (property.name.escapedText === "exports") {
visit(property as ts.Node);
}
});
});
}
if (ts.isExportDeclaration(node)) {
if (node.exportClause) {
node.exportClause.elements.forEach(exportCurrent => {
extractExport(exportCurrent as ts.Node);
});
} else {
(node.parent as any).resolvedModules.forEach((currentModule) => {
if (currentModule) {
let find;
exportedAllPath.forEach((currentExported) => {
if (currentModule.resolvedFileName === currentExported) {
find = currentExported;
}
})
if (!find) {
exportedAllPath.push(currentModule.resolvedFileName);
}
}
})
visit(node.moduleSpecifier);
}
}
if (ts.isModuleDeclaration(node)) {
// This is a namespace, visit its children
ts.forEachChild(node, visit);
}
}
/** Serialize a symbol into a json object */
function serializeSymbol(className: string, line?: number, character?: number, fileName?: string, arryCalls?: string[]): DocEntry {
return {
position: {
line: line,
character: character,
fileName: fileName
},
name: className
};
}
/** Serialize a class symbol information */
function serializeClass(className: string, line?: number, character?: number, fileName?: string, arryCalls?: string[]) {
let details = serializeSymbol(className, line, character, fileName, arryCalls);
return details;
}
/** True if this is visible outside this file, false otherwise */
function isNodeExported(node: ts.Node): boolean {
return (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) !== 0 || (!!node.parent && node.parent.kind === ts.SyntaxKind.SourceFile);
}
}
generatExportList(process.argv.slice(2), {
target: ts.ScriptTarget.ES5, module: ts.ModuleKind.CommonJS, removeComments: false
});

7
tools/tslint-rules/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
/npm-debug.log
/.idea
node_modules
coverage
/temp/
local.log
/rules/*.js

View File

@@ -0,0 +1,16 @@
.idea
coverage/
node_modules
temp/
test/
/.editorconfig
/.travis.yml
/gulpfile.js
/.npmignore
*.tgz
/assets/
local.log

View File

@@ -0,0 +1,36 @@
# adf-tslint-rules
A set of [TSLint](https://github.com/palantir/tslint) rules used on [ADF](https://github.com/Alfresco/alfresco-ng2-components) project.
## Installation
```sh
npm install adf-tslint-rules
```
## Configuration
```javascript
{
"rulesDirectory": [
"node_modules/codelyzer",
"node_modules/adf-tslint-rules"
],
"rules": {
"adf-file-name": true,
"adf-class-name": true,
"adf-no-on-prefix-output-name": true
}
}
```
Supported Rules
-----
Rule Name | Description |
---------- | ------------ |
`adf-file-name` | The name of the File should not start with ADF Alfresco or Activiti prefix |
`adf-class-name` | The name of the class should not start with ADF Alfresco or Activiti prefix |
`adf-no-on-prefix-output-name` | Angular allows for an alternative syntax on-*. If the event itself was prefixed with on this would result in an on-onEvent binding expression |
|

View File

@@ -0,0 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Lint = require("tslint");
const sprintf_js_1 = require("sprintf-js");
const walkerFactory_1 = require("codelyzer/walkerFactory/walkerFactory");
const walkerFn_1 = require("codelyzer/walkerFactory/walkerFn");
const function_1 = require("codelyzer/util/function");
class Rule extends Lint.Rules.AbstractRule {
static invalidName(className) {
var whiteList = ['ActivitiContentComponent', 'ActivitiForm'];
var classNameReg = /^(alfresco|activiti|adf|activity)/ig;
var classNameMatch = classNameReg.exec(className);
var isWhiteListName = whiteList.find((currentWhiteListName) => {
return currentWhiteListName === className;
});
if (classNameMatch && !isWhiteListName) {
return true;
}
return false;
}
apply(sourceFile) {
return this.applyWithWalker(Rule.walkerBuilder(sourceFile, this.getOptions()));
}
}
Rule.metadata = {
ruleName: 'adf-class-name',
type: 'maintainability',
description: `Enforce consistent name avoid prefix`,
descriptionDetails: `See more at https://angular.io/styleguide#style-05-13.`,
rationale: `Consistent conventions make it easy to quickly identify class when you search with autocomplete.`,
options: null,
optionsDescription: "Not configurable.",
typescriptOnly: true,
};
Rule.FAILURE_STRING = 'The name of the class should not start with ADF Alfresco or Activiti prefix ';
Rule.walkerBuilder = walkerFn_1.all(walkerFn_1.validateComponent((meta, suffixList) => function_1.Maybe.lift(meta.controller)
.fmap(controller => controller.name)
.fmap(name => {
const className = name.text;
if (Rule.invalidName(className)) {
return [new walkerFactory_1.Failure(name, sprintf_js_1.sprintf(Rule.FAILURE_STRING + className, className, suffixList))];
}
})));
exports.Rule = Rule;

View File

@@ -0,0 +1,61 @@
import * as Lint from 'tslint';
import * as ts from 'typescript';
import { sprintf } from 'sprintf-js';
import { ComponentMetadata } from 'codelyzer/angular/metadata';
import { Failure } from 'codelyzer/walkerFactory/walkerFactory';
import { all, validateComponent } from 'codelyzer/walkerFactory/walkerFn';
import { Maybe, F2 } from 'codelyzer/util/function';
import { IOptions } from 'tslint';
import { NgWalker } from 'codelyzer/angular/ngWalker';
export class Rule extends Lint.Rules.AbstractRule {
public static metadata: Lint.IRuleMetadata = {
ruleName: 'adf-class-name',
type: 'maintainability',
description: `Enforce consistent name avoid prefix`,
descriptionDetails: `See more at https://angular.io/styleguide#style-05-13.`,
rationale: `Consistent conventions make it easy to quickly identify class when you search with autocomplete.`,
options: null,
optionsDescription: "Not configurable.",
typescriptOnly: true,
};
public static FAILURE_STRING = 'The name of the class should not start with ADF Alfresco or Activiti prefix ';
static walkerBuilder: F2<ts.SourceFile, IOptions, NgWalker> =
all(
validateComponent((meta: ComponentMetadata, suffixList?: string[]) =>
Maybe.lift(meta.controller)
.fmap(controller => controller.name)
.fmap(name => {
const className = name.text;
if (Rule.invalidName(className)) {
return [new Failure(name, sprintf(Rule.FAILURE_STRING + className, className, suffixList))];
}
})
));
static invalidName(className: string): boolean {
var whiteList = ['ActivitiContentComponent', 'ActivitiForm'];
var classNameReg = /^(alfresco|activiti|adf|activity)/ig;
var classNameMatch = classNameReg.exec(className);
var isWhiteListName = whiteList.find((currentWhiteListName) => {
return currentWhiteListName === className;
});
if (classNameMatch && !isWhiteListName) {
return true;
}
return false;
}
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(
Rule.walkerBuilder(sourceFile, this.getOptions())
);
}
}

View File

@@ -0,0 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Lint = require("tslint");
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
return this.applyWithWalker(new AdfFileName(sourceFile, this.getOptions()));
}
}
Rule.metadata = {
ruleName: 'adf-file-name',
type: 'maintainability',
description: `Enforce consistent name avoid prefix`,
descriptionDetails: `See more at https://angular.io/styleguide#style-05-13.`,
rationale: `Consistent conventions make it easy to quickly identify files when you search with autocomplete.`,
options: null,
optionsDescription: "Not configurable.",
typescriptOnly: true,
};
Rule.FAILURE_STRING = 'The name of the File should not start with ADF Alfresco or Activiti prefix ';
exports.Rule = Rule;
class AdfFileName extends Lint.RuleWalker {
visitSourceFile(node) {
var whiteList = ['activiti-alfresco.service.ts', 'activiti-alfresco.service.spec.ts',
'alfresco-api.service.ts', 'alfresco-api.service.spects'];
var fileName = this.getFilename();
var fileNameReg = /^(alfresco|activiti|adf|activity)/ig;
var filenameMatch = fileNameReg.exec(fileName);
var isWhiteListName = whiteList.find((currentWhiteListName) => {
return currentWhiteListName === fileName;
});
if (filenameMatch && !isWhiteListName) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING + fileName));
super.visitSourceFile(node);
}
}
getFilename() {
const filename = this.getSourceFile().fileName;
const lastSlash = filename.lastIndexOf('/');
if (lastSlash > -1) {
return filename.substring(lastSlash + 1);
}
return filename;
}
}

View File

@@ -0,0 +1,53 @@
import * as ts from "typescript";
import * as Lint from "tslint";
export class Rule extends Lint.Rules.AbstractRule {
public static metadata: Lint.IRuleMetadata = {
ruleName: 'adf-file-name',
type: 'maintainability',
description: `Enforce consistent name avoid prefix`,
descriptionDetails: `See more at https://angular.io/styleguide#style-05-13.`,
rationale: `Consistent conventions make it easy to quickly identify files when you search with autocomplete.`,
options: null,
optionsDescription: "Not configurable.",
typescriptOnly: true,
};
public static FAILURE_STRING = 'The name of the File should not start with ADF Alfresco or Activiti prefix ';
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(new AdfFileName(sourceFile, this.getOptions()));
}
}
// The walker takes care of all the work.
class AdfFileName extends Lint.RuleWalker {
public visitSourceFile(node: ts.SourceFile) {
var whiteList = ['activiti-alfresco.service.ts', 'activiti-alfresco.service.spec.ts',
'alfresco-api.service.ts', 'alfresco-api.service.spects'];
var fileName = this.getFilename();
var fileNameReg = /^(alfresco|activiti|adf|activity)/ig;
var filenameMatch = fileNameReg.exec(fileName);
var isWhiteListName = whiteList.find((currentWhiteListName) => {
return currentWhiteListName === fileName;
});
if (filenameMatch && !isWhiteListName) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING + fileName));
super.visitSourceFile(node);
}
}
private getFilename(): string {
const filename = this.getSourceFile().fileName;
const lastSlash = filename.lastIndexOf('/');
if (lastSlash > -1) {
return filename.substring(lastSlash + 1);
}
return filename;
}
}

View File

@@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Lint = require("tslint");
const sprintf_js_1 = require("sprintf-js");
const ngWalker_1 = require("codelyzer/angular/ngWalker");
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
return this.applyWithWalker(new ADFOutputPrefixNameRule(sourceFile, this.getOptions()));
}
}
Rule.metadata = {
ruleName: 'adf-prefix-name',
type: 'maintainability',
description: `Name events without the prefix on`,
descriptionDetails: `See more at https://angular.io/guide/styleguide#dont-prefix-output-properties`,
rationale: `Angular allows for an alternative syntax on-*. If the event itself was prefixed with on this would result in an on-onEvent binding expression`,
options: null,
optionsDescription: `Not configurable.`,
typescriptOnly: true,
};
Rule.FAILURE_STRING = 'In the class "%s", the output ' +
'property "%s" should not be prefixed with on';
exports.Rule = Rule;
class ADFOutputPrefixNameRule extends ngWalker_1.NgWalker {
visitNgOutput(property, output, args) {
let className = property.parent.name.text;
let memberName = property.name.text;
if (memberName && memberName.startsWith('on')) {
let failureConfig = [className, memberName];
failureConfig.unshift(Rule.FAILURE_STRING);
this.addFailure(this.createFailure(property.getStart(), property.getWidth(), sprintf_js_1.sprintf.apply(this, failureConfig)));
}
}
}

View File

@@ -0,0 +1,43 @@
import * as Lint from 'tslint';
import * as ts from 'typescript';
import { sprintf } from 'sprintf-js';
import { NgWalker } from 'codelyzer/angular/ngWalker';
export class Rule extends Lint.Rules.AbstractRule {
public static metadata: Lint.IRuleMetadata = {
ruleName: 'adf-prefix-name',
type: 'maintainability',
description: `Name events without the prefix on`,
descriptionDetails: `See more at https://angular.io/guide/styleguide#dont-prefix-output-properties`,
rationale: `Angular allows for an alternative syntax on-*. If the event itself was prefixed with on this would result in an on-onEvent binding expression`,
options: null,
optionsDescription: `Not configurable.`,
typescriptOnly: true,
};
static FAILURE_STRING: string = 'In the class "%s", the output ' +
'property "%s" should not be prefixed with on';
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(
new ADFOutputPrefixNameRule(sourceFile,
this.getOptions()));
}
}
class ADFOutputPrefixNameRule extends NgWalker {
visitNgOutput(property: ts.PropertyDeclaration, output: ts.Decorator, args: string[]) {
let className = (<any>property).parent.name.text;
let memberName = (<any>property.name).text;
if (memberName && memberName.startsWith('on')) {
let failureConfig: string[] = [className, memberName];
failureConfig.unshift(Rule.FAILURE_STRING);
this.addFailure(
this.createFailure(
property.getStart(),
property.getWidth(),
sprintf.apply(this, failureConfig)));
}
}
}

View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var adfClassNameRule_1 = require("./adfClassNameRule");
exports.ADFClassNameRule = adfClassNameRule_1.Rule;
var adfFileNameRule_1 = require("./adfFileNameRule");
exports.ADFComponentSelectorRule = adfFileNameRule_1.Rule;
var adfPrefixNameRule_1 = require("./adfPrefixNameRule");
exports.ADFOutputPrefixNameRule = adfPrefixNameRule_1.Rule;

View File

@@ -0,0 +1,3 @@
export { Rule as ADFClassNameRule } from './adfClassNameRule';
export { Rule as ADFComponentSelectorRule } from './adfFileNameRule';
export { Rule as ADFOutputPrefixNameRule } from './adfPrefixNameRule';

2179
tools/tslint-rules/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,56 @@
{
"name": "adf-tslint-rules",
"description": "Custom Rules for the ADF project",
"version": "0.0.4",
"author": "Alfresco Software, Ltd.",
"scripts": {
"build": "tsc",
"tscv": "tsc --version",
"tsc": "tsc",
"tsc:watch": "tsc --w"
},
"contributors": [
{
"name": "Eugenio Romano",
"email": "eugenio.romano@alfresco.com"
}
],
"devDependencies": {
"@angular/compiler": "4.2.3",
"@angular/core": "4.2.3",
"@types/chai": "3.4.33",
"@types/less": "0.0.31",
"@types/mocha": "2.2.32",
"@types/node": "6.0.41",
"@types/node-sass": "3.10.31",
"@types/source-map": "0.5.0",
"@types/sprintf-js": "0.0.27",
"chai": "3.5.0",
"chai-spies": "0.7.1",
"minimalist": "1.0.0",
"mocha": "3.0.2",
"node-sass": "3.13.0",
"rimraf": "2.5.2",
"rxjs": "5.4.1",
"ts-node": "1.2.2",
"tslint": "5.0.0",
"typescript": "2.4.0",
"zone.js": "0.8.4",
"js-yaml": "3.8.4",
"json-stringify-pretty-compact": "1.0.4",
"@types/js-yaml": "3.5.31"
},
"peerDependencies": {
"tslint": "5.0.0"
},
"dependencies": {
"app-root-path": "2.0.1",
"css-selector-tokenizer": "0.7.0",
"cssauron": "1.4.0",
"semver-dsl": "1.0.1",
"source-map": "0.5.6",
"sprintf-js": "1.0.3",
"codelyzer": "3.1.2"
},
"license": "Apache-2.0"
}

View File

@@ -0,0 +1,22 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"target": "es6",
"module": "commonjs",
"declaration": false,
"noImplicitAny": false,
"removeComments": true,
"lib": ["es6", "es2015", "dom"],
"noLib": false,
"typeRoots": [
"./node_modules/@types",
"./node_modules"
],
"types": [
"mocha",
"chai",
"node",
"sprintf-js"
]
}
}

View File

@@ -0,0 +1,5 @@
{
"rules": {
"adf-file-naming": true
}
}