@servicenow/eslint-plugin-sdk-app-plugin 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.js ADDED
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ module.exports = {
4
+ parserOptions: {
5
+ ecmaVersion: 'latest',
6
+ },
7
+ root: true,
8
+ extends: [
9
+ 'eslint:recommended',
10
+ 'plugin:eslint-plugin/recommended',
11
+ 'plugin:n/recommended',
12
+ ],
13
+ env: {
14
+ node: true,
15
+ }
16
+ };
package/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # @servicenow/eslint-plugin-sdk-app-plugin
2
+
3
+ Plugin to disallow Browser and Node.js APIs not supported in rhino engine
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install && npm i -g .
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ Add `@servicenow/sdk-app-plugin` to the plugins section and update the extends array with "plugin:sdk-app-plugin/recommended" as shown below in your `.eslintrc` configuration file.
14
+
15
+ ```json
16
+ {
17
+ "plugins": ["@servicenow/sdk-app-plugin"],
18
+ "extends": ["plugin:@servicenow/sdk-app-plugin/recommended"]
19
+ }
20
+ ```
21
+
22
+ Refer to [ServiceNow ](https://docs.servicenow.com/bundle/washingtondc-api-reference/page/script/sdk/concept/servicenow-sdk.html) docs for more information
@@ -0,0 +1,17 @@
1
+ const { getRestrictedGlobals } = require('../util/utility')
2
+ const restrictedGlobals = getRestrictedGlobals()
3
+
4
+ module.exports = {
5
+ plugins:['@servicenow/sdk-app-plugin'],
6
+ rules:{
7
+ '@servicenow/sdk-app-plugin/file-extension-in-import':['error','always'],
8
+ 'no-restricted-globals':['error',...restrictedGlobals],
9
+ '@servicenow/sdk-app-plugin/no-promise':'error',
10
+ '@servicenow/sdk-app-plugin/no-async-functions': 'error',
11
+ '@servicenow/sdk-app-plugin/no-dynamic-import': 'error',
12
+ '@servicenow/sdk-app-plugin/no-regexp-lookbehind-assertions': 'error',
13
+ '@servicenow/sdk-app-plugin/no-regexp-unicode-property-escapes': 'error',
14
+ 'no-console': 'error',
15
+ '@servicenow/sdk-app-plugin/no-unsupported-node-builtins': 'error'
16
+ }
17
+ }
package/lib/index.js ADDED
@@ -0,0 +1,14 @@
1
+ module.exports = {
2
+ configs:{
3
+ 'recommended':require('./configs/recommended')
4
+ },
5
+ rules:{
6
+ 'file-extension-in-import':require('eslint-plugin-n/lib/rules/file-extension-in-import'),
7
+ 'no-async-functions':require('eslint-plugin-es-x/lib/rules/no-async-functions'),
8
+ 'no-promise':require('./rules/no-promise'),
9
+ 'no-dynamic-import': require('eslint-plugin-es-x/lib/rules/no-dynamic-import'),
10
+ 'no-regexp-lookbehind-assertions': require('eslint-plugin-es-x/lib/rules/no-regexp-lookbehind-assertions'),
11
+ 'no-regexp-unicode-property-escapes': require('eslint-plugin-es-x/lib/rules/no-regexp-unicode-property-escapes'),
12
+ 'no-unsupported-node-builtins': require('./rules/no-unsupported-node-builtins')
13
+ }
14
+ }
@@ -0,0 +1,43 @@
1
+ const PROMISE_STATIC_METHODS = {
2
+ all: true,
3
+ allSettled: true,
4
+ any: true,
5
+ race: true,
6
+ reject: true,
7
+ resolve: true,
8
+ withResolvers: true,
9
+ }
10
+
11
+ module.exports = {
12
+ meta: {
13
+ docs: {
14
+ description: 'disallow the `Promise` class.',
15
+ category: 'ES2015',
16
+ recommended: false
17
+ },
18
+ fixable: null,
19
+ messages: {
20
+ forbidden: 'ES2015 Promise class is not supported in now platform.'
21
+ },
22
+ schema:[],
23
+ type:'problem',
24
+ },
25
+ create(context) {
26
+ return {
27
+ CallExpression(node) {
28
+ if(node.callee.type === 'MemberExpression' &&
29
+ node.callee.object.name === 'Promise' &&
30
+ node.callee.object.type === 'Identifier' &&
31
+ PROMISE_STATIC_METHODS[node.callee.property.name]) {
32
+ context.report({context,node, messageId:'forbidden'})
33
+ }
34
+ },
35
+
36
+ NewExpression(node) {
37
+ if(node.callee.name === 'Promise') {
38
+ context.report({context,node, messageId:'forbidden'})
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
@@ -0,0 +1,37 @@
1
+ const { createTrackMap } = require('../util/utility')
2
+ const { ReferenceTracker } = require('@eslint-community/eslint-utils')
3
+
4
+ module.exports = {
5
+ meta: {
6
+ docs: {
7
+ description: 'disallow unsupported Node.js built-in APIs',
8
+ recommended: true
9
+ },
10
+ fixable: null,
11
+ messages: {
12
+ forbidden: 'The {{name}} Node.js API is not supported in now platform.'
13
+ },
14
+ schema:[],
15
+ type:'problem',
16
+ },
17
+ create(context) {
18
+ return {
19
+ "Program:exit"(node){
20
+ const sourceCode = context.sourceCode
21
+ const tracker = new ReferenceTracker(sourceCode.getScope(node), { mode: 'legacy' })
22
+ const trackMap = createTrackMap(false)
23
+ const globalsTrackMap = createTrackMap(true)
24
+
25
+ const references = [
26
+ ...tracker.iterateCjsReferences(trackMap),
27
+ ...tracker.iterateEsmReferences(trackMap),
28
+ ...tracker.iterateGlobalReferences(globalsTrackMap)
29
+ ]
30
+
31
+ for(const { node, info } of references) {
32
+ context.report({ node, messageId: 'forbidden', data: info })
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,45 @@
1
+ const globals = require('globals')
2
+ const { READ } = require('@eslint-community/eslint-utils')
3
+
4
+ const globalsAllowList = []
5
+ const BROWSER_API_WARNING = 'Web APIs are not supported by the now platform'
6
+ const NO_GLOBAL_THIS = 'ES2020 `globalThis` variable is not supported by the now platform'
7
+
8
+ const getRestrictedGlobals = () => {
9
+ const globalRules = [{name:'globalThis', message: NO_GLOBAL_THIS}]
10
+ const browserRules = Object.keys(globals.browser)
11
+ .filter((key) => !globalsAllowList.includes(key))
12
+ .map((key) => {
13
+ return {
14
+ name: key,
15
+ message: BROWSER_API_WARNING,
16
+ }
17
+ })
18
+ return globalRules.concat(browserRules)
19
+ }
20
+
21
+ const getCoreNodeModules = () => ["assert","buffer","child_process","cluster","crypto","dgram","dns","domain","events","freelist","fs","http","https","module","net","os","path","punycode","querystring","readline","repl","smalloc","stream","string_decoder","sys","timers","tls","tracing","tty","url","util","vm","zlib"]
22
+
23
+ const getNodeGlobals = () => Object.keys(globals.nodeBuiltin)
24
+
25
+ const createTrackMap = (isNodeGlobals) => {
26
+ const trackMapItems = isNodeGlobals ? getNodeGlobals() : getCoreNodeModules()
27
+ const trackMap = {}
28
+
29
+ for(const item of trackMapItems) {
30
+ trackMap[item] = {
31
+ [READ] : {
32
+ name: item
33
+ }
34
+ }
35
+ }
36
+
37
+ return trackMap
38
+ }
39
+
40
+ module.exports = {
41
+ getRestrictedGlobals,
42
+ createTrackMap,
43
+ getCoreNodeModules,
44
+ getNodeGlobals
45
+ }
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@servicenow/eslint-plugin-sdk-app-plugin",
3
+ "version": "1.0.1",
4
+ "description": "Plugin to disallow Browser and Node.js APIs not supported in rhino engine",
5
+ "keywords": [
6
+ "eslint",
7
+ "eslintplugin",
8
+ "eslint-plugin"
9
+ ],
10
+ "author": "",
11
+ "main": "./lib/index.js",
12
+ "exports": "./lib/index.js",
13
+ "scripts": {
14
+ "lint": "npm-run-all \"lint:*\"",
15
+ "lint:js": "eslint .",
16
+ "test": "mocha tests --recursive"
17
+ },
18
+ "dependencies": {
19
+ "@eslint-community/eslint-utils": "4.4.0",
20
+ "eslint": "8.50.0",
21
+ "eslint-plugin-n": "16.3.1",
22
+ "eslint-plugin-es-x": "7.2.0",
23
+ "eslint-plugin-eslint-plugin": "5.0.0",
24
+ "globals": "13.23.0"
25
+ },
26
+ "devDependencies": {
27
+ "mocha": "10.0.0",
28
+ "npm-run-all": "4.1.5"
29
+ },
30
+ "engines": {
31
+ "node": "^14.17.0 || ^16.0.0 || >= 18.0.0"
32
+ },
33
+ "peerDependencies": {
34
+ "eslint": ">=8"
35
+ },
36
+ "license": "ISC"
37
+ }
@@ -0,0 +1,26 @@
1
+ const { RuleTester } = require('eslint');
2
+ const noPromise = require('../../lib/rules/no-promise');
3
+
4
+ const ruleTester = new RuleTester({
5
+ parserOptions: { ecmaVersion: 2015 }
6
+ });
7
+
8
+ const errorMessages = [{ message: 'ES2015 Promise class is not supported in now platform.' }]
9
+
10
+ ruleTester.run(
11
+ 'no-promise',
12
+ noPromise,
13
+ {
14
+ valid: [{
15
+ code: "const Promise = 'value';",
16
+ }],
17
+ invalid: [{
18
+ code: 'const p = new Promise()',
19
+ errors: errorMessages,
20
+ },
21
+ {
22
+ code: 'Promise.all()',
23
+ errors: errorMessages
24
+ }],
25
+ }
26
+ );
@@ -0,0 +1,52 @@
1
+ const { RuleTester } = require('eslint');
2
+ const noUnsupportedNodeBuiltins = require('../../lib/rules/no-unsupported-node-builtins');
3
+ const { getCoreNodeModules, getNodeGlobals } = require('../../lib/util/utility');
4
+
5
+ const ruleTester = new RuleTester({
6
+ parserOptions: { sourceType: 'module' },
7
+ env: {node: true, es6: true}
8
+ });
9
+
10
+ const getInvalidsForNoUnsupportedNodeBuiltsRule = () => {
11
+ const invalids = []
12
+ const nodeModules = getCoreNodeModules()
13
+ const nodeGlobals = getNodeGlobals()
14
+
15
+ for(const module of nodeModules) {
16
+ invalids.push({
17
+ code: `const ${module} = require('${module}')`,
18
+ errors: [{ message: `The ${module} Node.js API is not supported in now platform.` }]
19
+ })
20
+ }
21
+
22
+ for(const module of nodeModules) {
23
+ invalids.push({
24
+ code: `import ${module} from '${module}'`,
25
+ errors: [{ message: `The ${module} Node.js API is not supported in now platform.` }]
26
+ })
27
+ }
28
+
29
+ for(const global of nodeGlobals) {
30
+ invalids.push({
31
+ code: `const x = ${global}`,
32
+ errors: [{ message: `The ${global} Node.js API is not supported in now platform.` }]
33
+ })
34
+ }
35
+
36
+ return invalids
37
+ }
38
+
39
+ ruleTester.run(
40
+ 'no-unsupported-node-builtins',
41
+ noUnsupportedNodeBuiltins,
42
+ {
43
+ valid: [{
44
+ code: "const fs = {'Dir':'cool'}; const x = fs.Dir",
45
+ },{
46
+ code: "const fs = {readFileSync: function(){}}; fs.readFileSync()"
47
+ },{
48
+ code: "const Buffer = {from: function(){}}; Buffer.from()"
49
+ }],
50
+ invalid: getInvalidsForNoUnsupportedNodeBuiltsRule()
51
+ }
52
+ );