Initial import
This is just a retructuring of the vscode-salesforcedx to salesforcedx-vscode.
This commit is contained in:
Коммит
60c016028d
|
@ -0,0 +1,16 @@
|
|||
# Salesforce Development Tools for Visual Studio Code
|
||||
|
||||
## Getting Started
|
||||
|
||||
1. Install Visual Studio Code from https://code.visualstudio.com
|
||||
1. Clone this repository using `git clone git@git.soma.salesforce.com:DevTools/vscode-salesforcedx.git`.
|
||||
1. Open the cloned repository in Visual Studio Code. This is the host instance.
|
||||
1. Open the integrated terminal and execute `npm install` to bring in all the Node.js dependencies.
|
||||
1. Hit Cmd + Shift + B to initialize the project builder. This will build all the files that you need in the `out` directory. It also watches for any changes you make to the file and automatically compiles them.
|
||||
1. Hit F5 to launch another instance of Visual Studio Code. This is a special version of Visual Studio code with the extension loaded. You can debug your things in it.
|
||||
|
||||
## Including your own version of the Apex Language Server
|
||||
|
||||
1. For the Apex Language Server, you need to issue `git clonegit@git.soma.salesforce.com:DevTools/apex-jorje.git`.
|
||||
1. In the directory where you clone the previous repository, switch to the `nick/apex-lsp` branch.
|
||||
1. __This part is not as smoothly automated yet__ Run the script in `scripts/pre-jars.sh` (after modifications to point it to where you have the apex-jorje source checked out).
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"lerna": "2.0.0-rc.5",
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "0.1.0"
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"devDependencies": {
|
||||
"lerna": "^2.0.0-rc.5"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
#
|
||||
# TypeScript generated files
|
||||
#
|
||||
|
||||
dist/
|
||||
|
||||
#
|
||||
# Istanbul code coverage files
|
||||
#
|
||||
|
||||
coverage/
|
||||
|
||||
#
|
||||
# https://github.com/github/gitignore/blob/master/Node.gitignore
|
||||
#
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules
|
||||
jspm_packages
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Generated vscode package
|
||||
*.vsix
|
|
@ -0,0 +1,37 @@
|
|||
// A launch configuration that compiles the extension and then opens it inside a new window
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch Extension",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceRoot}"
|
||||
],
|
||||
"stopOnEntry": false,
|
||||
"sourceMaps": true,
|
||||
"outFiles": [
|
||||
"${workspaceRoot}/dist/src/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "npm"
|
||||
},
|
||||
{
|
||||
"name": "Launch Tests",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceRoot}",
|
||||
"--extensionTestsPath=${workspaceRoot}/dist/test"
|
||||
],
|
||||
"stopOnEntry": false,
|
||||
"sourceMaps": true,
|
||||
"outFiles": [
|
||||
"${workspaceRoot}/out/test/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "npm"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
"files.exclude": {
|
||||
"dist": false // set this to true to hide the "dist" folder with the compiled JS files
|
||||
},
|
||||
"search.exclude": {
|
||||
"dist": true // set this to false to include "dist" folder in search results
|
||||
},
|
||||
"typescript.tsdk": "./node_modules/typescript/lib" // we want to use the TS server from our node_modules folder to control its version
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
// Available variables which can be used inside of strings.
|
||||
// ${workspaceRoot}: the root folder of the team
|
||||
// ${file}: the current opened file
|
||||
// ${fileBasename}: the current opened file's basename
|
||||
// ${fileDirname}: the current opened file's dirname
|
||||
// ${fileExtname}: the current opened file's extension
|
||||
// ${cwd}: the current working directory of the spawned process
|
||||
|
||||
// A task runner that calls a custom npm script that compiles the extension.
|
||||
{
|
||||
"version": "0.1.0",
|
||||
|
||||
// we want to run npm
|
||||
"command": "npm",
|
||||
|
||||
// the command is a shell script
|
||||
"isShellCommand": true,
|
||||
|
||||
// show the output window only if unrecognized errors occur.
|
||||
"showOutput": "silent",
|
||||
|
||||
// we run the custom script "compile" as defined in package.json
|
||||
"args": ["run", "compile", "--loglevel", "silent"],
|
||||
|
||||
// The tsc compiler is started in watching mode
|
||||
"isWatching": true,
|
||||
|
||||
// use the standard tsc in watch mode problem matcher to find compile problems in the output.
|
||||
"problemMatcher": "$tsc-watch"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
tsconfig.json
|
||||
|
||||
.vscode/**
|
||||
screenshots/**
|
||||
scripts/**
|
||||
src/**
|
||||
dist/test/**
|
|
@ -0,0 +1,91 @@
|
|||
{
|
||||
"name": "salesforcedx-vscode",
|
||||
"displayName": "Salesforce Code Editor for Visual Studio Code",
|
||||
"description": "Tools for developing on the Salesforce DX platform.",
|
||||
"version": "0.1.0",
|
||||
"publisher": "salesforce",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"vscode": "^1.10.0"
|
||||
},
|
||||
"categories": [
|
||||
"Languages",
|
||||
"Debuggers",
|
||||
"Other"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/mocha": "2.2.38",
|
||||
"@types/node": "^6.0.40",
|
||||
"mocha": "3.2.0",
|
||||
"typescript": "2.3.4",
|
||||
"vscode": "1.1.0"
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "tsc -p ./",
|
||||
"compile": "tsc -watch -p .",
|
||||
"postinstall": "node ./node_modules/vscode/bin/install"
|
||||
},
|
||||
"activationEvents": [
|
||||
"workspaceContains:sfdx-project.json"
|
||||
],
|
||||
"main": "./dist/src/salesforcedx",
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "sfdx.force.auth.web.login",
|
||||
"title": "force:auth:web:login"
|
||||
},
|
||||
{
|
||||
"command": "sfdx.force.org.create",
|
||||
"title": "force:org:create"
|
||||
},
|
||||
{
|
||||
"command": "sfdx.force.org.open",
|
||||
"title": "force:org:open"
|
||||
},
|
||||
{
|
||||
"command": "sfdx.force.source.pull",
|
||||
"title": "force:source:pull"
|
||||
},
|
||||
{
|
||||
"command": "sfdx.force.source.push",
|
||||
"title": "force:source:push"
|
||||
},
|
||||
{
|
||||
"command": "sfdx.force.source.status",
|
||||
"title": "force:source:status"
|
||||
},
|
||||
{
|
||||
"command": "sfdx.force.apex.test.run",
|
||||
"title": "force:apex:test:run"
|
||||
}
|
||||
],
|
||||
"languages": [
|
||||
{
|
||||
"id": "apex",
|
||||
"aliases": [
|
||||
"Apex",
|
||||
"apex"
|
||||
],
|
||||
"extensions": [
|
||||
".cls",
|
||||
".trigger"
|
||||
],
|
||||
"configuration": "./syntaxes/apex.configuration.json"
|
||||
}
|
||||
],
|
||||
"grammars": [
|
||||
{
|
||||
"language": "apex",
|
||||
"scopeName": "source.apex",
|
||||
"path": "./syntaxes/apex.tmLanguage"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"expand-home-dir": "0.0.3",
|
||||
"path-exists": "3.0.0",
|
||||
"portfinder": "1.0.12",
|
||||
"vscode-languageclient": "3.3.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,296 @@
|
|||
{
|
||||
"eslintrc": false,
|
||||
"env": {
|
||||
"browser": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 5
|
||||
},
|
||||
"globals": {
|
||||
"$A": true,
|
||||
"AuraContext": true,
|
||||
"AuraSerializationService": true,
|
||||
"AuraExpressionService": true,
|
||||
"AuraEventService": true,
|
||||
"AuraLocalizationService": true,
|
||||
"AuraStorageService": true,
|
||||
"AuraStyleService": true,
|
||||
"MetricsService": true,
|
||||
"AuraDevToolService": true,
|
||||
"Component": true,
|
||||
"CKEDITOR": true,
|
||||
"FORCE": true,
|
||||
"moment": true,
|
||||
"exports": true,
|
||||
"iScroll": true,
|
||||
"unescape": true,
|
||||
"Promise": true
|
||||
},
|
||||
"rules": {
|
||||
// custom rules
|
||||
"ecma-intrinsics": 2,
|
||||
"new-rule-template": 0,
|
||||
"secure-document": 2,
|
||||
"aura-api": 2,
|
||||
"secure-window": 2,
|
||||
// platform rules that as immutable
|
||||
"no-alert": 2,
|
||||
"no-array-constructor": 2, // help with instanceof
|
||||
"no-bitwise": 1, // usually a typo | -> ||
|
||||
"no-caller": 2, // strict mode compliance
|
||||
"no-catch-shadow": 2,
|
||||
"no-cond-assign": 2,
|
||||
"no-console": 2,
|
||||
"no-constant-condition": 2,
|
||||
"no-control-regex": 1,
|
||||
"no-debugger": 2,
|
||||
"no-delete-var": 1, // for perf reasons, we might want to set this to 2
|
||||
"no-div-regex": 1,
|
||||
"no-dupe-keys": 2,
|
||||
"no-dupe-args": 2,
|
||||
"no-duplicate-case": 2,
|
||||
"no-else-return": 0,
|
||||
"no-empty-character-class": 2,
|
||||
"no-eq-null": 1,
|
||||
"no-eval": 2,
|
||||
"no-ex-assign": 2,
|
||||
"no-extend-native": 2,
|
||||
"no-extra-bind": 2,
|
||||
"no-extra-boolean-cast": 2,
|
||||
"no-fallthrough": 2, // switch fallthrough
|
||||
"no-floating-decimal": 1, // var num = .5;
|
||||
"no-func-assign": 2,
|
||||
"no-implied-eval": 2,
|
||||
"no-inner-declarations": [
|
||||
2,
|
||||
"functions"
|
||||
],
|
||||
"no-invalid-regexp": 2,
|
||||
"no-irregular-whitespace": 2,
|
||||
"no-iterator": 2,
|
||||
"no-label-var": 2,
|
||||
"no-labels": 2,
|
||||
"no-loop-func": 2,
|
||||
"no-multi-str": 2,
|
||||
"no-native-reassign": 2,
|
||||
"no-negated-in-lhs": 2,
|
||||
"no-nested-ternary": 1,
|
||||
"no-new": 2,
|
||||
"no-new-func": 2,
|
||||
"no-new-object": 2,
|
||||
"no-new-wrappers": 2,
|
||||
"no-obj-calls": 2,
|
||||
"no-octal": 2,
|
||||
"no-octal-escape": 2,
|
||||
"no-param-reassign": 1,
|
||||
"no-plusplus": 1,
|
||||
"no-proto": 2,
|
||||
"no-redeclare": 2,
|
||||
"no-regex-spaces": 2,
|
||||
"no-return-assign": 2,
|
||||
"no-script-url": 2,
|
||||
"no-self-compare": 2,
|
||||
"no-sequences": 2, // var a = (3, 5);
|
||||
"no-shadow": 2,
|
||||
"no-shadow-restricted-names": 2,
|
||||
"no-sparse-arrays": 2,
|
||||
"no-ternary": 0,
|
||||
"no-throw-literal": 1,
|
||||
"no-undef": 1,
|
||||
"no-undef-init": 1,
|
||||
"no-undefined": 0,
|
||||
"no-underscore-dangle": 0,
|
||||
"no-unreachable": 2,
|
||||
"no-unused-expressions": 0,
|
||||
"no-unused-vars": [
|
||||
1,
|
||||
{
|
||||
"vars": "all",
|
||||
"args": "after-used"
|
||||
}
|
||||
],
|
||||
"no-use-before-define": [
|
||||
2,
|
||||
{
|
||||
"functions": false
|
||||
}
|
||||
],
|
||||
"no-void": 2,
|
||||
"no-var": 0,
|
||||
"no-with": 2,
|
||||
"consistent-return": 1,
|
||||
"default-case": 2,
|
||||
"dot-notation": [
|
||||
1,
|
||||
{
|
||||
"allowKeywords": true
|
||||
}
|
||||
],
|
||||
"eqeqeq": [
|
||||
"error",
|
||||
"smart"
|
||||
],
|
||||
"guard-for-in": 1,
|
||||
"handle-callback-err": 1,
|
||||
"new-parens": 2,
|
||||
"radix": 2,
|
||||
"strict": [
|
||||
2,
|
||||
"global"
|
||||
],
|
||||
"use-isnan": 2,
|
||||
"valid-typeof": 2,
|
||||
"wrap-iife": [
|
||||
1,
|
||||
"any"
|
||||
],
|
||||
// aside from this list, ./code-style-rules.js will have the rules that are not
|
||||
// important for the code to function, but just stylish.
|
||||
// code style rules, these are the default value, but the user can
|
||||
// customize them via --config in the linter by providing custom values
|
||||
// for each of these rules.
|
||||
"no-trailing-spaces": 1,
|
||||
"no-spaced-func": 1,
|
||||
"no-mixed-spaces-and-tabs": 0,
|
||||
"no-multi-spaces": 0,
|
||||
"no-multiple-empty-lines": 0,
|
||||
"no-lone-blocks": 1,
|
||||
"no-lonely-if": 1,
|
||||
"no-inline-comments": 0,
|
||||
"no-extra-parens": 0,
|
||||
"no-extra-semi": 1,
|
||||
"no-warning-comments": [
|
||||
0,
|
||||
{
|
||||
"terms": [
|
||||
"todo",
|
||||
"fixme",
|
||||
"xxx"
|
||||
],
|
||||
"location": "start"
|
||||
}
|
||||
],
|
||||
"block-scoped-var": 1,
|
||||
"brace-style": [
|
||||
1,
|
||||
"1tbs"
|
||||
],
|
||||
"camelcase": 1,
|
||||
"comma-dangle": [
|
||||
1,
|
||||
"never"
|
||||
],
|
||||
"comma-spacing": 1,
|
||||
"comma-style": 1,
|
||||
"complexity": [
|
||||
0,
|
||||
11
|
||||
],
|
||||
"consistent-this": [
|
||||
0,
|
||||
"that"
|
||||
],
|
||||
"curly": [
|
||||
1,
|
||||
"all"
|
||||
],
|
||||
"eol-last": 0,
|
||||
"func-names": 0,
|
||||
"func-style": [
|
||||
0,
|
||||
"declaration"
|
||||
],
|
||||
"generator-star-spacing": 0,
|
||||
"indent": 0,
|
||||
"key-spacing": 0,
|
||||
"keyword-spacing": [
|
||||
0
|
||||
],
|
||||
"max-depth": [
|
||||
0,
|
||||
4
|
||||
],
|
||||
"max-len": [
|
||||
0,
|
||||
80,
|
||||
4
|
||||
],
|
||||
"max-nested-callbacks": [
|
||||
0,
|
||||
2
|
||||
],
|
||||
"max-params": [
|
||||
0,
|
||||
3
|
||||
],
|
||||
"max-statements": [
|
||||
0,
|
||||
10
|
||||
],
|
||||
"new-cap": 0,
|
||||
"newline-after-var": 0,
|
||||
"one-var": [
|
||||
0,
|
||||
"never"
|
||||
],
|
||||
"operator-assignment": [
|
||||
0,
|
||||
"always"
|
||||
],
|
||||
"padded-blocks": 0,
|
||||
"quote-props": 0,
|
||||
"quotes": 0,
|
||||
"semi": 1,
|
||||
"semi-spacing": [
|
||||
0,
|
||||
{
|
||||
"before": false,
|
||||
"after": true
|
||||
}
|
||||
],
|
||||
"sort-vars": 0,
|
||||
"space-after-function-name": [
|
||||
0,
|
||||
"never"
|
||||
],
|
||||
"space-before-blocks": [
|
||||
0,
|
||||
"always"
|
||||
],
|
||||
"space-before-function-paren": [
|
||||
0,
|
||||
"always"
|
||||
],
|
||||
"space-before-function-parentheses": [
|
||||
0,
|
||||
"always"
|
||||
],
|
||||
"space-in-brackets": [
|
||||
0,
|
||||
"never"
|
||||
],
|
||||
"space-in-parens": [
|
||||
0,
|
||||
"never"
|
||||
],
|
||||
"space-infix-ops": 0,
|
||||
"space-unary-ops": [
|
||||
1,
|
||||
{
|
||||
"words": true,
|
||||
"nonwords": false
|
||||
}
|
||||
],
|
||||
"spaced-comment": [
|
||||
0,
|
||||
"always"
|
||||
],
|
||||
"vars-on-top": 0,
|
||||
"valid-jsdoc": 0,
|
||||
"wrap-regex": 0,
|
||||
"yoda": [
|
||||
1,
|
||||
"never"
|
||||
]
|
||||
}
|
||||
}
|
594
packages/salesforcedx-vscode/resources/lightning/eslint/lib/3rdparty/ses/whitelist.js
поставляемый
Normal file
594
packages/salesforcedx-vscode/resources/lightning/eslint/lib/3rdparty/ses/whitelist.js
поставляемый
Normal file
|
@ -0,0 +1,594 @@
|
|||
// Copyright (C) 2011 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Exports {@code ses.whitelist}, a recursively defined
|
||||
* JSON record enumerating all the naming paths in the ES5.1 spec,
|
||||
* those de-facto extensions that we judge to be safe, and SES and
|
||||
* Dr. SES extensions provided by the SES runtime.
|
||||
*
|
||||
* <p>Assumes only ES3. Compatible with ES5, ES5-strict, or
|
||||
* anticipated ES6.
|
||||
*
|
||||
* //provides ses.whitelist
|
||||
* @author Mark S. Miller,
|
||||
* @overrides ses, whitelistModule
|
||||
*/
|
||||
var ses = {}; module.exports = ses; // custom line to make it work in node env.
|
||||
|
||||
/**
|
||||
* <p>Each JSON record enumerates the disposition of the properties on
|
||||
* some corresponding primordial object, with the root record
|
||||
* representing the global object. For each such record, the values
|
||||
* associated with its property names can be
|
||||
* <ul>
|
||||
* <li>Another record, in which case this property is simply
|
||||
* whitelisted and that next record represents the disposition of
|
||||
* the object which is its value. For example, {@code "Object"}
|
||||
* leads to another record explaining what properties {@code
|
||||
* "Object"} may have and how each such property, if present,
|
||||
* and its value should be tamed.
|
||||
* <li>true, in which case this property is simply whitelisted. The
|
||||
* value associated with that property is still traversed and
|
||||
* tamed, but only according to the taming of the objects that
|
||||
* object inherits from. For example, {@code "Object.freeze"} leads
|
||||
* to true, meaning that the {@code "freeze"} property of {@code
|
||||
* Object} should be whitelisted and the value of the property (a
|
||||
* function) should be further tamed only according to the
|
||||
* markings of the other objects it inherits from, like {@code
|
||||
* "Function.prototype"} and {@code "Object.prototype").
|
||||
* If the property is an accessor property, it is not
|
||||
* whitelisted (as invoking an accessor might not be meaningful,
|
||||
* yet the accessor might return a value needing taming).
|
||||
* <li>"maybeAccessor", in which case this accessor property is simply
|
||||
* whitelisted and its getter and/or setter are tamed according to
|
||||
* inheritance. If the property is not an accessor property, its
|
||||
* value is tamed according to inheritance.
|
||||
* <li>"*", in which case this property on this object is whitelisted,
|
||||
* as is this property as inherited by all objects that inherit
|
||||
* from this object. The values associated with all such properties
|
||||
* are still traversed and tamed, but only according to the taming
|
||||
* of the objects that object inherits from. For example, {@code
|
||||
* "Object.prototype.constructor"} leads to "*", meaning that we
|
||||
* whitelist the {@code "constructor"} property on {@code
|
||||
* Object.prototype} and on every object that inherits from {@code
|
||||
* Object.prototype} that does not have a conflicting mark. Each
|
||||
* of these is tamed as if with true, so that the value of the
|
||||
* property is further tamed according to what other objects it
|
||||
* inherits from.
|
||||
* <li>false, which suppression permission inherited via "*".
|
||||
* </ul>
|
||||
*
|
||||
* <p>TODO: We want to do for constructor: something weaker than '*',
|
||||
* but rather more like what we do for [[Prototype]] links, which is
|
||||
* that it is whitelisted only if it points at an object which is
|
||||
* otherwise reachable by a whitelisted path.
|
||||
*
|
||||
* <p>The members of the whitelist are either
|
||||
* <ul>
|
||||
* <li>(uncommented) defined by the ES5.1 normative standard text,
|
||||
* <li>(questionable) provides a source of non-determinism, in
|
||||
* violation of pure object-capability rules, but allowed anyway
|
||||
* since we've given up on restricting JavaScript to a
|
||||
* deterministic subset.
|
||||
* <li>(ES5 Appendix B) common elements of de facto JavaScript
|
||||
* described by the non-normative Appendix B.
|
||||
* <li>(Harmless whatwg) extensions documented at
|
||||
* <a href="http://wiki.whatwg.org/wiki/Web_ECMAScript"
|
||||
* >http://wiki.whatwg.org/wiki/Web_ECMAScript</a> that seem to be
|
||||
* harmless. Note that the RegExp constructor extensions on that
|
||||
* page are <b>not harmless</b> and so must not be whitelisted.
|
||||
* <li>(ES-Harmony proposal) accepted as "proposal" status for
|
||||
* EcmaScript-Harmony.
|
||||
* </ul>
|
||||
*
|
||||
* <p>With the above encoding, there are some sensible whitelists we
|
||||
* cannot express, such as marking a property both with "*" and a JSON
|
||||
* record. This is an expedient decision based only on not having
|
||||
* encountered such a need. Should we need this extra expressiveness,
|
||||
* we'll need to refactor to enable a different encoding.
|
||||
*
|
||||
* <p>We factor out {@code true} into the variable {@code t} just to
|
||||
* get a bit better compression from simple minifiers.
|
||||
*/
|
||||
(function whitelistModule() {
|
||||
"use strict";
|
||||
|
||||
if (!ses) { ses = {}; }
|
||||
|
||||
var t = true;
|
||||
var TypedArrayWhitelist; // defined and used below
|
||||
|
||||
ses.whitelist = {
|
||||
cajaVM: { // Caja support
|
||||
// The accessible intrinsics which are not reachable by own
|
||||
// property name traversal are listed here so that they are
|
||||
// processed by the whitelist, although this also makes them
|
||||
// accessible by this path. See
|
||||
// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-well-known-intrinsic-objects
|
||||
// Of these, ThrowTypeError is the only one from ES5. All the
|
||||
// rest were introduced in ES6.
|
||||
anonIntrinsics: {
|
||||
ThrowTypeError: {},
|
||||
IteratorPrototype: {
|
||||
// Technically, for SES-on-ES5, we should not need to
|
||||
// whitelist 'next'. However, browsers are accidentally
|
||||
// relying on it
|
||||
// https://bugs.chromium.org/p/v8/issues/detail?id=4769#
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=154475
|
||||
// and we will be whitelisting it as we transition to ES6
|
||||
// anyway, so we unconditionally whitelist it now.
|
||||
next: '*',
|
||||
constructor: false
|
||||
},
|
||||
ArrayIteratorPrototype: {},
|
||||
StringIteratorPrototype: {},
|
||||
// TODO MapIteratorPrototype: {},
|
||||
// TODO SetIteratorPrototype: {},
|
||||
|
||||
// The %GeneratorFunction% intrinsic is the constructor of
|
||||
// generator functions, so %GeneratorFunction%.prototype is
|
||||
// the %Generator% intrinsic, which all generator functions
|
||||
// inherit from. A generator function is effectively the
|
||||
// constructor of its generator instances, so, for each
|
||||
// generator function (e.g., "g1" on the diagram at
|
||||
// http://people.mozilla.org/~jorendorff/figure-2.png )
|
||||
// its .prototype is a prototype that its instances inherit
|
||||
// from. Paralleling this structure, %Generator%.prototype,
|
||||
// i.e., %GeneratorFunction%.prototype.prototype, is the
|
||||
// object that all these generator function prototypes inherit
|
||||
// from. The .next, .return and .throw that generator
|
||||
// instances respond to are actually the builtin methods they
|
||||
// inherit from this object.
|
||||
GeneratorFunction: {
|
||||
prototype: {
|
||||
prototype: {
|
||||
next: '*',
|
||||
'return': '*',
|
||||
'throw': '*'
|
||||
}
|
||||
}
|
||||
},
|
||||
TypedArray: TypedArrayWhitelist = {
|
||||
length: '*', // does not inherit from Function.prototype on Chrome
|
||||
name: '*', // ditto
|
||||
BYTES_PER_ELEMENT: '*',
|
||||
from: t,
|
||||
of: t,
|
||||
prototype: {
|
||||
buffer: 'maybeAccessor',
|
||||
byteOffset: 'maybeAccessor',
|
||||
byteLength: 'maybeAccessor',
|
||||
length: 'maybeAccessor',
|
||||
BYTES_PER_ELEMENT: '*',
|
||||
set: '*',
|
||||
subarray: '*'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
log: t,
|
||||
tamperProof: t,
|
||||
constFunc: t,
|
||||
Nat: t,
|
||||
def: t,
|
||||
is: t,
|
||||
|
||||
compileExpr: t,
|
||||
confine: t,
|
||||
compileModule: t, // experimental
|
||||
compileProgram: t, // Cannot be implemented in just ES5.1.
|
||||
eval: t,
|
||||
Function: t,
|
||||
|
||||
sharedImports: t,
|
||||
makeImports: t,
|
||||
copyToImports: t,
|
||||
|
||||
GuardT: {
|
||||
coerce: t
|
||||
},
|
||||
makeTableGuard: t,
|
||||
Trademark: {
|
||||
stamp: t
|
||||
},
|
||||
guard: t,
|
||||
passesGuard: t,
|
||||
stamp: t,
|
||||
makeSealerUnsealerPair: t,
|
||||
|
||||
makeArrayLike: {
|
||||
canBeFullyLive: t
|
||||
}
|
||||
},
|
||||
WeakMap: { // ES-Harmony proposal as currently implemented by FF6.0a1
|
||||
prototype: {
|
||||
// Note: coordinate this list with maintenance of repairES5.js
|
||||
get: t,
|
||||
set: t,
|
||||
has: t,
|
||||
'delete': t
|
||||
}
|
||||
},
|
||||
StringMap: { // A specialized approximation of ES-Harmony's Map.
|
||||
prototype: {} // Technically, the methods should be on the prototype,
|
||||
// but doing so while preserving encapsulation will be
|
||||
// needlessly expensive for current usage.
|
||||
},
|
||||
// As of this writing, the WeakMap emulation in WeakMap.js relies on
|
||||
// the unguessability and undiscoverability of HIDDEN_NAME, a
|
||||
// secret property name. However, on a platform with built-in
|
||||
// Proxies, if whitelisted but not properly monkey patched, proxies
|
||||
// could be used to trap and thereby discover HIDDEN_NAME. So until we
|
||||
// (TODO(erights)) write the needed monkey patching of proxies, we
|
||||
// omit them from our whitelist.
|
||||
//
|
||||
// We now have an additional reason to omit Proxy from the whitelist.
|
||||
// The makeBrandTester in repairES5 uses Allen's trick at
|
||||
// https://esdiscuss.org/topic/tostringtag-spoofing-for-null-and-undefined#content-59
|
||||
// , but testing reveals that, on FF 35.0.1, a proxy on an exotic
|
||||
// object X will pass this brand test when X will. This is fixed as of
|
||||
// FF Nightly 38.0a1.
|
||||
//
|
||||
// Proxy: { // ES-Harmony proposal
|
||||
// create: t,
|
||||
// createFunction: t
|
||||
// },
|
||||
escape: t, // ES5 Appendix B
|
||||
unescape: t, // ES5 Appendix B
|
||||
Object: {
|
||||
// If any new methods are added here that may reveal the
|
||||
// HIDDEN_NAME within WeakMap.js, such as the proposed
|
||||
// getOwnPropertyDescriptors or getPropertyDescriptors, then
|
||||
// extend WeakMap.js to monkey patch these to avoid revealing
|
||||
// HIDDEN_NAME.
|
||||
assign: t,
|
||||
getPropertyDescriptor: t, // ES-Harmony proposal
|
||||
getPropertyNames: t, // ES-Harmony proposal
|
||||
is: t, // ES-Harmony proposal
|
||||
prototype: {
|
||||
|
||||
// Whitelisted only to work around a Chrome debugger
|
||||
// stratification bug (TODO(erights): report). These are
|
||||
// redefined in startSES.js in terms of standard methods, so
|
||||
// that we can be confident they introduce no non-standard
|
||||
// possibilities.
|
||||
__defineGetter__: t,
|
||||
__defineSetter__: t,
|
||||
__lookupGetter__: t,
|
||||
__lookupSetter__: t,
|
||||
|
||||
// There are only here to support repair_THROWING_THAWS_FROZEN_OBJECT,
|
||||
// which repairs Safari-only bug
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=141878 by
|
||||
// preemptively adding these properties to any objects that
|
||||
// are about to become non-extensible. When these are already
|
||||
// present, then the Safari bug does not add them.
|
||||
line: '*',
|
||||
column: '*',
|
||||
sourceUrl: '*',
|
||||
stack: '*',
|
||||
|
||||
constructor: '*',
|
||||
toString: '*',
|
||||
toLocaleString: '*',
|
||||
valueOf: t,
|
||||
hasOwnProperty: t,
|
||||
isPrototypeOf: t,
|
||||
propertyIsEnumerable: t
|
||||
},
|
||||
getPrototypeOf: t,
|
||||
getOwnPropertyDescriptor: t,
|
||||
getOwnPropertyNames: t,
|
||||
create: t,
|
||||
defineProperty: t,
|
||||
defineProperties: t,
|
||||
seal: t,
|
||||
freeze: t,
|
||||
preventExtensions: t,
|
||||
isSealed: t,
|
||||
isFrozen: t,
|
||||
isExtensible: t,
|
||||
keys: t
|
||||
},
|
||||
NaN: t,
|
||||
Infinity: t,
|
||||
undefined: t,
|
||||
// eval: t, // Whitelisting under separate control
|
||||
// by TAME_GLOBAL_EVAL in startSES.js
|
||||
parseInt: t,
|
||||
parseFloat: t,
|
||||
isNaN: t,
|
||||
isFinite: t,
|
||||
decodeURI: t,
|
||||
decodeURIComponent: t,
|
||||
encodeURI: t,
|
||||
encodeURIComponent: t,
|
||||
Function: {
|
||||
prototype: {
|
||||
apply: t,
|
||||
call: t,
|
||||
bind: t,
|
||||
prototype: '*',
|
||||
length: '*',
|
||||
arity: '*', // non-std, deprecated in favor of length
|
||||
name: '*' // non-std
|
||||
}
|
||||
},
|
||||
Array: {
|
||||
prototype: {
|
||||
concat: t,
|
||||
join: t,
|
||||
pop: t,
|
||||
push: t,
|
||||
reverse: t,
|
||||
shift: t,
|
||||
slice: t,
|
||||
sort: t,
|
||||
splice: t,
|
||||
unshift: t,
|
||||
indexOf: t,
|
||||
lastIndexOf: t,
|
||||
every: t,
|
||||
some: t,
|
||||
forEach: t,
|
||||
map: t,
|
||||
filter: t,
|
||||
reduce: t,
|
||||
reduceRight: t,
|
||||
length: t
|
||||
},
|
||||
isArray: t
|
||||
},
|
||||
String: {
|
||||
prototype: {
|
||||
substr: t, // ES5 Appendix B
|
||||
anchor: t, // Harmless whatwg
|
||||
big: t, // Harmless whatwg
|
||||
blink: t, // Harmless whatwg
|
||||
bold: t, // Harmless whatwg
|
||||
fixed: t, // Harmless whatwg
|
||||
fontcolor: t, // Harmless whatwg
|
||||
fontsize: t, // Harmless whatwg
|
||||
italics: t, // Harmless whatwg
|
||||
link: t, // Harmless whatwg
|
||||
small: t, // Harmless whatwg
|
||||
strike: t, // Harmless whatwg
|
||||
sub: t, // Harmless whatwg
|
||||
sup: t, // Harmless whatwg
|
||||
trimLeft: t, // non-standard
|
||||
trimRight: t, // non-standard
|
||||
valueOf: t,
|
||||
charAt: t,
|
||||
charCodeAt: t,
|
||||
concat: t,
|
||||
indexOf: t,
|
||||
lastIndexOf: t,
|
||||
localeCompare: t,
|
||||
match: t,
|
||||
replace: t,
|
||||
search: t,
|
||||
slice: t,
|
||||
split: t,
|
||||
substring: t,
|
||||
toLowerCase: t,
|
||||
toLocaleLowerCase: t,
|
||||
toUpperCase: t,
|
||||
toLocaleUpperCase: t,
|
||||
trim: t,
|
||||
length: '*'
|
||||
},
|
||||
fromCharCode: t
|
||||
},
|
||||
Boolean: {
|
||||
prototype: {
|
||||
valueOf: t
|
||||
}
|
||||
},
|
||||
Number: {
|
||||
prototype: {
|
||||
valueOf: t,
|
||||
toFixed: t,
|
||||
toExponential: t,
|
||||
toPrecision: t
|
||||
},
|
||||
MAX_VALUE: t,
|
||||
MIN_VALUE: t,
|
||||
NaN: t,
|
||||
NEGATIVE_INFINITY: t,
|
||||
POSITIVE_INFINITY: t
|
||||
},
|
||||
Math: {
|
||||
E: t,
|
||||
LN10: t,
|
||||
LN2: t,
|
||||
LOG2E: t,
|
||||
LOG10E: t,
|
||||
PI: t,
|
||||
SQRT1_2: t,
|
||||
SQRT2: t,
|
||||
|
||||
abs: t,
|
||||
acos: t,
|
||||
asin: t,
|
||||
atan: t,
|
||||
atan2: t,
|
||||
ceil: t,
|
||||
cos: t,
|
||||
exp: t,
|
||||
floor: t,
|
||||
log: t,
|
||||
max: t,
|
||||
min: t,
|
||||
pow: t,
|
||||
random: t, // questionable
|
||||
round: t,
|
||||
sin: t,
|
||||
sqrt: t,
|
||||
tan: t
|
||||
},
|
||||
Date: { // no-arg Date constructor is questionable
|
||||
prototype: {
|
||||
// Note: coordinate this list with maintanence of repairES5.js
|
||||
getYear: t, // ES5 Appendix B
|
||||
setYear: t, // ES5 Appendix B
|
||||
toGMTString: t, // ES5 Appendix B
|
||||
toDateString: t,
|
||||
toTimeString: t,
|
||||
toLocaleString: t,
|
||||
toLocaleDateString: t,
|
||||
toLocaleTimeString: t,
|
||||
valueOf: t,
|
||||
getTime: t,
|
||||
getFullYear: t,
|
||||
getUTCFullYear: t,
|
||||
getMonth: t,
|
||||
getUTCMonth: t,
|
||||
getDate: t,
|
||||
getUTCDate: t,
|
||||
getDay: t,
|
||||
getUTCDay: t,
|
||||
getHours: t,
|
||||
getUTCHours: t,
|
||||
getMinutes: t,
|
||||
getUTCMinutes: t,
|
||||
getSeconds: t,
|
||||
getUTCSeconds: t,
|
||||
getMilliseconds: t,
|
||||
getUTCMilliseconds: t,
|
||||
getTimezoneOffset: t,
|
||||
setTime: t,
|
||||
setFullYear: t,
|
||||
setUTCFullYear: t,
|
||||
setMonth: t,
|
||||
setUTCMonth: t,
|
||||
setDate: t,
|
||||
setUTCDate: t,
|
||||
setHours: t,
|
||||
setUTCHours: t,
|
||||
setMinutes: t,
|
||||
setUTCMinutes: t,
|
||||
setSeconds: t,
|
||||
setUTCSeconds: t,
|
||||
setMilliseconds: t,
|
||||
setUTCMilliseconds: t,
|
||||
toUTCString: t,
|
||||
toISOString: t,
|
||||
toJSON: t
|
||||
},
|
||||
parse: t,
|
||||
UTC: t,
|
||||
now: t // questionable
|
||||
},
|
||||
RegExp: {
|
||||
prototype: {
|
||||
exec: t,
|
||||
test: t,
|
||||
source: 'maybeAccessor',
|
||||
global: 'maybeAccessor',
|
||||
ignoreCase: 'maybeAccessor',
|
||||
multiline: 'maybeAccessor',
|
||||
flags: 'maybeAccessor',
|
||||
unicode: 'maybeAccessor',
|
||||
lastIndex: '*',
|
||||
options: '*', // non-std
|
||||
sticky: 'maybeAccessor' // non-std
|
||||
}
|
||||
},
|
||||
Error: {
|
||||
prototype: {
|
||||
name: '*',
|
||||
message: '*'
|
||||
}
|
||||
},
|
||||
// In ES6 the *Error "subclasses" of Error inherit from Error,
|
||||
// since constructor inheritance generally mirrors prototype
|
||||
// inheritance. As explained at
|
||||
// https://code.google.com/p/google-caja/issues/detail?id=1963 ,
|
||||
// debug.js hides away the Error constructor itself, and so needs
|
||||
// to rewire these "subclass" constructors. Until we have a more
|
||||
// general mechanism, please maintain this list of whitelisted
|
||||
// subclasses in sync with the list in debug.js of subclasses to
|
||||
// be rewired.
|
||||
EvalError: {
|
||||
prototype: t
|
||||
},
|
||||
RangeError: {
|
||||
prototype: t
|
||||
},
|
||||
ReferenceError: {
|
||||
prototype: t
|
||||
},
|
||||
SyntaxError: {
|
||||
prototype: t
|
||||
},
|
||||
TypeError: {
|
||||
prototype: t
|
||||
},
|
||||
URIError: {
|
||||
prototype: t
|
||||
},
|
||||
JSON: {
|
||||
parse: t,
|
||||
stringify: t
|
||||
},
|
||||
|
||||
|
||||
///////////////// Standard Starting in ES6 //////////////////
|
||||
|
||||
ArrayBuffer: { // Khronos Typed Arrays spec; ops are safe
|
||||
length: t, // does not inherit from Function.prototype on Chrome
|
||||
name: t, // ditto
|
||||
isView: t,
|
||||
prototype: {
|
||||
byteLength: 'maybeAccessor',
|
||||
slice: t
|
||||
}
|
||||
},
|
||||
Int8Array: TypedArrayWhitelist,
|
||||
Uint8Array: TypedArrayWhitelist,
|
||||
Uint8ClampedArray: TypedArrayWhitelist,
|
||||
Int16Array: TypedArrayWhitelist,
|
||||
Uint16Array: TypedArrayWhitelist,
|
||||
Int32Array: TypedArrayWhitelist,
|
||||
Uint32Array: TypedArrayWhitelist,
|
||||
Float32Array: TypedArrayWhitelist,
|
||||
Float64Array: TypedArrayWhitelist,
|
||||
DataView: { // Typed Arrays spec
|
||||
length: t, // does not inherit from Function.prototype on Chrome
|
||||
name: t, // ditto
|
||||
prototype: {
|
||||
buffer: 'maybeAccessor',
|
||||
byteOffset: 'maybeAccessor',
|
||||
byteLength: 'maybeAccessor',
|
||||
getInt8: t,
|
||||
getUint8: t,
|
||||
getInt16: t,
|
||||
getUint16: t,
|
||||
getInt32: t,
|
||||
getUint32: t,
|
||||
getFloat32: t,
|
||||
getFloat64: t,
|
||||
setInt8: t,
|
||||
setUint8: t,
|
||||
setInt16: t,
|
||||
setUint16: t,
|
||||
setInt32: t,
|
||||
setUint32: t,
|
||||
setFloat32: t,
|
||||
setFloat64: t
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright (C) 2016 salesforce.com, inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
// to guarantee that all custom rules are loaded before creating the config
|
||||
require('./load-rules.js');
|
||||
|
||||
var ERROR = 2;
|
||||
var WARNING = 1;
|
||||
var IGNORE = 0;
|
||||
|
||||
// eslint config
|
||||
module.exports = {
|
||||
version: false,
|
||||
eslintrc: false,
|
||||
env: {
|
||||
browser: true
|
||||
},
|
||||
parserOptions: {
|
||||
ecmaVersion: 5
|
||||
},
|
||||
globals: {
|
||||
"$A": true,
|
||||
"AuraContext": true,
|
||||
"AuraSerializationService": true,
|
||||
"AuraExpressionService": true,
|
||||
"AuraEventService": true,
|
||||
"AuraLocalizationService": true,
|
||||
"AuraStorageService": true,
|
||||
"AuraStyleService": true,
|
||||
"MetricsService": true,
|
||||
"AuraDevToolService": true,
|
||||
"Component": true,
|
||||
"CKEDITOR": true,
|
||||
"FORCE": true,
|
||||
"moment": true,
|
||||
"exports": true,
|
||||
"iScroll": true,
|
||||
"unescape": true,
|
||||
"Promise": true
|
||||
},
|
||||
rules: {
|
||||
// custom rules
|
||||
"ecma-intrinsics": ERROR,
|
||||
"new-rule-template": IGNORE,
|
||||
"secure-document": ERROR,
|
||||
"aura-api": ERROR,
|
||||
"secure-window": ERROR,
|
||||
|
||||
// platform rules that as immutable
|
||||
"no-alert": ERROR,
|
||||
"no-array-constructor": ERROR, // help with instanceof
|
||||
"no-bitwise": WARNING, // usually a typo | -> ||
|
||||
"no-caller": ERROR, // strict mode compliance
|
||||
"no-catch-shadow": ERROR,
|
||||
"no-cond-assign": ERROR,
|
||||
"no-console": ERROR,
|
||||
"no-constant-condition": ERROR,
|
||||
"no-control-regex": WARNING,
|
||||
"no-debugger": ERROR,
|
||||
"no-delete-var": WARNING, // for perf reasons, we might want to set this to 2
|
||||
"no-div-regex": WARNING,
|
||||
"no-dupe-keys": ERROR,
|
||||
"no-dupe-args": ERROR,
|
||||
"no-duplicate-case": ERROR,
|
||||
"no-else-return": IGNORE,
|
||||
"no-empty-character-class": ERROR,
|
||||
"no-eq-null": WARNING,
|
||||
"no-eval": ERROR,
|
||||
"no-ex-assign": ERROR,
|
||||
"no-extend-native": ERROR,
|
||||
"no-extra-bind": ERROR,
|
||||
"no-extra-boolean-cast": ERROR,
|
||||
"no-fallthrough": ERROR, // switch fallthrough
|
||||
"no-floating-decimal": WARNING, // var num = .5;
|
||||
"no-func-assign": ERROR,
|
||||
"no-implied-eval": ERROR,
|
||||
"no-inner-declarations": [ERROR, "functions"],
|
||||
"no-invalid-regexp": ERROR,
|
||||
"no-irregular-whitespace": ERROR,
|
||||
"no-iterator": ERROR,
|
||||
"no-label-var": ERROR,
|
||||
"no-labels": ERROR,
|
||||
"no-loop-func": ERROR,
|
||||
"no-multi-str": ERROR,
|
||||
"no-native-reassign": ERROR,
|
||||
"no-negated-in-lhs": ERROR,
|
||||
"no-nested-ternary": WARNING,
|
||||
"no-new": ERROR,
|
||||
"no-new-func": ERROR,
|
||||
"no-new-object": ERROR,
|
||||
"no-new-wrappers": ERROR,
|
||||
"no-obj-calls": ERROR,
|
||||
"no-octal": ERROR,
|
||||
"no-octal-escape": ERROR,
|
||||
"no-param-reassign": WARNING,
|
||||
"no-plusplus": WARNING,
|
||||
"no-proto": ERROR,
|
||||
"no-redeclare": ERROR,
|
||||
"no-regex-spaces": ERROR,
|
||||
"no-return-assign": ERROR,
|
||||
"no-script-url": ERROR,
|
||||
"no-self-compare": ERROR,
|
||||
"no-sequences": ERROR, // var a = (3, 5);
|
||||
"no-shadow": ERROR,
|
||||
"no-shadow-restricted-names": ERROR,
|
||||
"no-sparse-arrays": ERROR,
|
||||
"no-ternary": IGNORE,
|
||||
"no-throw-literal": WARNING,
|
||||
"no-undef": WARNING,
|
||||
"no-undef-init": WARNING,
|
||||
"no-undefined": IGNORE,
|
||||
"no-underscore-dangle": IGNORE,
|
||||
"no-unreachable": ERROR,
|
||||
"no-unused-expressions": WARNING,
|
||||
"no-unused-vars": [WARNING, {"vars": "all", "args": "after-used"}],
|
||||
"no-use-before-define": [ERROR, { "functions": false }],
|
||||
"no-void": ERROR,
|
||||
"no-var": IGNORE,
|
||||
"no-with": ERROR,
|
||||
"consistent-return": WARNING,
|
||||
"default-case": ERROR,
|
||||
"dot-notation": [WARNING, { "allowKeywords": true }],
|
||||
"eqeqeq": ["error", "smart"],
|
||||
"guard-for-in": WARNING,
|
||||
"handle-callback-err": WARNING,
|
||||
"new-parens": ERROR,
|
||||
"radix": ERROR,
|
||||
"strict": [ERROR, "global"],
|
||||
"use-isnan": ERROR,
|
||||
"valid-typeof": ERROR,
|
||||
"wrap-iife": [WARNING, "any"]
|
||||
|
||||
// aside from this list, ./code-style-rules.js will have the rules that are not
|
||||
// important for the code to function, but just stylish.
|
||||
}
|
||||
};
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (C) 2016 salesforce.com, inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
rules: {
|
||||
// code style rules, these are the default value, but the user can
|
||||
// customize them via --config in the linter by providing custom values
|
||||
// for each of these rules.
|
||||
"no-trailing-spaces": 1,
|
||||
"no-spaced-func": 1,
|
||||
"no-mixed-spaces-and-tabs": 0,
|
||||
"no-multi-spaces": 0,
|
||||
"no-multiple-empty-lines": 0,
|
||||
"no-lone-blocks": 1,
|
||||
"no-lonely-if": 1,
|
||||
"no-inline-comments": 0,
|
||||
"no-extra-parens": 0,
|
||||
"no-extra-semi": 1,
|
||||
"no-warning-comments": [0, { "terms": ["todo", "fixme", "xxx"], "location": "start" }],
|
||||
"block-scoped-var": 1,
|
||||
"brace-style": [1, "1tbs"],
|
||||
"camelcase": 1,
|
||||
"comma-dangle": [1, "never"],
|
||||
"comma-spacing": 1,
|
||||
"comma-style": 1,
|
||||
"complexity": [0, 11],
|
||||
"consistent-this": [0, "that"],
|
||||
"curly": [1, "all"],
|
||||
"eol-last": 0,
|
||||
"func-names": 0,
|
||||
"func-style": [0, "declaration"],
|
||||
"generator-star-spacing": 0,
|
||||
"indent": 0,
|
||||
"key-spacing": 0,
|
||||
"keyword-spacing": [0],
|
||||
"max-depth": [0, 4],
|
||||
"max-len": [0, 80, 4],
|
||||
"max-nested-callbacks": [0, 2],
|
||||
"max-params": [0, 3],
|
||||
"max-statements": [0, 10],
|
||||
"new-cap": 0,
|
||||
"newline-after-var": 0,
|
||||
"one-var": [0, "never"],
|
||||
"operator-assignment": [0, "always"],
|
||||
"padded-blocks": 0,
|
||||
"quote-props": 0,
|
||||
"quotes": 0,
|
||||
"semi": 1,
|
||||
"semi-spacing": [0, {"before": false, "after": true}],
|
||||
"sort-vars": 0,
|
||||
"space-after-function-name": [0, "never"],
|
||||
"space-before-blocks": [0, "always"],
|
||||
"space-before-function-paren": [0, "always"],
|
||||
"space-before-function-parentheses": [0, "always"],
|
||||
"space-in-brackets": [0, "never"],
|
||||
"space-in-parens": [0, "never"],
|
||||
"space-infix-ops": 0,
|
||||
"space-unary-ops": [1, { "words": true, "nonwords": false }],
|
||||
"spaced-comment": [0, "always"],
|
||||
"vars-on-top": 0,
|
||||
"valid-jsdoc": 0,
|
||||
"wrap-regex": 0,
|
||||
"yoda": [1, "never"]
|
||||
}
|
||||
};
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2016 salesforce.com, inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var defaultConfig = require('./aura-component-config');
|
||||
var defaultStyle = require('./code-style-rules');
|
||||
var objectAssign = require('object-assign');
|
||||
|
||||
var config = {};
|
||||
objectAssign(config, defaultConfig);
|
||||
objectAssign(config.rules, defaultStyle.rules);
|
||||
|
||||
module.exports = config;
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (C) 2016 salesforce.com, inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
// Standard Global Event handlers
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers
|
||||
onabort: true,
|
||||
onblur: true,
|
||||
onchange: true,
|
||||
onclick: true,
|
||||
onclose: true,
|
||||
oncontextmenu: true,
|
||||
ondblclick: true,
|
||||
onerror: true,
|
||||
onfocus: true,
|
||||
oninput: true,
|
||||
onkeydown: true,
|
||||
onkeypress: true,
|
||||
onkeyup: true,
|
||||
onload: true,
|
||||
onmousedown: true,
|
||||
onmousemove: true,
|
||||
onmouseout: true,
|
||||
onmouseover: true,
|
||||
onmouseup: true,
|
||||
onreset: true,
|
||||
onresize: true,
|
||||
onscroll: true,
|
||||
onselect: true,
|
||||
onsubmit: true,
|
||||
|
||||
// Standard Element interface represents an object of a Document.
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Element#Properties
|
||||
childElementCount: '*',
|
||||
classList: '*',
|
||||
className: '*',
|
||||
id: '*',
|
||||
tagName: '*',
|
||||
namespaceURI: '*',
|
||||
// Note: ignoring 'firstElementChild', 'lastElementChild',
|
||||
// 'nextElementSibling' and 'previousElementSibling' from the list
|
||||
// above.
|
||||
|
||||
// Standard HTMLElement interface represents any HTML element
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement#Properties
|
||||
accessKey: '*',
|
||||
accessKeyLabel: '*',
|
||||
contentEditable: '*',
|
||||
isContentEditable: '*',
|
||||
contextMenu: '*',
|
||||
dataset: '*',
|
||||
dir: '*',
|
||||
draggable: '*',
|
||||
dropzone: '*',
|
||||
hidden: '*',
|
||||
lang: '*',
|
||||
spellcheck: '*',
|
||||
style: '*',
|
||||
tabIndex: '*',
|
||||
title: '*',
|
||||
offsetHeight: '*',
|
||||
offsetLeft: '*',
|
||||
offsetParent: '*',
|
||||
offsetTop: '*',
|
||||
offsetWidth: '*',
|
||||
clientWidth: '*',
|
||||
clientHeight: '*',
|
||||
clientLeft: '*',
|
||||
clientTop: '*',
|
||||
nodeValue: '*',
|
||||
nodeType: '*',
|
||||
childNodes: '*',
|
||||
|
||||
// other DOM methods
|
||||
getElementById: true,
|
||||
getElementsByClassName: true,
|
||||
getElementsByName: true,
|
||||
getElementsByTagName: true,
|
||||
getElementsByTagNameNS: true,
|
||||
querySelector: true,
|
||||
querySelectorAll: true
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2016 salesforce.com, inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
// event target methods
|
||||
addEventListener: true,
|
||||
dispatchEvent: true,
|
||||
removeEventListener: true
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (C) 2016 salesforce.com, inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
// Standard Global Event handlers
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers
|
||||
onabort: true,
|
||||
onblur: true,
|
||||
onchange: true,
|
||||
onclick: true,
|
||||
onclose: true,
|
||||
oncontextmenu: true,
|
||||
ondblclick: true,
|
||||
onerror: true,
|
||||
onfocus: true,
|
||||
oninput: true,
|
||||
onkeydown: true,
|
||||
onkeypress: true,
|
||||
onkeyup: true,
|
||||
onload: true,
|
||||
onmousedown: true,
|
||||
onmousemove: true,
|
||||
onmouseout: true,
|
||||
onmouseover: true,
|
||||
onmouseup: true,
|
||||
onreset: true,
|
||||
onresize: true,
|
||||
onscroll: true,
|
||||
onselect: true,
|
||||
onsubmit: true
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (C) 2016 salesforce.com, inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
// Standard Node APIs
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Node
|
||||
ATTRIBUTE_NODE: '*',
|
||||
CDATA_SECTION_NODE: '*',
|
||||
COMMENT_NODE: '*',
|
||||
DOCUMENT_FRAGMENT_NODE: '*',
|
||||
DOCUMENT_NODE: '*',
|
||||
DOCUMENT_POSITION_CONTAINED_BY: '*',
|
||||
DOCUMENT_POSITION_CONTAINS: '*',
|
||||
DOCUMENT_POSITION_DISCONNECTED: '*',
|
||||
DOCUMENT_POSITION_FOLLOWING: '*',
|
||||
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: '*',
|
||||
DOCUMENT_POSITION_PRECEDING: '*',
|
||||
DOCUMENT_TYPE_NODE: '*',
|
||||
ELEMENT_NODE: '*',
|
||||
ENTITY_NODE: '*',
|
||||
ENTITY_REFERENCE_NODE: '*',
|
||||
NOTATION_NODE: '*',
|
||||
PROCESSING_INSTRUCTION_NODE: '*',
|
||||
TEXT_NODE: '*',
|
||||
appendChild: true,
|
||||
baseURI: '*',
|
||||
childNodes: '*',
|
||||
cloneNode: true,
|
||||
compareDocumentPosition: true,
|
||||
contains: true,
|
||||
firstChild: '*',
|
||||
insertBefore: true,
|
||||
isDefaultNamespace: true,
|
||||
isEqualNode: true,
|
||||
isSameNode: true,
|
||||
lastChild: '*',
|
||||
lookupNamespaceURI: true,
|
||||
lookupPrefix: true,
|
||||
nextSibling: '*',
|
||||
nodeName: '*',
|
||||
nodeType: '*',
|
||||
nodeValue: '*',
|
||||
normalize: true,
|
||||
ownerDocument: '*',
|
||||
parentElement: '*',
|
||||
parentNode: '*',
|
||||
previousSibling: '*',
|
||||
removeChild: true,
|
||||
replaceChild: true,
|
||||
textContent: '*'
|
||||
};
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* Copyright (C) 2016 salesforce.com, inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var glob = require('glob');
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var cli = require('heroku-cli-util');
|
||||
var linter = require('eslint').linter;
|
||||
var defaultConfig = require('./config');
|
||||
var defaultStyle = require('./code-style-rules');
|
||||
var objectAssign = require('object-assign');
|
||||
var formatter = require('eslint-friendly-formatter');
|
||||
|
||||
var SINGLETON_FILE_REGEXP = /(Controller|Renderer|Helper|Provider|Test|Model)\.js$/;
|
||||
|
||||
function noop() {}
|
||||
|
||||
// this computes the first position after all the comments (multi-line and single-line)
|
||||
// from the top of the code
|
||||
function afterCommentsPosition(code) {
|
||||
var position = 0;
|
||||
var match;
|
||||
do {
|
||||
// /\*.*?\*/
|
||||
match = code.match(/^(\s*(\/\*([\s\S]*?)\*\/)?\s*)/);
|
||||
if (!match || !match[1]) {
|
||||
match = code.match(/^(\s*\/\/.*\s*)/);
|
||||
}
|
||||
if (match && match[1]) {
|
||||
position += match[1].length;
|
||||
code = code.slice(match[1].length);
|
||||
}
|
||||
} while (match);
|
||||
return position;
|
||||
}
|
||||
|
||||
function processSingletonCode(code) {
|
||||
// transform `({...})` into `"use strict"; exports = ({...});`
|
||||
var pos = afterCommentsPosition(code);
|
||||
if (code.charAt(pos) === '(') {
|
||||
code = code.slice(0, pos) + '"use strict"; exports = ' + code.slice(pos);
|
||||
pos = code.lastIndexOf(')') + 1;
|
||||
if (code.charAt(pos) !== ';') {
|
||||
code = code.slice(0, pos) + ';' + code.slice(pos);
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
function processFunctionCode(code) {
|
||||
// transform `function () {}` into `"use strict"; exports = function () {};`
|
||||
var pos = afterCommentsPosition(code);
|
||||
if (code.indexOf('function', pos) === pos) {
|
||||
code = code.slice(0, pos) + '"use strict"; exports = ' + code.slice(pos);
|
||||
pos = code.lastIndexOf('}') + 1;
|
||||
if (code.charAt(pos) !== ';') {
|
||||
code = code.slice(0, pos) + ';' + code.slice(pos);
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
function process(src, config, options) {
|
||||
var messages = linter.verify(src, config, {
|
||||
allowInlineConfig: true, // TODO: internal code should be linted with this set to false
|
||||
quiet: true
|
||||
});
|
||||
|
||||
if (!options.verbose) {
|
||||
messages = messages.filter(function (msg) {
|
||||
return msg.severity > 1;
|
||||
});
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
module.exports = function (cwd, opts, context) {
|
||||
// No log, debug or warn functions if --json option is passed
|
||||
var log = opts.json ? noop : cli.log;
|
||||
var debug = opts.json ? noop : cli.debug;
|
||||
var warn = opts.json ? noop : cli.warn;
|
||||
|
||||
var ignore = [
|
||||
// these are the things that we know for sure we never want to inspect
|
||||
'**/node_modules/**',
|
||||
'**/jsdoc/**',
|
||||
'**/htdocs/**',
|
||||
'**/invalidTest/**',
|
||||
'**/purposelyInvalid/**',
|
||||
'**/invalidTestData/**',
|
||||
'**/validationTest/**',
|
||||
'**/lintTest/**',
|
||||
'**/target/**',
|
||||
'**/parseError/**',
|
||||
'**/*.junk.js',
|
||||
'**/*_mock?.js'
|
||||
].concat(opts.ignore ? [opts.ignore] : []);
|
||||
|
||||
var globOptions = {
|
||||
silent: true,
|
||||
cwd: cwd,
|
||||
nodir: true,
|
||||
realpath: true,
|
||||
ignore: ignore
|
||||
};
|
||||
|
||||
var patterns = [opts.files || '**/*.js'];
|
||||
|
||||
var config = {};
|
||||
objectAssign(config, defaultConfig);
|
||||
config.rules = objectAssign({}, defaultConfig.rules);
|
||||
|
||||
if (opts.config) {
|
||||
log('Applying custom rules from ' + opts.config);
|
||||
var customStyle = require(path.join(context.cwd, opts.config));
|
||||
if (customStyle && customStyle.rules) {
|
||||
Object.keys(customStyle.rules).forEach(function (name) {
|
||||
if (defaultStyle.rules.hasOwnProperty(name)) {
|
||||
config.rules[name] = customStyle.rules[name];
|
||||
debug(' -> Rule: ' + name + ' is now set to ' + JSON.stringify(config.rules[name]));
|
||||
} else {
|
||||
debug(' -> Ignoring non-style rule: ' + name);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Using local debug function for non-json text
|
||||
debug('Search for "' + patterns.join('" or "') + '" in folder "' + cwd + '"');
|
||||
debug(' -> Ignoring: ' + ignore.join(','));
|
||||
|
||||
var files = [];
|
||||
// for blt-like structures we look for aura structures
|
||||
// and we search from there to narrow down the search.
|
||||
var folders = glob.sync('**/*.{app,cmp,lib}', globOptions);
|
||||
folders = folders.map(function (v) {
|
||||
return path.dirname(v);
|
||||
});
|
||||
folders = folders.filter(function (v, i) {
|
||||
return folders.indexOf(v) === i;
|
||||
});
|
||||
|
||||
folders.forEach(function (folder) {
|
||||
globOptions.cwd = folder;
|
||||
patterns.forEach(function (pattern) {
|
||||
files = files.concat(glob.sync(pattern, globOptions));
|
||||
});
|
||||
});
|
||||
|
||||
// deduping...
|
||||
files = files.filter(function (v, i) {
|
||||
return files.indexOf(v) === i;
|
||||
});
|
||||
|
||||
if (files.length) {
|
||||
log('Found ' + files.length + ' matching files.\n----------------');
|
||||
|
||||
var output = [];
|
||||
files.forEach(function (file) {
|
||||
var source = fs.readFileSync(file, 'utf8');
|
||||
|
||||
// in some cases, we need to massage the source before linting it
|
||||
if (SINGLETON_FILE_REGEXP.test(file)) {
|
||||
source = processSingletonCode(source);
|
||||
} else {
|
||||
source = processFunctionCode(source);
|
||||
}
|
||||
|
||||
var messages = process(source, config, opts);
|
||||
if (messages) {
|
||||
if (opts.json) {
|
||||
output.push({
|
||||
file: file,
|
||||
result: messages
|
||||
})
|
||||
} else {
|
||||
log('FILE: ' + file + ':');
|
||||
log(formatter([{
|
||||
messages: messages,
|
||||
filePath: '<input>'
|
||||
}]).replace(/<input>/g, 'Line'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// printout JSON string to STDOUT
|
||||
if (opts.json) {
|
||||
cli.log(JSON.stringify(output, null, 4));
|
||||
}
|
||||
} else {
|
||||
warn('Did not find matching files.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (C) 2016 salesforce.com, inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var rules = require('eslint/lib/rules');
|
||||
var ruleLoader = require('eslint/lib/load-rules');
|
||||
var customRules = ruleLoader('../rules', __dirname);
|
||||
|
||||
Object.keys(customRules).forEach(function (name) {
|
||||
rules.define(name, customRules[name]);
|
||||
});
|
||||
|
||||
module.exports = rules;
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (C) 2016 salesforce.com, inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the property name of a MemberExpression.
|
||||
* @param {ASTNode} memberExpressionNode The MemberExpression node.
|
||||
* @returns {string|null} Returns the property name if available, null else.
|
||||
*/
|
||||
function getPropertyName(memberExpressionNode) {
|
||||
if (memberExpressionNode.computed) {
|
||||
if (memberExpressionNode.property.type === "Literal") {
|
||||
return memberExpressionNode.property.value;
|
||||
}
|
||||
} else {
|
||||
return memberExpressionNode.property.name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the escope reference in the given scope.
|
||||
* @param {Object} scope The scope to search.
|
||||
* @param {ASTNode} node The identifier node.
|
||||
* @returns {Reference|null} Returns the found reference or null if none were found.
|
||||
*/
|
||||
function findReference(scope, node) {
|
||||
var references = scope.references.filter(function(reference) {
|
||||
return reference.identifier.range[0] === node.range[0] &&
|
||||
reference.identifier.range[1] === node.range[1];
|
||||
});
|
||||
|
||||
if (references.length === 1) {
|
||||
return references[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given identifier node is shadowed in the given scope.
|
||||
* @param {Object} scope The current scope.
|
||||
* @param {Object} globalScope The global scope.
|
||||
* @param {string} node The identifier node to check
|
||||
* @returns {boolean} Whether or not the name is shadowed.
|
||||
*/
|
||||
function isShadowed(scope, globalScope, node) {
|
||||
var reference = findReference(scope, node);
|
||||
return reference && reference.resolved && reference.resolved.defs.length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all the nodes used by a composed member expression.
|
||||
* E.g.: Array.prototype.slice should produce
|
||||
* [{type: "Identifier", name: "Array"}, {type: "Identifier", name: "prototype"}, {type: "Identifier", name: "slice"}]
|
||||
* @param {ASTNode} node The MemberExpression node.
|
||||
* @returns {Array} Returns a list of nodes that represent the namespace.
|
||||
*/
|
||||
function buildMemberExpressionNamespace(currentScope, globalScope, node) {
|
||||
var ns = [];
|
||||
do {
|
||||
ns.unshift(node.property);
|
||||
if (node.object.type === "MemberExpression") {
|
||||
node = node.object;
|
||||
} else if (!isGlobalThisReferenceOrGlobalWindow(currentScope, globalScope, node.object)) {
|
||||
ns.unshift(node.object);
|
||||
node = undefined;
|
||||
} else {
|
||||
node = undefined;
|
||||
}
|
||||
} while (node);
|
||||
return ns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given identifier node is a ThisExpression in the global scope or the global window property.
|
||||
* @param {Object} scope The current scope.
|
||||
* @param {Object} globalScope The global scope.
|
||||
* @param {string} node The identifier node to check
|
||||
* @returns {boolean} Whether or not the node is a reference to the global object.
|
||||
*/
|
||||
function isGlobalThisReferenceOrGlobalWindow(scope, globalScope, node) {
|
||||
if (scope.type === "global" && node.type === "ThisExpression") {
|
||||
return true;
|
||||
} else if (node.name === "window") {
|
||||
return !isShadowed(scope, globalScope, node);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getPropertyName,
|
||||
findReference,
|
||||
isShadowed,
|
||||
isGlobalThisReferenceOrGlobalWindow,
|
||||
buildMemberExpressionNamespace
|
||||
};
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Copyright (C) 2016 salesforce.com, inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var util = require('../lib/util.js');
|
||||
|
||||
// This structure follows the same schema of the whitelisting mechanism from SES
|
||||
// for ecma intrinsics, more details on ../lib/3rdparty/ses/whiteslit.js
|
||||
var AuraAPI = {
|
||||
$A: {
|
||||
createComponent: true,
|
||||
createComponents: true,
|
||||
enqueueAction: true,
|
||||
get: true,
|
||||
getCallback: true,
|
||||
getComponent: true,
|
||||
getReference: true,
|
||||
getRoot: true,
|
||||
getToken: true,
|
||||
log: true,
|
||||
reportError: true,
|
||||
toString: true,
|
||||
warning: true,
|
||||
util: {
|
||||
addClass: true,
|
||||
getBooleanValue: true,
|
||||
hasClass: true,
|
||||
isArray: true,
|
||||
isEmpty: true,
|
||||
isObject: true,
|
||||
isUndefined: true,
|
||||
isUndefinedOrNull: true,
|
||||
removeClass: true,
|
||||
toggleClass: true
|
||||
},
|
||||
localizationService: {
|
||||
displayDuration: true,
|
||||
displayDurationInDays: true,
|
||||
displayDurationInHours: true,
|
||||
displayDurationInMilliseconds: true,
|
||||
displayDurationInMinutes: true,
|
||||
displayDurationInMonths: true,
|
||||
displayDurationInSeconds: true,
|
||||
duration: true,
|
||||
endOf: true,
|
||||
formatCurrency: true,
|
||||
formatDate: true,
|
||||
formatDateTime: true,
|
||||
formatDateTimeUTC: true,
|
||||
formatDateUTC: true,
|
||||
formatNumber: true,
|
||||
formatPercent: true,
|
||||
formatTime: true,
|
||||
formatTimeUTC: true,
|
||||
getDateStringBasedOnTimezone: true,
|
||||
getDaysInDuration: true,
|
||||
getDefaultCurrencyFormat: true,
|
||||
getDefaultNumberFormat: true,
|
||||
getDefaultPercentFormat: true,
|
||||
getHoursInDuration: true,
|
||||
getLocalizedDateTimeLabels: true,
|
||||
getMillisecondsInDuration: true,
|
||||
getMinutesInDuration: true,
|
||||
getMonthsInDuration: true,
|
||||
getNumberFormat: true,
|
||||
getSecondsInDuration: true,
|
||||
getToday: true,
|
||||
getYearsInDuration: true,
|
||||
isAfter: true,
|
||||
isBefore: true,
|
||||
isPeriodTimeView: true,
|
||||
isSame: true,
|
||||
parseDateTime: true,
|
||||
parseDateTimeISO8601: true,
|
||||
parseDateTimeUTC: true,
|
||||
startOf: true,
|
||||
toISOString: true,
|
||||
translateFromLocalizedDigits: true,
|
||||
translateFromOtherCalendar: true,
|
||||
translateToLocalizedDigits: true,
|
||||
translateToOtherCalendar: true,
|
||||
UTCToWallTime: true,
|
||||
WallTimeToUTC: true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = function(context) {
|
||||
var globalScope;
|
||||
|
||||
return {
|
||||
|
||||
"Program": function() {
|
||||
globalScope = context.getScope();
|
||||
},
|
||||
|
||||
MemberExpression: function(node) {
|
||||
if (node.parent.type === "MemberExpression") {
|
||||
// ignoring intermediate member expressions
|
||||
return;
|
||||
}
|
||||
var currentScope = context.getScope();
|
||||
var ns = util.buildMemberExpressionNamespace(currentScope, globalScope, node);
|
||||
if (ns.length > 0) {
|
||||
var rootIdentifier = ns[0];
|
||||
if (rootIdentifier.type !== "Identifier" || rootIdentifier.name !== "$A" || util.isShadowed(currentScope, globalScope, rootIdentifier)) {
|
||||
return;
|
||||
}
|
||||
var api = AuraAPI;
|
||||
for (var i = 0; i < ns.length; i++) {
|
||||
var identifier = ns[i];
|
||||
if (identifier.type !== 'Identifier') {
|
||||
context.report(node, "Invalid Aura API, use dot notation instead");
|
||||
return;
|
||||
}
|
||||
var token = identifier.name;
|
||||
var nextIdentifier = ns[i + 1];
|
||||
if (typeof api !== "object") {
|
||||
context.report(node, "Invalid Aura API");
|
||||
return;
|
||||
}
|
||||
if (!api.hasOwnProperty(token)) {
|
||||
context.report(node, "Invalid Aura API");
|
||||
return;
|
||||
}
|
||||
if (api[token] === '*') {
|
||||
// anything from this point on is good
|
||||
return;
|
||||
}
|
||||
if (typeof (api[token]) === 'object' && Object.keys(api[token]).length === 0) {
|
||||
// nothing else to inspect
|
||||
return;
|
||||
}
|
||||
if (api[token] === true && !nextIdentifier) {
|
||||
// function call
|
||||
return;
|
||||
}
|
||||
if (api[token] === true && nextIdentifier && nextIdentifier.type === 'Identifier' && (nextIdentifier.name === 'apply' || nextIdentifier.name === 'call')) {
|
||||
// function call with .apply() or .call() are still valid
|
||||
return;
|
||||
}
|
||||
if (api[token] === false && nextIdentifier === undefined) {
|
||||
return;
|
||||
}
|
||||
api = api[token];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
module.exports.schema = [];
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (C) 2016 salesforce.com, inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var util = require('../lib/util.js');
|
||||
var intrinsics = require('../lib/3rdparty/ses/whitelist').whitelist;
|
||||
var anonIntrinsics = intrinsics.cajaVM.anonIntrinsics;
|
||||
|
||||
module.exports = function(context) {
|
||||
var globalScope;
|
||||
|
||||
return {
|
||||
|
||||
"Program": function() {
|
||||
globalScope = context.getScope();
|
||||
},
|
||||
|
||||
MemberExpression: function(node) {
|
||||
if (node.parent.type === "MemberExpression") {
|
||||
// ignoring intermediate member expressions
|
||||
return;
|
||||
}
|
||||
var currentScope = context.getScope();
|
||||
var ns = util.buildMemberExpressionNamespace(currentScope, globalScope, node);
|
||||
if (ns.length > 0) {
|
||||
var rootIdentifier = ns[0];
|
||||
if (rootIdentifier.type !== "Identifier" || util.isShadowed(currentScope, globalScope, rootIdentifier)) {
|
||||
return;
|
||||
}
|
||||
var api;
|
||||
if (intrinsics.hasOwnProperty(rootIdentifier.name)) {
|
||||
api = intrinsics;
|
||||
} else if (anonIntrinsics.hasOwnProperty(rootIdentifier.name)) {
|
||||
api = anonIntrinsics;
|
||||
} else {
|
||||
return; // nothing to do here, it is not intrinsic
|
||||
}
|
||||
for (var i = 0; i < ns.length; i++) {
|
||||
var identifier = ns[i];
|
||||
if (identifier.type !== 'Identifier') {
|
||||
context.report(node, "Invalid Intrinsic API, use dot notation instead");
|
||||
return;
|
||||
}
|
||||
var token = identifier.name;
|
||||
var nextIdentifier = ns[i + 1];
|
||||
if (typeof api !== "object") {
|
||||
context.report(node, "Invalid Intrinsic API");
|
||||
return;
|
||||
}
|
||||
if (!api || !Object.hasOwnProperty.call(api, token)) {
|
||||
context.report(node, "Invalid Intrinsic API");
|
||||
return;
|
||||
}
|
||||
if (api[token] === '*') {
|
||||
// anything from this point on is good
|
||||
return;
|
||||
}
|
||||
if (typeof (api[token]) === 'object' && Object.keys(api[token]).length === 0) {
|
||||
// nothing else to inspect
|
||||
return;
|
||||
}
|
||||
if (api[token] === true && !nextIdentifier) {
|
||||
// function call
|
||||
return;
|
||||
}
|
||||
if (api[token] === true && nextIdentifier && nextIdentifier.type === 'Identifier' && (nextIdentifier.name === 'apply' || nextIdentifier.name === 'call')) {
|
||||
// function call with .apply() or .call() are still valid
|
||||
return;
|
||||
}
|
||||
if (api[token] === false && nextIdentifier === undefined) {
|
||||
return;
|
||||
}
|
||||
api = api[token];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
module.exports.schema = [];
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (C) 2016 salesforce.com, inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// reference: http://eslint.org/docs/developer-guide/working-with-rules
|
||||
|
||||
"use strict";
|
||||
|
||||
module.exports = function(context) {
|
||||
|
||||
return {
|
||||
// reference AST explorer (https://astexplorer.net/) when constructing your rule.
|
||||
MyNewRule: function(node) {
|
||||
// do something with node
|
||||
context.report({
|
||||
node: node,
|
||||
message: "just for demonstration."
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
module.exports.schema = [];
|
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
* Copyright (C) 2016 salesforce.com, inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var util = require('../lib/util.js');
|
||||
var objectAssign = require('object-assign');
|
||||
|
||||
// This structure follows the same schema of the whitelisting mechanism from SES
|
||||
// for ecma intrinsics, more details on ../lib/3rdparty/ses/whiteslit.js
|
||||
var SecureDocumentAPI = {
|
||||
document: {
|
||||
toString: true,
|
||||
|
||||
// HTMLDocument
|
||||
location: '*',
|
||||
fgColor: '*',
|
||||
linkColor: '*',
|
||||
vlinkColor: '*',
|
||||
alinkColor: '*',
|
||||
bgColor: '*',
|
||||
clear: true,
|
||||
captureEvents: true,
|
||||
releaseEvents: true,
|
||||
|
||||
// Document
|
||||
URL: '*',
|
||||
activeElement: '*',
|
||||
adoptNode: true,
|
||||
anchors: '*',
|
||||
applets: '*',
|
||||
body: '*',
|
||||
caretRangeFromPoint: true,
|
||||
characterSet: '*',
|
||||
charset: '*',
|
||||
childElementCount: '*',
|
||||
children: '*',
|
||||
close: true,
|
||||
compatMode: '*',
|
||||
contentType: '*',
|
||||
cookie: '*',
|
||||
createAttribute: true,
|
||||
createAttributeNS: true,
|
||||
createCDATASection: true,
|
||||
createComment: true,
|
||||
createDocumentFragment: true,
|
||||
createElement: true,
|
||||
createElementNS: true,
|
||||
createEvent: true,
|
||||
createExpression: true,
|
||||
createNSResolver: true,
|
||||
createNodeIterator: true,
|
||||
createProcessingInstruction: true,
|
||||
createRange: true,
|
||||
createTextNode: true,
|
||||
createTreeWalker: true,
|
||||
defaultView: '*',
|
||||
designMode: '*',
|
||||
dir: '*',
|
||||
doctype: '*',
|
||||
documentElement: '*',
|
||||
documentURI: '*',
|
||||
domain: '*',
|
||||
elementFromPoint: true,
|
||||
elementsFromPoint: true,
|
||||
embeds: '*',
|
||||
evaluate: true,
|
||||
execCommand: true,
|
||||
exitPointerLock: true,
|
||||
firstElementChild: '*',
|
||||
fonts: '*',
|
||||
forms: '*',
|
||||
getElementById: true,
|
||||
getElementsByClassName: true,
|
||||
getElementsByName: true,
|
||||
getElementsByTagName: true,
|
||||
getElementsByTagNameNS: true,
|
||||
getSelection: true,
|
||||
hasFocus: true,
|
||||
head: '*',
|
||||
hidden: '*',
|
||||
images: '*',
|
||||
implementation: '*',
|
||||
importNode: true,
|
||||
inputEncoding: '*',
|
||||
lastElementChild: '*',
|
||||
lastModified: '*',
|
||||
links: '*',
|
||||
onabort: true,
|
||||
onautocomplete: true,
|
||||
onautocompleteerror: true,
|
||||
onbeforecopy: true,
|
||||
onbeforecut: true,
|
||||
onbeforepaste: true,
|
||||
onblur: true,
|
||||
oncancel: true,
|
||||
oncanplay: true,
|
||||
oncanplaythrough: true,
|
||||
onchange: true,
|
||||
onclick: true,
|
||||
onclose: true,
|
||||
oncontextmenu: true,
|
||||
oncopy: true,
|
||||
oncuechange: true,
|
||||
oncut: true,
|
||||
ondblclick: true,
|
||||
ondrag: true,
|
||||
ondragend: true,
|
||||
ondragenter: true,
|
||||
ondragleave: true,
|
||||
ondragover: true,
|
||||
ondragstart: true,
|
||||
ondrop: true,
|
||||
ondurationchange: true,
|
||||
onemptied: true,
|
||||
onended: true,
|
||||
onerror: true,
|
||||
onfocus: true,
|
||||
oninput: true,
|
||||
oninvalid: true,
|
||||
onkeydown: true,
|
||||
onkeypress: true,
|
||||
onkeyup: true,
|
||||
onload: true,
|
||||
onloadeddata: true,
|
||||
onloadedmetadata: true,
|
||||
onloadstart: true,
|
||||
onmousedown: true,
|
||||
onmouseenter: true,
|
||||
onmouseleave: true,
|
||||
onmousemove: true,
|
||||
onmouseout: true,
|
||||
onmouseover: true,
|
||||
onmouseup: true,
|
||||
onmousewheel: true,
|
||||
onpaste: true,
|
||||
onpause: true,
|
||||
onplay: true,
|
||||
onplaying: true,
|
||||
onpointerlockchange: true,
|
||||
onpointerlockerror: true,
|
||||
onprogress: true,
|
||||
onratechange: true,
|
||||
onreadystatechange: true,
|
||||
onreset: true,
|
||||
onresize: true,
|
||||
onscroll: true,
|
||||
onsearch: true,
|
||||
onseeked: true,
|
||||
onseeking: true,
|
||||
onselect: true,
|
||||
onselectionchange: true,
|
||||
onselectstart: true,
|
||||
onshow: true,
|
||||
onstalled: true,
|
||||
onsubmit: true,
|
||||
onsuspend: true,
|
||||
ontimeupdate: true,
|
||||
ontoggle: true,
|
||||
ontouchcancel: true,
|
||||
ontouchend: true,
|
||||
ontouchmove: true,
|
||||
ontouchstart: true,
|
||||
onvolumechange: true,
|
||||
onwaiting: true,
|
||||
onwebkitfullscreenchange: true,
|
||||
onwebkitfullscreenerror: true,
|
||||
onwheel: true,
|
||||
open: true,
|
||||
origin: '*',
|
||||
plugins: '*',
|
||||
pointerLockElement: '*',
|
||||
preferredStylesheetSet: '*',
|
||||
queryCommandEnabled: true,
|
||||
queryCommandIndeterm: true,
|
||||
queryCommandState: true,
|
||||
queryCommandSupported: true,
|
||||
queryCommandValue: true,
|
||||
querySelector: true,
|
||||
querySelectorAll: true,
|
||||
readyState: '*',
|
||||
referrer: '*',
|
||||
registerElement: true,
|
||||
rootElement: '*',
|
||||
scripts: '*',
|
||||
scrollingElement: '*',
|
||||
selectedStylesheetSet: '*',
|
||||
styleSheets: '*',
|
||||
title: '*',
|
||||
visibilityState: '*',
|
||||
webkitCancelFullScreen: true,
|
||||
webkitCurrentFullScreenElement: '*',
|
||||
webkitExitFullscreen: true,
|
||||
webkitFullscreenElement: '*',
|
||||
webkitFullscreenEnabled: '*',
|
||||
webkitHidden: '*',
|
||||
webkitIsFullScreen: '*',
|
||||
webkitVisibilityState: '*',
|
||||
write: true,
|
||||
writeln: true,
|
||||
xmlEncoding: '*',
|
||||
xmlStandalone: '*',
|
||||
xmlVersion: '*'
|
||||
}
|
||||
};
|
||||
|
||||
objectAssign(SecureDocumentAPI.document, require('../lib/dom/element.js'));
|
||||
objectAssign(SecureDocumentAPI.document, require('../lib/dom/global-event-handlers.js'));
|
||||
objectAssign(SecureDocumentAPI.document, require('../lib/dom/event-target-methods.js'));
|
||||
objectAssign(SecureDocumentAPI.document, require('../lib/dom/node.js'));
|
||||
|
||||
module.exports = function(context) {
|
||||
var globalScope;
|
||||
|
||||
return {
|
||||
|
||||
"Program" : function() {
|
||||
globalScope = context.getScope();
|
||||
},
|
||||
|
||||
MemberExpression: function(node) {
|
||||
if (node.parent.type === "MemberExpression") {
|
||||
// ignoring intermediate member expressions
|
||||
return;
|
||||
}
|
||||
var currentScope = context.getScope();
|
||||
var ns = util.buildMemberExpressionNamespace(currentScope, globalScope, node);
|
||||
if (ns.length > 0) {
|
||||
var rootIdentifier = ns[0];
|
||||
if (rootIdentifier.type !== "Identifier" || rootIdentifier.name !== "document" || util.isShadowed(currentScope, globalScope, rootIdentifier)) {
|
||||
return;
|
||||
}
|
||||
var api = SecureDocumentAPI;
|
||||
for (var i = 0; i < ns.length; i++) {
|
||||
var identifier = ns[i];
|
||||
if (identifier.type !== 'Identifier') {
|
||||
context.report(node, "Invalid SecureDocument API, use dot notation instead");
|
||||
return;
|
||||
}
|
||||
var token = identifier.name;
|
||||
var nextIdentifier = ns[i + 1];
|
||||
if (typeof api !== "object") {
|
||||
context.report(node, "Invalid SecureDocument API");
|
||||
return;
|
||||
}
|
||||
if (!api.hasOwnProperty(token)) {
|
||||
context.report(node, "Invalid SecureDocument API");
|
||||
return;
|
||||
}
|
||||
if (api[token] === '*') {
|
||||
// anything from this point on is good
|
||||
return;
|
||||
}
|
||||
if (typeof (api[token]) === 'object' && Object.keys(api[token]).length === 0) {
|
||||
// nothing else to inspect
|
||||
return;
|
||||
}
|
||||
if (api[token] === true && !nextIdentifier) {
|
||||
// function call
|
||||
return;
|
||||
}
|
||||
if (api[token] === true && nextIdentifier && nextIdentifier.type === 'Identifier' && (nextIdentifier.name === 'apply' || nextIdentifier.name === 'call')) {
|
||||
// function call with .apply() or .call() are still valid
|
||||
return;
|
||||
}
|
||||
if (api[token] === false && nextIdentifier === undefined) {
|
||||
return;
|
||||
}
|
||||
api = api[token];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
module.exports.schema = [];
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (C) 2016 salesforce.com, inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var util = require('../lib/util.js');
|
||||
|
||||
var globalBlackList = {
|
||||
setImmediate: true,
|
||||
MutationEvent: true,
|
||||
ServiceWorker: true,
|
||||
ServiceWorkerContainer: true,
|
||||
ServiceWorkerMessageEvent: true,
|
||||
ServiceWorkerRegistration: true,
|
||||
ShadowRoot: true,
|
||||
SharedWorker: true,
|
||||
WebKitMutationObserver: true,
|
||||
clientInformation: true,
|
||||
eval: true,
|
||||
onwebkitanimationend: true,
|
||||
onwebkitanimationiteration: true,
|
||||
onwebkitanimationstart: true,
|
||||
onwebkittransitionend: true,
|
||||
opener: true,
|
||||
top: true,
|
||||
webkitAudioContext: true,
|
||||
webkitCancelAnimationFrame: true,
|
||||
webkitCancelRequestAnimationFrame: true,
|
||||
webkitIDBCursor: true,
|
||||
webkitIDBDatabase: true,
|
||||
webkitIDBFactory: true,
|
||||
webkitIDBIndex: true,
|
||||
webkitIDBKeyRange: true,
|
||||
webkitIDBObjectStore: true,
|
||||
webkitIDBRequest: true,
|
||||
webkitIDBTransaction: true,
|
||||
webkitIndexedDB: true,
|
||||
webkitMediaStream: true,
|
||||
webkitOfflineAudioContext: true,
|
||||
webkitRTCPeerConnection: true,
|
||||
webkitRequestAnimationFrame: true,
|
||||
webkitRequestFileSystem: true,
|
||||
webkitResolveLocalFileSystemURL: true,
|
||||
webkitSpeechGrammar: true,
|
||||
webkitSpeechGrammarList: true,
|
||||
webkitSpeechRecognition: true,
|
||||
webkitSpeechRecognitionError: true,
|
||||
webkitSpeechRecognitionEvent: true,
|
||||
webkitStorageInfo: true,
|
||||
webkitURL: true
|
||||
};
|
||||
|
||||
module.exports = function(context) {
|
||||
var globalScope;
|
||||
|
||||
return {
|
||||
|
||||
Program: function() {
|
||||
globalScope = context.getScope();
|
||||
},
|
||||
|
||||
CallExpression: function(node) {
|
||||
var callee = node.callee,
|
||||
currentScope = context.getScope();
|
||||
|
||||
if (callee.type === "Identifier") {
|
||||
if (!util.isShadowed(currentScope, globalScope, callee)) {
|
||||
if (globalBlackList[callee.name]) {
|
||||
context.report(node, "Invalid SecureWindow API, " + callee.name + " was blacklisted");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
MemberExpression: function(node) {
|
||||
if (node.parent.type === "MemberExpression") {
|
||||
// ignoring intermediate member expressions
|
||||
return;
|
||||
}
|
||||
var currentScope = context.getScope();
|
||||
var ns = util.buildMemberExpressionNamespace(currentScope, globalScope, node);
|
||||
if (ns.length > 0) {
|
||||
var rootIdentifier = ns[0];
|
||||
var name = rootIdentifier.name;
|
||||
if (rootIdentifier.type === "Literal") {
|
||||
name = rootIdentifier.value;
|
||||
}
|
||||
if (util.isShadowed(currentScope, globalScope, rootIdentifier)) {
|
||||
// nothing to do here, it was shadowed by the user
|
||||
return;
|
||||
}
|
||||
if (globalBlackList[name]) {
|
||||
context.report(node, "Invalid SecureWindow API, " + name + " was blacklisted");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
module.exports.schema = [];
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"es6",
|
||||
"dom"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
".sfdx/tools/*.d.ts",
|
||||
"**/*.js"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
".vscode-test"
|
||||
]
|
||||
}
|
688
packages/salesforcedx-vscode/resources/lightning/typings/lightning.d.ts
поставляемый
Normal file
688
packages/salesforcedx-vscode/resources/lightning/typings/lightning.d.ts
поставляемый
Normal file
|
@ -0,0 +1,688 @@
|
|||
declare namespace $A {
|
||||
/**
|
||||
* Create a component from a type and a set of attributes.
|
||||
* It accepts the name of a type of component, a map of attributes,
|
||||
* and a callback to notify callers.
|
||||
*/
|
||||
export function createComponent(
|
||||
type: string,
|
||||
attributes: Object,
|
||||
callback: (component: Component, status: any, errorMessage: any) => void): any;
|
||||
|
||||
/**
|
||||
* Create an array of components from a list of types and attributes.
|
||||
* It accepts a list of component names and attribute maps, and a callback
|
||||
* to notify callers.
|
||||
*/
|
||||
export function createComponents(
|
||||
type: Object[][],
|
||||
attributes: Object,
|
||||
callback: (component: Component[], status: any, errorMessage: any) => void): any;
|
||||
|
||||
/**
|
||||
* This function must be called from within an event loop.
|
||||
*/
|
||||
export function enqueueAction(action: Action, background: boolean): any;
|
||||
|
||||
/**
|
||||
* Returns the value referenced using property syntax. Gets the value from the specified global value provider
|
||||
*/
|
||||
export function get(key: string, callback: (any: any) => void): any;
|
||||
|
||||
/**
|
||||
* Returns a callback which is safe to invoke from outside Aura, e.g. as an event handler or in a setTimeout.
|
||||
* The $A.getCallback() call ensures that the framework rerenders the modified component
|
||||
* and processes any enqueued actions.
|
||||
*/
|
||||
export function getCallback(callback: (any: any) => void): any;
|
||||
|
||||
/**
|
||||
* Gets an instance of a component from either a GlobalId or a DOM element that was created via a Component Render.
|
||||
*/
|
||||
export function getComponent(idenfitier: Object): Component;
|
||||
|
||||
/**
|
||||
* Gets the root component or application. For example, $A.getRoot().get("v.attrName"); returns the attribute from the root component.
|
||||
*/
|
||||
export function getRoot(): Component;
|
||||
|
||||
/**
|
||||
* Logs to the browser's JavaScript console if it is available.
|
||||
* This method doesn't log in PROD or PRODDEBUG modes.
|
||||
* If both value and error are passed in, value shows up in the console as a group with value logged within the group.
|
||||
* If only value is passed in, value is logged without grouping.
|
||||
*/
|
||||
export function log(value: Object, error: Object): any;
|
||||
|
||||
/**
|
||||
* Report error to the server after handling it.
|
||||
* Note that the method should only be used if try-catch mechanism
|
||||
* of error handling is not desired or not functional (ex: in nested promises)
|
||||
*/
|
||||
export function reportError(message: string, error: Error): any;
|
||||
|
||||
/**
|
||||
* Sets the value referenced using property syntax on the specified global value provider.
|
||||
*/
|
||||
export function set(key: string, value: Object): any;
|
||||
|
||||
|
||||
/**
|
||||
* $A.warning() should be used in the case where poor programming practices have been used.
|
||||
*
|
||||
* These warnings will not, in general, be displayed to the user, but they will appear in the console (if
|
||||
* available), and in the aura debug window.
|
||||
*/
|
||||
export function warning(warning: string, error: Error): any;
|
||||
|
||||
/**
|
||||
* Instance of the AuraLocalizationService which provides utility methods for localizing data or getting formatters for numbers, currencies, dates, etc.
|
||||
*/
|
||||
export const localizationService: AuraLocalizationService;
|
||||
|
||||
/**
|
||||
* Collection of basic utility methods to operate on the DOM and Aura Components.
|
||||
*/
|
||||
export const util: Util;
|
||||
|
||||
}
|
||||
|
||||
interface AuraLocalizationService {
|
||||
|
||||
/**
|
||||
* Converts a datetime from UTC to a specified timezone.
|
||||
*/
|
||||
UTCToWallTime(date: Date, timezone: string, callback: (any: any) => void): any;
|
||||
|
||||
/**
|
||||
* Converts a datetime from a specified timezone to UTC.
|
||||
*/
|
||||
WallTimeToUTC(date: Date, timezone: string, callback: (any: any) => void): any;
|
||||
|
||||
/**
|
||||
* Displays a length of time.
|
||||
*/
|
||||
displayDuration(d: Duration, noSuffix: boolean): string;
|
||||
|
||||
/**
|
||||
* Displays a length of time in days.
|
||||
*/
|
||||
displayDurationInDays(d: Duration): number;
|
||||
|
||||
/**
|
||||
* Displays a length of time in hours.
|
||||
*/
|
||||
displayDurationInHours(d: Duration): number;
|
||||
|
||||
/**
|
||||
* Displays a length of time in milliseconds
|
||||
*/
|
||||
displayDurationInMilliseconds(d: Duration): number;
|
||||
|
||||
/**
|
||||
*Displays a length of time in minutes.
|
||||
*/
|
||||
displayDurationInMinutes(d: Duration): number;
|
||||
|
||||
/**
|
||||
* Displays a length of time in months.
|
||||
*/
|
||||
displayDurationInMonths(d: Duration): number;
|
||||
|
||||
/**
|
||||
* Displays a length of time in seconds.
|
||||
*/
|
||||
displayDurationInSeconds(d: Duration): number;
|
||||
|
||||
/**
|
||||
* Creates an Object representing a length of time.
|
||||
*/
|
||||
duration(num: number | Object, unit: string): Duration
|
||||
|
||||
/**
|
||||
* Converts the passed in Date by setting it to the end of a unit of time.
|
||||
*/
|
||||
endOf(date: string | number | Date, unit: string): Date;
|
||||
|
||||
/**
|
||||
* Returns a currency number based on the default currency format.
|
||||
*/
|
||||
formatCurrency(number: number): number
|
||||
|
||||
/**
|
||||
* Formats a date.
|
||||
*/
|
||||
formatDate(date: string | number | Date, formatString: string, locale: string): string;
|
||||
|
||||
/**
|
||||
* Formats a datetime.
|
||||
*/
|
||||
formatDateTime(date: string | number | Date, formatString: string, locale: string): string;
|
||||
|
||||
/**
|
||||
* Formats a datetime in UTC.
|
||||
*/
|
||||
formatDateTimeUTC(date: string | number | Date, formatString: string, locale: string): string;
|
||||
|
||||
/**
|
||||
* Formats a date in UTC.
|
||||
*/
|
||||
formatDateUTC(date: string | number | Date, formatString: string, locale: string): string;
|
||||
|
||||
/**
|
||||
* Formats a number with the default number format.
|
||||
*/
|
||||
formatNumber(number: number): number;
|
||||
|
||||
/**
|
||||
* Returns a formatted percentage number based on the default percentage format.
|
||||
*/
|
||||
formatPercent(number: number): number;
|
||||
|
||||
/**
|
||||
* Formats a time.
|
||||
*/
|
||||
formatTime(date: string | number | Date, formatString: string, locale: string): string;
|
||||
|
||||
/**
|
||||
* Formats a time in UTC.
|
||||
*/
|
||||
formatTimeUTC(date: string | number | Date, formatString: string, locale: string): string;
|
||||
|
||||
/**
|
||||
* Get the date's date string based on a time zone.
|
||||
*/
|
||||
getDateStringBasedOnTimezone(timezone: string, date: Date, callback: (any: any) => void): string;
|
||||
|
||||
/**
|
||||
* Gets the number of days in a duration.
|
||||
*/
|
||||
getDaysInDuration(d: Duration): number;
|
||||
|
||||
/**
|
||||
* Returns the default currency format.
|
||||
*/
|
||||
getDefaultCurrencyFormat(): number;
|
||||
|
||||
/**
|
||||
* Returns the default NumberFormat Object.
|
||||
*/
|
||||
getDefaultNumberFormat(): number;
|
||||
|
||||
/**
|
||||
* Returns the default percentage Object.
|
||||
*/
|
||||
getDefaultPercentFormat(): number;
|
||||
|
||||
/**
|
||||
* Get the number of hours in a duration.
|
||||
*/
|
||||
getHoursInDuration(d: Duration): number;
|
||||
|
||||
/**
|
||||
* Get the date time related labels (month name, weekday name, am/pm etc.).
|
||||
*/
|
||||
getLocalizedDateTimeLabels(): Object;
|
||||
|
||||
/**
|
||||
* Gets the number of milliseconds in a duration.
|
||||
*/
|
||||
getMillisecondsInDuration(d: Duration): number;
|
||||
|
||||
/**
|
||||
* Gets the number of minutes in a duration.
|
||||
*/
|
||||
getMinutesInDuration(d: Duration): number;
|
||||
|
||||
/**
|
||||
* Gets the number of months in a duration.
|
||||
*/
|
||||
getMonthsInDuration(d: Duration): number;
|
||||
|
||||
/**
|
||||
* Returns a NumberFormat Object.
|
||||
*/
|
||||
getNumberFormat(format: string, symbols: string): number;
|
||||
|
||||
/**
|
||||
* Gets the number of seconds in a duration.
|
||||
*/
|
||||
getSecondsInDuration(d: Duration): number;
|
||||
|
||||
/**
|
||||
* Get today's date based on a time zone.
|
||||
*/
|
||||
getToday(timezone: string, callback: (any: any) => void): string;
|
||||
|
||||
/**
|
||||
* Gets the number of years in a duration.
|
||||
*/
|
||||
getYearsInDuration(d: Duration): number;
|
||||
|
||||
/**
|
||||
* Checks if date1 is after date2
|
||||
*/
|
||||
isAfter(date1: string | number | Date, date2: string | number | Date, unit: string): boolean;
|
||||
|
||||
/**
|
||||
* Checks if date1 is before date2
|
||||
*/
|
||||
isBefore(date1: string | number | Date, date2: string | number | Date, unit: string): boolean;
|
||||
|
||||
/**
|
||||
* A utility function to check if a datetime pattern string uses a 24-hour or period (12 hour with am/pm) time view.
|
||||
*/
|
||||
isPeriodTimeView(pattern: string): boolean;
|
||||
|
||||
/**
|
||||
* Checks if date1 is same as date2
|
||||
*/
|
||||
isSame(date1: string | number | Date, date2: string | number | Date, unit: string): boolean;
|
||||
|
||||
/**
|
||||
* Parses a string to a JavaScript Date.
|
||||
*/
|
||||
parseDateTime(dateTimeString: string, targetFormat: string, locale: string, strictParsing: boolean): Date;
|
||||
|
||||
/**
|
||||
* Parses a date time string in an ISO-8601 format.
|
||||
*/
|
||||
parseDateTimeISO8601(dateTimeString: string): Date;
|
||||
|
||||
/**
|
||||
* Parses a string to a JavaScript Date in UTC.
|
||||
*/
|
||||
parseDateTimeUTC(dateTimeString: string, targetFormat: string, locale: string, strictParsing: boolean): Date;
|
||||
|
||||
/**
|
||||
* Converts the passed in Date by setting it to the start of a unit of time.
|
||||
*/
|
||||
startOf(date: string | number | Date, unit: string): Date;
|
||||
|
||||
/**
|
||||
Most modern browsers support this method on Date Object. But that is not the case for IE8 and older.
|
||||
*/
|
||||
toISOString(date: Date): string;
|
||||
|
||||
/**
|
||||
* Translate the localized digit string to a string with Arabic digits if there is any.
|
||||
*/
|
||||
translateFromLocalizedDigits(input: string): string;
|
||||
|
||||
/**
|
||||
* Translate the input date from other calendar system (for example, Buddhist calendar) to Gregorian calendar based on the locale.
|
||||
*/
|
||||
translateFromOtherCalendar(date: Date): Date;
|
||||
|
||||
/**
|
||||
* Translate the input string to a string with localized digits (different from Arabic) if there is any.
|
||||
*/
|
||||
translateToLocalizedDigits(input: string): string;
|
||||
|
||||
/**
|
||||
* Translate the input date to a date in other calendar system, for example, Buddhist calendar based on the locale.
|
||||
*/
|
||||
translateToOtherCalendar(date: Date): Date;
|
||||
}
|
||||
|
||||
type Duration = Object;
|
||||
|
||||
interface Action {
|
||||
/**
|
||||
* Returns an array of error Objects only for server-side actions.
|
||||
* Each error Object has a message field.
|
||||
* In any mode except PROD mode, each Object also has a stack field, which is a list
|
||||
* describing the execution stack when the error occurred.
|
||||
*/
|
||||
getError(): Object[];
|
||||
|
||||
/**
|
||||
* Gets an action parameter value for a parameter name.
|
||||
*/
|
||||
getParam(name: string): Object;
|
||||
|
||||
/**
|
||||
* Gets the collection of parameters for this Action.
|
||||
*/
|
||||
getParams(): Object;
|
||||
|
||||
/**
|
||||
* Gets the return value of the Action. A server-side Action can return any Object containing serializable JSON data.
|
||||
*/
|
||||
getReturnValue(): any;
|
||||
|
||||
/**
|
||||
* Gets the current state of the Action. You should check the state of the action
|
||||
* in the callback after the server-side action completes.
|
||||
*/
|
||||
getState(): string;
|
||||
|
||||
/**
|
||||
* Returns true if the actions should be enqueued in the background, false if it should be run in the foreground.
|
||||
*/
|
||||
isBackground(): boolean
|
||||
|
||||
/**
|
||||
* Set the action as abortable. Abortable actions are not sent to the server if the component is not valid.
|
||||
* A component is automatically destroyed and marked invalid by the framework when it is unrendered.
|
||||
*
|
||||
* Actions not marked abortable are always sent to the server regardless of the validity of the component.
|
||||
* For example, a save/modify action should not be set abortable to ensure it's always sent to the server
|
||||
* even if the component is deleted.
|
||||
*
|
||||
* Setting an action as abortable cannot be undone
|
||||
*/
|
||||
setAbortable(): any;
|
||||
|
||||
/**
|
||||
* Sets the action to run as a background action. This cannot be unset. Background actions are usually long running and
|
||||
* lower priority actions. A background action is useful when you want your app to remain responsive to a user while it
|
||||
* executes a low priority, long-running action. A rough guideline is to use a background action if it takes more than
|
||||
* five seconds for the response to return from the server.
|
||||
*/
|
||||
setBackground(): any;
|
||||
|
||||
/**
|
||||
* Sets the callback function that is executed after the server-side action returns. Call a server-side action from a
|
||||
* client-side controller using <code>callback</code>.
|
||||
*
|
||||
* Note that you can register a callback for an explicit state, or you can use 'ALL' which registers callbacks for
|
||||
* "SUCCESS", "ERROR", and "INCOMPLETE" (but not "ABORTED" for historical compatibility). It is recommended that you
|
||||
* use an explicit name, and not the default 'undefined' to signify 'ALL'.
|
||||
*
|
||||
* The valid names are:
|
||||
* * SUCCESS: if the action successfully completes.
|
||||
* * ERROR: if the action has an error (including javascript errors for client side actions)
|
||||
* * INCOMPLETE: if a server side action failed to complete because there is no connection
|
||||
* * ABORTED: if the action is aborted via abort()
|
||||
* * REFRESH: for server side storable actions, this will be called instead of the SUCCESS action when the storage is refreshed.
|
||||
*/
|
||||
setCallback(scope: Object, callback: (any: any) => void, name: string): any;
|
||||
|
||||
/**
|
||||
* Sets a single parameter for the Action.
|
||||
*/
|
||||
setParam(key: string, value: Object): any;
|
||||
|
||||
/**
|
||||
* Sets parameters for the Action.
|
||||
*/
|
||||
setParams(config: Object): any;
|
||||
|
||||
/**
|
||||
* Marks the Action as storable. For server-side Actions only.
|
||||
* Mark an action as storable to have its response stored in the client-side cache by the framework. Caching can be useful
|
||||
* if you want your app to be functional for devices that temporarily don’t have a network connection.
|
||||
*/
|
||||
setStorable(config: Object): any;
|
||||
}
|
||||
|
||||
interface Component {
|
||||
/**
|
||||
* Adds an event handler. Resolving the handler Action happens at Event-handling
|
||||
* time, so the Action reference may be altered at runtime, and that change is
|
||||
* reflected in the handler.
|
||||
*/
|
||||
addHandler(eventName: string, valueProvider: Object, actionExpression: Object, insert: boolean, phase: string, includeFacets: boolean): any;
|
||||
|
||||
/**
|
||||
* Adds handlers to Values owned by the Component.
|
||||
*/
|
||||
addValueHandler(config: Object): any;
|
||||
|
||||
/**
|
||||
* Adds Custom ValueProviders to a component
|
||||
*/
|
||||
addValueProvider(key: string, valueProvider: Object): any;
|
||||
|
||||
/**
|
||||
* Sets a flag to tell the rendering service whether or not to destroy this component when it is removed
|
||||
* from its rendering facet. Set to false if you plan to keep a reference to a component after it has
|
||||
* been unrendered or removed from a parent facet. Default is true: destroy once orphaned.
|
||||
*/
|
||||
autoDestroy(destroy: boolean): any;
|
||||
|
||||
/**
|
||||
* Clears a live reference for the value indicated using property syntax.
|
||||
* For example, if you use aura:set to set a value and later want to reset the value using <code>component.set()</code>,
|
||||
* clear the reference before resetting the value.
|
||||
*/
|
||||
clearReference(key: string): any;
|
||||
|
||||
/**
|
||||
* Destroys the component and cleans up memory.
|
||||
* After a component that is declared in markup is no longer in use, the framework automatically destroys it
|
||||
* and frees up its memory.
|
||||
* If you create a component dynamically in JavaScript and that component isn't added to a facet (v.body or another
|
||||
* attribute of type Aura.Component[]), you have to destroy it manually using destroy() to avoid memory leaks.
|
||||
* destroy() destroys the component.
|
||||
*/
|
||||
destroy(sync: boolean): any;
|
||||
|
||||
/**
|
||||
* Locates a component using the localId. Shorthand: get("asdf"),
|
||||
* where "asdf" is the <code>aura:id</code> of the component to look for.
|
||||
* Returns different types depending on the result.
|
||||
* If the local ID is unique, find() returns the component.
|
||||
* If there are multiple components with the same local ID, find() returns an array of the components.
|
||||
* If there is no matching local ID, find() returns undefined.
|
||||
* Returns instances of a component using the format
|
||||
* cmp.find({ instancesOf : "auradocs:sampleComponent" }).
|
||||
*/
|
||||
find(name: string | Object): any;
|
||||
|
||||
/**
|
||||
* Returns the value referenced using property syntax.
|
||||
* For example, cmp.get("v.attr") returns the value of the attr aura:attribute.
|
||||
*/
|
||||
get(key: string): any;
|
||||
|
||||
/**
|
||||
* Gets the concrete implementation of a component. If the component is
|
||||
* concrete, the method returns the component itself. For example, call this
|
||||
* method to get the concrete component of a super component.
|
||||
*/
|
||||
getConcreteComponent(): any;
|
||||
|
||||
/**
|
||||
* If the component only rendered a single element, return it. Otherwise, you should use getElements().
|
||||
*/
|
||||
getElement(): any;
|
||||
|
||||
/**
|
||||
* Returns a map of the elements previously rendered by this component.
|
||||
*/
|
||||
getElements(): any;
|
||||
|
||||
/**
|
||||
* Returns a new event instance of the named component event.
|
||||
*/
|
||||
getEvent(name: string): any;
|
||||
|
||||
/**
|
||||
* Gets the globalId. This is the generated globally unique id of the component. It can be used to locate the instance later, but will change across page loads.
|
||||
*/
|
||||
getGlobalId(): any;
|
||||
|
||||
/**
|
||||
* Gets the id set using the aura:id attribute. Can be passed into find() on the parent to locate this child.
|
||||
*/
|
||||
getLocalId(): any;
|
||||
|
||||
/**
|
||||
* Returns the component's canonical name, e.g. 'ui:button'.
|
||||
*/
|
||||
getName(): any;
|
||||
|
||||
/**
|
||||
* Returns a live reference to the value indicated using property syntax. This is useful when you dynamically create a component.
|
||||
*/
|
||||
getReference(key: string): PropertyReferenceValue;
|
||||
|
||||
/**
|
||||
* Returns the super component.
|
||||
*/
|
||||
getSuper(): Component;
|
||||
|
||||
/**
|
||||
* Get the expected version number of a component based on its caller's requiredVersionDefs Note that for various rendering methods, we cannot rely on access stack. We use creation version instead.
|
||||
*/
|
||||
getVersion(): any;
|
||||
|
||||
/**
|
||||
* Returns true if the component is concrete, or false otherwise.
|
||||
*/
|
||||
isConcrete(): boolean;
|
||||
|
||||
/**
|
||||
* Checks whether the component is an instance of the given component name (or interface name).
|
||||
*/
|
||||
isInstanceOf(name: string): boolean;
|
||||
|
||||
/**
|
||||
* Returns true if the component has not been destroyed.
|
||||
*/
|
||||
isValid(): any;
|
||||
|
||||
/**
|
||||
* Sets the value referenced using property syntax.
|
||||
*/
|
||||
set(key: string, value: Object): any;
|
||||
|
||||
}
|
||||
|
||||
interface PropertyReferenceValue {
|
||||
|
||||
}
|
||||
|
||||
interface Event {
|
||||
/**
|
||||
* Fires the Event. Checks if the Event has already been fired before firing. Maps the component handlers to the event dispatcher
|
||||
*/
|
||||
fire(params: Object): any;
|
||||
|
||||
/**
|
||||
* Gets the name of the Event.
|
||||
*/
|
||||
getName(): string;
|
||||
|
||||
/**
|
||||
* Gets an Event parameter.
|
||||
*/
|
||||
getParam(name: string): string;
|
||||
|
||||
/**
|
||||
* Gets all the Event parameters.
|
||||
*/
|
||||
getParams(): Object;
|
||||
|
||||
/**
|
||||
* Gets the current phase of this event.
|
||||
* Returns undefined if the event has not yet been fired.
|
||||
* Possible return values for APPLICATION and COMPONENT events
|
||||
* are "capture", "bubble", and "default" once fired.
|
||||
* VALUE events return "default" once fired.
|
||||
*/
|
||||
getPhase(): any;
|
||||
|
||||
/**
|
||||
* Gets the source component that fired this event.
|
||||
*/
|
||||
getSource(): Object;
|
||||
|
||||
/**
|
||||
* Pauses this event such that event handlers will not be processed until
|
||||
* Event.resume() is called. The handling process will pause in the current
|
||||
* position of the event handler processing sequence. If the event is already
|
||||
* paused, calling this does nothing. This will throw an error
|
||||
* if called in the "default" phase.
|
||||
*/
|
||||
pause(): any;
|
||||
|
||||
/**
|
||||
* Prevents the default phase execution for this event. This will throw
|
||||
* an error if called in the "default" phase.
|
||||
* The default is true.
|
||||
*/
|
||||
preventDefault(): any;
|
||||
|
||||
/**
|
||||
* Resumes event handling for this event from the same position in the event
|
||||
* handler processing sequence from which it was previously paused.
|
||||
* If the event is not paused, calling this does nothing. This will throw an error
|
||||
* if called in the "default" phase.
|
||||
* This API does not define whether or not any remaining event handlers will
|
||||
* execute in the current call stack or be deferred and executed in a new call stack,
|
||||
* therefore the exact timing behavior is not dependable.
|
||||
*/
|
||||
resume(): any;
|
||||
|
||||
/**
|
||||
* Sets a parameter for the Event. Does not modify an event that has already been fired.
|
||||
*/
|
||||
setParam(key: string, value: Object): any;
|
||||
|
||||
/**
|
||||
* Sets parameters for the Event. Does not modify an event that has already been fired. Maps key in config to attributeDefs.
|
||||
*/
|
||||
setParams(config: Object): any;
|
||||
|
||||
/**
|
||||
* Sets whether the event can bubble or not. This will throw an error if called in the "default" phase. The default is false.
|
||||
*/
|
||||
stopPropagation(): any;
|
||||
}
|
||||
|
||||
interface Util {
|
||||
|
||||
/**
|
||||
* Adds a CSS class to a component.
|
||||
*/
|
||||
addClass(element: Component, newClass: string): any;
|
||||
|
||||
/**
|
||||
* Coerces truthy and falsy values into native booleans
|
||||
*/
|
||||
getBooleanValue(val: Object): boolean;
|
||||
|
||||
/**
|
||||
* Checks whether the component has the specified CSS class.
|
||||
*/
|
||||
hasClass(element: Object, className: string): boolean;
|
||||
|
||||
/**
|
||||
* Checks whether the specified Object is an array.
|
||||
*/
|
||||
isArray(obj: Object): boolean;
|
||||
|
||||
/**
|
||||
* Checks if the Object is empty. An empty Object's value is undefined, null, an empty array, or empty string. An Object with no native properties is not considered empty.
|
||||
*/
|
||||
isEmpty(obj: Object): boolean;
|
||||
|
||||
/**
|
||||
* Checks whether the specified Object is a valid Object. A valid Object: Is not a DOM element, is not a native browser class (XMLHttpRequest) is not falsey, and is not an array, error, function string or number
|
||||
*/
|
||||
isObject(obj: Object): boolean;
|
||||
|
||||
/**
|
||||
* Checks if the Object is undefined.
|
||||
*/
|
||||
isUndefined(obj: Object): boolean;
|
||||
|
||||
/**
|
||||
* Checks if the Object is undefined or null.
|
||||
*/
|
||||
isUndefinedOrNull(obj: Object): boolean;
|
||||
|
||||
/**
|
||||
* Removes a CSS class from a component.
|
||||
*/
|
||||
removeClass(element: Object, newClass: string): any;
|
||||
|
||||
/**
|
||||
* Toggles (adds or removes) a CSS class from a component.
|
||||
*/
|
||||
toggleClass(element: Object, className: string): any;
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
JORJE_LOCATION=/Users/nchen/Development/IdeaProjects/apex-jorje
|
||||
|
||||
(cd $JORJE_LOCATION; mvn clean install -Plsp -DskipTests)
|
||||
|
||||
cp `find $JORJE_LOCATION -type f -name 'apex-jorje-lsp-*-SNAPSHOT.jar' -not -name 'apex-jorje-lsp-test-*-SNAPSHOT.jar'` dist/apex-jorje-lsp.jar
|
|
@ -0,0 +1,189 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as child_process from 'child_process';
|
||||
import * as path from 'path';
|
||||
import * as status from './status';
|
||||
|
||||
let channel = vscode.window.createOutputChannel('Salesforce');
|
||||
|
||||
export function forceAuthWebLogin() {
|
||||
channel.appendLine('force:auth:web:login');
|
||||
|
||||
status.showStatus('Authenticating');
|
||||
child_process.exec(
|
||||
`sfdx force:auth:web:login -d`,
|
||||
{
|
||||
cwd: vscode.workspace.rootPath
|
||||
},
|
||||
(err, stdout, stderr) => {
|
||||
genericOutputHandler(err, stdout, stderr, 'force:auth:web:login');
|
||||
status.hideStatus();
|
||||
});
|
||||
}
|
||||
|
||||
export function forceOrgCreate() {
|
||||
channel.appendLine('force:org:create');
|
||||
|
||||
vscode.workspace.findFiles('config/*.json', '').then(files => {
|
||||
let fileItems: vscode.QuickPickItem[] = files.map(file => {
|
||||
return {
|
||||
label: path.basename(file.toString()),
|
||||
description: file.fsPath,
|
||||
}
|
||||
});
|
||||
vscode.window.showQuickPick(fileItems).then(selection => {
|
||||
if (selection) {
|
||||
status.showStatus('Creating org');
|
||||
let rootPath = vscode.workspace.rootPath!;
|
||||
let selectionPath = path.relative(rootPath, selection.description.toString());
|
||||
child_process.exec(
|
||||
`sfdx force:org:create -f ${selectionPath} -s`,
|
||||
{
|
||||
cwd: vscode.workspace.rootPath
|
||||
},
|
||||
(err, stdout, stderr) => {
|
||||
genericOutputHandler(err, stdout, stderr, 'force:org:create');
|
||||
status.hideStatus();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function forceOrgOpen() {
|
||||
channel.appendLine('force:org:open');
|
||||
|
||||
status.showStatus('Opening org');
|
||||
child_process.exec(
|
||||
`sfdx force:org:open`,
|
||||
{
|
||||
cwd: vscode.workspace.rootPath
|
||||
},
|
||||
(err, stdout, stderr) => {
|
||||
genericOutputHandler(err, stdout, stderr, 'force:org:open');
|
||||
status.hideStatus();
|
||||
});
|
||||
}
|
||||
|
||||
export function forceSourcePull() {
|
||||
channel.appendLine('force:source:pull');
|
||||
|
||||
status.showStatus('Pulling from org...');
|
||||
child_process.exec(
|
||||
`sfdx force:source:pull`,
|
||||
{
|
||||
cwd: vscode.workspace.rootPath
|
||||
},
|
||||
(err, stdout, stderr) => {
|
||||
genericOutputHandler(err, stdout, stderr, `force:source:pull`);
|
||||
status.hideStatus();
|
||||
});
|
||||
}
|
||||
|
||||
export function forceSourcePush() {
|
||||
channel.appendLine('force:source:push');
|
||||
|
||||
status.showStatus('Pushing to org');
|
||||
child_process.exec(
|
||||
`sfdx force:source:push`,
|
||||
{
|
||||
cwd: vscode.workspace.rootPath
|
||||
},
|
||||
(err, stdout, stderr) => {
|
||||
genericOutputHandler(err, stdout, stderr, `force:source:push`);
|
||||
status.hideStatus();
|
||||
});
|
||||
}
|
||||
|
||||
export function forceSourceStatus() {
|
||||
channel.appendLine('force:source:status');
|
||||
|
||||
status.showStatus('Checking status against org');
|
||||
child_process.exec(
|
||||
`sfdx force:source:status`,
|
||||
{
|
||||
cwd: vscode.workspace.rootPath
|
||||
},
|
||||
(err, stdout, stderr) => {
|
||||
genericOutputHandler(err, stdout, stderr, `force:source:status`);
|
||||
status.hideStatus();
|
||||
});
|
||||
}
|
||||
|
||||
export function forceApexTestRun(testClass?: string) {
|
||||
channel.appendLine('force:apex:test:run');
|
||||
|
||||
if (testClass) {
|
||||
status.showStatus('Running apex tests');
|
||||
child_process.exec(
|
||||
`sfdx force:apex:test:run -n ${testClass} -r human`,
|
||||
{
|
||||
cwd: vscode.workspace.rootPath
|
||||
},
|
||||
(err, stdout, stderr) => {
|
||||
genericOutputHandler(err, stdout, stderr, 'force:apex:test:run');
|
||||
status.hideStatus();
|
||||
});
|
||||
} else {
|
||||
vscode.workspace.findFiles('**/*.testSuite-meta.xml', '').then(files => {
|
||||
let fileItems: vscode.QuickPickItem[] = files.map(file => {
|
||||
return {
|
||||
label: path.basename(file.toString()).replace('.testSuite-meta.xml', ''),
|
||||
description: file.fsPath,
|
||||
}
|
||||
});
|
||||
|
||||
fileItems.push({
|
||||
label: 'All tests',
|
||||
description: 'Runs all tests in the current workspace',
|
||||
});
|
||||
|
||||
vscode.window.showQuickPick(fileItems).then(selection => {
|
||||
if (selection) {
|
||||
status.showStatus('Running apex tests');
|
||||
if (selection.label === 'All tests') {
|
||||
child_process.exec(
|
||||
`sfdx force:apex:test:run -r human`,
|
||||
{
|
||||
cwd: vscode.workspace.rootPath
|
||||
},
|
||||
(err, stdout, stderr) => {
|
||||
genericOutputHandler(err, stdout, stderr, 'force:apex:test:run');
|
||||
status.hideStatus();
|
||||
});
|
||||
} else {
|
||||
child_process.exec(
|
||||
`sfdx force:apex:test:run -s ${selection.label} -r human`,
|
||||
{
|
||||
cwd: vscode.workspace.rootPath
|
||||
},
|
||||
(err, stdout, stderr) => {
|
||||
genericOutputHandler(err, stdout, stderr, 'force:apex:test:run');
|
||||
status.hideStatus();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function genericOutputHandler(err: Error, stdout: string, stderr: string, command: string) {
|
||||
if (err) {
|
||||
vscode.window.showErrorMessage(err.message);
|
||||
}
|
||||
|
||||
channel.clear();
|
||||
|
||||
if (stdout) {
|
||||
channel.append(stdout);
|
||||
channel.show();
|
||||
}
|
||||
|
||||
if (stderr) {
|
||||
vscode.window.showErrorMessage(`Failed to execute${command}. Check the console for errors.`);
|
||||
channel.append(stderr);
|
||||
channel.show(true);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as child_process from 'child_process';
|
||||
import * as path from 'path';
|
||||
import * as net from 'net';
|
||||
import * as portFinder from 'portfinder';
|
||||
import * as requirements from './requirements';
|
||||
import { LanguageClient, LanguageClientOptions, ServerOptions, StreamInfo } from 'vscode-languageclient';
|
||||
|
||||
const UBER_JAR_NAME = 'apex-jorje-lsp.jar';
|
||||
const JDWP_DEBUG_PORT = 2739;
|
||||
const APEX_LANGUAGE_SERVER_MAIN = 'apex.jorje.lsp.ApexLanguageServerLauncher';
|
||||
|
||||
declare var v8debug: any;
|
||||
const DEBUG = (typeof v8debug === 'object') || startedInDebugMode();
|
||||
|
||||
async function createServer(context: vscode.ExtensionContext): Promise<StreamInfo> {
|
||||
try {
|
||||
let requirementsData = await requirements.resolveRequirements();
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
portFinder.getPort((err, port) => {
|
||||
let uberJar = path.resolve(context.extensionPath, 'dist', UBER_JAR_NAME);
|
||||
let javaExecutable = path.resolve(`${requirementsData.java_home}/bin/java`);
|
||||
let args: string[];
|
||||
if (DEBUG) {
|
||||
args = [
|
||||
'-cp',
|
||||
uberJar,
|
||||
`-Dapex-lsp.port=${port}`,
|
||||
'-Ddebug.internal.errors=true',
|
||||
'-Ddebug.semantic.errors=false',
|
||||
'-Dtrace.protocol=false',
|
||||
`-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=${JDWP_DEBUG_PORT}`,
|
||||
APEX_LANGUAGE_SERVER_MAIN
|
||||
];
|
||||
} else {
|
||||
args = [
|
||||
'-cp',
|
||||
uberJar,
|
||||
`-Dapex-lsp.port=${port}`,
|
||||
'-Ddebug.internal.errors=true',
|
||||
'-Ddebug.semantic.errors=false',
|
||||
APEX_LANGUAGE_SERVER_MAIN
|
||||
]
|
||||
}
|
||||
|
||||
net.createServer(socket => {
|
||||
resolve({
|
||||
reader: socket,
|
||||
writer: socket
|
||||
});
|
||||
|
||||
}).listen(port, () => {
|
||||
let options = {
|
||||
cwd: vscode.workspace.rootPath
|
||||
};
|
||||
|
||||
let lspProcess = child_process.spawn(javaExecutable, args, options);
|
||||
console.log('PROCESS INFO');
|
||||
console.log(lspProcess);
|
||||
|
||||
lspProcess.stdout.on('data', (data) => {
|
||||
console.log(`${data}`);
|
||||
});
|
||||
lspProcess.stderr.on('data', (data) => {
|
||||
console.log(`${data}`);
|
||||
});
|
||||
lspProcess.on('close', (code) => {
|
||||
console.log(`language server exited with code: ${code}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
vscode.window.showErrorMessage(err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
function startedInDebugMode(): boolean {
|
||||
let args = (process as any).execArgv;
|
||||
if (args) {
|
||||
return args.some((arg: any) => /^--debug=?/.test(arg) || /^--debug-brk=?/.test(arg));
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
export function createLanguageServer(context: vscode.ExtensionContext): LanguageClient {
|
||||
let clientOptions: LanguageClientOptions = {
|
||||
// Register the server for Apex documents
|
||||
documentSelector: ['apex'],
|
||||
synchronize: {
|
||||
configurationSection: 'apex',
|
||||
fileEvents: [
|
||||
vscode.workspace.createFileSystemWatcher('**/*.cls'), // Apex classes
|
||||
vscode.workspace.createFileSystemWatcher('**/*.trigger'), // Apex triggers
|
||||
vscode.workspace.createFileSystemWatcher('**/sfdx-project.json') // SFDX workspace configuration file
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
let client = new LanguageClient('apex', 'Apex Language Server', () => createServer(context), clientOptions);
|
||||
return client;
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
// From https://github.com/redhat-developer/vscode-java
|
||||
// Original version licensed under the Eclipse Public License (EPL)
|
||||
|
||||
import { workspace, Uri } from 'vscode';
|
||||
import * as cp from 'child_process';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
const pathExists = require('path-exists');
|
||||
const expandHomeDir = require('expand-home-dir');
|
||||
const isWindows = process.platform.indexOf('win') === 0;
|
||||
const JAVAC_FILENAME = 'javac' + (isWindows ? '.exe' : '');
|
||||
|
||||
interface RequirementsData {
|
||||
java_home: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the requirements needed to run the extension.
|
||||
* Returns a promise that will resolve to a RequirementsData if all requirements are resolved.
|
||||
*
|
||||
*/
|
||||
export async function resolveRequirements(): Promise<RequirementsData> {
|
||||
let java_home = await checkJavaRuntime();
|
||||
await checkJavaVersion(java_home);
|
||||
return Promise.resolve({ java_home: java_home }
|
||||
);
|
||||
}
|
||||
|
||||
function checkJavaRuntime(): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
let source: string;
|
||||
let javaHome: string = readJavaConfig();
|
||||
if (javaHome) {
|
||||
source = 'The java.home variable defined in VS Code settings';
|
||||
} else {
|
||||
javaHome = process.env['JDK_HOME'];
|
||||
if (javaHome) {
|
||||
source = 'The JDK_HOME environment variable';
|
||||
} else {
|
||||
javaHome = process.env['JAVA_HOME'];
|
||||
source = 'The JAVA_HOME environment variable';
|
||||
}
|
||||
}
|
||||
if (javaHome) {
|
||||
javaHome = expandHomeDir(javaHome);
|
||||
if (!pathExists.sync(javaHome)) {
|
||||
reject(`${source} points to a missing folder`);
|
||||
}
|
||||
return resolve(javaHome);
|
||||
}
|
||||
|
||||
reject('Java runtime could not be located');
|
||||
});
|
||||
}
|
||||
|
||||
function readJavaConfig(): string {
|
||||
const config = workspace.getConfiguration();
|
||||
return config.get<string>('java.home', '');
|
||||
}
|
||||
|
||||
function checkJavaVersion(java_home: string): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
cp.execFile(java_home + '/bin/java', ['-version'], {}, (error, stdout, stderr) => {
|
||||
if (stderr.indexOf('1.8') < 0) {
|
||||
reject('Java 8 is required to run. Please download and install a JRE.');
|
||||
} else {
|
||||
resolve(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as child_process from 'child_process';
|
||||
import * as path from 'path';
|
||||
import * as net from 'net';
|
||||
import * as portFinder from 'portfinder';
|
||||
import * as status from './status';
|
||||
import * as scratchOrgDecorator from './scratch-org-decorator';
|
||||
import * as commands from './commands';
|
||||
import * as languageServer from './language-server';
|
||||
import { LanguageClient, LanguageClientOptions, SettingMonitor, ServerOptions, StreamInfo } from 'vscode-languageclient';
|
||||
|
||||
function registerCommands(): vscode.Disposable {
|
||||
let forceAuthWebLoginCmd = vscode.commands.registerCommand('sfdx.force.auth.web.login', commands.forceAuthWebLogin);
|
||||
let forceOrgCreateCmd = vscode.commands.registerCommand('sfdx.force.org.create', commands.forceOrgCreate);
|
||||
let forceOrgOpenCmd = vscode.commands.registerCommand('sfdx.force.org.open', commands.forceOrgOpen);
|
||||
let forceSourcePullCmd = vscode.commands.registerCommand('sfdx.force.source.pull', commands.forceSourcePull);
|
||||
let forceSourcePushCmd = vscode.commands.registerCommand('sfdx.force.source.push', commands.forceSourcePush);
|
||||
let forceSourceStatusCmd = vscode.commands.registerCommand('sfdx.force.source.status', commands.forceSourceStatus);
|
||||
let forceApexTestRunCmd = vscode.commands.registerCommand('sfdx.force.apex.test.run', commands.forceApexTestRun);
|
||||
return vscode.Disposable.from(
|
||||
forceOrgCreateCmd,
|
||||
forceOrgOpenCmd,
|
||||
forceSourcePullCmd,
|
||||
forceSourcePushCmd,
|
||||
forceApexTestRunCmd
|
||||
);
|
||||
}
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
console.log('Salesforce Extension Activated');
|
||||
const commands = registerCommands();
|
||||
const apexServer = languageServer.createLanguageServer(context).start();
|
||||
context.subscriptions.push(commands);
|
||||
context.subscriptions.push(apexServer);
|
||||
scratchOrgDecorator.showOrg();
|
||||
scratchOrgDecorator.monitorConfigChanges();
|
||||
}
|
||||
|
||||
export function deactivate() {
|
||||
console.log('Salesforce Extension Deactivated');
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import { window, workspace, StatusBarItem, StatusBarAlignment } from 'vscode';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
|
||||
const CONFIG_FILE = (path.join(workspace.rootPath!, '.sfdx/sfdx-config.json'));
|
||||
|
||||
let statusBarItem: StatusBarItem;
|
||||
|
||||
export function showOrg() {
|
||||
if (!statusBarItem) {
|
||||
statusBarItem = window.createStatusBarItem(StatusBarAlignment.Left, 50);
|
||||
statusBarItem.command= 'sfdx.force.org.open';
|
||||
statusBarItem.show();
|
||||
}
|
||||
displayDefaultUserName(CONFIG_FILE);
|
||||
}
|
||||
|
||||
export function monitorConfigChanges() {
|
||||
let watcher = workspace.createFileSystemWatcher(CONFIG_FILE);
|
||||
watcher.onDidChange(uri => {
|
||||
displayDefaultUserName(uri.fsPath);
|
||||
});
|
||||
}
|
||||
|
||||
function displayDefaultUserName(configPath: string) {
|
||||
fs.readFile(configPath, (err, data) => {
|
||||
if (!err) {
|
||||
const config = JSON.parse(data.toString());
|
||||
if (config['defaultusername']) {
|
||||
statusBarItem.text = `$(browser) ${config['defaultusername']}`;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import { window, StatusBarItem, StatusBarAlignment } from 'vscode';
|
||||
|
||||
let statusBarItem: StatusBarItem;
|
||||
let statusTimer: NodeJS.Timer;
|
||||
|
||||
export function showStatus(status: string) {
|
||||
if (!statusBarItem) {
|
||||
statusBarItem = window.createStatusBarItem(StatusBarAlignment.Left, -10);
|
||||
}
|
||||
statusBarItem.text = `$(beaker) ${status}`;
|
||||
statusTimer = setInterval(() => statusBarItem.text = statusBarItem.text + '.', 1000);
|
||||
statusBarItem.show();
|
||||
}
|
||||
|
||||
export function hideStatus() {
|
||||
if (statusBarItem) {
|
||||
statusBarItem.hide();
|
||||
}
|
||||
if (statusTimer) {
|
||||
clearInterval(statusTimer);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"comments": {
|
||||
"lineComment": "//",
|
||||
"blockComment": [ "/*", "*/" ]
|
||||
},
|
||||
// symbols used as brackets
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"]
|
||||
],
|
||||
// symbols that are auto closed when typing
|
||||
"autoClosingPairs": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"],
|
||||
["'", "'"]
|
||||
],
|
||||
// symbols that that can be used to surround a selection
|
||||
"surroundingPairs": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"],
|
||||
["'", "'"]
|
||||
]
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"sourceMap": true,
|
||||
"moduleResolution": "node",
|
||||
"noImplicitAny": true,
|
||||
"rootDir": ".",
|
||||
"outDir": "dist",
|
||||
"preserveConstEnums": true,
|
||||
"strictNullChecks": true
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
".vscode-test"
|
||||
]
|
||||
}
|
Загрузка…
Ссылка в новой задаче