├── test-files ├── img-error.png ├── video-error.mp4 ├── img-pass.png └── video-pass.mp4 ├── tslint-contrib ├── .gitattributes ├── utils │ ├── attributes │ │ ├── IAria.js │ │ ├── IDom.js │ │ └── IRole.js │ ├── ExtendedMetadata.js │ ├── implicitRoles │ │ ├── tr.js │ │ ├── dl.js │ │ ├── dt.js │ │ ├── h1.js │ │ ├── h2.js │ │ ├── h3.js │ │ ├── h4.js │ │ ├── h5.js │ │ ├── h6.js │ │ ├── ol.js │ │ ├── td.js │ │ ├── ul.js │ │ ├── dd.js │ │ ├── hr.js │ │ ├── th.js │ │ ├── body.js │ │ ├── form.js │ │ ├── main.js │ │ ├── math.js │ │ ├── nav.js │ │ ├── table.js │ │ ├── tbody.js │ │ ├── tfoot.js │ │ ├── thead.js │ │ ├── aside.js │ │ ├── button.js │ │ ├── dialog.js │ │ ├── meter.js │ │ ├── option.js │ │ ├── output.js │ │ ├── select.js │ │ ├── article.js │ │ ├── details.js │ │ ├── section.js │ │ ├── summary.js │ │ ├── datalist.js │ │ ├── optgroup.js │ │ ├── textarea.js │ │ ├── progress.js │ │ ├── a.js │ │ ├── area.js │ │ ├── link.js │ │ ├── header.js │ │ ├── footer.js │ │ ├── img.js │ │ ├── li.js │ │ ├── menu.js │ │ ├── menuitem.js │ │ ├── input.js │ │ └── index.js │ ├── getImplicitRole.js │ ├── Utils.js │ ├── ErrorTolerantWalker.js │ ├── TypeGuard.js │ ├── MochaUtils.js │ ├── ChaiUtils.js │ ├── NoStringParameterToFunctionCallWalker.js │ ├── BaseFormatter.js │ └── Scope.js ├── fixNoVarKeywordFormatter.js ├── fixPreferConstFormatter.js ├── noBannedTermsRule.js ├── noStringBasedSetTimeoutRule.js ├── noStringBasedSetIntervalRule.js ├── noStringBasedSetImmediateRule.js ├── fixNoUnusedImportsFormatter.js ├── fixNoRequireImportsFormatter.js ├── missingJsdocRule.js ├── noWithStatementRule.js ├── noRegexSpacesRule.js ├── noReservedKeywordsRule.js ├── noForInRule.js ├── useIsnanRule.js ├── noMultipleVarDeclRule.js ├── noExecScriptRule.js ├── noDisableAutoSanitizationRule.js ├── noMultilineStringRule.js ├── noOctalLiteralRule.js ├── preferTypeCastRule.js ├── useNamedParameterRule.js ├── reactA11yPropsRule.js ├── insecureRandomRule.js ├── noDeleteExpressionRule.js ├── noSparseArraysRule.js ├── noVarSelfRule.js ├── noEmptyInterfacesRule.js ├── noDocumentWriteRule.js ├── noDocumentDomainRule.js ├── noIncrementDecrementRule.js ├── noDuplicateCaseRule.js ├── noInvalidRegexpRule.js ├── reactA11yTabindexNoPositiveRule.js ├── noTypeofUndefinedRule.js ├── noFunctionConstructorWithStringArgsRule.js ├── noBackboneGetSetOutsideModelRule.js ├── noUnnecessarySemicolonsRule.js ├── possibleTimingAttackRule.js ├── noEmptyLineAfterOpeningBraceRule.js ├── noControlRegexRule.js ├── noFunctionExpressionRule.js ├── noHttpStringRule.js ├── noCookiesRule.js ├── nonLiteralRequireRule.js ├── noRelativeImportsRule.js ├── preferArrayLiteralRule.js ├── noInnerHtmlRule.js ├── reactA11yEventHasRoleRule.js ├── noMissingVisibilityModifiersRule.js ├── reactA11yImageButtonHasAltRule.js ├── reactA11yRoleRule.js ├── noDuplicateParameterNamesRule.js ├── noSingleLineBlockCommentRule.js ├── missingOptionalAnnotationRule.js └── reactA11yAriaUnsupportedElementsRule.js ├── coverage.png ├── .gitignore ├── .travis.yml ├── postcss.config.js ├── src ├── index.ts ├── TypeChecker.ts ├── types.ts └── ImageChecker.ts ├── tsconfig.json ├── spec ├── utils.ts └── TypeChecker.spec.ts ├── demo ├── index.html └── main.css ├── LICENSE ├── server.dev.js ├── karma.conf.js ├── tslintConfig.js ├── webpack.demo.config.js ├── package.json ├── .gitattributes └── webpack.dev.config.js /test-files/img-error.png: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test-files/video-error.mp4: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tslint-contrib/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /coverage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dtysky/UploadChecker/HEAD/coverage.png -------------------------------------------------------------------------------- /tslint-contrib/utils/attributes/IAria.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | //# sourceMappingURL=IAria.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/attributes/IDom.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | //# sourceMappingURL=IDom.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/attributes/IRole.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | //# sourceMappingURL=IRole.js.map -------------------------------------------------------------------------------- /test-files/img-pass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dtysky/UploadChecker/HEAD/test-files/img-pass.png -------------------------------------------------------------------------------- /tslint-contrib/utils/ExtendedMetadata.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | //# sourceMappingURL=ExtendedMetadata.js.map -------------------------------------------------------------------------------- /test-files/video-pass.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dtysky/UploadChecker/HEAD/test-files/video-pass.mp4 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | node_modules 4 | *.log 5 | 6 | **/dist 7 | reports 8 | 9 | demo/main.bundle.css 10 | demo/main.bundle.js -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/tr.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForTr() { 3 | return 'row'; 4 | } 5 | exports.tr = getImplicitRoleForTr; 6 | //# sourceMappingURL=tr.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/dl.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForDl() { 3 | return 'list'; 4 | } 5 | exports.dl = getImplicitRoleForDl; 6 | //# sourceMappingURL=dl.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/dt.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForDt() { 3 | return 'listitem'; 4 | } 5 | exports.dt = getImplicitRoleForDt; 6 | //# sourceMappingURL=dt.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/h1.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForH1() { 3 | return 'heading'; 4 | } 5 | exports.h1 = getImplicitRoleForH1; 6 | //# sourceMappingURL=h1.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/h2.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForH2() { 3 | return 'heading'; 4 | } 5 | exports.h2 = getImplicitRoleForH2; 6 | //# sourceMappingURL=h2.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/h3.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForH3() { 3 | return 'heading'; 4 | } 5 | exports.h3 = getImplicitRoleForH3; 6 | //# sourceMappingURL=h3.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/h4.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForH4() { 3 | return 'heading'; 4 | } 5 | exports.h4 = getImplicitRoleForH4; 6 | //# sourceMappingURL=h4.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/h5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForH5() { 3 | return 'heading'; 4 | } 5 | exports.h5 = getImplicitRoleForH5; 6 | //# sourceMappingURL=h5.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/h6.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForH6() { 3 | return 'heading'; 4 | } 5 | exports.h6 = getImplicitRoleForH6; 6 | //# sourceMappingURL=h6.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/ol.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForOl() { 3 | return 'list'; 4 | } 5 | exports.ol = getImplicitRoleForOl; 6 | //# sourceMappingURL=ol.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/td.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForTd() { 3 | return 'cell'; 4 | } 5 | exports.td = getImplicitRoleForTd; 6 | //# sourceMappingURL=td.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/ul.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForUl() { 3 | return 'list'; 4 | } 5 | exports.ul = getImplicitRoleForUl; 6 | //# sourceMappingURL=ul.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/dd.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForDd() { 3 | return 'definition'; 4 | } 5 | exports.dd = getImplicitRoleForDd; 6 | //# sourceMappingURL=dd.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/hr.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForHr() { 3 | return 'separator'; 4 | } 5 | exports.hr = getImplicitRoleForHr; 6 | //# sourceMappingURL=hr.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/th.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForTh() { 3 | return 'columnheader'; 4 | } 5 | exports.th = getImplicitRoleForTh; 6 | //# sourceMappingURL=th.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/body.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForBody() { 3 | return 'document'; 4 | } 5 | exports.body = getImplicitRoleForBody; 6 | //# sourceMappingURL=body.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/form.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForForm() { 3 | return 'form'; 4 | } 5 | exports.form = getImplicitRoleForForm; 6 | //# sourceMappingURL=form.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForMain() { 3 | return 'main'; 4 | } 5 | exports.main = getImplicitRoleForMain; 6 | //# sourceMappingURL=main.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/math.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForMath() { 3 | return 'math'; 4 | } 5 | exports.math = getImplicitRoleForMath; 6 | //# sourceMappingURL=math.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/nav.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForNav() { 3 | return 'navigation'; 4 | } 5 | exports.nav = getImplicitRoleForNav; 6 | //# sourceMappingURL=nav.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/table.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForTable() { 3 | return 'table'; 4 | } 5 | exports.table = getImplicitRoleForTable; 6 | //# sourceMappingURL=table.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/tbody.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForTbody() { 3 | return 'rowgroup'; 4 | } 5 | exports.tbody = getImplicitRoleForTbody; 6 | //# sourceMappingURL=tbody.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/tfoot.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForTfoot() { 3 | return 'rowgroup'; 4 | } 5 | exports.tfoot = getImplicitRoleForTfoot; 6 | //# sourceMappingURL=tfoot.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/thead.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForThead() { 3 | return 'rowgroup'; 4 | } 5 | exports.thead = getImplicitRoleForThead; 6 | //# sourceMappingURL=thead.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/aside.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForAside() { 3 | return 'complementary'; 4 | } 5 | exports.aside = getImplicitRoleForAside; 6 | //# sourceMappingURL=aside.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/button.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForButton() { 3 | return 'button'; 4 | } 5 | exports.button = getImplicitRoleForButton; 6 | //# sourceMappingURL=button.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/dialog.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForDialog() { 3 | return 'dialog'; 4 | } 5 | exports.dialog = getImplicitRoleForDialog; 6 | //# sourceMappingURL=dialog.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/meter.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForMeter() { 3 | return 'progressbar'; 4 | } 5 | exports.meter = getImplicitRoleForMeter; 6 | //# sourceMappingURL=meter.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/option.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForOption() { 3 | return 'option'; 4 | } 5 | exports.option = getImplicitRoleForOption; 6 | //# sourceMappingURL=option.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/output.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForOutput() { 3 | return 'status'; 4 | } 5 | exports.output = getImplicitRoleForOutput; 6 | //# sourceMappingURL=output.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/select.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForSelect() { 3 | return 'listbox'; 4 | } 5 | exports.select = getImplicitRoleForSelect; 6 | //# sourceMappingURL=select.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/article.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForArticle() { 3 | return 'article'; 4 | } 5 | exports.article = getImplicitRoleForArticle; 6 | //# sourceMappingURL=article.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/details.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForDetails() { 3 | return 'group'; 4 | } 5 | exports.details = getImplicitRoleForDetails; 6 | //# sourceMappingURL=details.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/section.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForSection() { 3 | return 'region'; 4 | } 5 | exports.section = getImplicitRoleForSection; 6 | //# sourceMappingURL=section.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/summary.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForSummary() { 3 | return 'button'; 4 | } 5 | exports.summary = getImplicitRoleForSummary; 6 | //# sourceMappingURL=summary.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/datalist.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForDatalist() { 3 | return 'listbox'; 4 | } 5 | exports.datalist = getImplicitRoleForDatalist; 6 | //# sourceMappingURL=datalist.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/optgroup.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForOptgroup() { 3 | return 'group'; 4 | } 5 | exports.optgroup = getImplicitRoleForOptgroup; 6 | //# sourceMappingURL=optgroup.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/textarea.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForTextarea() { 3 | return 'textbox'; 4 | } 5 | exports.textarea = getImplicitRoleForTextarea; 6 | //# sourceMappingURL=textarea.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/progress.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function getImplicitRoleForProgress() { 3 | return 'progressbar'; 4 | } 5 | exports.progress = getImplicitRoleForProgress; 6 | //# sourceMappingURL=progress.js.map -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | sudo: false 4 | 5 | node_js: 6 | - '7.1.0' 7 | 8 | before_install: 9 | - export CHROME_BIN=chromium-browser 10 | - export DISPLAY=:99.0 11 | - sh -e /etc/init.d/xvfb start 12 | 13 | install: 14 | - npm install 15 | 16 | script: 17 | - npm run unittest 18 | -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/a.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var JsxAttribute_1 = require("../JsxAttribute"); 3 | var hrefString = 'href'; 4 | function getImplicitRoleForAnchor(node) { 5 | return JsxAttribute_1.getJsxAttributesFromJsxElement(node)[hrefString] ? 'link' : undefined; 6 | } 7 | exports.a = getImplicitRoleForAnchor; 8 | //# sourceMappingURL=a.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/area.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var JsxAttribute_1 = require("../JsxAttribute"); 3 | var hrefString = 'href'; 4 | function getImplicitRoleForArea(node) { 5 | return JsxAttribute_1.getJsxAttributesFromJsxElement(node)[hrefString] ? 'link' : undefined; 6 | } 7 | exports.area = getImplicitRoleForArea; 8 | //# sourceMappingURL=area.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/link.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var JsxAttribute_1 = require("../JsxAttribute"); 3 | var hrefString = 'href'; 4 | function getImplicitRoleForLink(node) { 5 | return JsxAttribute_1.getJsxAttributesFromJsxElement(node)[hrefString] ? 'link' : undefined; 6 | } 7 | exports.link = getImplicitRoleForLink; 8 | //# sourceMappingURL=link.js.map -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: ひまわり(dtysky) 3 | * Github: https://github.com/dtysky 4 | * Created: 2017/4/21 5 | */ 6 | module.exports = { 7 | plugins: [ 8 | require('postcss-smart-import')({ /* ...options */ }), 9 | require('precss')({ /* ...options */ }), 10 | require('autoprefixer')({ /* ...options */ }) 11 | ] 12 | }; 13 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright(c) dtysky 3 | * Created: 2017/6/11 4 | * Description: 5 | */ 6 | import 'es6-shim'; 7 | 8 | export * from './types'; 9 | export * from './TypeChecker'; 10 | export * from './ImageChecker'; 11 | export * from './VideoChecker'; 12 | 13 | import UploadChecker from './UploadChecker'; 14 | export default UploadChecker; 15 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | // "sourceMap": true, 4 | // "noImplicitAny": true, 5 | "module": "commonjs", 6 | "target": "es5", 7 | "jsx": "react", 8 | "allowJs": true, 9 | "types": [] 10 | }, 11 | "include": [ 12 | "src/**/*.ts", 13 | "src/**/*.tsx", 14 | "demo/**/*.ts", 15 | "demo/**/*.tsx" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/header.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var JsxAttribute_1 = require("../JsxAttribute"); 3 | function getImplicitRoleForHeader(node) { 4 | return JsxAttribute_1.getAncestorNode(node, 'article') || JsxAttribute_1.getAncestorNode(node, 'section') ? undefined : 'banner'; 5 | } 6 | exports.header = getImplicitRoleForHeader; 7 | //# sourceMappingURL=header.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/footer.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var JsxAttribute_1 = require("../JsxAttribute"); 3 | function getImplicitRoleForFooter(node) { 4 | return JsxAttribute_1.getAncestorNode(node, 'article') || JsxAttribute_1.getAncestorNode(node, 'section') ? undefined : 'contentinfo'; 5 | } 6 | exports.footer = getImplicitRoleForFooter; 7 | //# sourceMappingURL=footer.js.map -------------------------------------------------------------------------------- /spec/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright(c) dtysky 3 | * Created: 2017/6/16 4 | * Description: 5 | */ 6 | import {TFile} from '../src/types'; 7 | 8 | export const loadFile = (fp: string, callback: (file: TFile) => void) => { 9 | const xhr = new XMLHttpRequest(); 10 | xhr.open('GET', `/base/test-files/${fp}`); 11 | xhr.responseType = 'blob'; 12 | xhr.onload = () => { 13 | callback(xhr.response); 14 | }; 15 | xhr.send(); 16 | }; 17 | -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/img.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var JsxAttribute_1 = require("../JsxAttribute"); 3 | var altString = 'alt'; 4 | function getImplicitRoleForImg(node) { 5 | var alt = JsxAttribute_1.getJsxAttributesFromJsxElement(node)[altString]; 6 | if (alt && JsxAttribute_1.getStringLiteral(alt)) { 7 | return 'img'; 8 | } 9 | return 'presentation'; 10 | } 11 | exports.img = getImplicitRoleForImg; 12 | //# sourceMappingURL=img.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/li.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var TypeGuard_1 = require("../TypeGuard"); 3 | function getImplicitRoleForLi(node) { 4 | var parentNode = node.parent; 5 | var parentTagName; 6 | if (TypeGuard_1.isJsxElement(parentNode)) { 7 | parentTagName = parentNode.openingElement.tagName.getText(); 8 | } 9 | return (parentTagName === 'ol' || parentTagName === 'ul') ? 'listitem' : undefined; 10 | } 11 | exports.li = getImplicitRoleForLi; 12 | //# sourceMappingURL=li.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/menu.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var JsxAttribute_1 = require("../JsxAttribute"); 3 | var typeString = 'type'; 4 | function getImplicitRoleForMenu(node) { 5 | var typeAttribute = JsxAttribute_1.getJsxAttributesFromJsxElement(node)[typeString]; 6 | if (typeAttribute) { 7 | var value = JsxAttribute_1.getStringLiteral(typeAttribute) || undefined; 8 | return (value && value.toUpperCase() === 'TOOLBAR') ? 'toolbar' : undefined; 9 | } 10 | return undefined; 11 | } 12 | exports.menu = getImplicitRoleForMenu; 13 | //# sourceMappingURL=menu.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/getImplicitRole.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var implicitRoles = require("./implicitRoles"); 3 | var TypeGuard_1 = require("./TypeGuard"); 4 | function getImplicitRole(node) { 5 | var tagName; 6 | if (TypeGuard_1.isJsxElement(node)) { 7 | tagName = node.openingElement.tagName.getText(); 8 | } 9 | else if (TypeGuard_1.isJsxSelfClosingElement(node)) { 10 | tagName = node.tagName.getText(); 11 | } 12 | else if (TypeGuard_1.isJsxOpeningElement(node)) { 13 | tagName = node.tagName.getText(); 14 | } 15 | else { 16 | tagName = undefined; 17 | } 18 | return tagName && implicitRoles[tagName] && implicitRoles[tagName](node); 19 | } 20 | exports.getImplicitRole = getImplicitRole; 21 | //# sourceMappingURL=getImplicitRole.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/menuitem.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var JsxAttribute_1 = require("../JsxAttribute"); 3 | var typeString = 'type'; 4 | function getImplicitRoleForMenuitem(node) { 5 | var typeAttribute = JsxAttribute_1.getJsxAttributesFromJsxElement(node)[typeString]; 6 | if (typeAttribute) { 7 | var value = JsxAttribute_1.getStringLiteral(typeAttribute) || ''; 8 | switch (value.toUpperCase()) { 9 | case 'COMMAND': 10 | return 'menuitem'; 11 | case 'CHECKBOX': 12 | return 'menuitemcheckbox'; 13 | case 'RADIO': 14 | return 'menuitemradio'; 15 | default: 16 | return undefined; 17 | } 18 | } 19 | return undefined; 20 | } 21 | exports.menuitem = getImplicitRoleForMenuitem; 22 | //# sourceMappingURL=menuitem.js.map -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | UploadChecker 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Tianyu Dai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tslint-contrib/fixNoVarKeywordFormatter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var BaseFormatter_1 = require("./utils/BaseFormatter"); 8 | var Formatter = (function (_super) { 9 | __extends(Formatter, _super); 10 | function Formatter() { 11 | return _super.call(this, 'no-var-keyword', function (failure) { 12 | var fileName = failure.getFileName(); 13 | var fileContents = this.readFile(fileName); 14 | var end = failure.getEndPosition().getPosition(); 15 | var leftSide = fileContents.substring(0, end); 16 | leftSide = leftSide.replace(/var$/, 'let'); 17 | var rightSide = fileContents.substring(end); 18 | var newContent = leftSide + rightSide; 19 | this.writeFile(fileName, newContent); 20 | console.log('Automatically converting var to let. Please re-compile and re-lint: ' + fileName); 21 | }) || this; 22 | } 23 | return Formatter; 24 | }(BaseFormatter_1.BaseFormatter)); 25 | exports.Formatter = Formatter; 26 | //# sourceMappingURL=fixNoVarKeywordFormatter.js.map -------------------------------------------------------------------------------- /tslint-contrib/fixPreferConstFormatter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var BaseFormatter_1 = require("./utils/BaseFormatter"); 8 | var Formatter = (function (_super) { 9 | __extends(Formatter, _super); 10 | function Formatter() { 11 | return _super.call(this, 'prefer-const', function (failure) { 12 | var fileName = failure.getFileName(); 13 | var fileContents = this.readFile(fileName); 14 | var start = failure.getStartPosition().getPosition(); 15 | var leftSide = fileContents.substring(0, start); 16 | leftSide = leftSide.replace(/let(\s*)$/, 'const$1'); 17 | var rightSide = fileContents.substring(start); 18 | var newContent = leftSide + rightSide; 19 | this.writeFile(fileName, newContent); 20 | console.log('Automatically converting var/let to const. Please re-compile and re-lint: ' + fileName); 21 | }) || this; 22 | } 23 | return Formatter; 24 | }(BaseFormatter_1.BaseFormatter)); 25 | exports.Formatter = Formatter; 26 | //# sourceMappingURL=fixPreferConstFormatter.js.map -------------------------------------------------------------------------------- /src/TypeChecker.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright(c) dtysky 3 | * Created: 2017/6/11 4 | * Description: 5 | */ 6 | 7 | import { 8 | TFileTypes, TFile, IFileInfo, CheckError, ICheckResponse 9 | } from './types'; 10 | 11 | export const checkType: ( 12 | file: TFile, 13 | types: TFileTypes 14 | ) => Promise 15 | = ( 16 | file: TFile, 17 | types: TFileTypes 18 | ) => { 19 | return new Promise((resolve, reject) => { 20 | const info: IFileInfo = {type: file.type}; 21 | 22 | if (types.length === 0) { 23 | return resolve({file, info}); 24 | } 25 | if (types.indexOf(file.type) >= 0) { 26 | return resolve({file, info}); 27 | } 28 | return reject({ 29 | error: new CheckError({ 30 | name: 'type', 31 | currentValue: file.type, 32 | limitValue: types, 33 | message: `The type of file should be ${types.join(', ')},current is ${file.type}` 34 | }), 35 | file, 36 | info 37 | }); 38 | }); 39 | } 40 | 41 | export class TypeChecker { 42 | private types: TFileTypes; 43 | 44 | constructor(types: TFileTypes = []) { 45 | this.types = types; 46 | } 47 | 48 | public setTypes = (types: TFileTypes) => { 49 | this.types = types; 50 | } 51 | 52 | public check = (file: TFile) => { 53 | return checkType(file, this.types); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /server.dev.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: ひまわり(dtysky) 3 | * Github: https://github.com/dtysky 4 | * Created: 16/12/29 5 | */ 6 | 7 | const path = require('path'); 8 | const webpack = require('webpack'); 9 | const webpackDevMiddleware = require('webpack-dev-middleware'); 10 | const webpackHotMiddleware = require('webpack-hot-middleware'); 11 | const config = require('./webpack.dev.config'); 12 | config.entry.push(path.resolve(__dirname, `./demo/main.tsx`)); 13 | config.plugins.push( 14 | new webpack.DefinePlugin({ 15 | 'globalEnv': { 16 | NODE_ENV: JSON.stringify('development'), 17 | // NODE_ENV: JSON.stringify('production'), 18 | } 19 | }) 20 | ); 21 | 22 | const express = require('express'); 23 | const app = new express(); 24 | const port = 4444; 25 | 26 | const compiler = webpack(config); 27 | 28 | app.use(webpackDevMiddleware(compiler, { 29 | publicPath: config.output.publicPath, 30 | stats: { 31 | colors: true, 32 | chunks: false 33 | } 34 | })); 35 | app.use(webpackHotMiddleware(compiler)); 36 | 37 | app.use('/', 38 | express.static(`${__dirname}/demo`) 39 | ); 40 | 41 | app.get('*', (req, res) => { 42 | res.sendFile(`${__dirname}/demo/index.html`) 43 | }); 44 | 45 | app.listen(port, function(error) { 46 | if (error) { 47 | console.error(error); 48 | } else { 49 | console.info('==> 🌎 Listening on port %s. Open up http://localhost:%s/ in your browser.', port, port); 50 | } 51 | }); 52 | -------------------------------------------------------------------------------- /tslint-contrib/noBannedTermsRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var Lint = require("tslint"); 8 | var BannedTermWalker_1 = require("./utils/BannedTermWalker"); 9 | var Rule = (function (_super) { 10 | __extends(Rule, _super); 11 | function Rule() { 12 | return _super.apply(this, arguments) || this; 13 | } 14 | Rule.prototype.apply = function (sourceFile) { 15 | var walker = new BannedTermWalker_1.BannedTermWalker(sourceFile, this.getOptions(), Rule.FAILURE_STRING, Rule.BANNED_TERMS); 16 | return this.applyWithWalker(walker); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'no-banned-terms', 22 | type: 'maintainability', 23 | description: 'Do not use banned terms: caller, callee, eval, arguments.', 24 | options: null, 25 | optionsDescription: '', 26 | typescriptOnly: true, 27 | issueClass: 'SDL', 28 | issueType: 'Error', 29 | severity: 'Critical', 30 | level: 'Mandatory', 31 | group: 'Security', 32 | commonWeaknessEnumeration: '676, 242, 116' 33 | }; 34 | Rule.FAILURE_STRING = 'Forbidden reference to banned term: '; 35 | Rule.BANNED_TERMS = ['caller', 'callee', 'arguments', 'eval']; 36 | exports.Rule = Rule; 37 | //# sourceMappingURL=noBannedTermsRule.js.map -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright(c) dtysky 3 | * Created: 2017/6/11 4 | * Description: 5 | */ 6 | declare const window: any; 7 | window.URL = window.URL || window.webkitURL; 8 | 9 | export type TFile = File; 10 | 11 | export type TFileType = string; 12 | export type TFileTypes = TFileType[]; 13 | 14 | export type TImageConstraintKey = 'maxBytesPerPixel' | 'maxSize' | 'maxWidth'; 15 | 16 | export type TVideoConstraintKey = 'maxBytesPerPixelPerSecond' | 'maxSize' | 'maxWidth' | 'maxDuration'; 17 | 18 | export const videoRegex = /^video/; 19 | export const imageRegex = /^image/; 20 | 21 | export interface IFileInfo { 22 | type: TFileType; 23 | width?: number; 24 | height?: number; 25 | size?: number; 26 | duration?: number; 27 | } 28 | 29 | export type TError = 'type' | 'width' | 'size' | 'duration' | 'bytes' | 'unknown'; 30 | 31 | export interface ICheckError { 32 | name: TError; 33 | currentValue: number | string[] | string; 34 | limitValue: number | string[] | string; 35 | stack?: string; 36 | message: string; 37 | } 38 | 39 | export class CheckError extends Error { 40 | public currentValue: number | string[] | string; 41 | public limitValue: number | string[] | string; 42 | 43 | constructor(params: ICheckError) { 44 | super(); 45 | this.name = params.name; 46 | this.currentValue = params.currentValue; 47 | this.limitValue = params.limitValue; 48 | this.stack = (new Error()).stack; 49 | this.message = params.message; 50 | } 51 | } 52 | 53 | export interface ICheckResponse { 54 | file: TFile; 55 | info: IFileInfo; 56 | error?: ICheckError; 57 | } 58 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: ひまわり(dtysky) 3 | * Github: https://github.com/dtysky 4 | * Created: 2017/6/15 5 | */ 6 | module.exports = function(config) { 7 | config.set({ 8 | 9 | basePath: '', 10 | 11 | frameworks: ['jasmine', 'karma-typescript'], 12 | 13 | files: [ 14 | {pattern: 'src/**/*.ts'}, 15 | {pattern: 'spec/**/*.ts'}, 16 | {pattern: 'test-files/*.png', watched: false, included: false, served: true, nocache: false}, 17 | {pattern: 'test-files/*.mp4', watched: false, included: false, served: true, nocache: false} 18 | ], 19 | 20 | port: 9876, 21 | 22 | logLevel: config.LOG_INFO, 23 | 24 | colors: true, 25 | 26 | autoWatch: true, 27 | 28 | browsers: ['ChromeNoSandbox'], 29 | 30 | customLaunchers: { 31 | ChromeNoSandbox: { 32 | base: 'Chrome', 33 | flags: ['--no-sandbox'] 34 | } 35 | }, 36 | 37 | preprocessors: { 38 | 'src/**/*.ts': ['karma-typescript'], 39 | 'spec/**/*.ts': ['karma-typescript'] 40 | }, 41 | 42 | reporters: ['progress', 'karma-typescript'], 43 | 44 | karmaTypescriptConfig: { 45 | bundlerOptions: { 46 | entrypoints: /\.spec\.ts$/ 47 | }, 48 | reports: { 49 | html: { 50 | directory: 'reports', 51 | subdirectory: '/' 52 | }, 53 | lcovonly: { 54 | directory: 'reports', 55 | subdirectory: '/' 56 | }, 57 | json: { 58 | directory: 'reports', 59 | subdirectory: '/' 60 | } 61 | } 62 | }, 63 | 64 | singleRun: true 65 | }) 66 | }; 67 | -------------------------------------------------------------------------------- /tslint-contrib/utils/Utils.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var Utils; 3 | (function (Utils) { 4 | function exists(list, predicate) { 5 | if (list != null) { 6 | for (var i = 0; i < list.length; i++) { 7 | var obj = list[i]; 8 | if (predicate(obj)) { 9 | return true; 10 | } 11 | } 12 | } 13 | return false; 14 | } 15 | Utils.exists = exists; 16 | function contains(list, element) { 17 | return exists(list, function (item) { 18 | return item === element; 19 | }); 20 | } 21 | Utils.contains = contains; 22 | function removeAll(source, elementsToRemove) { 23 | if (source == null || source.length === 0) { 24 | return []; 25 | } 26 | if (elementsToRemove == null || elementsToRemove.length === 0) { 27 | return [].concat(source); 28 | } 29 | return source.filter(function (sourceElement) { 30 | return !contains(elementsToRemove, sourceElement); 31 | }); 32 | } 33 | Utils.removeAll = removeAll; 34 | function remove(source, elementToRemove) { 35 | return removeAll(source, [elementToRemove]); 36 | } 37 | Utils.remove = remove; 38 | function trimTo(source, maxLength) { 39 | if (source == null) { 40 | return ''; 41 | } 42 | if (source.length <= maxLength) { 43 | return source; 44 | } 45 | return source.substr(0, maxLength - 2) + '...'; 46 | } 47 | Utils.trimTo = trimTo; 48 | })(Utils = exports.Utils || (exports.Utils = {})); 49 | //# sourceMappingURL=Utils.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/input.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var JsxAttribute_1 = require("../JsxAttribute"); 3 | var typeString = 'type'; 4 | var listString = 'list'; 5 | function getImplicitRoleForInput(node) { 6 | var attributes = JsxAttribute_1.getJsxAttributesFromJsxElement(node); 7 | var typeAttribute = attributes[typeString]; 8 | if (typeAttribute) { 9 | var value = JsxAttribute_1.getStringLiteral(typeAttribute) || ''; 10 | switch (value.toUpperCase()) { 11 | case 'BUTTON': 12 | case 'IMAGE': 13 | case 'RESET': 14 | case 'SUBMIT': 15 | return 'button'; 16 | case 'CHECKBOX': 17 | return 'checkbox'; 18 | case 'NUMBER': 19 | return 'spinbutton'; 20 | case 'PASSWORD': 21 | return 'textbox'; 22 | case 'RADIO': 23 | return 'radio'; 24 | case 'RANGE': 25 | return 'slider'; 26 | case 'SEARCH': 27 | return attributes[listString] ? 'combobox' : 'searchbox'; 28 | case 'EMAIL': 29 | case 'TEL': 30 | case 'URL': 31 | case 'TEXT': 32 | return attributes[listString] ? 'combobox' : 'textbox'; 33 | case 'COLOR': 34 | case 'DATE': 35 | case 'DATETIME': 36 | case 'FILE': 37 | case 'HIDDEN': 38 | case 'MONTH': 39 | case 'TIME': 40 | case 'WEEK': 41 | return undefined; 42 | default: 43 | return 'textbox'; 44 | } 45 | } 46 | return 'textbox'; 47 | } 48 | exports.input = getImplicitRoleForInput; 49 | //# sourceMappingURL=input.js.map -------------------------------------------------------------------------------- /demo/main.css: -------------------------------------------------------------------------------- 1 | html, body, .container { 2 | min-width: 100%; 3 | min-height: 100%; 4 | width: 100%; 5 | height: 100%; 6 | border: 0; 7 | margin: 0; 8 | padding: 0; 9 | background: #f6f6f6; 10 | } 11 | 12 | .root { 13 | width: 100%; 14 | padding-bottom: 24px; 15 | } 16 | 17 | .content { 18 | width: auto; 19 | padding: 0 24px; 20 | } 21 | 22 | .topbar { 23 | width: 100%; 24 | height: 84px; 25 | background: #efefef; 26 | box-shadow: 0 3px 4px #ddd; 27 | font-size: 18px; 28 | } 29 | 30 | .topbar a { 31 | font-family: Icons; 32 | position: absolute; 33 | right: 32px; 34 | top: 32px; 35 | color: #777; 36 | font-weight: bolder; 37 | transition: all .3s ease-out; 38 | } 39 | 40 | .topbar a:after { 41 | content: "\f09b"; 42 | margin-left: 12px; 43 | font-size: 28px; 44 | } 45 | 46 | .topbar a:hover { 47 | color: #444; 48 | } 49 | 50 | .upload { 51 | width: 100%; 52 | height: 240px; 53 | background: #26b4a8; 54 | font-size: 48px; 55 | line-height: 240px; 56 | text-align: center; 57 | cursor: pointer; 58 | color: white; 59 | margin-top: 24px; 60 | border-radius: 12px; 61 | font-family: Icons; 62 | } 63 | 64 | .upload:before { 65 | content: "\F25a"; 66 | margin-right: 18px; 67 | } 68 | 69 | .ui.checkbox { 70 | font-size: 16px; 71 | margin: 3px 0; 72 | } 73 | 74 | .ui.cards.card-group { 75 | margin-top: 24px; 76 | } 77 | 78 | .ui.cards.card-group>.card { 79 | flex: 1; 80 | min-width: 320px; 81 | } 82 | 83 | .ui.card.card-info { 84 | width: 100%; 85 | } 86 | 87 | .ui.table thead.info-error th { 88 | background: #cb8590; 89 | } 90 | 91 | .ui.table thead.info-pass th { 92 | background: #16aa9d; 93 | } 94 | -------------------------------------------------------------------------------- /tslint-contrib/utils/ErrorTolerantWalker.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var Lint = require("tslint"); 8 | var ErrorTolerantWalker = (function (_super) { 9 | __extends(ErrorTolerantWalker, _super); 10 | function ErrorTolerantWalker() { 11 | return _super.apply(this, arguments) || this; 12 | } 13 | ErrorTolerantWalker.prototype.visitNode = function (node) { 14 | try { 15 | _super.prototype.visitNode.call(this, node); 16 | } 17 | catch (e) { 18 | if (ErrorTolerantWalker.DEBUG) { 19 | var msg = 'An error occurred visiting a node.' 20 | + '\nWalker: ' + this.getClassName() 21 | + '\nNode: ' + (node.getFullText ? node.getFullText() : '') 22 | + '\n' + e; 23 | this.addFailure(this.createFailure(node.getStart ? node.getStart() : 0, node.getWidth ? node.getWidth() : 0, msg)); 24 | } 25 | } 26 | }; 27 | ErrorTolerantWalker.prototype.getClassName = function () { 28 | var result = this.constructor.toString().match(/function\s+([\w\$]+)\s*\(/)[1] || ''; 29 | if (result == null || result.length === 0) { 30 | throw new Error('Could not determine class name from input: ' + this.constructor.toString()); 31 | } 32 | return result; 33 | }; 34 | return ErrorTolerantWalker; 35 | }(Lint.RuleWalker)); 36 | ErrorTolerantWalker.DEBUG = false; 37 | exports.ErrorTolerantWalker = ErrorTolerantWalker; 38 | //# sourceMappingURL=ErrorTolerantWalker.js.map -------------------------------------------------------------------------------- /tslint-contrib/noStringBasedSetTimeoutRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var NoStringParameterToFunctionCallWalker_1 = require("./utils/NoStringParameterToFunctionCallWalker"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | var documentRegistry = ts.createDocumentRegistry(); 17 | var languageServiceHost = Lint.createLanguageServiceHost('file.ts', sourceFile.getFullText()); 18 | var languageService = ts.createLanguageService(languageServiceHost, documentRegistry); 19 | var walker = new NoStringParameterToFunctionCallWalker_1.NoStringParameterToFunctionCallWalker(sourceFile, 'setTimeout', this.getOptions(), languageService); 20 | return this.applyWithWalker(walker); 21 | }; 22 | return Rule; 23 | }(Lint.Rules.AbstractRule)); 24 | Rule.metadata = { 25 | ruleName: 'no-string-based-set-timeout', 26 | type: 'maintainability', 27 | description: 'Do not use the version of setTimeout that accepts code as a string argument.', 28 | options: null, 29 | optionsDescription: '', 30 | typescriptOnly: true, 31 | issueClass: 'SDL', 32 | issueType: 'Error', 33 | severity: 'Critical', 34 | level: 'Mandatory', 35 | group: 'Security', 36 | commonWeaknessEnumeration: '95, 676, 242, 116' 37 | }; 38 | exports.Rule = Rule; 39 | //# sourceMappingURL=noStringBasedSetTimeoutRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noStringBasedSetIntervalRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var NoStringParameterToFunctionCallWalker_1 = require("./utils/NoStringParameterToFunctionCallWalker"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | var documentRegistry = ts.createDocumentRegistry(); 17 | var languageServiceHost = Lint.createLanguageServiceHost('file.ts', sourceFile.getFullText()); 18 | var languageService = ts.createLanguageService(languageServiceHost, documentRegistry); 19 | var walker = new NoStringParameterToFunctionCallWalker_1.NoStringParameterToFunctionCallWalker(sourceFile, 'setInterval', this.getOptions(), languageService); 20 | return this.applyWithWalker(walker); 21 | }; 22 | return Rule; 23 | }(Lint.Rules.AbstractRule)); 24 | Rule.metadata = { 25 | ruleName: 'no-string-based-set-interval', 26 | type: 'maintainability', 27 | description: 'Do not use the version of setInterval that accepts code as a string argument.', 28 | options: null, 29 | optionsDescription: '', 30 | typescriptOnly: true, 31 | issueClass: 'SDL', 32 | issueType: 'Error', 33 | severity: 'Critical', 34 | level: 'Mandatory', 35 | group: 'Security', 36 | commonWeaknessEnumeration: '95, 676, 242, 116' 37 | }; 38 | exports.Rule = Rule; 39 | //# sourceMappingURL=noStringBasedSetIntervalRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noStringBasedSetImmediateRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var NoStringParameterToFunctionCallWalker_1 = require("./utils/NoStringParameterToFunctionCallWalker"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | var documentRegistry = ts.createDocumentRegistry(); 17 | var languageServiceHost = Lint.createLanguageServiceHost('file.ts', sourceFile.getFullText()); 18 | var languageService = ts.createLanguageService(languageServiceHost, documentRegistry); 19 | var walker = new NoStringParameterToFunctionCallWalker_1.NoStringParameterToFunctionCallWalker(sourceFile, 'setImmediate', this.getOptions(), languageService); 20 | return this.applyWithWalker(walker); 21 | }; 22 | return Rule; 23 | }(Lint.Rules.AbstractRule)); 24 | Rule.metadata = { 25 | ruleName: 'no-string-based-set-immediate', 26 | type: 'maintainability', 27 | description: 'Do not use the version of setImmediate that accepts code as a string argument.', 28 | options: null, 29 | optionsDescription: '', 30 | typescriptOnly: true, 31 | issueClass: 'SDL', 32 | issueType: 'Error', 33 | severity: 'Critical', 34 | level: 'Mandatory', 35 | group: 'Security', 36 | commonWeaknessEnumeration: '95, 676, 242, 116' 37 | }; 38 | exports.Rule = Rule; 39 | //# sourceMappingURL=noStringBasedSetImmediateRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/TypeGuard.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var ts = require("typescript"); 3 | function isJsxAttribute(node) { 4 | return node && node.kind === ts.SyntaxKind.JsxAttribute; 5 | } 6 | exports.isJsxAttribute = isJsxAttribute; 7 | function isJsxSpreadAttribute(node) { 8 | return node && node.kind === ts.SyntaxKind.JsxSpreadAttribute; 9 | } 10 | exports.isJsxSpreadAttribute = isJsxSpreadAttribute; 11 | function isJsxExpression(node) { 12 | return node && node.kind === ts.SyntaxKind.JsxExpression; 13 | } 14 | exports.isJsxExpression = isJsxExpression; 15 | function isNumericLiteral(node) { 16 | return node && node.kind === ts.SyntaxKind.NumericLiteral; 17 | } 18 | exports.isNumericLiteral = isNumericLiteral; 19 | function isStringLiteral(node) { 20 | return node && node.kind === ts.SyntaxKind.StringLiteral; 21 | } 22 | exports.isStringLiteral = isStringLiteral; 23 | function isJsxElement(node) { 24 | return node && node.kind === ts.SyntaxKind.JsxElement; 25 | } 26 | exports.isJsxElement = isJsxElement; 27 | function isJsxSelfClosingElement(node) { 28 | return node && node.kind === ts.SyntaxKind.JsxSelfClosingElement; 29 | } 30 | exports.isJsxSelfClosingElement = isJsxSelfClosingElement; 31 | function isJsxOpeningElement(node) { 32 | return node && node.kind === ts.SyntaxKind.JsxOpeningElement; 33 | } 34 | exports.isJsxOpeningElement = isJsxOpeningElement; 35 | function isTrueKeyword(node) { 36 | return node && node.kind === ts.SyntaxKind.TrueKeyword; 37 | } 38 | exports.isTrueKeyword = isTrueKeyword; 39 | function isFalseKeyword(node) { 40 | return node && node.kind === ts.SyntaxKind.FalseKeyword; 41 | } 42 | exports.isFalseKeyword = isFalseKeyword; 43 | function isNullKeyword(node) { 44 | return node && node.kind === ts.SyntaxKind.NullKeyword; 45 | } 46 | exports.isNullKeyword = isNullKeyword; 47 | //# sourceMappingURL=TypeGuard.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/MochaUtils.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var ts = require("typescript"); 3 | var AstUtils_1 = require("./AstUtils"); 4 | var Utils_1 = require("./Utils"); 5 | var MochaUtils; 6 | (function (MochaUtils) { 7 | function isMochaTest(node) { 8 | return Utils_1.Utils.exists(node.statements, function (statement) { 9 | return isStatementDescribeCall(statement); 10 | }); 11 | } 12 | MochaUtils.isMochaTest = isMochaTest; 13 | function isStatementDescribeCall(statement) { 14 | if (statement.kind === ts.SyntaxKind.ExpressionStatement) { 15 | var expression = statement.expression; 16 | if (expression.kind === ts.SyntaxKind.CallExpression) { 17 | var call = expression; 18 | return isDescribe(call); 19 | } 20 | } 21 | return false; 22 | } 23 | MochaUtils.isStatementDescribeCall = isStatementDescribeCall; 24 | function isDescribe(call) { 25 | var functionName = AstUtils_1.AstUtils.getFunctionName(call); 26 | var callText = call.expression.getText(); 27 | return functionName === 'describe' 28 | || functionName === 'context' 29 | || /(describe|context)\.(only|skip|timeout)/.test(callText); 30 | } 31 | MochaUtils.isDescribe = isDescribe; 32 | function isLifecycleMethod(call) { 33 | var functionName = AstUtils_1.AstUtils.getFunctionName(call); 34 | return functionName === 'it' || functionName === 'specify' 35 | || functionName === 'before' || functionName === 'beforeEach' || functionName === 'beforeAll' 36 | || functionName === 'after' || functionName === 'afterEach' || functionName === 'afterAll'; 37 | } 38 | MochaUtils.isLifecycleMethod = isLifecycleMethod; 39 | })(MochaUtils = exports.MochaUtils || (exports.MochaUtils = {})); 40 | //# sourceMappingURL=MochaUtils.js.map -------------------------------------------------------------------------------- /tslint-contrib/fixNoUnusedImportsFormatter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var BaseFormatter_1 = require("./utils/BaseFormatter"); 8 | var Formatter = (function (_super) { 9 | __extends(Formatter, _super); 10 | function Formatter() { 11 | return _super.call(this, 'no-unused-imports', function (failure) { 12 | var fileName = failure.getFileName(); 13 | var start = failure.getStartPosition(); 14 | var end = failure.getEndPosition(); 15 | var fileContents = this.readFile(fileName); 16 | var startOfViolation = fileContents.lastIndexOf('\n', start.getPosition()); 17 | if (startOfViolation === -1) { 18 | startOfViolation = 0; 19 | } 20 | var endOfViolation = fileContents.indexOf('\n', end.getPosition()); 21 | var line = fileContents.substring(startOfViolation, endOfViolation); 22 | line = line.trim(); 23 | line = line.replace(/\(/, '\\(').replace(/\)/, '\\)'); 24 | var regex = new RegExp('\\n*' + line + '\\n*', 'mg'); 25 | if (startOfViolation === 0) { 26 | fileContents = fileContents.replace(regex, ''); 27 | } 28 | else { 29 | fileContents = fileContents.replace(regex, '\n'); 30 | } 31 | this.writeFile(fileName, fileContents); 32 | console.log('Automatically removing unused import. Please re-compile and re-lint: ' + fileName); 33 | }) || this; 34 | } 35 | return Formatter; 36 | }(BaseFormatter_1.BaseFormatter)); 37 | exports.Formatter = Formatter; 38 | //# sourceMappingURL=fixNoUnusedImportsFormatter.js.map -------------------------------------------------------------------------------- /tslint-contrib/fixNoRequireImportsFormatter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var BaseFormatter_1 = require("./utils/BaseFormatter"); 8 | var Formatter = (function (_super) { 9 | __extends(Formatter, _super); 10 | function Formatter() { 11 | return _super.call(this, 'no-require-imports', function (failure) { 12 | var fileName = failure.getFileName(); 13 | var fileContents = this.readFile(fileName); 14 | var start = failure.getStartPosition().getPosition(); 15 | var end = failure.getEndPosition().getPosition(); 16 | var importStartIndex = fileContents.lastIndexOf('\n', start) + 1; 17 | if (importStartIndex === -1) { 18 | importStartIndex = 0; 19 | } 20 | var importEndIndex = fileContents.indexOf('\n', end); 21 | var leftSide = fileContents.substring(0, importStartIndex); 22 | var middle = fileContents.substring(importStartIndex, importEndIndex).trim(); 23 | var rightSide = fileContents.substring(importEndIndex); 24 | var newImport = middle.replace(/import\s+(.*)\s+=\s*require\(((.|\s)*)\);/m, 'import {$1} from $2;'); 25 | newImport = newImport.replace(/from \n/, 'from\n'); 26 | var newContent = leftSide + newImport + rightSide; 27 | this.writeFile(fileName, newContent); 28 | console.log('Automatically converting require-style import to an ES6 import. Please re-compile and re-lint: ' + fileName); 29 | }) || this; 30 | } 31 | return Formatter; 32 | }(BaseFormatter_1.BaseFormatter)); 33 | exports.Formatter = Formatter; 34 | //# sourceMappingURL=fixNoRequireImportsFormatter.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/ChaiUtils.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var ts = require("typescript"); 3 | var ChaiUtils; 4 | (function (ChaiUtils) { 5 | function isExpectInvocation(node) { 6 | var callExpression = getLeftMostCallExpression(node); 7 | if (callExpression == null) { 8 | return false; 9 | } 10 | return /.*\.?expect/.test(callExpression.expression.getText()); 11 | } 12 | ChaiUtils.isExpectInvocation = isExpectInvocation; 13 | function getLeftMostCallExpression(node) { 14 | var leftSide = node.expression; 15 | while (leftSide != null) { 16 | if (leftSide.kind === ts.SyntaxKind.CallExpression) { 17 | return leftSide; 18 | } 19 | else if (leftSide.kind === (ts.SyntaxKind.PropertyAccessExpression)) { 20 | leftSide = leftSide.expression; 21 | } 22 | else { 23 | return null; 24 | } 25 | } 26 | return null; 27 | } 28 | ChaiUtils.getLeftMostCallExpression = getLeftMostCallExpression; 29 | function getFirstExpectCallParameter(node) { 30 | var expectCall = ChaiUtils.getLeftMostCallExpression(node); 31 | if (expectCall.arguments.length > 0) { 32 | return expectCall.arguments[0]; 33 | } 34 | return null; 35 | } 36 | ChaiUtils.getFirstExpectCallParameter = getFirstExpectCallParameter; 37 | function getFirstExpectationParameter(node) { 38 | if (node.arguments.length > 0) { 39 | return node.arguments[0]; 40 | } 41 | return null; 42 | } 43 | ChaiUtils.getFirstExpectationParameter = getFirstExpectationParameter; 44 | function isEqualsInvocation(propExpression) { 45 | return /equal|equals|eq|eql|eqs/.test(propExpression.name.getText()); 46 | } 47 | ChaiUtils.isEqualsInvocation = isEqualsInvocation; 48 | })(ChaiUtils = exports.ChaiUtils || (exports.ChaiUtils = {})); 49 | //# sourceMappingURL=ChaiUtils.js.map -------------------------------------------------------------------------------- /tslintConfig.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright(c) dtysky 3 | * Created: 16/12/18 4 | * Description: 5 | */ 6 | 7 | const fs = require('fs'); 8 | const path = require('path'); 9 | 10 | module.exports = { 11 | configuration: { 12 | rulesDirectory: './tslint-contrib', 13 | configuration: JSON.parse(fs.readFileSync(path.resolve(__dirname, 'tslint.json'))) 14 | }, 15 | 16 | // enables type checked rules like 'for-in-array' 17 | // uses tsconfig.json from current working directory 18 | typeCheck: false, 19 | 20 | // can specify a custom config file relative to current directory 21 | // 'tslint-custom.json' 22 | configFile: false, 23 | 24 | // tslint errors are displayed by default as warnings 25 | // set emitErrors to true to display them as errors 26 | emitErrors: false, 27 | 28 | // tslint does not interrupt the compilation by default 29 | // if you want any file with tslint errors to fail 30 | // set failOnHint to true 31 | failOnHint: true, 32 | 33 | // name of your formatter (optional) 34 | // formatter: 'yourformatter', 35 | 36 | // path to directory containing formatter (optional) 37 | // formattersDirectory: 'node_modules/tslint-loader/formatters/', 38 | 39 | // These options are useful if you want to save output to files 40 | // for your continuous integration server 41 | fileOutput: { 42 | // The directory where each file's report is saved 43 | dir: './report/tslint', 44 | 45 | // The extension to use for each report's filename. Defaults to 'txt' 46 | ext: 'xml', 47 | 48 | // If true, all files are removed from the report directory at the beginning of run 49 | clean: true, 50 | 51 | // A string to include at the top of every report file. 52 | // Useful for some report formats. 53 | header: '\n', 54 | 55 | // A string to include at the bottom of every report file. 56 | // Useful for some report formats. 57 | footer: '' 58 | } 59 | }; 60 | -------------------------------------------------------------------------------- /tslint-contrib/utils/NoStringParameterToFunctionCallWalker.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ScopedSymbolTrackingWalker_1 = require("./ScopedSymbolTrackingWalker"); 8 | var AstUtils_1 = require("./AstUtils"); 9 | var NoStringParameterToFunctionCallWalker = (function (_super) { 10 | __extends(NoStringParameterToFunctionCallWalker, _super); 11 | function NoStringParameterToFunctionCallWalker(sourceFile, targetFunctionName, options, languageServices) { 12 | var _this = _super.call(this, sourceFile, options, languageServices) || this; 13 | _this.targetFunctionName = targetFunctionName; 14 | _this.failureString = 'Forbidden ' + targetFunctionName + ' string parameter: '; 15 | return _this; 16 | } 17 | NoStringParameterToFunctionCallWalker.prototype.visitCallExpression = function (node) { 18 | this.validateExpression(node); 19 | _super.prototype.visitCallExpression.call(this, node); 20 | }; 21 | NoStringParameterToFunctionCallWalker.prototype.validateExpression = function (node) { 22 | var functionName = AstUtils_1.AstUtils.getFunctionName(node); 23 | var firstArg = node.arguments[0]; 24 | if (functionName === this.targetFunctionName && firstArg != null) { 25 | if (!this.isExpressionEvaluatingToFunction(firstArg)) { 26 | var msg = this.failureString + firstArg.getFullText().trim().substring(0, 40); 27 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), msg)); 28 | } 29 | } 30 | }; 31 | return NoStringParameterToFunctionCallWalker; 32 | }(ScopedSymbolTrackingWalker_1.ScopedSymbolTrackingWalker)); 33 | exports.NoStringParameterToFunctionCallWalker = NoStringParameterToFunctionCallWalker; 34 | //# sourceMappingURL=NoStringParameterToFunctionCallWalker.js.map -------------------------------------------------------------------------------- /tslint-contrib/missingJsdocRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var Lint = require("tslint"); 8 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 9 | var Rule = (function (_super) { 10 | __extends(Rule, _super); 11 | function Rule() { 12 | return _super.apply(this, arguments) || this; 13 | } 14 | Rule.prototype.apply = function (sourceFile) { 15 | return this.applyWithWalker(new MissingJSDocWalker(sourceFile, this.getOptions())); 16 | }; 17 | return Rule; 18 | }(Lint.Rules.AbstractRule)); 19 | Rule.metadata = { 20 | ruleName: 'missing-jsdoc', 21 | type: 'maintainability', 22 | description: 'All files must have a top level JSDoc comment.', 23 | options: null, 24 | optionsDescription: '', 25 | typescriptOnly: true, 26 | issueClass: 'Non-SDL', 27 | issueType: 'Warning', 28 | severity: 'Low', 29 | level: 'Opportunity for Excellence', 30 | group: 'Clarity', 31 | commonWeaknessEnumeration: '398, 710' 32 | }; 33 | Rule.FAILURE_STRING = 'File missing JSDoc comment at the top-level: '; 34 | exports.Rule = Rule; 35 | var MissingJSDocWalker = (function (_super) { 36 | __extends(MissingJSDocWalker, _super); 37 | function MissingJSDocWalker() { 38 | return _super.apply(this, arguments) || this; 39 | } 40 | MissingJSDocWalker.prototype.visitSourceFile = function (node) { 41 | if (!/^\/\*\*\s*$/gm.test(node.getFullText())) { 42 | var failureString = Rule.FAILURE_STRING + this.getSourceFile().fileName; 43 | var failure = this.createFailure(node.getStart(), node.getWidth(), failureString); 44 | this.addFailure(failure); 45 | } 46 | }; 47 | return MissingJSDocWalker; 48 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 49 | //# sourceMappingURL=missingJsdocRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noWithStatementRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | return this.applyWithWalker(new NoWithStatementWalker(sourceFile, this.getOptions())); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'no-with-statement', 22 | type: 'maintainability', 23 | description: 'Do not use with statements. Assign the item to a new variable instead', 24 | options: null, 25 | optionsDescription: '', 26 | typescriptOnly: true, 27 | issueClass: 'Non-SDL', 28 | issueType: 'Warning', 29 | severity: 'Important', 30 | level: 'Opportunity for Excellence', 31 | group: 'Correctness', 32 | commonWeaknessEnumeration: '398, 710' 33 | }; 34 | Rule.FAILURE_STRING = 'Forbidden with statement'; 35 | exports.Rule = Rule; 36 | var NoWithStatementWalker = (function (_super) { 37 | __extends(NoWithStatementWalker, _super); 38 | function NoWithStatementWalker() { 39 | return _super.apply(this, arguments) || this; 40 | } 41 | NoWithStatementWalker.prototype.visitNode = function (node) { 42 | if (node.kind === ts.SyntaxKind.WithStatement) { 43 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); 44 | } 45 | _super.prototype.visitNode.call(this, node); 46 | }; 47 | return NoWithStatementWalker; 48 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 49 | //# sourceMappingURL=noWithStatementRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/BaseFormatter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var fs = require("fs"); 8 | var tslint_1 = require("tslint"); 9 | var BaseFormatter = (function (_super) { 10 | __extends(BaseFormatter, _super); 11 | function BaseFormatter(ruleName, applyFix) { 12 | var _this = _super.call(this) || this; 13 | _this.ruleName = ruleName; 14 | _this.applyFix = applyFix.bind(_this); 15 | return _this; 16 | } 17 | BaseFormatter.prototype.format = function (allFailures) { 18 | for (var index = allFailures.length - 1; index >= 0; index--) { 19 | var failure = allFailures[index]; 20 | if (failure.getRuleName() === this.ruleName) { 21 | this.applyFix(failure); 22 | } 23 | } 24 | var outputLines = allFailures.map(this.formatFailure); 25 | return outputLines.join('\n') + '\n'; 26 | }; 27 | BaseFormatter.prototype.readFile = function (fileName) { 28 | return fs.readFileSync(fileName, { encoding: 'UTF-8' }); 29 | }; 30 | BaseFormatter.prototype.writeFile = function (fileName, fileContents) { 31 | fs.writeFileSync(fileName, fileContents, { encoding: 'UTF-8' }); 32 | }; 33 | BaseFormatter.prototype.formatFailure = function (failure) { 34 | var fileName = failure.getFileName(); 35 | var failureString = failure.getFailure(); 36 | var ruleName = failure.getRuleName(); 37 | var lineAndCharacter = failure.getStartPosition().getLineAndCharacter(); 38 | var positionTuple = '[' + (lineAndCharacter.line + 1) + ', ' + (lineAndCharacter.character + 1) + ']'; 39 | return '(' + ruleName + ') ' + fileName + positionTuple + ': ' + failureString; 40 | }; 41 | return BaseFormatter; 42 | }(tslint_1.Formatters.AbstractFormatter)); 43 | exports.BaseFormatter = BaseFormatter; 44 | //# sourceMappingURL=BaseFormatter.js.map -------------------------------------------------------------------------------- /tslint-contrib/noRegexSpacesRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var Lint = require("tslint"); 8 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 9 | var Rule = (function (_super) { 10 | __extends(Rule, _super); 11 | function Rule() { 12 | return _super.apply(this, arguments) || this; 13 | } 14 | Rule.prototype.apply = function (sourceFile) { 15 | return this.applyWithWalker(new NoRegexSpacesRuleWalker(sourceFile, this.getOptions())); 16 | }; 17 | return Rule; 18 | }(Lint.Rules.AbstractRule)); 19 | Rule.metadata = { 20 | ruleName: 'no-regex-spaces', 21 | type: 'maintainability', 22 | description: 'Do not use multiple spaces in a regular expression literal. Similar to the ESLint no-regex-spaces rule', 23 | options: null, 24 | optionsDescription: '', 25 | typescriptOnly: true, 26 | issueClass: 'Non-SDL', 27 | issueType: 'Error', 28 | severity: 'Critical', 29 | level: 'Opportunity for Excellence', 30 | group: 'Correctness' 31 | }; 32 | Rule.FAILURE_STRING = 'Spaces in regular expressions are hard to count. Use '; 33 | exports.Rule = Rule; 34 | var NoRegexSpacesRuleWalker = (function (_super) { 35 | __extends(NoRegexSpacesRuleWalker, _super); 36 | function NoRegexSpacesRuleWalker() { 37 | return _super.apply(this, arguments) || this; 38 | } 39 | NoRegexSpacesRuleWalker.prototype.visitRegularExpressionLiteral = function (node) { 40 | var match = /( {2,})+?/.exec(node.getText()); 41 | if (match != null) { 42 | var replacement = '{' + match[0].length + '}'; 43 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING + replacement)); 44 | } 45 | _super.prototype.visitRegularExpressionLiteral.call(this, node); 46 | }; 47 | return NoRegexSpacesRuleWalker; 48 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 49 | //# sourceMappingURL=noRegexSpacesRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noReservedKeywordsRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var Lint = require("tslint"); 8 | var BannedTermWalker_1 = require("./utils/BannedTermWalker"); 9 | var Rule = (function (_super) { 10 | __extends(Rule, _super); 11 | function Rule() { 12 | return _super.apply(this, arguments) || this; 13 | } 14 | Rule.prototype.apply = function (sourceFile) { 15 | var walker = new BannedTermWalker_1.BannedTermWalker(sourceFile, this.getOptions(), Rule.FAILURE_STRING, Rule.BANNED_TERMS); 16 | return this.applyWithWalker(walker); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'no-reserved-keywords', 22 | type: 'maintainability', 23 | description: 'Do not use reserved keywords as names of local variables, fields, functions, or other identifiers.', 24 | options: null, 25 | optionsDescription: '', 26 | typescriptOnly: true, 27 | issueClass: 'SDL', 28 | issueType: 'Error', 29 | severity: 'Critical', 30 | level: 'Mandatory', 31 | group: 'Security', 32 | commonWeaknessEnumeration: '398' 33 | }; 34 | Rule.FAILURE_STRING = 'Forbidden reference to reserved keyword: '; 35 | Rule.BANNED_TERMS = [ 36 | 'break', 'case', 'catch', 'class', 37 | 'const', 'continue', 'debugger', 'default', 38 | 'delete', 'do', 'else', 'enum', 'export', 39 | 'extends', 'false', 'finally', 'for', 40 | 'function', 'if', 'import', 'in', 41 | 'instanceof', 'new', 'null', 'return', 42 | 'super', 'switch', 'this', 'throw', 43 | 'true', 'try', 'typeof', 'var', 44 | 'void', 'while', 'with', 45 | 'as', 'implements', 'interface', 'let', 46 | 'package', 'private', 'protected', 47 | 'public', 'static', 'yield', 48 | 'any', 'boolean', 'constructor', 49 | 'declare', 'get', 'module', 50 | 'require', 'number', 'set', 51 | 'string', 'symbol', 'type', 52 | 'from', 'of' 53 | ]; 54 | exports.Rule = Rule; 55 | //# sourceMappingURL=noReservedKeywordsRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noForInRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var Lint = require("tslint"); 8 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 9 | var Rule = (function (_super) { 10 | __extends(Rule, _super); 11 | function Rule() { 12 | return _super.apply(this, arguments) || this; 13 | } 14 | Rule.prototype.apply = function (sourceFile) { 15 | return this.applyWithWalker(new NoForInRuleWalker(sourceFile, this.getOptions())); 16 | }; 17 | return Rule; 18 | }(Lint.Rules.AbstractRule)); 19 | Rule.metadata = { 20 | ruleName: 'no-for-in', 21 | type: 'maintainability', 22 | description: 'Avoid use of for-in statements. They can be replaced by Object.keys', 23 | options: null, 24 | optionsDescription: '', 25 | typescriptOnly: true, 26 | issueClass: 'Non-SDL', 27 | issueType: 'Warning', 28 | severity: 'Moderate', 29 | level: 'Opportunity for Excellence', 30 | group: 'Clarity', 31 | commonWeaknessEnumeration: '398, 710' 32 | }; 33 | Rule.FAILURE_STRING_FACTORY = function (initializer, expression) { 34 | return "Do not use the 'for in' statement: 'for (" + initializer + " in " + expression + ")'. If this is an object, use 'Object.keys' instead. If this is an array use a standard 'for' loop instead."; 35 | }; 36 | exports.Rule = Rule; 37 | var NoForInRuleWalker = (function (_super) { 38 | __extends(NoForInRuleWalker, _super); 39 | function NoForInRuleWalker() { 40 | return _super.apply(this, arguments) || this; 41 | } 42 | NoForInRuleWalker.prototype.visitForInStatement = function (node) { 43 | var initializer = node.initializer.getText(); 44 | var expression = node.expression.getText(); 45 | var msg = Rule.FAILURE_STRING_FACTORY(initializer, expression); 46 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), msg)); 47 | }; 48 | return NoForInRuleWalker; 49 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 50 | //# sourceMappingURL=noForInRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/useIsnanRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | return this.applyWithWalker(new UseIsnanRuleWalker(sourceFile, this.getOptions())); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'use-isnan', 22 | type: 'maintainability', 23 | description: 'enforces that you use the isNaN() function to check for NaN references instead of a comparison to the NaN constant.', 24 | options: null, 25 | optionsDescription: '', 26 | typescriptOnly: true, 27 | issueClass: 'Ignored', 28 | issueType: 'Error', 29 | severity: 'Critical', 30 | level: 'Opportunity for Excellence', 31 | group: 'Ignored' 32 | }; 33 | Rule.FAILURE_STRING = 'Found an invalid comparison for NaN: '; 34 | exports.Rule = Rule; 35 | var UseIsnanRuleWalker = (function (_super) { 36 | __extends(UseIsnanRuleWalker, _super); 37 | function UseIsnanRuleWalker() { 38 | return _super.apply(this, arguments) || this; 39 | } 40 | UseIsnanRuleWalker.prototype.visitBinaryExpression = function (node) { 41 | if (this.isExpressionNaN(node.left) || this.isExpressionNaN(node.right)) { 42 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING + node.getText())); 43 | } 44 | _super.prototype.visitBinaryExpression.call(this, node); 45 | }; 46 | UseIsnanRuleWalker.prototype.isExpressionNaN = function (node) { 47 | return node.kind === ts.SyntaxKind.Identifier && node.getText() === 'NaN'; 48 | }; 49 | return UseIsnanRuleWalker; 50 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 51 | //# sourceMappingURL=useIsnanRule.js.map -------------------------------------------------------------------------------- /webpack.demo.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: ひまわり(dtysky) 3 | * Github: https://github.com/dtysky 4 | * Created: 2017/6/15 5 | */ 6 | const webpack = require('webpack'); 7 | const ExtractTextPlugin = require('extract-text-webpack-plugin'); 8 | const path = require('path'); 9 | const fs = require('fs'); 10 | const CompressionPlugin = require('compression-webpack-plugin'); 11 | 12 | module.exports = { 13 | entry: path.resolve(__dirname, `./demo/main.tsx`), 14 | output: { 15 | path: path.resolve(__dirname, 'demo'), 16 | filename: 'main.bundle.js', 17 | publicPath: '/' 18 | }, 19 | 20 | resolve: { 21 | // Add '.ts' and '.tsx' as resolvable extensions. 22 | extensions: [".ts", ".tsx", ".js"] 23 | }, 24 | 25 | module: { 26 | rules: [ 27 | // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'. 28 | { 29 | enforce: 'pre', 30 | test: /\.tsx?$/, 31 | use: [ 32 | { 33 | loader: "awesome-typescript-loader" 34 | }, 35 | { 36 | loader: 'tslint-loader', 37 | query: { 38 | configFile: path.resolve(__dirname, './tslintConfig.js') 39 | } 40 | } 41 | ], 42 | exclude: /node_modules/ 43 | }, 44 | 45 | { 46 | test: /\.css$/, 47 | use: ExtractTextPlugin.extract({ 48 | fallback: "style-loader", 49 | use: ["css-loader", 'postcss-loader'] 50 | }), 51 | exclude: /node_modules/ 52 | } 53 | ] 54 | }, 55 | 56 | plugins: [ 57 | new ExtractTextPlugin({ 58 | filename: 'main.bundle.css', 59 | allChunks: true 60 | }), 61 | new webpack.ProvidePlugin({}), 62 | new webpack.DefinePlugin({ 63 | 'globalEnv': { 64 | NODE_ENV: JSON.stringify('production'), 65 | BROWSER: JSON.stringify(true), 66 | PLAT: JSON.stringify(process.env.PLAT) 67 | } 68 | }), 69 | new webpack.optimize.UglifyJsPlugin(), 70 | new webpack.optimize.AggressiveMergingPlugin(), 71 | new CompressionPlugin({ 72 | asset: "[path]", 73 | algorithm: "gzip", 74 | test: /\.js$|\.css$/, 75 | threshold: 10240, 76 | minRatio: 0.8 77 | }) 78 | ] 79 | }; 80 | -------------------------------------------------------------------------------- /tslint-contrib/noMultipleVarDeclRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var Lint = require("tslint"); 8 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 9 | var Rule = (function (_super) { 10 | __extends(Rule, _super); 11 | function Rule() { 12 | return _super.apply(this, arguments) || this; 13 | } 14 | Rule.prototype.apply = function (sourceFile) { 15 | return this.applyWithWalker(new NoMultipleVarDeclRuleWalker(sourceFile, this.getOptions())); 16 | }; 17 | return Rule; 18 | }(Lint.Rules.AbstractRule)); 19 | Rule.metadata = { 20 | ruleName: 'no-multiple-var-decl', 21 | type: 'maintainability', 22 | description: 'Deprecated - This rule is now part of the base TSLint product as the rule named \'one-variable-per-declaration\'', 23 | options: null, 24 | optionsDescription: '', 25 | typescriptOnly: true, 26 | issueClass: 'Ignored', 27 | issueType: 'Warning', 28 | severity: 'Low', 29 | level: 'Opportunity for Excellence', 30 | group: 'Deprecated', 31 | recommendation: 'false, // use tslint one-variable-per-declaration rule instead', 32 | commonWeaknessEnumeration: '710' 33 | }; 34 | Rule.FAILURE_STRING = 'Do not use comma separated variable declarations: '; 35 | exports.Rule = Rule; 36 | var NoMultipleVarDeclRuleWalker = (function (_super) { 37 | __extends(NoMultipleVarDeclRuleWalker, _super); 38 | function NoMultipleVarDeclRuleWalker() { 39 | return _super.apply(this, arguments) || this; 40 | } 41 | NoMultipleVarDeclRuleWalker.prototype.visitVariableStatement = function (node) { 42 | if (node.declarationList.declarations.length > 1) { 43 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING + node.declarationList.declarations[0].getText() + ',')); 44 | } 45 | _super.prototype.visitVariableStatement.call(this, node); 46 | }; 47 | return NoMultipleVarDeclRuleWalker; 48 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 49 | //# sourceMappingURL=noMultipleVarDeclRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noExecScriptRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var Lint = require("tslint"); 8 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 9 | var AstUtils_1 = require("./utils/AstUtils"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | return this.applyWithWalker(new NoEvalScriptWalker(sourceFile, this.getOptions())); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'no-exec-script', 22 | type: 'maintainability', 23 | description: 'Do not use the execScript functions', 24 | options: null, 25 | optionsDescription: '', 26 | typescriptOnly: true, 27 | issueClass: 'SDL', 28 | issueType: 'Error', 29 | severity: 'Critical', 30 | level: 'Mandatory', 31 | group: 'Security', 32 | commonWeaknessEnumeration: '95, 676' 33 | }; 34 | Rule.FAILURE_STRING = 'forbidden execScript: '; 35 | exports.Rule = Rule; 36 | var NoEvalScriptWalker = (function (_super) { 37 | __extends(NoEvalScriptWalker, _super); 38 | function NoEvalScriptWalker() { 39 | return _super.apply(this, arguments) || this; 40 | } 41 | NoEvalScriptWalker.prototype.visitCallExpression = function (node) { 42 | this.validateExpression(node); 43 | _super.prototype.visitCallExpression.call(this, node); 44 | }; 45 | NoEvalScriptWalker.prototype.validateExpression = function (node) { 46 | var expression = node.expression; 47 | var functionName = AstUtils_1.AstUtils.getFunctionName(node); 48 | if (functionName === 'execScript') { 49 | var msg = Rule.FAILURE_STRING + expression.getFullText().trim(); 50 | this.addFailure(this.createFailure(expression.getStart(), expression.getWidth(), msg)); 51 | } 52 | }; 53 | return NoEvalScriptWalker; 54 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 55 | //# sourceMappingURL=noExecScriptRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noDisableAutoSanitizationRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var Lint = require("tslint"); 8 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 9 | var AstUtils_1 = require("./utils/AstUtils"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | return this.applyWithWalker(new NoDisableAutoSanitizationWalker(sourceFile, this.getOptions())); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'no-disable-auto-sanitization', 22 | type: 'maintainability', 23 | description: 'Do not disable auto-sanitization of HTML because this opens up your page to an XSS attack. ', 24 | options: null, 25 | optionsDescription: '', 26 | typescriptOnly: true, 27 | issueClass: 'SDL', 28 | issueType: 'Error', 29 | severity: 'Critical', 30 | level: 'Mandatory', 31 | group: 'Security', 32 | commonWeaknessEnumeration: '157, 159, 75, 79, 85, 749, 676' 33 | }; 34 | Rule.FAILURE_STRING = 'Forbidden call to '; 35 | exports.Rule = Rule; 36 | var NoDisableAutoSanitizationWalker = (function (_super) { 37 | __extends(NoDisableAutoSanitizationWalker, _super); 38 | function NoDisableAutoSanitizationWalker() { 39 | return _super.apply(this, arguments) || this; 40 | } 41 | NoDisableAutoSanitizationWalker.prototype.visitCallExpression = function (node) { 42 | var functionName = AstUtils_1.AstUtils.getFunctionName(node); 43 | if (functionName === 'execUnsafeLocalFunction' || functionName === 'setInnerHTMLUnsafe') { 44 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING + functionName)); 45 | } 46 | _super.prototype.visitCallExpression.call(this, node); 47 | }; 48 | return NoDisableAutoSanitizationWalker; 49 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 50 | //# sourceMappingURL=noDisableAutoSanitizationRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noMultilineStringRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | return this.applyWithWalker(new NoMultilineStringWalker(sourceFile, this.getOptions())); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'no-multiline-string', 22 | type: 'maintainability', 23 | description: 'Do not declare multiline strings', 24 | options: null, 25 | optionsDescription: '', 26 | typescriptOnly: true, 27 | issueClass: 'Non-SDL', 28 | issueType: 'Warning', 29 | severity: 'Low', 30 | level: 'Opportunity for Excellence', 31 | group: 'Clarity', 32 | recommendation: 'true, // multiline-strings often introduce unnecessary whitespace into the string literals', 33 | commonWeaknessEnumeration: '710' 34 | }; 35 | Rule.FAILURE_STRING = 'Forbidden Multiline string: '; 36 | exports.Rule = Rule; 37 | var NoMultilineStringWalker = (function (_super) { 38 | __extends(NoMultilineStringWalker, _super); 39 | function NoMultilineStringWalker() { 40 | return _super.apply(this, arguments) || this; 41 | } 42 | NoMultilineStringWalker.prototype.visitNode = function (node) { 43 | if (node.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral) { 44 | var fullText = node.getFullText(); 45 | var firstLine = fullText.substring(0, fullText.indexOf('\n')); 46 | var trimmed = firstLine.substring(0, 40).trim(); 47 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING + trimmed + '...')); 48 | } 49 | _super.prototype.visitNode.call(this, node); 50 | }; 51 | return NoMultilineStringWalker; 52 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 53 | //# sourceMappingURL=noMultilineStringRule.js.map -------------------------------------------------------------------------------- /spec/TypeChecker.spec.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright(c) dtysky 3 | * Created: 2017/6/15 4 | * Description: 5 | */ 6 | import {checkType, TypeChecker} from '../src/TypeChecker'; 7 | import * as TC from '../src/TypeChecker'; 8 | import {spy} from 'sinon'; 9 | import {TFile} from '../src/types'; 10 | 11 | describe('TypeChecker', () => { 12 | describe('checkType', () => { 13 | let file; 14 | beforeEach(() => { 15 | file = {type: 'image/png'}; 16 | }); 17 | 18 | it('checkType, pass', done => { 19 | checkType(file, ['image/png', 'image/jpeg']) 20 | .then(res => { 21 | expect(res.error).toBeUndefined(); 22 | expect(res.file).toEqual(file); 23 | expect(res.info).toEqual({type: 'image/png'}); 24 | done(); 25 | }); 26 | }); 27 | 28 | it('checkType, empty types', done => { 29 | checkType(file, []) 30 | .then(res => { 31 | expect(res.error).toBeUndefined(); 32 | expect(res.file).toEqual(file); 33 | expect(res.info).toEqual({type: 'image/png'}); 34 | done(); 35 | }); 36 | }); 37 | 38 | it('checkType, error', done => { 39 | checkType(file, ['image/jpeg']) 40 | .catch(res => { 41 | expect(res.error).toEqual(jasmine.objectContaining({ 42 | name: 'type', 43 | currentValue: 'image/png', 44 | limitValue: ['image/jpeg'] 45 | })); 46 | expect(res.file).toEqual(file); 47 | expect(res.info).toEqual({type: 'image/png'}); 48 | done(); 49 | }); 50 | }); 51 | }); 52 | 53 | describe('TypeChecker', () => { 54 | let file; 55 | let checker: TypeChecker; 56 | 57 | beforeEach(() => { 58 | checker = new TypeChecker(['image/png']); 59 | file = {type: 'image/png'}; 60 | }); 61 | 62 | it('Constructor', () => { 63 | expect(checker['types']).toEqual(['image/png']); 64 | }); 65 | 66 | it('setAttr', () => { 67 | checker.setTypes(['image/jpeg']); 68 | expect(checker['types']).toEqual(['image/jpeg']); 69 | }); 70 | 71 | it('check', done => { 72 | (TC).checkType = spy(checkType); 73 | checker.check(file) 74 | .then(() => { 75 | expect((TC.checkType).calledWith(file, ['image/png'])).toBeTruthy(); 76 | done(); 77 | }); 78 | }); 79 | }); 80 | }); 81 | -------------------------------------------------------------------------------- /tslint-contrib/noOctalLiteralRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | var noOctalLiteral = new NoOctalLiteral(sourceFile, this.getOptions()); 17 | return this.applyWithWalker(noOctalLiteral); 18 | }; 19 | return Rule; 20 | }(Lint.Rules.AbstractRule)); 21 | Rule.metadata = { 22 | ruleName: 'no-octal-literal', 23 | type: 'maintainability', 24 | description: 'Do not use octal literals or escaped octal sequences', 25 | options: null, 26 | optionsDescription: '', 27 | typescriptOnly: true, 28 | issueClass: 'SDL', 29 | issueType: 'Error', 30 | severity: 'Critical', 31 | level: 'Mandatory', 32 | group: 'Security' 33 | }; 34 | Rule.FAILURE_STRING = 'Octal literals should not be used: '; 35 | exports.Rule = Rule; 36 | var NoOctalLiteral = (function (_super) { 37 | __extends(NoOctalLiteral, _super); 38 | function NoOctalLiteral() { 39 | return _super.apply(this, arguments) || this; 40 | } 41 | NoOctalLiteral.prototype.visitNode = function (node) { 42 | if (node.kind === ts.SyntaxKind.StringLiteral) { 43 | this.failOnOctalString(node); 44 | } 45 | _super.prototype.visitNode.call(this, node); 46 | }; 47 | NoOctalLiteral.prototype.failOnOctalString = function (node) { 48 | var match = /("|')(.*(\\-?[0-7]{1,3}(?![0-9])).*("|'))/g.exec(node.getText()); 49 | if (match) { 50 | var octalValue = match[3]; 51 | var startOfMatch = node.getStart() + node.getText().indexOf(octalValue); 52 | var width = octalValue.length; 53 | this.addFailure(this.createFailure(startOfMatch, width, Rule.FAILURE_STRING + octalValue)); 54 | } 55 | }; 56 | return NoOctalLiteral; 57 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 58 | //# sourceMappingURL=noOctalLiteralRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/preferTypeCastRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var FAILURE_STRING = 'Found as-cast instead of a traditional type-cast. Please convert to a type-cast: '; 11 | var Rule = (function (_super) { 12 | __extends(Rule, _super); 13 | function Rule() { 14 | return _super.apply(this, arguments) || this; 15 | } 16 | Rule.prototype.apply = function (sourceFile) { 17 | return this.applyWithWalker(new PreferTypeCastRuleWalker(sourceFile, this.getOptions())); 18 | }; 19 | return Rule; 20 | }(Lint.Rules.AbstractRule)); 21 | Rule.metadata = { 22 | ruleName: 'prefer-type-cast', 23 | type: 'maintainability', 24 | description: 'Prefer the tradition type casts instead of the new \'as-cast\' syntax', 25 | options: null, 26 | optionsDescription: '', 27 | typescriptOnly: true, 28 | issueClass: 'Ignored', 29 | issueType: 'Warning', 30 | severity: 'Low', 31 | level: 'Opportunity for Excellence', 32 | group: 'Configurable', 33 | recommendation: 'true, // pick either type-cast format and use it consistently', 34 | commonWeaknessEnumeration: '398, 710' 35 | }; 36 | exports.Rule = Rule; 37 | var PreferTypeCastRuleWalker = (function (_super) { 38 | __extends(PreferTypeCastRuleWalker, _super); 39 | function PreferTypeCastRuleWalker() { 40 | return _super.apply(this, arguments) || this; 41 | } 42 | PreferTypeCastRuleWalker.prototype.visitSourceFile = function (node) { 43 | if (/.*\.tsx/.test(node.fileName) === false) { 44 | _super.prototype.visitSourceFile.call(this, node); 45 | } 46 | }; 47 | PreferTypeCastRuleWalker.prototype.visitNode = function (node) { 48 | if (node.kind === ts.SyntaxKind.AsExpression) { 49 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), FAILURE_STRING + node.getText())); 50 | } 51 | _super.prototype.visitNode.call(this, node); 52 | }; 53 | return PreferTypeCastRuleWalker; 54 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 55 | //# sourceMappingURL=preferTypeCastRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/useNamedParameterRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | return this.applyWithWalker(new UseNamedParameterWalker(sourceFile, this.getOptions())); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'use-named-parameter', 22 | type: 'maintainability', 23 | description: 'Do not reference the arguments object by numerical index; instead, use a named parameter.', 24 | options: null, 25 | optionsDescription: '', 26 | typescriptOnly: true, 27 | issueClass: 'Non-SDL', 28 | issueType: 'Warning', 29 | severity: 'Important', 30 | level: 'Opportunity for Excellence', 31 | group: 'Correctness', 32 | commonWeaknessEnumeration: '710' 33 | }; 34 | Rule.FAILURE_STRING = 'Use a named parameter instead: '; 35 | exports.Rule = Rule; 36 | var UseNamedParameterWalker = (function (_super) { 37 | __extends(UseNamedParameterWalker, _super); 38 | function UseNamedParameterWalker() { 39 | return _super.apply(this, arguments) || this; 40 | } 41 | UseNamedParameterWalker.prototype.visitElementAccessExpression = function (node) { 42 | if (node.argumentExpression != null) { 43 | if (node.argumentExpression.kind === ts.SyntaxKind.NumericLiteral) { 44 | if (node.expression.getText() === 'arguments') { 45 | var failureString = Rule.FAILURE_STRING + '\'' + node.getText() + '\''; 46 | var failure = this.createFailure(node.getStart(), node.getWidth(), failureString); 47 | this.addFailure(failure); 48 | } 49 | } 50 | } 51 | _super.prototype.visitElementAccessExpression.call(this, node); 52 | }; 53 | return UseNamedParameterWalker; 54 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 55 | //# sourceMappingURL=useNamedParameterRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/reactA11yPropsRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var JsxAttribute_1 = require("./utils/JsxAttribute"); 10 | var ARIA_SCHEMA = require('./utils/attributes/ariaSchema.json'); 11 | function getFailureString(name) { 12 | return "This attribute name '" + name + "' is an invalid ARIA attribute. A reference to valid ARIA attributes can be found at https://www.w3.org/TR/2014/REC-wai-aria-20140320/states_and_properties#state_prop_def "; 13 | } 14 | exports.getFailureString = getFailureString; 15 | var Rule = (function (_super) { 16 | __extends(Rule, _super); 17 | function Rule() { 18 | return _super.apply(this, arguments) || this; 19 | } 20 | Rule.prototype.apply = function (sourceFile) { 21 | return sourceFile.languageVariant === ts.LanguageVariant.JSX 22 | ? this.applyWithWalker(new A11yPropsWalker(sourceFile, this.getOptions())) 23 | : []; 24 | }; 25 | return Rule; 26 | }(Lint.Rules.AbstractRule)); 27 | Rule.metadata = { 28 | ruleName: 'react-a11y-props', 29 | type: 'maintainability', 30 | description: 'Enforce all `aria-*` attributes are valid. Elements cannot use an invalid `aria-*` attribute.', 31 | options: null, 32 | optionsDescription: '', 33 | typescriptOnly: true, 34 | issueClass: 'Non-SDL', 35 | issueType: 'Warning', 36 | severity: 'Important', 37 | level: 'Opportunity for Excellence', 38 | group: 'Accessibility' 39 | }; 40 | exports.Rule = Rule; 41 | var A11yPropsWalker = (function (_super) { 42 | __extends(A11yPropsWalker, _super); 43 | function A11yPropsWalker() { 44 | return _super.apply(this, arguments) || this; 45 | } 46 | A11yPropsWalker.prototype.visitJsxAttribute = function (node) { 47 | var name = JsxAttribute_1.getPropName(node); 48 | if (!name || !name.match(/^aria-/i)) { 49 | return; 50 | } 51 | if (!ARIA_SCHEMA[name.toLowerCase()]) { 52 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), getFailureString(name))); 53 | } 54 | }; 55 | return A11yPropsWalker; 56 | }(Lint.RuleWalker)); 57 | //# sourceMappingURL=reactA11yPropsRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/insecureRandomRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var Lint = require("tslint"); 8 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 9 | var MATH_FAIL_STRING = 'Math.random produces insecure random numbers. ' + 10 | 'Use crypto.randomBytes() or window.crypto.getRandomValues() instead'; 11 | var NODE_FAIL_STRING = 'crypto.pseudoRandomBytes produces insecure random numbers. ' + 12 | 'Use crypto.randomBytes() instead'; 13 | var Rule = (function (_super) { 14 | __extends(Rule, _super); 15 | function Rule() { 16 | return _super.apply(this, arguments) || this; 17 | } 18 | Rule.prototype.apply = function (sourceFile) { 19 | return this.applyWithWalker(new InsecureRandomRuleWalker(sourceFile, this.getOptions())); 20 | }; 21 | return Rule; 22 | }(Lint.Rules.AbstractRule)); 23 | Rule.metadata = { 24 | ruleName: 'insecure-random', 25 | type: 'functionality', 26 | description: 'Do not use insecure sources for random bytes', 27 | options: null, 28 | optionsDescription: '', 29 | typescriptOnly: true, 30 | issueClass: 'SDL', 31 | issueType: 'Error', 32 | severity: 'Important', 33 | level: 'Opportunity for Excellence', 34 | group: 'Security', 35 | commonWeaknessEnumeration: '330' 36 | }; 37 | exports.Rule = Rule; 38 | var InsecureRandomRuleWalker = (function (_super) { 39 | __extends(InsecureRandomRuleWalker, _super); 40 | function InsecureRandomRuleWalker() { 41 | return _super.apply(this, arguments) || this; 42 | } 43 | InsecureRandomRuleWalker.prototype.visitPropertyAccessExpression = function (node) { 44 | if (node.expression.getText() === 'Math' && node.name.text === 'random') { 45 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), MATH_FAIL_STRING)); 46 | } 47 | else if (node.name.text === 'pseudoRandomBytes') { 48 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), NODE_FAIL_STRING)); 49 | } 50 | _super.prototype.visitPropertyAccessExpression.call(this, node); 51 | }; 52 | return InsecureRandomRuleWalker; 53 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 54 | //# sourceMappingURL=insecureRandomRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noDeleteExpressionRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | var noDeleteExpression = new NoDeleteExpression(sourceFile, this.getOptions()); 17 | return this.applyWithWalker(noDeleteExpression); 18 | }; 19 | return Rule; 20 | }(Lint.Rules.AbstractRule)); 21 | Rule.metadata = { 22 | ruleName: 'no-delete-expression', 23 | type: 'maintainability', 24 | description: 'Do not delete expressions. Only properties should be deleted', 25 | options: null, 26 | optionsDescription: '', 27 | typescriptOnly: true, 28 | issueClass: 'SDL', 29 | issueType: 'Error', 30 | severity: 'Critical', 31 | level: 'Mandatory', 32 | group: 'Security' 33 | }; 34 | Rule.FAILURE_STRING = 'Variables should not be deleted: '; 35 | exports.Rule = Rule; 36 | var NoDeleteExpression = (function (_super) { 37 | __extends(NoDeleteExpression, _super); 38 | function NoDeleteExpression() { 39 | return _super.apply(this, arguments) || this; 40 | } 41 | NoDeleteExpression.prototype.visitExpressionStatement = function (node) { 42 | _super.prototype.visitExpressionStatement.call(this, node); 43 | if (node.expression.kind === ts.SyntaxKind.DeleteExpression) { 44 | var deletedObject = node.expression.getChildren()[1]; 45 | if (deletedObject != null && deletedObject.kind === ts.SyntaxKind.Identifier) { 46 | this.addNoDeleteFailure(deletedObject); 47 | } 48 | } 49 | }; 50 | NoDeleteExpression.prototype.addNoDeleteFailure = function (deletedObject) { 51 | var msg = Rule.FAILURE_STRING + deletedObject.getFullText().trim(); 52 | this.addFailure(this.createFailure(deletedObject.getStart(), deletedObject.getWidth(), msg)); 53 | }; 54 | return NoDeleteExpression; 55 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 56 | //# sourceMappingURL=noDeleteExpressionRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noSparseArraysRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var Utils_1 = require("./utils/Utils"); 11 | var Rule = (function (_super) { 12 | __extends(Rule, _super); 13 | function Rule() { 14 | return _super.apply(this, arguments) || this; 15 | } 16 | Rule.prototype.apply = function (sourceFile) { 17 | return this.applyWithWalker(new NoSparseArraysRuleWalker(sourceFile, this.getOptions())); 18 | }; 19 | return Rule; 20 | }(Lint.Rules.AbstractRule)); 21 | Rule.metadata = { 22 | ruleName: 'no-sparse-arrays', 23 | type: 'maintainability', 24 | description: 'Do not use sparse arrays. Sparse arrays contain empty slots, most frequently due to multiple ' + 25 | 'commas being used in an array literal.', 26 | options: null, 27 | optionsDescription: '', 28 | typescriptOnly: true, 29 | issueClass: 'Non-SDL', 30 | issueType: 'Warning', 31 | severity: 'Important', 32 | level: 'Opportunity for Excellence', 33 | group: 'Correctness', 34 | commonWeaknessEnumeration: '398, 710' 35 | }; 36 | Rule.FAILURE_STRING = 'Unexpected comma in middle of array'; 37 | exports.Rule = Rule; 38 | var NoSparseArraysRuleWalker = (function (_super) { 39 | __extends(NoSparseArraysRuleWalker, _super); 40 | function NoSparseArraysRuleWalker() { 41 | return _super.apply(this, arguments) || this; 42 | } 43 | NoSparseArraysRuleWalker.prototype.visitNode = function (node) { 44 | if (node.kind === ts.SyntaxKind.ArrayLiteralExpression) { 45 | if (this.isSparseArray(node)) { 46 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); 47 | } 48 | } 49 | _super.prototype.visitNode.call(this, node); 50 | }; 51 | NoSparseArraysRuleWalker.prototype.isSparseArray = function (node) { 52 | return Utils_1.Utils.exists(node.elements, function (element) { 53 | return element.kind === ts.SyntaxKind.OmittedExpression; 54 | }); 55 | }; 56 | return NoSparseArraysRuleWalker; 57 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 58 | //# sourceMappingURL=noSparseArraysRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noVarSelfRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var FAILURE_STRING = 'Assigning this reference to local variable: '; 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | return this.applyWithWalker(new NoVarSelfRuleWalker(sourceFile, this.getOptions())); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'no-var-self', 22 | type: 'maintainability', 23 | description: 'Do not use var self = this; instead, manage scope with arrow functions/lambdas.', 24 | options: null, 25 | optionsDescription: '', 26 | typescriptOnly: true, 27 | issueClass: 'Non-SDL', 28 | issueType: 'Warning', 29 | severity: 'Important', 30 | level: 'Opportunity for Excellence', 31 | group: 'Clarity', 32 | commonWeaknessEnumeration: '398, 710' 33 | }; 34 | exports.Rule = Rule; 35 | var NoVarSelfRuleWalker = (function (_super) { 36 | __extends(NoVarSelfRuleWalker, _super); 37 | function NoVarSelfRuleWalker(sourceFile, options) { 38 | var _this = _super.call(this, sourceFile, options) || this; 39 | _this.bannedVariableNames = /.*/; 40 | if (options.ruleArguments != null && options.ruleArguments.length > 0) { 41 | _this.bannedVariableNames = new RegExp(options.ruleArguments[0]); 42 | } 43 | return _this; 44 | } 45 | NoVarSelfRuleWalker.prototype.visitVariableDeclaration = function (node) { 46 | if (node.initializer != null && node.initializer.kind === ts.SyntaxKind.ThisKeyword) { 47 | if (node.name.kind === ts.SyntaxKind.Identifier) { 48 | var identifier = node.name; 49 | if (this.bannedVariableNames.test(identifier.text)) { 50 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), FAILURE_STRING + node.getText())); 51 | } 52 | } 53 | } 54 | _super.prototype.visitVariableDeclaration.call(this, node); 55 | }; 56 | return NoVarSelfRuleWalker; 57 | }(Lint.RuleWalker)); 58 | //# sourceMappingURL=noVarSelfRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noEmptyInterfacesRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var Lint = require("tslint"); 8 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 9 | var Rule = (function (_super) { 10 | __extends(Rule, _super); 11 | function Rule() { 12 | return _super.apply(this, arguments) || this; 13 | } 14 | Rule.prototype.apply = function (sourceFile) { 15 | return this.applyWithWalker(new NoEmptyInterfacesRuleWalker(sourceFile, this.getOptions())); 16 | }; 17 | return Rule; 18 | }(Lint.Rules.AbstractRule)); 19 | Rule.metadata = { 20 | ruleName: 'no-empty-interfaces', 21 | type: 'maintainability', 22 | description: 'Do not use empty interfaces.', 23 | options: null, 24 | optionsDescription: '', 25 | typescriptOnly: true, 26 | issueClass: 'Non-SDL', 27 | issueType: 'Warning', 28 | severity: 'Moderate', 29 | level: 'Opportunity for Excellence', 30 | group: 'Clarity', 31 | commonWeaknessEnumeration: '398, 710' 32 | }; 33 | Rule.FAILURE_STRING = 'Do not declare empty interfaces: '; 34 | exports.Rule = Rule; 35 | var NoEmptyInterfacesRuleWalker = (function (_super) { 36 | __extends(NoEmptyInterfacesRuleWalker, _super); 37 | function NoEmptyInterfacesRuleWalker() { 38 | return _super.apply(this, arguments) || this; 39 | } 40 | NoEmptyInterfacesRuleWalker.prototype.visitInterfaceDeclaration = function (node) { 41 | if (this.isInterfaceEmpty(node) && !this.hasMultipleParents(node)) { 42 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING + '\'' + node.name.getText() + '\'')); 43 | } 44 | _super.prototype.visitInterfaceDeclaration.call(this, node); 45 | }; 46 | NoEmptyInterfacesRuleWalker.prototype.isInterfaceEmpty = function (node) { 47 | return node.members == null || node.members.length === 0; 48 | }; 49 | NoEmptyInterfacesRuleWalker.prototype.hasMultipleParents = function (node) { 50 | if (node.heritageClauses == null || node.heritageClauses.length === 0) { 51 | return false; 52 | } 53 | return node.heritageClauses[0].types.length >= 2; 54 | }; 55 | return NoEmptyInterfacesRuleWalker; 56 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 57 | //# sourceMappingURL=noEmptyInterfacesRule.js.map -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "upload-checker", 3 | "version": "1.1.1", 4 | "description": "Check type/size/resolution while uploading files in pure front-end way.", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "dev": "node server.dev.js", 8 | "unittest": "./node_modules/.bin/karma start karma.conf.js", 9 | "public": "./node_modules/.bin/tsc src/index.ts --jsx react -d -outDir dist", 10 | "build-demo": "webpack -p --config ./webpack.demo.config.js " 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/dtysky/UploadChecker.git" 15 | }, 16 | "keywords": [ 17 | "upload", 18 | "file", 19 | "react", 20 | "checker" 21 | ], 22 | "author": "dtysky", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/dtysky/UploadChecker/issues" 26 | }, 27 | "homepage": "https://github.com/dtysky/UploadChecker#readme", 28 | "files": [ 29 | "dist", 30 | "README.md", 31 | "LICENSE" 32 | ], 33 | "devDependencies": { 34 | "@types/jasmine": "^2.5.52", 35 | "@types/node": "^7.0.11", 36 | "@types/sinon": "^2.3.1", 37 | "autoprefixer": "^6.7.7", 38 | "awesome-typescript-loader": "^3.1.2", 39 | "clean-webpack-plugin": "^0.1.16", 40 | "compression-webpack-plugin": "^0.4.0", 41 | "copy-webpack-plugin": "^4.0.1", 42 | "css-loader": "^0.27.1", 43 | "express": "4.14.0", 44 | "extract-text-webpack-plugin": "^2.1.0", 45 | "file-loader": "^0.10.1", 46 | "jasmine-core": "^2.5.2", 47 | "karma": "^1.3.0", 48 | "karma-chrome-launcher": "^2.1.1", 49 | "karma-jasmine": "^1.1.0", 50 | "karma-typescript": "^3.0.1", 51 | "postcss-loader": "^1.3.3", 52 | "postcss-smart-import": "^0.6.11", 53 | "precss": "^1.4.0", 54 | "raw-loader": "^0.5.1", 55 | "react-hot-loader": "^3.0.0-beta.6", 56 | "sinon": "^2.3.4", 57 | "source-map-loader": "^0.2.0", 58 | "style-loader": "^0.13.2", 59 | "tslint": "4.1.1", 60 | "tslint-loader": "^3.3.0", 61 | "tslint-microsoft-contrib": "^4.0.0", 62 | "typescript": "^2.1.4", 63 | "typings": "^2.0.0", 64 | "url-loader": "^0.5.7", 65 | "webpack": "^2.2.1", 66 | "webpack-dev-middleware": "^1.9.0", 67 | "webpack-hot-middleware": "^2.17.1", 68 | "es6-shim": "^0.35.3", 69 | "react": "^15.4.1", 70 | "react-dom": "^15.4.1", 71 | "semantic-ui-react": "^0.68.5", 72 | "@types/es6-shim": "^0.31.32", 73 | "@types/react": "^15.0.15", 74 | "@types/react-dom": "^0.14.23" 75 | }, 76 | "dependencies": { 77 | "@types/classnames": "0.0.32", 78 | "classnames": "^2.2.5" 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /tslint-contrib/noDocumentWriteRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var Lint = require("tslint"); 8 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 9 | var AstUtils_1 = require("./utils/AstUtils"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | return this.applyWithWalker(new NoDocumentWriteWalker(sourceFile, this.getOptions())); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'no-document-write', 22 | type: 'maintainability', 23 | description: 'Do not use document.write', 24 | options: null, 25 | optionsDescription: '', 26 | typescriptOnly: true, 27 | issueClass: 'SDL', 28 | issueType: 'Error', 29 | severity: 'Critical', 30 | level: 'Mandatory', 31 | group: 'Security', 32 | commonWeaknessEnumeration: '79, 85' 33 | }; 34 | Rule.WRITE_FAILURE = 'Forbidden call to document.write'; 35 | Rule.WRITELN_FAILURE = 'Forbidden call to document.writeln'; 36 | exports.Rule = Rule; 37 | var NoDocumentWriteWalker = (function (_super) { 38 | __extends(NoDocumentWriteWalker, _super); 39 | function NoDocumentWriteWalker() { 40 | return _super.apply(this, arguments) || this; 41 | } 42 | NoDocumentWriteWalker.prototype.visitCallExpression = function (node) { 43 | var functionTarget = AstUtils_1.AstUtils.getFunctionTarget(node); 44 | if (functionTarget === 'document' || functionTarget === 'window.document') { 45 | if (node.arguments.length === 1) { 46 | var functionName = AstUtils_1.AstUtils.getFunctionName(node); 47 | if (functionName === 'write') { 48 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.WRITE_FAILURE)); 49 | } 50 | else if (functionName === 'writeln') { 51 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.WRITELN_FAILURE)); 52 | } 53 | } 54 | } 55 | _super.prototype.visitCallExpression.call(this, node); 56 | }; 57 | return NoDocumentWriteWalker; 58 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 59 | //# sourceMappingURL=noDocumentWriteRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noDocumentDomainRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | return this.applyWithWalker(new NoDocumentDomainRuleWalker(sourceFile, this.getOptions())); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'no-document-domain', 22 | type: 'maintainability', 23 | description: 'Do not write to document.domain. Scripts setting document.domain to any value should be ' + 24 | 'validated to ensure that the value is on a list of allowed sites.', 25 | options: null, 26 | optionsDescription: '', 27 | typescriptOnly: true, 28 | issueClass: 'SDL', 29 | issueType: 'Error', 30 | severity: 'Critical', 31 | level: 'Mandatory', 32 | group: 'Security' 33 | }; 34 | Rule.FAILURE_STRING = 'Forbidden write to document.domain: '; 35 | exports.Rule = Rule; 36 | var NoDocumentDomainRuleWalker = (function (_super) { 37 | __extends(NoDocumentDomainRuleWalker, _super); 38 | function NoDocumentDomainRuleWalker() { 39 | return _super.apply(this, arguments) || this; 40 | } 41 | NoDocumentDomainRuleWalker.prototype.visitBinaryExpression = function (node) { 42 | if (node.operatorToken.getText() === '=' 43 | && node.left.kind === ts.SyntaxKind.PropertyAccessExpression 44 | && this.isDocumentDomainProperty(node.left)) { 45 | var msg = Rule.FAILURE_STRING + node.getFullText().trim(); 46 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), msg)); 47 | } 48 | _super.prototype.visitBinaryExpression.call(this, node); 49 | }; 50 | NoDocumentDomainRuleWalker.prototype.isDocumentDomainProperty = function (node) { 51 | if (node.name.text !== 'domain') { 52 | return false; 53 | } 54 | return node.expression.getText() === 'document' 55 | || node.expression.getText() === 'window.document'; 56 | }; 57 | return NoDocumentDomainRuleWalker; 58 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 59 | //# sourceMappingURL=noDocumentDomainRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noIncrementDecrementRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | return this.applyWithWalker(new NoIncrementDecrementWalker(sourceFile, this.getOptions())); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'no-increment-decrement', 22 | type: 'maintainability', 23 | description: 'Avoid use of increment and decrement operators particularly as part of complicated expressions', 24 | options: null, 25 | optionsDescription: '', 26 | typescriptOnly: true, 27 | issueClass: 'Non-SDL', 28 | issueType: 'Warning', 29 | severity: 'Low', 30 | level: 'Opportunity for Excellence', 31 | group: 'Correctness', 32 | commonWeaknessEnumeration: '398, 710' 33 | }; 34 | exports.Rule = Rule; 35 | var NoIncrementDecrementWalker = (function (_super) { 36 | __extends(NoIncrementDecrementWalker, _super); 37 | function NoIncrementDecrementWalker() { 38 | return _super.apply(this, arguments) || this; 39 | } 40 | NoIncrementDecrementWalker.prototype.visitPostfixUnaryExpression = function (node) { 41 | this.validateUnaryExpression(node); 42 | _super.prototype.visitPostfixUnaryExpression.call(this, node); 43 | }; 44 | NoIncrementDecrementWalker.prototype.visitPrefixUnaryExpression = function (node) { 45 | this.validateUnaryExpression(node); 46 | _super.prototype.visitPrefixUnaryExpression.call(this, node); 47 | }; 48 | NoIncrementDecrementWalker.prototype.validateUnaryExpression = function (node) { 49 | if (node.operator === ts.SyntaxKind.PlusPlusToken) { 50 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), 'Forbidden ++ operator')); 51 | } 52 | else if (node.operator === ts.SyntaxKind.MinusMinusToken) { 53 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), 'Forbidden -- operator')); 54 | } 55 | }; 56 | return NoIncrementDecrementWalker; 57 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 58 | //# sourceMappingURL=noIncrementDecrementRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noDuplicateCaseRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | return this.applyWithWalker(new NoDuplicateCaseRuleWalker(sourceFile, this.getOptions())); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'no-duplicate-case', 22 | type: 'maintainability', 23 | description: 'Do not use duplicate case labels in switch statements.', 24 | options: null, 25 | optionsDescription: '', 26 | typescriptOnly: true, 27 | issueClass: 'Non-SDL', 28 | issueType: 'Error', 29 | severity: 'Critical', 30 | level: 'Opportunity for Excellence', 31 | group: 'Correctness', 32 | commonWeaknessEnumeration: '398, 710' 33 | }; 34 | Rule.FAILURE_STRING = 'Duplicate case found in switch statement: '; 35 | exports.Rule = Rule; 36 | var NoDuplicateCaseRuleWalker = (function (_super) { 37 | __extends(NoDuplicateCaseRuleWalker, _super); 38 | function NoDuplicateCaseRuleWalker() { 39 | return _super.apply(this, arguments) || this; 40 | } 41 | NoDuplicateCaseRuleWalker.prototype.visitSwitchStatement = function (node) { 42 | var _this = this; 43 | var seenLabels = []; 44 | node.caseBlock.clauses.forEach(function (clauseOrDefault) { 45 | if (clauseOrDefault.kind === ts.SyntaxKind.CaseClause) { 46 | var clause = clauseOrDefault; 47 | if (clause.expression != null) { 48 | var caseText = clause.expression.getText(); 49 | if (seenLabels.indexOf(caseText) > -1) { 50 | _this.addFailure(_this.createFailure(clause.getStart(), clause.getWidth(), Rule.FAILURE_STRING + caseText)); 51 | } 52 | else { 53 | seenLabels.push(caseText); 54 | } 55 | } 56 | } 57 | }); 58 | _super.prototype.visitSwitchStatement.call(this, node); 59 | }; 60 | return NoDuplicateCaseRuleWalker; 61 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 62 | //# sourceMappingURL=noDuplicateCaseRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noInvalidRegexpRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | return this.applyWithWalker(new NoInvalidRegexpRuleWalker(sourceFile, this.getOptions())); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'no-invalid-regexp', 22 | type: 'maintainability', 23 | description: 'Do not use invalid regular expression strings in the RegExp constructor.', 24 | options: null, 25 | optionsDescription: '', 26 | typescriptOnly: true, 27 | issueClass: 'Non-SDL', 28 | issueType: 'Error', 29 | severity: 'Critical', 30 | level: 'Opportunity for Excellence', 31 | group: 'Correctness' 32 | }; 33 | exports.Rule = Rule; 34 | var NoInvalidRegexpRuleWalker = (function (_super) { 35 | __extends(NoInvalidRegexpRuleWalker, _super); 36 | function NoInvalidRegexpRuleWalker() { 37 | return _super.apply(this, arguments) || this; 38 | } 39 | NoInvalidRegexpRuleWalker.prototype.visitNewExpression = function (node) { 40 | this.validateCall(node); 41 | _super.prototype.visitNewExpression.call(this, node); 42 | }; 43 | NoInvalidRegexpRuleWalker.prototype.visitCallExpression = function (node) { 44 | this.validateCall(node); 45 | _super.prototype.visitCallExpression.call(this, node); 46 | }; 47 | NoInvalidRegexpRuleWalker.prototype.validateCall = function (expression) { 48 | if (expression.expression.getText() === 'RegExp') { 49 | if (expression.arguments.length > 0) { 50 | var arg1 = expression.arguments[0]; 51 | if (arg1.kind === ts.SyntaxKind.StringLiteral) { 52 | var regexpText = arg1.text; 53 | try { 54 | new RegExp(regexpText); 55 | } 56 | catch (e) { 57 | this.addFailure(this.createFailure(arg1.getStart(), arg1.getWidth(), e.message)); 58 | } 59 | } 60 | } 61 | } 62 | }; 63 | return NoInvalidRegexpRuleWalker; 64 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 65 | //# sourceMappingURL=noInvalidRegexpRule.js.map -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | #*.bmp binary 47 | #*.mp4 binary 48 | #*.webm binary 49 | 50 | ############################################################################### 51 | # diff behavior for common document formats 52 | # 53 | # Convert binary document formats to text before diffing them. This feature 54 | # is only available from the command line. Turn it on by uncommenting the 55 | # entries below. 56 | ############################################################################### 57 | #*.doc diff=astextplain 58 | #*.DOC diff=astextplain 59 | #*.docx diff=astextplain 60 | #*.DOCX diff=astextplain 61 | #*.dot diff=astextplain 62 | #*.DOT diff=astextplain 63 | #*.pdf diff=astextplain 64 | #*.PDF diff=astextplain 65 | #*.rtf diff=astextplain 66 | #*.RTF diff=astextplain 67 | -------------------------------------------------------------------------------- /tslint-contrib/reactA11yTabindexNoPositiveRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var JsxAttribute_1 = require("./utils/JsxAttribute"); 10 | function getFailureString() { 11 | return 'The value of tabindex attribute is invalid or undefined. It must be either -1 or 0.'; 12 | } 13 | exports.getFailureString = getFailureString; 14 | var Rule = (function (_super) { 15 | __extends(Rule, _super); 16 | function Rule() { 17 | return _super.apply(this, arguments) || this; 18 | } 19 | Rule.prototype.apply = function (sourceFile) { 20 | return sourceFile.languageVariant === ts.LanguageVariant.JSX 21 | ? this.applyWithWalker(new A11yTabindexNoPositiveWalker(sourceFile, this.getOptions())) 22 | : []; 23 | }; 24 | return Rule; 25 | }(Lint.Rules.AbstractRule)); 26 | Rule.metadata = { 27 | ruleName: 'react-a11y-tabindex-no-positive', 28 | type: 'maintainability', 29 | description: 'Enforce tabindex value is **not greater than zero**.', 30 | options: null, 31 | optionsDescription: '', 32 | typescriptOnly: true, 33 | issueClass: 'Non-SDL', 34 | issueType: 'Warning', 35 | severity: 'Important', 36 | level: 'Opportunity for Excellence', 37 | group: 'Accessibility' 38 | }; 39 | exports.Rule = Rule; 40 | var A11yTabindexNoPositiveWalker = (function (_super) { 41 | __extends(A11yTabindexNoPositiveWalker, _super); 42 | function A11yTabindexNoPositiveWalker() { 43 | return _super.apply(this, arguments) || this; 44 | } 45 | A11yTabindexNoPositiveWalker.prototype.visitJsxAttribute = function (node) { 46 | var name = JsxAttribute_1.getPropName(node); 47 | if (!name || name.toLowerCase() !== 'tabindex') { 48 | return; 49 | } 50 | var literalString = JsxAttribute_1.getNumericLiteral(node) || JsxAttribute_1.getStringLiteral(node); 51 | if (literalString === '') { 52 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), getFailureString())); 53 | } 54 | else if (literalString && literalString !== '-1' && literalString !== '0') { 55 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), getFailureString())); 56 | } 57 | else if (JsxAttribute_1.isEmpty(node)) { 58 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), getFailureString())); 59 | } 60 | }; 61 | return A11yTabindexNoPositiveWalker; 62 | }(Lint.RuleWalker)); 63 | //# sourceMappingURL=reactA11yTabindexNoPositiveRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noTypeofUndefinedRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var FAILURE_STRING = 'Avoid typeof x === \'undefined\' comparisons. Prefer x == undefined or x === undefined: '; 11 | var Rule = (function (_super) { 12 | __extends(Rule, _super); 13 | function Rule() { 14 | return _super.apply(this, arguments) || this; 15 | } 16 | Rule.prototype.apply = function (sourceFile) { 17 | return this.applyWithWalker(new NoTypeofUndefinedRuleWalker(sourceFile, this.getOptions())); 18 | }; 19 | return Rule; 20 | }(Lint.Rules.AbstractRule)); 21 | Rule.metadata = { 22 | ruleName: 'no-typeof-undefined', 23 | type: 'maintainability', 24 | description: 'Do not use the idiom typeof `x === \'undefined\'`. You can safely use the simpler x === undefined ' + 25 | 'or perhaps x == null if you want to check for either null or undefined.', 26 | options: null, 27 | optionsDescription: '', 28 | typescriptOnly: true, 29 | issueClass: 'Non-SDL', 30 | issueType: 'Warning', 31 | severity: 'Important', 32 | level: 'Opportunity for Excellence', 33 | group: 'Clarity', 34 | commonWeaknessEnumeration: '710' 35 | }; 36 | exports.Rule = Rule; 37 | var NoTypeofUndefinedRuleWalker = (function (_super) { 38 | __extends(NoTypeofUndefinedRuleWalker, _super); 39 | function NoTypeofUndefinedRuleWalker() { 40 | return _super.apply(this, arguments) || this; 41 | } 42 | NoTypeofUndefinedRuleWalker.prototype.visitBinaryExpression = function (node) { 43 | if ((this.isUndefinedString(node.left) && this.isTypeOfExpression(node.right)) 44 | || this.isUndefinedString(node.right) && this.isTypeOfExpression(node.left)) { 45 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), FAILURE_STRING + node.getText())); 46 | } 47 | _super.prototype.visitBinaryExpression.call(this, node); 48 | }; 49 | NoTypeofUndefinedRuleWalker.prototype.isTypeOfExpression = function (node) { 50 | return node.kind === ts.SyntaxKind.TypeOfExpression; 51 | }; 52 | NoTypeofUndefinedRuleWalker.prototype.isUndefinedString = function (node) { 53 | if (node.kind === ts.SyntaxKind.StringLiteral) { 54 | if (node.text === 'undefined') { 55 | return true; 56 | } 57 | } 58 | return false; 59 | }; 60 | return NoTypeofUndefinedRuleWalker; 61 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 62 | //# sourceMappingURL=noTypeofUndefinedRule.js.map -------------------------------------------------------------------------------- /webpack.dev.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: ひまわり(dtysky) 3 | * Github: https://github.com/dtysky 4 | * Created: 2017/6/11 5 | */ 6 | const webpack = require('webpack'); 7 | const ExtractTextPlugin = require('extract-text-webpack-plugin'); 8 | const path = require('path'); 9 | 10 | module.exports = { 11 | entry: ['webpack-hot-middleware/client?path=http://localhost:4444/__webpack_hmr&reload=true'], 12 | output: { 13 | path: path.resolve(__dirname), 14 | filename: 'main.bundle.js', 15 | publicPath: '/' 16 | }, 17 | 18 | resolve: { 19 | // Add '.ts' and '.tsx' as resolvable extensions. 20 | extensions: [".ts", ".tsx", ".js"] 21 | }, 22 | 23 | module: { 24 | rules: [ 25 | // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'. 26 | { 27 | enforce: 'pre', 28 | test: /\.tsx?$/, 29 | use: [ 30 | { 31 | loader: 'react-hot-loader/webpack' 32 | }, 33 | { 34 | loader: "awesome-typescript-loader" 35 | }, 36 | { 37 | loader: 'tslint-loader', 38 | query: { 39 | configFile: path.resolve(__dirname, './tslintConfig.js') 40 | } 41 | } 42 | ], 43 | exclude: /node_modules/ 44 | }, 45 | 46 | // can't hot-load when use extract-text-webpack-plugin 47 | { 48 | test: /\.css/, 49 | use: [ 50 | { 51 | loader: 'style-loader' 52 | }, 53 | { 54 | loader: 'css-loader' 55 | }, 56 | { 57 | loader: 'postcss-loader' 58 | } 59 | ], 60 | exclude: /node_modules/ 61 | }, 62 | { 63 | test: /\.glsl$/, 64 | use: [ 65 | { 66 | loader: 'raw-loader' 67 | } 68 | ], 69 | exclude: /node_modules/ 70 | }, 71 | { 72 | test: /\.json$/, 73 | use: [ 74 | { 75 | loader: 'json-loader' 76 | } 77 | ], 78 | exclude: /node_modules/ 79 | }, 80 | { 81 | test: /\.(png|jpg|gif|svg|mp4)$/, 82 | use: { 83 | loader: 'url-loader', 84 | query: { 85 | limit: 10000, 86 | // emitFile: false 87 | // name: 'static/images/[name].[ext]' 88 | } 89 | } 90 | }, 91 | { 92 | test: /\.woff|\.woff2|.eot|\.ttf/, 93 | use: { 94 | loader: 'url-loader', 95 | query: { 96 | limit: 5000, 97 | // emitFile: false 98 | // name: 'static/font/[name].[ext]' 99 | } 100 | } 101 | } 102 | ] 103 | }, 104 | 105 | plugins: [ 106 | new webpack.HotModuleReplacementPlugin(), 107 | new webpack.ProvidePlugin({}) 108 | ] 109 | }; 110 | -------------------------------------------------------------------------------- /tslint-contrib/noFunctionConstructorWithStringArgsRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var AstUtils_1 = require("./utils/AstUtils"); 11 | var Rule = (function (_super) { 12 | __extends(Rule, _super); 13 | function Rule() { 14 | return _super.apply(this, arguments) || this; 15 | } 16 | Rule.prototype.apply = function (sourceFile) { 17 | var documentRegistry = ts.createDocumentRegistry(); 18 | var languageServiceHost = Lint.createLanguageServiceHost('file.ts', sourceFile.getFullText()); 19 | var languageService = ts.createLanguageService(languageServiceHost, documentRegistry); 20 | return this.applyWithWalker(new NoFunctionConstructorWithStringArgsWalker(sourceFile, this.getOptions(), languageService)); 21 | }; 22 | return Rule; 23 | }(Lint.Rules.AbstractRule)); 24 | Rule.metadata = { 25 | ruleName: 'no-function-constructor-with-string-args', 26 | type: 'maintainability', 27 | description: 'Do not use the version of the Function constructor that accepts a string argument to define the body of the function', 28 | options: null, 29 | optionsDescription: '', 30 | typescriptOnly: true, 31 | issueClass: 'SDL', 32 | issueType: 'Error', 33 | severity: 'Critical', 34 | level: 'Mandatory', 35 | group: 'Security', 36 | commonWeaknessEnumeration: '95, 676, 242, 116' 37 | }; 38 | Rule.FAILURE_STRING = 'forbidden: Function constructor with string arguments '; 39 | exports.Rule = Rule; 40 | var NoFunctionConstructorWithStringArgsWalker = (function (_super) { 41 | __extends(NoFunctionConstructorWithStringArgsWalker, _super); 42 | function NoFunctionConstructorWithStringArgsWalker(sourceFile, options, languageServices) { 43 | var _this = _super.call(this, sourceFile, options) || this; 44 | _this.languageService = languageServices; 45 | _this.typeChecker = _this.languageService.getProgram().getTypeChecker(); 46 | return _this; 47 | } 48 | NoFunctionConstructorWithStringArgsWalker.prototype.visitNewExpression = function (node) { 49 | var functionName = AstUtils_1.AstUtils.getFunctionName(node); 50 | if (functionName === 'Function') { 51 | if (node.arguments.length > 0) { 52 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); 53 | } 54 | } 55 | _super.prototype.visitNewExpression.call(this, node); 56 | }; 57 | return NoFunctionConstructorWithStringArgsWalker; 58 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 59 | //# sourceMappingURL=noFunctionConstructorWithStringArgsRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noBackboneGetSetOutsideModelRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var AstUtils_1 = require("./utils/AstUtils"); 11 | var Rule = (function (_super) { 12 | __extends(Rule, _super); 13 | function Rule() { 14 | return _super.apply(this, arguments) || this; 15 | } 16 | Rule.prototype.apply = function (sourceFile) { 17 | return this.applyWithWalker(new NoBackboneGetSetOutsideModelRuleWalker(sourceFile, this.getOptions())); 18 | }; 19 | return Rule; 20 | }(Lint.Rules.AbstractRule)); 21 | Rule.metadata = { 22 | ruleName: 'no-backbone-get-set-outside-model', 23 | type: 'maintainability', 24 | description: 'Avoid using `model.get(\'x\')` and `model.set(\'x\', value)` Backbone accessors outside of the owning model.', 25 | options: null, 26 | optionsDescription: '', 27 | typescriptOnly: true, 28 | issueClass: 'Non-SDL', 29 | issueType: 'Warning', 30 | severity: 'Important', 31 | level: 'Opportunity for Excellence', 32 | group: 'Correctness', 33 | commonWeaknessEnumeration: '398, 710' 34 | }; 35 | Rule.GET_FAILURE_STRING = 'Backbone get() called outside of owning model: '; 36 | Rule.SET_FAILURE_STRING = 'Backbone set() called outside of owning model: '; 37 | exports.Rule = Rule; 38 | var NoBackboneGetSetOutsideModelRuleWalker = (function (_super) { 39 | __extends(NoBackboneGetSetOutsideModelRuleWalker, _super); 40 | function NoBackboneGetSetOutsideModelRuleWalker() { 41 | return _super.apply(this, arguments) || this; 42 | } 43 | NoBackboneGetSetOutsideModelRuleWalker.prototype.visitCallExpression = function (node) { 44 | if (AstUtils_1.AstUtils.getFunctionTarget(node) !== 'this') { 45 | var functionName = AstUtils_1.AstUtils.getFunctionName(node); 46 | if (functionName === 'get' && node.arguments.length === 1 && node.arguments[0].kind === ts.SyntaxKind.StringLiteral) { 47 | var msg = Rule.GET_FAILURE_STRING + node.getText(); 48 | this.addFailure(this.createFailure(node.getStart(), node.getEnd(), msg)); 49 | } 50 | if (functionName === 'set' && node.arguments.length === 2 && node.arguments[0].kind === ts.SyntaxKind.StringLiteral) { 51 | var msg = Rule.SET_FAILURE_STRING + node.getText(); 52 | this.addFailure(this.createFailure(node.getStart(), node.getEnd(), msg)); 53 | } 54 | } 55 | _super.prototype.visitCallExpression.call(this, node); 56 | }; 57 | return NoBackboneGetSetOutsideModelRuleWalker; 58 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 59 | //# sourceMappingURL=noBackboneGetSetOutsideModelRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noUnnecessarySemicolonsRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | return this.applyWithWalker(new NoUnnecessarySemicolonsWalker(sourceFile, this.getOptions())); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.FAILURE_STRING = 'unnecessary semi-colon'; 21 | Rule.metadata = { 22 | ruleName: 'no-unnecessary-semicolons', 23 | type: 'maintainability', 24 | description: 'Remove unnecessary semicolons', 25 | options: null, 26 | optionsDescription: '', 27 | typescriptOnly: true, 28 | issueClass: 'Non-SDL', 29 | issueType: 'Warning', 30 | severity: 'Moderate', 31 | level: 'Opportunity for Excellence', 32 | group: 'Whitespace', 33 | commonWeaknessEnumeration: '398, 710' 34 | }; 35 | exports.Rule = Rule; 36 | var NoUnnecessarySemicolonsWalker = (function (_super) { 37 | __extends(NoUnnecessarySemicolonsWalker, _super); 38 | function NoUnnecessarySemicolonsWalker() { 39 | return _super.apply(this, arguments) || this; 40 | } 41 | NoUnnecessarySemicolonsWalker.prototype.visitNode = function (node) { 42 | if (node.kind === ts.SyntaxKind.EmptyStatement) { 43 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); 44 | } 45 | _super.prototype.visitNode.call(this, node); 46 | }; 47 | NoUnnecessarySemicolonsWalker.prototype.visitForStatement = function (node) { 48 | if (node.statement.kind === ts.SyntaxKind.EmptyStatement) { 49 | if (node.initializer) { 50 | this.visitNode(node.initializer); 51 | } 52 | if (node.condition) { 53 | this.visitNode(node.condition); 54 | } 55 | if (node.incrementor) { 56 | this.visitNode(node.incrementor); 57 | } 58 | } 59 | else { 60 | _super.prototype.visitForStatement.call(this, node); 61 | } 62 | }; 63 | NoUnnecessarySemicolonsWalker.prototype.visitWhileStatement = function (node) { 64 | if (node.statement.kind === ts.SyntaxKind.EmptyStatement) { 65 | this.visitNode(node.expression); 66 | } 67 | else { 68 | _super.prototype.visitWhileStatement.call(this, node); 69 | } 70 | }; 71 | return NoUnnecessarySemicolonsWalker; 72 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 73 | //# sourceMappingURL=noUnnecessarySemicolonsRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/possibleTimingAttackRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var Utils_1 = require("./utils/Utils"); 11 | var FAILURE_STRING = 'Possible timing attack detected. Direct comparison found: '; 12 | var SENSITIVE_VAR_NAME = /^(password|secret|api|apiKey|token|auth|pass|hash)$/im; 13 | var Rule = (function (_super) { 14 | __extends(Rule, _super); 15 | function Rule() { 16 | return _super.apply(this, arguments) || this; 17 | } 18 | Rule.prototype.apply = function (sourceFile) { 19 | return this.applyWithWalker(new PossibleTimingAttackRuleWalker(sourceFile, this.getOptions())); 20 | }; 21 | return Rule; 22 | }(Lint.Rules.AbstractRule)); 23 | Rule.metadata = { 24 | ruleName: 'possible-timing-attack', 25 | type: 'functionality', 26 | description: 'Avoid timing attacks by not making direct comaprisons to sensitive data', 27 | options: null, 28 | optionsDescription: '', 29 | typescriptOnly: true, 30 | issueClass: 'Non-SDL', 31 | issueType: 'Warning', 32 | severity: 'Moderate', 33 | level: 'Opportunity for Excellence', 34 | group: 'Security', 35 | commonWeaknessEnumeration: '710,749' 36 | }; 37 | exports.Rule = Rule; 38 | var PossibleTimingAttackRuleWalker = (function (_super) { 39 | __extends(PossibleTimingAttackRuleWalker, _super); 40 | function PossibleTimingAttackRuleWalker() { 41 | return _super.apply(this, arguments) || this; 42 | } 43 | PossibleTimingAttackRuleWalker.prototype.visitBinaryExpression = function (node) { 44 | if (node.operatorToken.kind === ts.SyntaxKind.EqualsEqualsToken 45 | || node.operatorToken.kind === ts.SyntaxKind.EqualsEqualsEqualsToken 46 | || node.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsToken 47 | || node.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsEqualsToken) { 48 | if ((SENSITIVE_VAR_NAME.test(node.left.getText()) || SENSITIVE_VAR_NAME.test(node.right.getText())) 49 | && node.left.getText() !== 'null' && node.right.getText() !== 'null' 50 | && node.left.getText() !== 'undefined' && node.right.getText() !== 'undefined') { 51 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), FAILURE_STRING + Utils_1.Utils.trimTo(node.getText(), 20))); 52 | } 53 | else { 54 | _super.prototype.visitBinaryExpression.call(this, node); 55 | } 56 | } 57 | else { 58 | _super.prototype.visitBinaryExpression.call(this, node); 59 | } 60 | }; 61 | return PossibleTimingAttackRuleWalker; 62 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 63 | //# sourceMappingURL=possibleTimingAttackRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noEmptyLineAfterOpeningBraceRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | return this.applyWithWalker(new NoEmptyLineAfterOpeningBraceWalker(sourceFile, this.getOptions())); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'no-empty-line-after-opening-brace', 22 | type: 'maintainability', 23 | description: 'Avoid an empty line after an opening brace', 24 | options: null, 25 | optionsDescription: '', 26 | typescriptOnly: true, 27 | issueClass: 'Ignored', 28 | issueType: 'Warning', 29 | severity: 'Low', 30 | level: 'Opportunity for Excellence', 31 | group: 'Whitespace', 32 | recommendation: 'false,', 33 | commonWeaknessEnumeration: '710' 34 | }; 35 | Rule.FAILURE_STRING = 'Opening brace cannot be followed by empty line'; 36 | exports.Rule = Rule; 37 | var NoEmptyLineAfterOpeningBraceWalker = (function (_super) { 38 | __extends(NoEmptyLineAfterOpeningBraceWalker, _super); 39 | function NoEmptyLineAfterOpeningBraceWalker(sourceFile, options) { 40 | var _this = _super.call(this, sourceFile, options) || this; 41 | _this.scanner = ts.createScanner(1, false, 0, sourceFile.text); 42 | return _this; 43 | } 44 | NoEmptyLineAfterOpeningBraceWalker.prototype.visitSourceFile = function (node) { 45 | this.scanAllTokens(node); 46 | _super.prototype.visitSourceFile.call(this, node); 47 | }; 48 | NoEmptyLineAfterOpeningBraceWalker.prototype.scanAllTokens = function (node) { 49 | var _this = this; 50 | this.scanner.setTextPos(0); 51 | var previous; 52 | var previousPrevious; 53 | Lint.scanAllTokens(this.scanner, function (scanner) { 54 | if (previousPrevious === ts.SyntaxKind.OpenBraceToken && 55 | previous === ts.SyntaxKind.NewLineTrivia && 56 | scanner.getToken() === ts.SyntaxKind.NewLineTrivia) { 57 | var leadingEmptyLineFailure = _this.createFailure(scanner.getStartPos(), 1, Rule.FAILURE_STRING); 58 | _this.addFailure(leadingEmptyLineFailure); 59 | } 60 | if (scanner.getToken() !== ts.SyntaxKind.WhitespaceTrivia) { 61 | previousPrevious = previous; 62 | previous = scanner.getToken(); 63 | } 64 | }); 65 | }; 66 | return NoEmptyLineAfterOpeningBraceWalker; 67 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 68 | //# sourceMappingURL=noEmptyLineAfterOpeningBraceRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noControlRegexRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | return this.applyWithWalker(new NoControlRegexRuleWalker(sourceFile, this.getOptions())); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'no-control-regex', 22 | type: 'maintainability', 23 | description: 'Do not use control characters in regular expressions', 24 | options: null, 25 | optionsDescription: '', 26 | typescriptOnly: true, 27 | issueClass: 'Non-SDL', 28 | issueType: 'Warning', 29 | severity: 'Important', 30 | level: 'Opportunity for Excellence', 31 | group: 'Correctness' 32 | }; 33 | Rule.FAILURE_STRING = 'Unexpected control character in regular expression'; 34 | exports.Rule = Rule; 35 | var NoControlRegexRuleWalker = (function (_super) { 36 | __extends(NoControlRegexRuleWalker, _super); 37 | function NoControlRegexRuleWalker() { 38 | return _super.apply(this, arguments) || this; 39 | } 40 | NoControlRegexRuleWalker.prototype.visitNewExpression = function (node) { 41 | this.validateCall(node); 42 | _super.prototype.visitNewExpression.call(this, node); 43 | }; 44 | NoControlRegexRuleWalker.prototype.visitCallExpression = function (node) { 45 | this.validateCall(node); 46 | _super.prototype.visitCallExpression.call(this, node); 47 | }; 48 | NoControlRegexRuleWalker.prototype.visitRegularExpressionLiteral = function (node) { 49 | if (/(\\x[0-1][0-9a-f])/.test(node.getText())) { 50 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); 51 | } 52 | _super.prototype.visitRegularExpressionLiteral.call(this, node); 53 | }; 54 | NoControlRegexRuleWalker.prototype.validateCall = function (expression) { 55 | if (expression.expression.getText() === 'RegExp') { 56 | if (expression.arguments.length > 0) { 57 | var arg1 = expression.arguments[0]; 58 | if (arg1.kind === ts.SyntaxKind.StringLiteral) { 59 | var regexpText = arg1.text; 60 | if (/[\x00-\x1f]/.test(regexpText)) { 61 | this.addFailure(this.createFailure(arg1.getStart(), arg1.getWidth(), Rule.FAILURE_STRING)); 62 | } 63 | } 64 | } 65 | } 66 | }; 67 | return NoControlRegexRuleWalker; 68 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 69 | //# sourceMappingURL=noControlRegexRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noFunctionExpressionRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var Lint = require("tslint"); 8 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 9 | var Rule = (function (_super) { 10 | __extends(Rule, _super); 11 | function Rule() { 12 | return _super.apply(this, arguments) || this; 13 | } 14 | Rule.prototype.apply = function (sourceFile) { 15 | return this.applyWithWalker(new NoFunctionExpressionRuleWalker(sourceFile, this.getOptions())); 16 | }; 17 | return Rule; 18 | }(Lint.Rules.AbstractRule)); 19 | Rule.metadata = { 20 | ruleName: 'no-function-expression', 21 | type: 'maintainability', 22 | description: 'Do not use function expressions; use arrow functions (lambdas) instead.', 23 | options: null, 24 | optionsDescription: '', 25 | typescriptOnly: true, 26 | issueClass: 'Non-SDL', 27 | issueType: 'Warning', 28 | severity: 'Important', 29 | level: 'Opportunity for Excellence', 30 | group: 'Clarity', 31 | commonWeaknessEnumeration: '398, 710' 32 | }; 33 | Rule.FAILURE_STRING = 'Use arrow function instead of function expression'; 34 | exports.Rule = Rule; 35 | var NoFunctionExpressionRuleWalker = (function (_super) { 36 | __extends(NoFunctionExpressionRuleWalker, _super); 37 | function NoFunctionExpressionRuleWalker() { 38 | return _super.apply(this, arguments) || this; 39 | } 40 | NoFunctionExpressionRuleWalker.prototype.visitFunctionExpression = function (node) { 41 | var walker = new SingleFunctionWalker(this.getSourceFile(), this.getOptions()); 42 | node.getChildren().forEach(function (node) { 43 | walker.walk(node); 44 | }); 45 | if (!walker.isAccessingThis) { 46 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); 47 | } 48 | _super.prototype.visitFunctionExpression.call(this, node); 49 | }; 50 | return NoFunctionExpressionRuleWalker; 51 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 52 | var SingleFunctionWalker = (function (_super) { 53 | __extends(SingleFunctionWalker, _super); 54 | function SingleFunctionWalker() { 55 | var _this = _super.apply(this, arguments) || this; 56 | _this.isAccessingThis = false; 57 | return _this; 58 | } 59 | SingleFunctionWalker.prototype.visitNode = function (node) { 60 | if (node.getText() === 'this') { 61 | this.isAccessingThis = true; 62 | } 63 | _super.prototype.visitNode.call(this, node); 64 | }; 65 | SingleFunctionWalker.prototype.visitFunctionExpression = function (node) { 66 | }; 67 | SingleFunctionWalker.prototype.visitArrowFunction = function (node) { 68 | }; 69 | return SingleFunctionWalker; 70 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 71 | //# sourceMappingURL=noFunctionExpressionRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noHttpStringRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var Utils_1 = require("./utils/Utils"); 11 | var Rule = (function (_super) { 12 | __extends(Rule, _super); 13 | function Rule() { 14 | return _super.apply(this, arguments) || this; 15 | } 16 | Rule.prototype.apply = function (sourceFile) { 17 | return this.applyWithWalker(new NoHttpStringWalker(sourceFile, this.getOptions())); 18 | }; 19 | return Rule; 20 | }(Lint.Rules.AbstractRule)); 21 | Rule.metadata = { 22 | ruleName: 'no-http-string', 23 | type: 'maintainability', 24 | description: 'Do not use strings that start with \'http:\'. URL strings should start with \'https:\'. ', 25 | options: null, 26 | optionsDescription: '', 27 | typescriptOnly: true, 28 | issueClass: 'SDL', 29 | issueType: 'Error', 30 | severity: 'Critical', 31 | level: 'Mandatory', 32 | group: 'Security', 33 | recommendation: '[true, "http://www.example.com/?.*", "http://www.examples.com/?.*"],', 34 | commonWeaknessEnumeration: '319' 35 | }; 36 | Rule.FAILURE_STRING = 'Forbidden http url in string: '; 37 | exports.Rule = Rule; 38 | var NoHttpStringWalker = (function (_super) { 39 | __extends(NoHttpStringWalker, _super); 40 | function NoHttpStringWalker() { 41 | return _super.apply(this, arguments) || this; 42 | } 43 | NoHttpStringWalker.prototype.visitNode = function (node) { 44 | if (node.kind === ts.SyntaxKind.StringLiteral) { 45 | var stringText = node.text; 46 | if (/.*http:.*/.test(stringText)) { 47 | if (!this.isSuppressed(stringText)) { 48 | var failureString = Rule.FAILURE_STRING + '\'' + stringText + '\''; 49 | var failure = this.createFailure(node.getStart(), node.getWidth(), failureString); 50 | this.addFailure(failure); 51 | } 52 | } 53 | } 54 | _super.prototype.visitNode.call(this, node); 55 | }; 56 | NoHttpStringWalker.prototype.isSuppressed = function (stringText) { 57 | var allExceptions = NoHttpStringWalker.getExceptions(this.getOptions()); 58 | return Utils_1.Utils.exists(allExceptions, function (exception) { 59 | return new RegExp(exception).test(stringText); 60 | }); 61 | }; 62 | NoHttpStringWalker.getExceptions = function (options) { 63 | if (options.ruleArguments instanceof Array) { 64 | return options.ruleArguments[0]; 65 | } 66 | if (options instanceof Array) { 67 | return options; 68 | } 69 | return null; 70 | }; 71 | return NoHttpStringWalker; 72 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 73 | //# sourceMappingURL=noHttpStringRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noCookiesRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | var documentRegistry = ts.createDocumentRegistry(); 17 | var languageServiceHost = Lint.createLanguageServiceHost('file.ts', sourceFile.getFullText()); 18 | var languageService = ts.createLanguageService(languageServiceHost, documentRegistry); 19 | return this.applyWithWalker(new NoCookiesWalker(sourceFile, this.getOptions(), languageService)); 20 | }; 21 | return Rule; 22 | }(Lint.Rules.AbstractRule)); 23 | Rule.metadata = { 24 | ruleName: 'no-cookies', 25 | type: 'maintainability', 26 | description: 'Do not use cookies', 27 | options: null, 28 | optionsDescription: '', 29 | typescriptOnly: true, 30 | issueClass: 'SDL', 31 | issueType: 'Error', 32 | severity: 'Critical', 33 | level: 'Mandatory', 34 | group: 'Security', 35 | commonWeaknessEnumeration: '315, 539, 565, 614' 36 | }; 37 | Rule.FAILURE_STRING = 'Forbidden call to document.cookie'; 38 | exports.Rule = Rule; 39 | var NoCookiesWalker = (function (_super) { 40 | __extends(NoCookiesWalker, _super); 41 | function NoCookiesWalker(sourceFile, options, languageService) { 42 | var _this = _super.call(this, sourceFile, options) || this; 43 | _this.languageService = languageService; 44 | _this.typeChecker = languageService.getProgram().getTypeChecker(); 45 | return _this; 46 | } 47 | NoCookiesWalker.prototype.visitPropertyAccessExpression = function (node) { 48 | var propertyName = node.name.text; 49 | if (propertyName === 'cookie') { 50 | var leftSide = node.expression; 51 | try { 52 | var leftSideType = this.typeChecker.getTypeAtLocation(leftSide); 53 | var typeAsString = this.typeChecker.typeToString(leftSideType); 54 | if (leftSideType.flags === ts.TypeFlags.Any || typeAsString === 'Document') { 55 | this.addFailure(this.createFailure(leftSide.getStart(), leftSide.getWidth(), Rule.FAILURE_STRING)); 56 | } 57 | } 58 | catch (e) { 59 | if (leftSide.getFullText().trim() === 'document') { 60 | this.addFailure(this.createFailure(leftSide.getStart(), leftSide.getWidth(), Rule.FAILURE_STRING)); 61 | } 62 | } 63 | } 64 | _super.prototype.visitPropertyAccessExpression.call(this, node); 65 | }; 66 | return NoCookiesWalker; 67 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 68 | //# sourceMappingURL=noCookiesRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/nonLiteralRequireRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var AstUtils_1 = require("./utils/AstUtils"); 11 | var Utils_1 = require("./utils/Utils"); 12 | var FAILURE_STRING = 'Non-literal (insecure) parameter passed to require(): '; 13 | var Rule = (function (_super) { 14 | __extends(Rule, _super); 15 | function Rule() { 16 | return _super.apply(this, arguments) || this; 17 | } 18 | Rule.prototype.apply = function (sourceFile) { 19 | return this.applyWithWalker(new NonLiteralRequireRuleWalker(sourceFile, this.getOptions())); 20 | }; 21 | return Rule; 22 | }(Lint.Rules.AbstractRule)); 23 | Rule.metadata = { 24 | ruleName: 'non-literal-require', 25 | type: 'functionality', 26 | description: 'Detect require includes that are not for string literals', 27 | options: null, 28 | optionsDescription: '', 29 | typescriptOnly: true, 30 | issueClass: 'SDL', 31 | issueType: 'Error', 32 | severity: 'Critical', 33 | level: 'Mandatory', 34 | group: 'Security', 35 | commonWeaknessEnumeration: '95,676' 36 | }; 37 | exports.Rule = Rule; 38 | var NonLiteralRequireRuleWalker = (function (_super) { 39 | __extends(NonLiteralRequireRuleWalker, _super); 40 | function NonLiteralRequireRuleWalker() { 41 | return _super.apply(this, arguments) || this; 42 | } 43 | NonLiteralRequireRuleWalker.prototype.visitCallExpression = function (node) { 44 | var _this = this; 45 | if (AstUtils_1.AstUtils.getFunctionName(node) === 'require' 46 | && AstUtils_1.AstUtils.getFunctionTarget(node) == null 47 | && node.arguments.length > 0) { 48 | if (node.arguments[0].kind === ts.SyntaxKind.ArrayLiteralExpression) { 49 | var arrayExp = node.arguments[0]; 50 | arrayExp.elements.forEach(function (initExpression) { 51 | if (initExpression.kind !== ts.SyntaxKind.StringLiteral) { 52 | _this.fail(initExpression); 53 | } 54 | }); 55 | } 56 | else if (node.arguments[0].kind !== ts.SyntaxKind.StringLiteral) { 57 | this.fail(node.arguments[0]); 58 | } 59 | } 60 | _super.prototype.visitCallExpression.call(this, node); 61 | }; 62 | NonLiteralRequireRuleWalker.prototype.fail = function (expression) { 63 | var start = expression.getStart(); 64 | var width = expression.getWidth(); 65 | var message = FAILURE_STRING + Utils_1.Utils.trimTo(expression.getText(), 25); 66 | this.addFailure(this.createFailure(start, width, message)); 67 | }; 68 | return NonLiteralRequireRuleWalker; 69 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 70 | //# sourceMappingURL=nonLiteralRequireRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noRelativeImportsRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var FAILURE_STRING_EXT = 'External module is being loaded from a relative path. Please use an absolute path: '; 11 | var FAILURE_STRING_IMPORT = 'Imported module is being loaded from a relative path. Please use an absolute path: '; 12 | var Rule = (function (_super) { 13 | __extends(Rule, _super); 14 | function Rule() { 15 | return _super.apply(this, arguments) || this; 16 | } 17 | Rule.prototype.apply = function (sourceFile) { 18 | return this.applyWithWalker(new NoRelativeImportsRuleWalker(sourceFile, this.getOptions())); 19 | }; 20 | return Rule; 21 | }(Lint.Rules.AbstractRule)); 22 | Rule.metadata = { 23 | ruleName: 'no-relative-imports', 24 | type: 'maintainability', 25 | description: 'Do not use relative paths when importing external modules or ES6 import declarations', 26 | options: null, 27 | optionsDescription: '', 28 | typescriptOnly: true, 29 | issueClass: 'Ignored', 30 | issueType: 'Warning', 31 | severity: 'Low', 32 | level: 'Opportunity for Excellence', 33 | group: 'Clarity', 34 | commonWeaknessEnumeration: '710' 35 | }; 36 | exports.Rule = Rule; 37 | var NoRelativeImportsRuleWalker = (function (_super) { 38 | __extends(NoRelativeImportsRuleWalker, _super); 39 | function NoRelativeImportsRuleWalker() { 40 | return _super.apply(this, arguments) || this; 41 | } 42 | NoRelativeImportsRuleWalker.prototype.visitNode = function (node) { 43 | if (node.kind === ts.SyntaxKind.ExternalModuleReference) { 44 | var moduleExpression = node.expression; 45 | if (!this.isModuleExpressionValid(moduleExpression)) { 46 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), FAILURE_STRING_EXT + node.getText())); 47 | } 48 | } 49 | else if (node.kind === ts.SyntaxKind.ImportDeclaration) { 50 | var moduleExpression = node.moduleSpecifier; 51 | if (!this.isModuleExpressionValid(moduleExpression)) { 52 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), FAILURE_STRING_IMPORT + node.getText())); 53 | } 54 | } 55 | _super.prototype.visitNode.call(this, node); 56 | }; 57 | NoRelativeImportsRuleWalker.prototype.isModuleExpressionValid = function (expression) { 58 | if (expression.kind === ts.SyntaxKind.StringLiteral) { 59 | var moduleName = expression; 60 | if (moduleName.text[0] === '.') { 61 | return false; 62 | } 63 | } 64 | return true; 65 | }; 66 | return NoRelativeImportsRuleWalker; 67 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 68 | //# sourceMappingURL=noRelativeImportsRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/preferArrayLiteralRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var Lint = require("tslint"); 8 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 9 | var AstUtils_1 = require("./utils/AstUtils"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | return this.applyWithWalker(new NoGenericArrayWalker(sourceFile, this.getOptions())); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'prefer-array-literal', 22 | type: 'maintainability', 23 | description: 'Use array literal syntax when declaring or instantiating array types.', 24 | options: null, 25 | optionsDescription: '', 26 | typescriptOnly: true, 27 | issueClass: 'Non-SDL', 28 | issueType: 'Warning', 29 | severity: 'Moderate', 30 | level: 'Opportunity for Excellence', 31 | group: 'Clarity', 32 | commonWeaknessEnumeration: '398, 710' 33 | }; 34 | Rule.GENERICS_FAILURE_STRING = 'Replace generic-typed Array with array literal: '; 35 | Rule.CONSTRUCTOR_FAILURE_STRING = 'Replace Array constructor with an array literal: '; 36 | exports.Rule = Rule; 37 | var NoGenericArrayWalker = (function (_super) { 38 | __extends(NoGenericArrayWalker, _super); 39 | function NoGenericArrayWalker(sourceFile, options) { 40 | var _this = _super.call(this, sourceFile, options) || this; 41 | _this.allowTypeParameters = false; 42 | _this.getOptions().forEach(function (opt) { 43 | if (typeof (opt) === 'object') { 44 | _this.allowTypeParameters = opt['allow-type-parameters'] === true; 45 | } 46 | }); 47 | return _this; 48 | } 49 | NoGenericArrayWalker.prototype.visitTypeReference = function (node) { 50 | if (this.allowTypeParameters === false) { 51 | if (node.typeName.text === 'Array') { 52 | var failureString = Rule.GENERICS_FAILURE_STRING + node.getText(); 53 | var failure = this.createFailure(node.getStart(), node.getWidth(), failureString); 54 | this.addFailure(failure); 55 | } 56 | } 57 | _super.prototype.visitTypeReference.call(this, node); 58 | }; 59 | NoGenericArrayWalker.prototype.visitNewExpression = function (node) { 60 | var functionName = AstUtils_1.AstUtils.getFunctionName(node); 61 | if (functionName === 'Array') { 62 | var failureString = Rule.CONSTRUCTOR_FAILURE_STRING + node.getText(); 63 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), failureString)); 64 | } 65 | _super.prototype.visitNewExpression.call(this, node); 66 | }; 67 | return NoGenericArrayWalker; 68 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 69 | //# sourceMappingURL=preferArrayLiteralRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noInnerHtmlRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 10 | var AstUtils_1 = require("./utils/AstUtils"); 11 | var FAILURE_INNER = 'Writing a string to the innerHTML property is insecure: '; 12 | var FAILURE_OUTER = 'Writing a string to the outerHTML property is insecure: '; 13 | var FAILURE_JQUERY = 'Using the html() function to write a string to innerHTML is insecure: '; 14 | var Rule = (function (_super) { 15 | __extends(Rule, _super); 16 | function Rule() { 17 | return _super.apply(this, arguments) || this; 18 | } 19 | Rule.prototype.apply = function (sourceFile) { 20 | return this.applyWithWalker(new NoInnerHtmlRuleWalker(sourceFile, this.getOptions())); 21 | }; 22 | return Rule; 23 | }(Lint.Rules.AbstractRule)); 24 | Rule.metadata = { 25 | ruleName: 'no-inner-html', 26 | type: 'maintainability', 27 | description: 'Do not write values to innerHTML, outerHTML, or set HTML using the JQuery html() function.', 28 | options: null, 29 | optionsDescription: '', 30 | typescriptOnly: true, 31 | issueClass: 'SDL', 32 | issueType: 'Error', 33 | severity: 'Critical', 34 | level: 'Mandatory', 35 | group: 'Security', 36 | commonWeaknessEnumeration: '79, 85, 710' 37 | }; 38 | exports.Rule = Rule; 39 | var NoInnerHtmlRuleWalker = (function (_super) { 40 | __extends(NoInnerHtmlRuleWalker, _super); 41 | function NoInnerHtmlRuleWalker() { 42 | return _super.apply(this, arguments) || this; 43 | } 44 | NoInnerHtmlRuleWalker.prototype.visitBinaryExpression = function (node) { 45 | if (node.operatorToken.kind === ts.SyntaxKind.EqualsToken) { 46 | if (node.left.kind === ts.SyntaxKind.PropertyAccessExpression) { 47 | var propAccess = node.left; 48 | var propName = propAccess.name.text; 49 | if (propName === 'innerHTML') { 50 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), FAILURE_INNER + node.getText())); 51 | } 52 | else if (propName === 'outerHTML') { 53 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), FAILURE_OUTER + node.getText())); 54 | } 55 | } 56 | } 57 | _super.prototype.visitBinaryExpression.call(this, node); 58 | }; 59 | NoInnerHtmlRuleWalker.prototype.visitCallExpression = function (node) { 60 | var functionName = AstUtils_1.AstUtils.getFunctionName(node); 61 | if (functionName === 'html') { 62 | if (node.arguments.length > 0) { 63 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), FAILURE_JQUERY + node.getText())); 64 | } 65 | } 66 | _super.prototype.visitCallExpression.call(this, node); 67 | }; 68 | return NoInnerHtmlRuleWalker; 69 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 70 | //# sourceMappingURL=noInnerHtmlRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/reactA11yEventHasRoleRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var JsxAttribute_1 = require("./utils/JsxAttribute"); 10 | var getImplicitRole_1 = require("./utils/getImplicitRole"); 11 | var DOM_SCHEMA = require('./utils/attributes/domSchema.json'); 12 | var FAILURE_STRING = 'Elements with event handlers must have role attribute.'; 13 | var ROLE_STRING = 'role'; 14 | var TARGET_EVENTS = ['click', 'keyup', 'keydown', 'keypress', 'mousedown', 'mouseup', 15 | 'mousemove', 'mouseout', 'mouseover', 'onclick', 'onkeyup', 'onkeydown', 'onkeypress', 'onmousedown', 16 | 'onmouseup', 'onmousemove', 'onmouseout', 'onmouseover']; 17 | var Rule = (function (_super) { 18 | __extends(Rule, _super); 19 | function Rule() { 20 | return _super.apply(this, arguments) || this; 21 | } 22 | Rule.prototype.apply = function (sourceFile) { 23 | return sourceFile.languageVariant === ts.LanguageVariant.JSX 24 | ? this.applyWithWalker(new ReactA11yEventHasRoleWalker(sourceFile, this.getOptions())) 25 | : []; 26 | }; 27 | return Rule; 28 | }(Lint.Rules.AbstractRule)); 29 | Rule.metadata = { 30 | ruleName: 'react-a11y-event-has-role', 31 | type: 'maintainability', 32 | description: 'Elements with event handlers must have role attribute.', 33 | options: null, 34 | optionsDescription: '', 35 | typescriptOnly: true, 36 | issueClass: 'Non-SDL', 37 | issueType: 'Warning', 38 | severity: 'Important', 39 | level: 'Opportunity for Excellence', 40 | group: 'Accessibility' 41 | }; 42 | exports.Rule = Rule; 43 | var ReactA11yEventHasRoleWalker = (function (_super) { 44 | __extends(ReactA11yEventHasRoleWalker, _super); 45 | function ReactA11yEventHasRoleWalker() { 46 | return _super.apply(this, arguments) || this; 47 | } 48 | ReactA11yEventHasRoleWalker.prototype.visitJsxElement = function (node) { 49 | this.checkJsxOpeningElement(node.openingElement); 50 | _super.prototype.visitJsxElement.call(this, node); 51 | }; 52 | ReactA11yEventHasRoleWalker.prototype.visitJsxSelfClosingElement = function (node) { 53 | this.checkJsxOpeningElement(node); 54 | _super.prototype.visitJsxSelfClosingElement.call(this, node); 55 | }; 56 | ReactA11yEventHasRoleWalker.prototype.checkJsxOpeningElement = function (node) { 57 | var tagName = node.tagName.getText(); 58 | if (!DOM_SCHEMA[tagName]) { 59 | return; 60 | } 61 | var attributes = JsxAttribute_1.getJsxAttributesFromJsxElement(node); 62 | var events = TARGET_EVENTS.filter(function (eventName) { return !!attributes[eventName]; }); 63 | var hasAriaRole = !!attributes[ROLE_STRING] || !!getImplicitRole_1.getImplicitRole(node); 64 | if (events.length > 0 && !hasAriaRole) { 65 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), FAILURE_STRING)); 66 | } 67 | }; 68 | return ReactA11yEventHasRoleWalker; 69 | }(Lint.RuleWalker)); 70 | //# sourceMappingURL=reactA11yEventHasRoleRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noMissingVisibilityModifiersRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var Lint = require("tslint"); 8 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 9 | var AstUtils_1 = require("./utils/AstUtils"); 10 | var Rule = (function (_super) { 11 | __extends(Rule, _super); 12 | function Rule() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | Rule.prototype.apply = function (sourceFile) { 16 | return this.applyWithWalker(new MissingVisibilityModifierWalker(sourceFile, this.getOptions())); 17 | }; 18 | return Rule; 19 | }(Lint.Rules.AbstractRule)); 20 | Rule.metadata = { 21 | ruleName: 'no-missing-visibility-modifiers', 22 | type: 'maintainability', 23 | description: 'Deprecated - This rule is in the TSLint product as `member-access`', 24 | options: null, 25 | optionsDescription: '', 26 | typescriptOnly: true, 27 | issueClass: 'Ignored', 28 | issueType: 'Warning', 29 | severity: 'Low', 30 | level: 'Opportunity for Excellence', 31 | group: 'Deprecated', 32 | recommendation: 'false, // use tslint member-access rule instead', 33 | commonWeaknessEnumeration: '398, 710' 34 | }; 35 | exports.Rule = Rule; 36 | var MissingVisibilityModifierWalker = (function (_super) { 37 | __extends(MissingVisibilityModifierWalker, _super); 38 | function MissingVisibilityModifierWalker() { 39 | return _super.apply(this, arguments) || this; 40 | } 41 | MissingVisibilityModifierWalker.prototype.visitPropertyDeclaration = function (node) { 42 | if (this.isMissingVisibilityModifier(node)) { 43 | var failureString = 'Field missing visibility modifier: ' + this.getFailureCodeSnippet(node); 44 | var failure = this.createFailure(node.getStart(), node.getWidth(), failureString); 45 | this.addFailure(failure); 46 | } 47 | _super.prototype.visitPropertyDeclaration.call(this, node); 48 | }; 49 | MissingVisibilityModifierWalker.prototype.visitMethodDeclaration = function (node) { 50 | if (this.isMissingVisibilityModifier(node)) { 51 | var failureString = 'Method missing visibility modifier: ' + this.getFailureCodeSnippet(node); 52 | var failure = this.createFailure(node.getStart(), node.getWidth(), failureString); 53 | this.addFailure(failure); 54 | } 55 | _super.prototype.visitMethodDeclaration.call(this, node); 56 | }; 57 | MissingVisibilityModifierWalker.prototype.isMissingVisibilityModifier = function (node) { 58 | return !(AstUtils_1.AstUtils.isPrivate(node) || AstUtils_1.AstUtils.isProtected(node) || AstUtils_1.AstUtils.isPublic(node)); 59 | }; 60 | MissingVisibilityModifierWalker.prototype.getFailureCodeSnippet = function (node) { 61 | var message = node.getText(); 62 | if (message.indexOf('\n') > 0) { 63 | return message.substr(0, message.indexOf('\n')); 64 | } 65 | return message; 66 | }; 67 | return MissingVisibilityModifierWalker; 68 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 69 | //# sourceMappingURL=noMissingVisibilityModifiersRule.js.map -------------------------------------------------------------------------------- /src/ImageChecker.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright(c) dtysky 3 | * Created: 2017/6/11 4 | * Description: 5 | */ 6 | import { 7 | TFile, TImageConstraintKey, IFileInfo, CheckError, ICheckResponse 8 | } from './types'; 9 | 10 | export const checkImage: ( 11 | file: TFile, 12 | maxBytesPerPixel: number, 13 | maxSize: number, 14 | maxWidth?: number 15 | ) => Promise 16 | = ( 17 | file: TFile, 18 | maxBytesPerPixel: number, 19 | maxSize: number, 20 | maxWidth?: number 21 | ) => { 22 | return new Promise((resolve, reject) => { 23 | const image = new Image(); 24 | image.onload = () => { 25 | URL.revokeObjectURL(image.src); 26 | const width = image.width; 27 | const height = image.height; 28 | const size = width * height; 29 | 30 | const info: IFileInfo = {type: file.type, width, height, size}; 31 | 32 | if (maxWidth && width > maxWidth) { 33 | return reject({ 34 | error: new CheckError({ 35 | name: 'width', 36 | currentValue: width, 37 | limitValue: maxWidth, 38 | message: `The max width of image is ${maxWidth},current is ${width}` 39 | }), 40 | info, 41 | file 42 | }); 43 | } 44 | if (maxSize && size > maxSize) { 45 | return reject({ 46 | error: new CheckError({ 47 | name: 'size', 48 | currentValue: size, 49 | limitValue: maxSize, 50 | message: `The max size of image is ${maxSize},current is ${width * height}` 51 | }), 52 | info, 53 | file 54 | }); 55 | } 56 | 57 | const maxKB = ~~(maxBytesPerPixel * size / 1024) + 1; 58 | 59 | if (maxSize && maxBytesPerPixel && file.size > maxKB * 1024) { 60 | return reject({ 61 | error: new CheckError({ 62 | name: 'bytes', 63 | currentValue: file.size, 64 | limitValue: maxKB * 1024, 65 | message: `In current size ${width} x ${height},image should be less than ${maxKB}KB` 66 | }), 67 | info, 68 | file 69 | }); 70 | } 71 | return resolve({file, info}); 72 | }; 73 | image.onerror = () => { 74 | URL.revokeObjectURL(image.src); 75 | return reject({ 76 | error: new CheckError({ 77 | name: 'unknown', 78 | currentValue: 'unknown', 79 | limitValue: 'image', 80 | message: `Please upload the real image that could be open in the browser` 81 | }), 82 | info: {type: 'unknown'}, 83 | file 84 | }); 85 | }; 86 | image.src = URL.createObjectURL(file); 87 | }); 88 | } 89 | 90 | export class ImageChecker { 91 | private maxBytesPerPixel = 0; 92 | private maxSize = 0; 93 | private maxWidth = 0; 94 | 95 | constructor(maxBytesPerPixel: number, maxSize: number, maxWidth?: number) { 96 | this.maxBytesPerPixel = maxBytesPerPixel; 97 | this.maxSize = maxSize; 98 | if (maxWidth) { 99 | this.maxWidth = maxWidth; 100 | } 101 | } 102 | 103 | public setAttr = (key: TImageConstraintKey, value: number) => { 104 | this[key] = value; 105 | } 106 | 107 | public check = (file: TFile) => { 108 | return checkImage(file, this.maxBytesPerPixel, this.maxSize, this.maxWidth); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /tslint-contrib/reactA11yImageButtonHasAltRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var JsxAttribute_1 = require("./utils/JsxAttribute"); 10 | var NO_ALT_ATTRIBUTE_FAILURE_STRING = 'Inputs element with type="image" must have alt attribute.'; 11 | var EMPTY_ALT_ATTRIBUTE_FAILURE_STRING = 'Inputs element with type="image" must have non-empty alt attribute.'; 12 | var TYPE_STRING = 'type'; 13 | var ALT_STRING = 'alt'; 14 | var Rule = (function (_super) { 15 | __extends(Rule, _super); 16 | function Rule() { 17 | return _super.apply(this, arguments) || this; 18 | } 19 | Rule.prototype.apply = function (sourceFile) { 20 | return sourceFile.languageVariant === ts.LanguageVariant.JSX 21 | ? this.applyWithWalker(new ReactA11yImageButtonHasAltWalker(sourceFile, this.getOptions())) 22 | : []; 23 | }; 24 | return Rule; 25 | }(Lint.Rules.AbstractRule)); 26 | Rule.metadata = { 27 | ruleName: 'react-a11y-image-button-has-alt', 28 | type: 'maintainability', 29 | description: 'Enforce that inputs element with type="image" must have alt attribute.', 30 | options: null, 31 | optionsDescription: '', 32 | typescriptOnly: true, 33 | issueClass: 'Non-SDL', 34 | issueType: 'Warning', 35 | severity: 'Important', 36 | level: 'Opportunity for Excellence', 37 | group: 'Accessibility' 38 | }; 39 | exports.Rule = Rule; 40 | var ReactA11yImageButtonHasAltWalker = (function (_super) { 41 | __extends(ReactA11yImageButtonHasAltWalker, _super); 42 | function ReactA11yImageButtonHasAltWalker() { 43 | return _super.apply(this, arguments) || this; 44 | } 45 | ReactA11yImageButtonHasAltWalker.prototype.visitJsxElement = function (node) { 46 | this.validateOpeningElement(node.openingElement); 47 | _super.prototype.visitJsxElement.call(this, node); 48 | }; 49 | ReactA11yImageButtonHasAltWalker.prototype.visitJsxSelfClosingElement = function (node) { 50 | this.validateOpeningElement(node); 51 | _super.prototype.visitJsxSelfClosingElement.call(this, node); 52 | }; 53 | ReactA11yImageButtonHasAltWalker.prototype.validateOpeningElement = function (node) { 54 | var tagName = node.tagName.getText(); 55 | if (tagName !== 'input') { 56 | return; 57 | } 58 | var attributes = JsxAttribute_1.getJsxAttributesFromJsxElement(node); 59 | var typeAttribute = attributes[TYPE_STRING]; 60 | if (!typeAttribute || JsxAttribute_1.getStringLiteral(typeAttribute).toLowerCase() !== 'image') { 61 | return; 62 | } 63 | var altAttribute = attributes[ALT_STRING]; 64 | if (!altAttribute) { 65 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), NO_ALT_ATTRIBUTE_FAILURE_STRING)); 66 | } 67 | else if (JsxAttribute_1.isEmpty(altAttribute) || !JsxAttribute_1.getStringLiteral(altAttribute)) { 68 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), EMPTY_ALT_ATTRIBUTE_FAILURE_STRING)); 69 | } 70 | }; 71 | return ReactA11yImageButtonHasAltWalker; 72 | }(Lint.RuleWalker)); 73 | //# sourceMappingURL=reactA11yImageButtonHasAltRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/reactA11yRoleRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var JsxAttribute_1 = require("./utils/JsxAttribute"); 10 | var ROLE_SCHEMA = require('./utils/attributes/roleSchema.json'); 11 | var ROLES = ROLE_SCHEMA.roles; 12 | var VALID_ROLES = Object.keys(ROLES).filter(function (role) { return ROLES[role].isAbstract === false; }); 13 | function getFailureStringUndefinedRole() { 14 | return '\'role\' attribute empty. Either select a role from https://www.w3.org/TR/wai-aria/roles#role_definitions, ' + 15 | 'or simply remove this attribute'; 16 | } 17 | exports.getFailureStringUndefinedRole = getFailureStringUndefinedRole; 18 | function getFailureStringInvalidRole(invalidRoleName) { 19 | return "Invalid role attribute value '" + invalidRoleName + "', elements with ARIA roles must use a valid, non-abstract ARIA role. A reference to role definitions can be found at https://www.w3.org/TR/wai-aria/roles#role_definitions."; 20 | } 21 | exports.getFailureStringInvalidRole = getFailureStringInvalidRole; 22 | var Rule = (function (_super) { 23 | __extends(Rule, _super); 24 | function Rule() { 25 | return _super.apply(this, arguments) || this; 26 | } 27 | Rule.prototype.apply = function (sourceFile) { 28 | return sourceFile.languageVariant === ts.LanguageVariant.JSX 29 | ? this.applyWithWalker(new A11yRoleRuleWalker(sourceFile, this.getOptions())) 30 | : []; 31 | }; 32 | return Rule; 33 | }(Lint.Rules.AbstractRule)); 34 | Rule.metadata = { 35 | ruleName: 'react-a11y-role', 36 | type: 'maintainability', 37 | description: 'Elements with aria roles must use a **valid**, **non-abstract** aria role.', 38 | options: null, 39 | optionsDescription: '', 40 | typescriptOnly: true, 41 | issueClass: 'Non-SDL', 42 | issueType: 'Warning', 43 | severity: 'Important', 44 | level: 'Opportunity for Excellence', 45 | group: 'Accessibility' 46 | }; 47 | exports.Rule = Rule; 48 | var A11yRoleRuleWalker = (function (_super) { 49 | __extends(A11yRoleRuleWalker, _super); 50 | function A11yRoleRuleWalker() { 51 | return _super.apply(this, arguments) || this; 52 | } 53 | A11yRoleRuleWalker.prototype.visitJsxAttribute = function (node) { 54 | var name = JsxAttribute_1.getPropName(node); 55 | if (!name || name.toLowerCase() !== 'role') { 56 | return; 57 | } 58 | var roleValue = JsxAttribute_1.getStringLiteral(node); 59 | if (roleValue) { 60 | var normalizedValues = roleValue.toLowerCase().split(' '); 61 | if (normalizedValues.some(function (value) { return value && VALID_ROLES.indexOf(value) === -1; })) { 62 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), getFailureStringInvalidRole(roleValue))); 63 | } 64 | } 65 | else if (roleValue === '' || JsxAttribute_1.isEmpty(node)) { 66 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), getFailureStringUndefinedRole())); 67 | } 68 | _super.prototype.visitJsxAttribute.call(this, node); 69 | }; 70 | return A11yRoleRuleWalker; 71 | }(Lint.RuleWalker)); 72 | //# sourceMappingURL=reactA11yRoleRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/implicitRoles/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var a_1 = require("./a"); 3 | exports.a = a_1.a; 4 | var area_1 = require("./area"); 5 | exports.area = area_1.area; 6 | var article_1 = require("./article"); 7 | exports.article = article_1.article; 8 | var aside_1 = require("./aside"); 9 | exports.aside = aside_1.aside; 10 | var body_1 = require("./body"); 11 | exports.body = body_1.body; 12 | var button_1 = require("./button"); 13 | exports.button = button_1.button; 14 | var datalist_1 = require("./datalist"); 15 | exports.datalist = datalist_1.datalist; 16 | var dd_1 = require("./dd"); 17 | exports.dd = dd_1.dd; 18 | var details_1 = require("./details"); 19 | exports.details = details_1.details; 20 | var dialog_1 = require("./dialog"); 21 | exports.dialog = dialog_1.dialog; 22 | var dl_1 = require("./dl"); 23 | exports.dl = dl_1.dl; 24 | var dt_1 = require("./dt"); 25 | exports.dt = dt_1.dt; 26 | var footer_1 = require("./footer"); 27 | exports.footer = footer_1.footer; 28 | var form_1 = require("./form"); 29 | exports.form = form_1.form; 30 | var h1_1 = require("./h1"); 31 | exports.h1 = h1_1.h1; 32 | var h2_1 = require("./h2"); 33 | exports.h2 = h2_1.h2; 34 | var h3_1 = require("./h3"); 35 | exports.h3 = h3_1.h3; 36 | var h4_1 = require("./h4"); 37 | exports.h4 = h4_1.h4; 38 | var h5_1 = require("./h5"); 39 | exports.h5 = h5_1.h5; 40 | var h6_1 = require("./h6"); 41 | exports.h6 = h6_1.h6; 42 | var header_1 = require("./header"); 43 | exports.header = header_1.header; 44 | var hr_1 = require("./hr"); 45 | exports.hr = hr_1.hr; 46 | var img_1 = require("./img"); 47 | exports.img = img_1.img; 48 | var input_1 = require("./input"); 49 | exports.input = input_1.input; 50 | var li_1 = require("./li"); 51 | exports.li = li_1.li; 52 | var link_1 = require("./link"); 53 | exports.link = link_1.link; 54 | var main_1 = require("./main"); 55 | exports.main = main_1.main; 56 | var math_1 = require("./math"); 57 | exports.math = math_1.math; 58 | var menu_1 = require("./menu"); 59 | exports.menu = menu_1.menu; 60 | var menuitem_1 = require("./menuitem"); 61 | exports.menuitem = menuitem_1.menuitem; 62 | var meter_1 = require("./meter"); 63 | exports.meter = meter_1.meter; 64 | var nav_1 = require("./nav"); 65 | exports.nav = nav_1.nav; 66 | var ol_1 = require("./ol"); 67 | exports.ol = ol_1.ol; 68 | var optgroup_1 = require("./optgroup"); 69 | exports.optgroup = optgroup_1.optgroup; 70 | var option_1 = require("./option"); 71 | exports.option = option_1.option; 72 | var output_1 = require("./output"); 73 | exports.output = output_1.output; 74 | var progress_1 = require("./progress"); 75 | exports.progress = progress_1.progress; 76 | var section_1 = require("./section"); 77 | exports.section = section_1.section; 78 | var select_1 = require("./select"); 79 | exports.select = select_1.select; 80 | var summary_1 = require("./summary"); 81 | exports.summary = summary_1.summary; 82 | var table_1 = require("./table"); 83 | exports.table = table_1.table; 84 | var tbody_1 = require("./tbody"); 85 | exports.tbody = tbody_1.tbody; 86 | var td_1 = require("./td"); 87 | exports.td = td_1.td; 88 | var textarea_1 = require("./textarea"); 89 | exports.textarea = textarea_1.textarea; 90 | var tfoot_1 = require("./tfoot"); 91 | exports.tfoot = tfoot_1.tfoot; 92 | var th_1 = require("./th"); 93 | exports.th = th_1.th; 94 | var thead_1 = require("./thead"); 95 | exports.thead = thead_1.thead; 96 | var tr_1 = require("./tr"); 97 | exports.tr = tr_1.tr; 98 | var ul_1 = require("./ul"); 99 | exports.ul = ul_1.ul; 100 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /tslint-contrib/noDuplicateParameterNamesRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var Lint = require("tslint"); 8 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 9 | var Rule = (function (_super) { 10 | __extends(Rule, _super); 11 | function Rule() { 12 | return _super.apply(this, arguments) || this; 13 | } 14 | Rule.prototype.apply = function (sourceFile) { 15 | return this.applyWithWalker(new NoDuplicateParameterNamesWalker(sourceFile, this.getOptions())); 16 | }; 17 | return Rule; 18 | }(Lint.Rules.AbstractRule)); 19 | Rule.metadata = { 20 | ruleName: 'no-duplicate-parameter-names', 21 | type: 'maintainability', 22 | description: 'Deprecated - This rule is now enforced by the TypeScript compiler', 23 | options: null, 24 | optionsDescription: '', 25 | typescriptOnly: true, 26 | issueClass: 'Ignored', 27 | issueType: 'Warning', 28 | severity: 'Low', 29 | level: 'Opportunity for Excellence', 30 | group: 'Deprecated', 31 | recommendation: 'false, // now supported by TypeScript compiler' 32 | }; 33 | Rule.FAILURE_STRING = 'Duplicate parameter name: '; 34 | exports.Rule = Rule; 35 | var NoDuplicateParameterNamesWalker = (function (_super) { 36 | __extends(NoDuplicateParameterNamesWalker, _super); 37 | function NoDuplicateParameterNamesWalker() { 38 | return _super.apply(this, arguments) || this; 39 | } 40 | NoDuplicateParameterNamesWalker.prototype.visitMethodDeclaration = function (node) { 41 | this.validateParameterNames(node); 42 | _super.prototype.visitMethodDeclaration.call(this, node); 43 | }; 44 | NoDuplicateParameterNamesWalker.prototype.visitConstructorDeclaration = function (node) { 45 | this.validateParameterNames(node); 46 | _super.prototype.visitConstructorDeclaration.call(this, node); 47 | }; 48 | NoDuplicateParameterNamesWalker.prototype.visitArrowFunction = function (node) { 49 | this.validateParameterNames(node); 50 | _super.prototype.visitArrowFunction.call(this, node); 51 | }; 52 | NoDuplicateParameterNamesWalker.prototype.visitFunctionDeclaration = function (node) { 53 | this.validateParameterNames(node); 54 | _super.prototype.visitFunctionDeclaration.call(this, node); 55 | }; 56 | NoDuplicateParameterNamesWalker.prototype.visitFunctionExpression = function (node) { 57 | this.validateParameterNames(node); 58 | _super.prototype.visitFunctionExpression.call(this, node); 59 | }; 60 | NoDuplicateParameterNamesWalker.prototype.validateParameterNames = function (node) { 61 | var _this = this; 62 | var seenNames = {}; 63 | node.parameters.forEach(function (parameter) { 64 | var parameterName = parameter.name.text; 65 | if (parameterName != null) { 66 | if (seenNames[parameterName]) { 67 | _this.addFailure(_this.createFailure(parameter.name.getStart(), parameterName.length, Rule.FAILURE_STRING + '\'' + parameterName + '\'')); 68 | } 69 | else { 70 | seenNames[parameterName] = true; 71 | } 72 | } 73 | }); 74 | }; 75 | return NoDuplicateParameterNamesWalker; 76 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 77 | //# sourceMappingURL=noDuplicateParameterNamesRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/noSingleLineBlockCommentRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var AstUtils_1 = require("./utils/AstUtils"); 10 | var FAILURE_STRING = 'Replace block comment with a single-line comment'; 11 | var Rule = (function (_super) { 12 | __extends(Rule, _super); 13 | function Rule() { 14 | return _super.apply(this, arguments) || this; 15 | } 16 | Rule.prototype.apply = function (sourceFile) { 17 | return this.applyWithWalker(new NoSingleLineBlockCommentRuleWalker(sourceFile, this.getOptions())); 18 | }; 19 | return Rule; 20 | }(Lint.Rules.AbstractRule)); 21 | Rule.metadata = { 22 | ruleName: 'no-single-line-block-comment', 23 | type: 'maintainability', 24 | description: 'Avoid single line block comments; use single line comments instead', 25 | options: null, 26 | optionsDescription: '', 27 | typescriptOnly: true, 28 | issueClass: 'Non-SDL', 29 | issueType: 'Warning', 30 | severity: 'Low', 31 | level: 'Opportunity for Excellence', 32 | group: 'Whitespace', 33 | commonWeaknessEnumeration: '710' 34 | }; 35 | exports.Rule = Rule; 36 | var NoSingleLineBlockCommentRuleWalker = (function (_super) { 37 | __extends(NoSingleLineBlockCommentRuleWalker, _super); 38 | function NoSingleLineBlockCommentRuleWalker() { 39 | return _super.apply(this, arguments) || this; 40 | } 41 | NoSingleLineBlockCommentRuleWalker.prototype.visitSourceFile = function (node) { 42 | var _this = this; 43 | var scanner = ts.createScanner(ts.ScriptTarget.ES5, false, AstUtils_1.AstUtils.getLanguageVariant(node), node.text); 44 | Lint.scanAllTokens(scanner, function (scanner) { 45 | var startPos = scanner.getStartPos(); 46 | if (_this.tokensToSkipStartEndMap[startPos] != null) { 47 | scanner.setTextPos(_this.tokensToSkipStartEndMap[startPos]); 48 | return; 49 | } 50 | if (scanner.getToken() === ts.SyntaxKind.MultiLineCommentTrivia) { 51 | var commentText = scanner.getTokenText(); 52 | var startPosition = scanner.getTokenPos(); 53 | if (_this.isSingleLineComment(commentText) 54 | && _this.isNextTokenOnANewLine(scanner) 55 | && _this.isTsLintSuppression(commentText) === false) { 56 | _this.addFailure(_this.createFailure(startPosition, commentText.length, FAILURE_STRING)); 57 | } 58 | } 59 | }); 60 | }; 61 | NoSingleLineBlockCommentRuleWalker.prototype.isNextTokenOnANewLine = function (scanner) { 62 | return scanner.lookAhead(function () { 63 | scanner.scan(); 64 | return scanner.hasPrecedingLineBreak(); 65 | }); 66 | }; 67 | NoSingleLineBlockCommentRuleWalker.prototype.isSingleLineComment = function (commentText) { 68 | var lines = commentText.split(/\r?\n/); 69 | return lines.length === 1; 70 | }; 71 | NoSingleLineBlockCommentRuleWalker.prototype.isTsLintSuppression = function (commentText) { 72 | return /\/*\s*tslint:(enable|disable):.*/.test(commentText); 73 | }; 74 | return NoSingleLineBlockCommentRuleWalker; 75 | }(Lint.SkippableTokenAwareRuleWalker)); 76 | //# sourceMappingURL=noSingleLineBlockCommentRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/utils/Scope.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var ErrorTolerantWalker_1 = require("./ErrorTolerantWalker"); 9 | var AstUtils_1 = require("./AstUtils"); 10 | var Scope = (function () { 11 | function Scope(parent) { 12 | this.symbols = {}; 13 | this.parent = parent; 14 | } 15 | Scope.prototype.addFunctionSymbol = function (symbolString) { 16 | this.symbols[symbolString] = ts.SyntaxKind.FunctionType; 17 | }; 18 | Scope.prototype.addNonFunctionSymbol = function (symbolString) { 19 | this.symbols[symbolString] = ts.SyntaxKind.Unknown; 20 | }; 21 | Scope.prototype.isFunctionSymbol = function (symbolString) { 22 | if (this.symbols[symbolString] === ts.SyntaxKind.FunctionType) { 23 | return true; 24 | } 25 | if (this.symbols[symbolString] === ts.SyntaxKind.Unknown) { 26 | return false; 27 | } 28 | if (this.parent != null) { 29 | return this.parent.isFunctionSymbol(symbolString); 30 | } 31 | return false; 32 | }; 33 | Scope.prototype.addParameters = function (parameters) { 34 | var _this = this; 35 | parameters.forEach(function (parm) { 36 | if (AstUtils_1.AstUtils.isDeclarationFunctionType(parm)) { 37 | _this.addFunctionSymbol(parm.name.getText()); 38 | } 39 | else { 40 | _this.addNonFunctionSymbol(parm.name.getText()); 41 | } 42 | }); 43 | }; 44 | Scope.prototype.addGlobalScope = function (node, sourceFile, options) { 45 | var _this = this; 46 | var refCollector = new GlobalReferenceCollector(sourceFile, options); 47 | refCollector.visitNode(node); 48 | refCollector.functionIdentifiers.forEach(function (identifier) { _this.addFunctionSymbol(identifier); }); 49 | refCollector.nonFunctionIdentifiers.forEach(function (identifier) { _this.addNonFunctionSymbol(identifier); }); 50 | }; 51 | return Scope; 52 | }()); 53 | exports.Scope = Scope; 54 | var GlobalReferenceCollector = (function (_super) { 55 | __extends(GlobalReferenceCollector, _super); 56 | function GlobalReferenceCollector() { 57 | var _this = _super.apply(this, arguments) || this; 58 | _this.functionIdentifiers = []; 59 | _this.nonFunctionIdentifiers = []; 60 | return _this; 61 | } 62 | GlobalReferenceCollector.prototype.visitModuleDeclaration = function (node) { }; 63 | GlobalReferenceCollector.prototype.visitClassDeclaration = function (node) { }; 64 | GlobalReferenceCollector.prototype.visitArrowFunction = function (node) { }; 65 | GlobalReferenceCollector.prototype.visitFunctionExpression = function (node) { }; 66 | GlobalReferenceCollector.prototype.visitNode = function (node) { 67 | _super.prototype.visitNode.call(this, node); 68 | }; 69 | GlobalReferenceCollector.prototype.visitVariableDeclaration = function (node) { 70 | if (AstUtils_1.AstUtils.isDeclarationFunctionType(node)) { 71 | this.functionIdentifiers.push(node.name.getText()); 72 | } 73 | else { 74 | this.nonFunctionIdentifiers.push(node.name.getText()); 75 | } 76 | }; 77 | return GlobalReferenceCollector; 78 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 79 | //# sourceMappingURL=Scope.js.map -------------------------------------------------------------------------------- /tslint-contrib/missingOptionalAnnotationRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var Lint = require("tslint"); 8 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker"); 9 | var Rule = (function (_super) { 10 | __extends(Rule, _super); 11 | function Rule() { 12 | return _super.apply(this, arguments) || this; 13 | } 14 | Rule.prototype.apply = function (sourceFile) { 15 | return this.applyWithWalker(new MissingOptionalAnnotationWalker(sourceFile, this.getOptions())); 16 | }; 17 | return Rule; 18 | }(Lint.Rules.AbstractRule)); 19 | Rule.metadata = { 20 | ruleName: 'missing-optional-annotation', 21 | type: 'maintainability', 22 | description: 'Deprecated - This rule is now enforced by the TypeScript compiler', 23 | options: null, 24 | optionsDescription: '', 25 | typescriptOnly: true, 26 | issueClass: 'Ignored', 27 | issueType: 'Warning', 28 | severity: 'Low', 29 | level: 'Opportunity for Excellence', 30 | group: 'Deprecated', 31 | recommendation: 'false, // now supported by TypeScript compiler' 32 | }; 33 | Rule.FAILURE_STRING = 'Argument following optional argument missing optional annotation: '; 34 | exports.Rule = Rule; 35 | var MissingOptionalAnnotationWalker = (function (_super) { 36 | __extends(MissingOptionalAnnotationWalker, _super); 37 | function MissingOptionalAnnotationWalker() { 38 | return _super.apply(this, arguments) || this; 39 | } 40 | MissingOptionalAnnotationWalker.prototype.visitMethodDeclaration = function (node) { 41 | this.validateParameters(node); 42 | _super.prototype.visitMethodDeclaration.call(this, node); 43 | }; 44 | MissingOptionalAnnotationWalker.prototype.visitConstructorDeclaration = function (node) { 45 | this.validateParameters(node); 46 | _super.prototype.visitConstructorDeclaration.call(this, node); 47 | }; 48 | MissingOptionalAnnotationWalker.prototype.visitArrowFunction = function (node) { 49 | this.validateParameters(node); 50 | _super.prototype.visitArrowFunction.call(this, node); 51 | }; 52 | MissingOptionalAnnotationWalker.prototype.visitFunctionDeclaration = function (node) { 53 | this.validateParameters(node); 54 | _super.prototype.visitFunctionDeclaration.call(this, node); 55 | }; 56 | MissingOptionalAnnotationWalker.prototype.visitFunctionExpression = function (node) { 57 | this.validateParameters(node); 58 | _super.prototype.visitFunctionExpression.call(this, node); 59 | }; 60 | MissingOptionalAnnotationWalker.prototype.validateParameters = function (node) { 61 | var _this = this; 62 | var optionalParameterFound = false; 63 | if (node.parameters == null) { 64 | return; 65 | } 66 | node.parameters.forEach(function (parameter) { 67 | if (parameter.questionToken != null || parameter.initializer != null) { 68 | optionalParameterFound = true; 69 | } 70 | else if (optionalParameterFound && parameter.initializer == null) { 71 | var msg = Rule.FAILURE_STRING + parameter.getFullText(); 72 | _this.addFailure(_this.createFailure(parameter.name.getStart(), parameter.name.getWidth(), msg)); 73 | } 74 | }); 75 | }; 76 | return MissingOptionalAnnotationWalker; 77 | }(ErrorTolerantWalker_1.ErrorTolerantWalker)); 78 | //# sourceMappingURL=missingOptionalAnnotationRule.js.map -------------------------------------------------------------------------------- /tslint-contrib/reactA11yAriaUnsupportedElementsRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 4 | function __() { this.constructor = d; } 5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6 | }; 7 | var ts = require("typescript"); 8 | var Lint = require("tslint"); 9 | var JsxAttribute_1 = require("./utils/JsxAttribute"); 10 | var DOM_SCHEMA = require('./utils/attributes/domSchema.json'); 11 | var ARIA_SCHEMA = require('./utils/attributes/ariaSchema.json'); 12 | function getFailureString(tagName, ariaAttributeNames) { 13 | return "This element " + tagName + " does not support ARIA roles, states and properties. " 14 | + ("Try removing attribute(s): " + ariaAttributeNames.join(', ') + "."); 15 | } 16 | exports.getFailureString = getFailureString; 17 | var Rule = (function (_super) { 18 | __extends(Rule, _super); 19 | function Rule() { 20 | return _super.apply(this, arguments) || this; 21 | } 22 | Rule.prototype.apply = function (sourceFile) { 23 | return sourceFile.languageVariant === ts.LanguageVariant.JSX 24 | ? this.applyWithWalker(new ReactA11yAriaUnsupportedElementsWalker(sourceFile, this.getOptions())) 25 | : []; 26 | }; 27 | return Rule; 28 | }(Lint.Rules.AbstractRule)); 29 | Rule.metadata = { 30 | ruleName: 'react-a11y-aria-unsupported-elements', 31 | type: 'maintainability', 32 | description: 'Enforce that elements that do not support ARIA roles, states, and properties do not have those attributes.', 33 | options: null, 34 | optionsDescription: '', 35 | typescriptOnly: true, 36 | issueClass: 'Non-SDL', 37 | issueType: 'Warning', 38 | severity: 'Important', 39 | level: 'Opportunity for Excellence', 40 | group: 'Accessibility' 41 | }; 42 | exports.Rule = Rule; 43 | var ReactA11yAriaUnsupportedElementsWalker = (function (_super) { 44 | __extends(ReactA11yAriaUnsupportedElementsWalker, _super); 45 | function ReactA11yAriaUnsupportedElementsWalker() { 46 | return _super.apply(this, arguments) || this; 47 | } 48 | ReactA11yAriaUnsupportedElementsWalker.prototype.visitJsxElement = function (node) { 49 | this.validateOpeningElement(node.openingElement); 50 | _super.prototype.visitJsxElement.call(this, node); 51 | }; 52 | ReactA11yAriaUnsupportedElementsWalker.prototype.visitJsxSelfClosingElement = function (node) { 53 | this.validateOpeningElement(node); 54 | _super.prototype.visitJsxSelfClosingElement.call(this, node); 55 | }; 56 | ReactA11yAriaUnsupportedElementsWalker.prototype.validateOpeningElement = function (node) { 57 | var tagName = node.tagName.getText(); 58 | if (!DOM_SCHEMA[tagName]) { 59 | return; 60 | } 61 | var supportAria = DOM_SCHEMA[tagName].supportAria != null 62 | ? DOM_SCHEMA[tagName].supportAria 63 | : false; 64 | if (supportAria) { 65 | return; 66 | } 67 | var checkAttributeNames = Object.keys(ARIA_SCHEMA).concat('role'); 68 | var attributes = JsxAttribute_1.getJsxAttributesFromJsxElement(node); 69 | var invalidAttributeNames = checkAttributeNames.filter(function (attributeName) { return !!attributes[attributeName]; }); 70 | if (invalidAttributeNames.length > 0) { 71 | var message = getFailureString(tagName, invalidAttributeNames); 72 | this.addFailure(this.createFailure(node.getStart(), node.getWidth(), message)); 73 | } 74 | }; 75 | return ReactA11yAriaUnsupportedElementsWalker; 76 | }(Lint.RuleWalker)); 77 | //# sourceMappingURL=reactA11yAriaUnsupportedElementsRule.js.map --------------------------------------------------------------------------------