@amazon-devices/eslint-plugin-kepler 0.1.4 → 0.1.8
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/README.md +198 -23
- package/dist/formatters/KeplerReport.js +40 -0
- package/dist/formatters/default.js +189 -8
- package/dist/index.js +107 -1
- package/dist/metrics/Metrics.js +69 -0
- package/dist/metrics/TelemetryService.js +48 -0
- package/dist/rules/apiPrivileges/ApiPrivilegeStateCheck.js +102 -0
- package/dist/rules/apiPrivileges/ApiPrivilegesCheck.js +67 -0
- package/dist/rules/apiPrivileges/apiPermissionsNeeded.js +58 -0
- package/dist/rules/apiPrivileges/manifestHelper.js +44 -0
- package/dist/rules/backwardCompatibility/BackwardCompatibility.js +119 -0
- package/dist/rules/backwardCompatibility/BackwardCompatibilityCopyOnPack.js +101 -0
- package/dist/rules/backwardCompatibility/BackwardCompatibilitySysconfCheck.js +73 -0
- package/dist/rules/performance/Animated.js +64 -0
- package/dist/rules/performance/CheckSubscription.js +150 -0
- package/dist/rules/performance/DetectSplashScreen.js +62 -0
- package/dist/rules/performance/DetectUseReportFullyDrawn.js +50 -0
- package/dist/rules/performance/FlatList.js +39 -0
- package/dist/rules/systemDistributedLibs/SDLPackageVersionCheck.js +136 -0
- package/dist/rules/systemDistributedLibs/SDLPackageVersionCheckImports.js +58 -0
- package/dist/rules/systemDistributedLibs/sdlHelpers.js +232 -0
- package/dist/rules/systemDistributedLibs/sdlRuleMessages.js +25 -0
- package/dist/state/KeplerESLintPluginStateManager.js +94 -0
- package/dist/utils/Constants.js +40 -0
- package/dist/utils/PackageUtils.js +50 -0
- package/dist/utils/RuleUtils.js +128 -0
- package/package.json +1 -1
- package/dist/formatters/default.js.LICENSE.txt +0 -1
package/dist/index.js
CHANGED
|
@@ -1 +1,107 @@
|
|
|
1
|
-
(()=>{"use strict";var e={24:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.getAppManifest=function(){if(p)return p;try{const e=n.readFileSync(a.join(l.PROJECT_DIR_PATH,u),"utf8");p=i.parse(e)}catch(e){return}return p},t.getKeplerESLintPackageJson=function(){return s};var n=c(r(896)),a=c(r(928)),i=c(r(94)),s=c(r(330)),l=r(624);function o(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(o=function(e){return e?r:t})(e)}function c(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var r=o(t);if(r&&r.has(e))return r.get(e);var n={__proto__:null},a=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var s=a?Object.getOwnPropertyDescriptor(e,i):null;s&&(s.get||s.set)?Object.defineProperty(n,i,s):n[i]=e[i]}return n.default=e,r&&r.set(e,n),n}let p;const u="manifest.toml"},94:e=>{e.exports=require("toml")},272:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.DetectSplashScreen=void 0;var n=r(816),a=r(886);const i="usePreventHideSplashScreen",s="useHideSplashScreenCallback";t.DetectSplashScreen={meta:{type:"suggestion",docs:{description:"usePreventHideSplashScreen() should be used to natively render splash screen, for better App launch performance",recommended:!0,category:"Performance"},fixable:"code",schema:[]},create(e){const t=new Set,r=new Set;return{VariableDeclarator(e){(0,a.isFunctionAssignedToVariable)(e,i)||(0,a.isModuleFunctionAssignedToVariable)(e,i)?t.add(e.id.name):((0,a.isFunctionAssignedToVariable)(e,s)||(0,a.isModuleFunctionAssignedToVariable)(e,s))&&r.add(e.id.name)},CallExpression(e){if((0,a.isDirectCall)(e,i)||(0,a.isAliasCall)(e,i,t)||(0,a.isNamespacedCall)(e,i)){const e=n.KeplerESLintPluginStateManager.getInstance().getKeplerESLintState();e.splashScreen.usePreventHideSplashScreenFound=!0,n.KeplerESLintPluginStateManager.getInstance().setKeplerESLintState(e)}else if((0,a.isDirectCall)(e,s)||(0,a.isAliasCall)(e,s,r)||(0,a.isNamespacedCall)(e,s)){const e=n.KeplerESLintPluginStateManager.getInstance().getKeplerESLintState();e.splashScreen.useHideSplashScreenCallbackFound=!0,n.KeplerESLintPluginStateManager.getInstance().setKeplerESLintState(e)}}}}}},330:e=>{e.exports=JSON.parse('{"name":"@amazon-devices/eslint-plugin-kepler","version":"0.1.4","description":"An ESLint Plugin to suggest Kepler App Development best practices","main":"dist/index.js","files":["dist","THIRD_PARTY_NOTICES.txt"],"scripts":{"test":"jest --colors","lint":"eslint src __tests__ --ext .js,.ts,.tsx","lint:fix":"eslint src __tests__ --ext .js,.ts,.tsx --fix","prepare":"npm run build","typeCheck":"tsc --noEmit","bundle":"webpack","build":"npm-run-all lint typeCheck test bundle","format":"prettier --config .prettierrc \'src/**/*.ts\' \'__tests__/**/*.ts\' --write","checkLicenses":"license-checker --production --exclude MIT,Apache-2.0,BSD-2-Clause,BSD-3-Clause,ISC,0BSD,Python-2.0","genAttribution":"generate-attribution -o ./.attr && mv .attr/attribution.txt ./dist/LICENSE-THIRD-PARTY && rm -rf .attr"},"devDependencies":{"@amazon-devices/kepler-telemetry-service-config":"*","@amazon-devices/kepler-telemetry-service-typescript-client":"*","@babel/cli":"^7.26.4","@babel/core":"^7.26.9","@babel/preset-env":"^7.26.9","@babel/preset-typescript":"^7.26.0","@eslint/js":"^8.12.0","@trivago/prettier-plugin-sort-imports":"^5.2.1","@types/eslint":"^8.4.1","@types/jest":"^29.5.14","@types/node":"^22.10.2","@typescript-eslint/eslint-plugin":"^8.18.0","@typescript-eslint/parser":"^8.18.0","@typescript-eslint/types":"^8.18.0","@typescript-eslint/utils":"^8.18.0","babel-loader":"^9.2.1","babel-plugin-transform-remove-console":"^6.9.4","eslint":"^8.12.0","globals":"^15.13.0","husky":"^9.1.7","jest":"^29.7.0","license-checker":"^25.0.1","npm-run-all":"^4.1.5","oss-attribution-generator":"^1.7.1","prettier-plugin-organize-imports":"^4.1.0","ts-jest":"^29.2.5","ts-node":"^10.9.2","typescript":"^5.7.2","typescript-eslint":"^8.18.0","webpack":"^5.98.0","webpack-cli":"^6.0.1"},"dependencies":{"chalk":"^4.1.2","toml":"^3.0.0","uuid":"^11.0.0"},"peerDependencies":{"eslint":">=8.12.0"},"husky":{"hooks":{"pre-commit":"npm run format"}}}')},407:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.CheckSubscription=void 0;const n=`See ${r(624).KEPLER_BEST_PRACTICE_URL}#listeners-event-subscriptions-and-timers for more.`;t.CheckSubscription={meta:{type:"suggestion",docs:{description:"Checks if subscriptions are set to be cleaned up",recommended:!0,category:"Performance"},fixable:"code",schema:[],messages:{failedToKeepSubscription:`Subscription must be kept in variable so that it can be cleaned up on the component is detached. ${n}`,missingCleanUp:`Subscription \`{{varName}}\` is not cleaned up. ${n}`}},create(e){const t=new Set,r=new Set,n=new Set;return{"VariableDeclarator[init.callee.name = /^useAdd(KeplerAppState|UserInput)ListenerCallback$/]":e=>{if("Identifier"===e.id.type){const r=e.id.name;t.add(r)}},"CallExpression[callee.name='useEffect'] :function CallExpression":a=>{if("Identifier"===a.callee.type&&t.has(a.callee.name)){const t=e.sourceCode??e.getSourceCode(),i=t.getAncestors?.(a)??e.getAncestors();if(i.length>=1){const e=i[i.length-1];if("VariableDeclarator"===e.type&&"Identifier"==e.id.type)return void r.add(e.id.name);if("AssignmentExpression"===e.type&&"Identifier"==e.left.type)return void r.add(e.left.name);if("CallExpression"===e.type&&e.arguments[0]===a&&"MemberExpression"===e.callee.type){const t=e.callee;if("Identifier"===t.property.type&&["add","push"].includes(t.property.name)&&"Identifier"===t.object.type)return void n.add(t.object.name)}}e.report({node:a,messageId:"failedToKeepSubscription"})}},"CallExpression[callee.name='useEffect'] :function ReturnStatement CallExpression[callee.property.name='remove']":e=>{if("MemberExpression"===e.callee.type){const t=e.callee;"Identifier"===t.object.type&&r.has(t.object.name)&&r.delete(t.object.name)}},"CallExpression[callee.name='useEffect'] :function ReturnStatement CallExpression[callee.property.name='forEach']":e=>{if("MemberExpression"===e.callee.type){const t=e.callee;"Identifier"===t.object.type&&n.has(t.object.name)&&n.delete(t.object.name)}},"CallExpression[callee.name='useEffect']:exit":t=>{for(const n of r)e.report({node:t,messageId:"missingCleanUp",data:{varName:n}});for(const r of n)e.report({node:t,messageId:"missingCleanUp",data:{varName:r}});r.clear(),n.clear()}}}}},624:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.UNKNOWN=t.PROJECT_DIR_PATH=t.KeplerESLintRuleIds=t.KEPLER_ESLINT_RULE_PREFIX=t.KEPLER_ESLINT_OUTPUT_DIR_PATH=t.KEPLER_DOC_BASE_URL=t.KEPLER_BEST_PRACTICE_URL=t.ICON_WARN=t.ICON_ERROR=t.ESLintRuleSeverity=void 0;var n=function(e,t){if(e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var r=a(t);if(r&&r.has(e))return r.get(e);var n={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var s in e)if("default"!==s&&{}.hasOwnProperty.call(e,s)){var l=i?Object.getOwnPropertyDescriptor(e,s):null;l&&(l.get||l.set)?Object.defineProperty(n,s,l):n[s]=e[s]}return n.default=e,r&&r.set(e,n),n}(r(928));function a(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(a=function(e){return e?r:t})(e)}t.KeplerESLintRuleIds=function(e){return e.FlatList="@amazon-devices/kepler/flat-list",e.Animated="@amazon-devices/kepler/animated",e.NoComplexScrollView="@amazon-devices/kepler/no-complex-scroll-view",e.DetectReportFullyDrawn="@amazon-devices/kepler/detect-report-fully-drawn",e.DetectSplashScreen="@amazon-devices/kepler/detect-splash-screen",e}({}),t.ESLintRuleSeverity=function(e){return e[e.OFF=0]="OFF",e[e.WARNING=1]="WARNING",e[e.ERROR=2]="ERROR",e}({});const i=t.PROJECT_DIR_PATH=process.cwd(),s=(t.KEPLER_ESLINT_OUTPUT_DIR_PATH=n.join(i,"generated","eslint-plugin-kepler"),t.ICON_WARN="⚠️",t.ICON_ERROR="❌",t.KEPLER_ESLINT_RULE_PREFIX="@amazon-devices/kepler",t.UNKNOWN="UNKNOWN",t.KEPLER_DOC_BASE_URL="https://developer.amazon.com/docs");t.KEPLER_BEST_PRACTICE_URL=`${s}/kepler/best_practices.html`},723:(e,t,r)=>{var n=r(737),a=r(407),i=r(272),s=r(970),l=r(819),o=r(816),c=r(24);o.KeplerESLintPluginStateManager.getInstance().initialize(),e.exports={meta:{name:(0,c.getKeplerESLintPackageJson)().name,version:(0,c.getKeplerESLintPackageJson)().version,filePatterns:["**/*.jsx","**/*.tsx"]},configs:{performance:{plugins:["@amazon-devices/eslint-plugin-kepler"],rules:{"@amazon-devices/kepler/flat-list":"warn","@amazon-devices/kepler/check-subscription":"warn","@amazon-devices/kepler/animated":"error","@amazon-devices/kepler/detect-report-fully-drawn":"warn","@amazon-devices/kepler/detect-splash-screen":"warn"}}},rules:{"flat-list":l.FlatList,"check-subscription":a.CheckSubscription,animated:n.Animated,"detect-report-fully-drawn":s.DetectUseReportFullyDrawn,"detect-splash-screen":i.DetectSplashScreen}}},737:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Animated=void 0;var n=r(624);const a="useNativeDriver";t.Animated={meta:{type:"suggestion",docs:{description:"Recommends performance optimization configs for 'Animated' component",recommended:!0,category:"Performance"},fixable:"code",schema:[]},create:e=>({CallExpression(t){if("MemberExpression"!==t.callee.type||"Animated"!==t.callee.object.name||"timing"!==t.callee.property.name&&"spring"!==t.callee.property.name&&"decay"!==t.callee.property.name)return;const r=`${t.callee.object.name}.${t.callee.property.name}()`;if(t.arguments.length<2)return;const i=t.arguments[1];if("ObjectExpression"!==i.type)return;const s=i.properties.find((e=>"Property"===e.type&&"Identifier"===e.key.type&&e.key.name===a));s?s&&"Literal"===s.value.type&&!0===s.value.value||e.report({node:t,message:`'${a}' property is set to 'false'. Set ${a} to 'true' to run animations on UI thread for better performance. See ${n.KEPLER_BEST_PRACTICE_URL}#animations for more.`}):e.report({node:t,message:`${r} missing props: '${a}'. Set ${a} to 'true' to run animations on UI thread for better performance. See ${n.KEPLER_BEST_PRACTICE_URL}#animations for more.`})}})}},816:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.KeplerESLintPluginStateManager=void 0;var n=l(r(896)),a=l(r(928)),i=r(624);function s(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(s=function(e){return e?r:t})(e)}function l(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var r=s(t);if(r&&r.has(e))return r.get(e);var n={__proto__:null},a=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var l=a?Object.getOwnPropertyDescriptor(e,i):null;l&&(l.get||l.set)?Object.defineProperty(n,i,l):n[i]=e[i]}return n.default=e,r&&r.set(e,n),n}const o=a.join(i.KEPLER_ESLINT_OUTPUT_DIR_PATH,"keplerESLintState.json");class c{constructor(){this.keplerESLintState={fullyDrawn:{useReportFullyDrawnFound:!1},splashScreen:{usePreventHideSplashScreenFound:!1,useHideSplashScreenCallbackFound:!1}}}static getInstance(){return c.instance||(c.instance=new c),c.instance}initialize(){n.existsSync(i.KEPLER_ESLINT_OUTPUT_DIR_PATH)||n.mkdirSync(i.KEPLER_ESLINT_OUTPUT_DIR_PATH,{recursive:!0}),this.persistKeplerAnalyzerState()}setKeplerESLintState(e){this.keplerESLintState=e,this.persistKeplerAnalyzerState()}getKeplerESLintState(){return this.keplerESLintState}persistKeplerAnalyzerState(){n.writeFileSync(o,JSON.stringify(this.keplerESLintState),"utf8")}static readKeplerESLintState(){let e;try{e=JSON.parse(n.readFileSync(o,"utf8"))}catch(e){console.error(e)}return e}static cleanUpKeplerESLintState(){try{n.rmSync(i.KEPLER_ESLINT_OUTPUT_DIR_PATH)}catch(e){console.error(`Error deleting ${i.KEPLER_ESLINT_OUTPUT_DIR_PATH}`),console.error(e)}}}t.KeplerESLintPluginStateManager=c},819:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.FlatList=void 0;var n=r(624);const a=["initialNumToRender","windowSize","removeClippedSubviews","maxToRenderPerBatch","updateCellsBatchingPeriod"];t.FlatList={meta:{type:"suggestion",docs:{description:"FlatList causes performance overhead and should be used carefully",recommended:!0,category:"Performance"},fixable:"code",schema:[]},create:e=>({JSXOpeningElement(t){if("FlatList"===t.name.name){const r=t.attributes.map((e=>e.name.name)),i=a.filter((e=>!r.includes(e)));i.length>0&&e.report({node:t,message:`FlatList missing props: '${i}'. FlatList performance is not fully unlocked without these props. See ${n.KEPLER_BEST_PRACTICE_URL}#flatlist for more.`})}}})}},886:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.isAliasCall=function(e,t,n){return e.callee.type===r&&n.has(e.callee.name)},t.isDirectCall=function(e,t){return e.callee.type===r&&e.callee.name===t},t.isFunctionAssignedToVariable=function(e,t){return e.init?.type===r&&e.init.name===t&&e.id.type===r},t.isModuleFunctionAssignedToVariable=function(e,t){return e.init?.type===n&&e.init.property.type===r&&e.init.property.name===t&&e.id.type===r},t.isNamespacedCall=function(e,t){return e.callee.type===n&&e.callee.property.type===r&&e.callee.property.name===t};const r="Identifier",n="MemberExpression"},896:e=>{e.exports=require("fs")},928:e=>{e.exports=require("path")},970:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.DetectUseReportFullyDrawn=void 0;var n=r(816),a=r(886);const i="useReportFullyDrawn";t.DetectUseReportFullyDrawn={meta:{type:"suggestion",docs:{description:"useReportFullyDrawn() callback should be used to measure Time to Fully Drawn",recommended:!0,category:"Performance"},fixable:"code",schema:[]},create(e){const t=new Set;return{VariableDeclarator(e){(0,a.isFunctionAssignedToVariable)(e,i)&&t.add(e.id.name),(0,a.isModuleFunctionAssignedToVariable)(e,i)&&t.add(e.id.name)},CallExpression(e){if((0,a.isDirectCall)(e,i)||(0,a.isAliasCall)(e,i,t)||(0,a.isNamespacedCall)(e,i)){const e=n.KeplerESLintPluginStateManager.getInstance().getKeplerESLintState();e.fullyDrawn.useReportFullyDrawnFound=!0,n.KeplerESLintPluginStateManager.getInstance().setKeplerESLintState(e)}}}}}}},t={},r=function r(n){var a=t[n];if(void 0!==a)return a.exports;var i=t[n]={exports:{}};return e[n](i,i.exports,r),i.exports}(723);module.exports=r})();
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _Animated = require("./rules/performance/Animated");
|
|
4
|
+
var _CheckSubscription = require("./rules/performance/CheckSubscription");
|
|
5
|
+
var _DetectSplashScreen = require("./rules/performance/DetectSplashScreen");
|
|
6
|
+
var _DetectUseReportFullyDrawn = require("./rules/performance/DetectUseReportFullyDrawn");
|
|
7
|
+
var _FlatList = require("./rules/performance/FlatList");
|
|
8
|
+
var _SDLPackageVersionCheck = require("./rules/systemDistributedLibs/SDLPackageVersionCheck");
|
|
9
|
+
var _SDLPackageVersionCheckImports = require("./rules/systemDistributedLibs/SDLPackageVersionCheckImports");
|
|
10
|
+
var _ApiPrivilegesCheck = require("./rules/apiPrivileges/ApiPrivilegesCheck");
|
|
11
|
+
var _ApiPrivilegeStateCheck = require("./rules/apiPrivileges/ApiPrivilegeStateCheck");
|
|
12
|
+
var _BackwardCompatibility = require("./rules/backwardCompatibility/BackwardCompatibility");
|
|
13
|
+
var _BackwardCompatibilityCopyOnPack = require("./rules/backwardCompatibility/BackwardCompatibilityCopyOnPack");
|
|
14
|
+
var _BackwardCompatibilitySysconfCheck = require("./rules/backwardCompatibility/BackwardCompatibilitySysconfCheck");
|
|
15
|
+
var _KeplerESLintPluginStateManager = require("./state/KeplerESLintPluginStateManager");
|
|
16
|
+
var _PackageUtils = require("./utils/PackageUtils");
|
|
17
|
+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All rights reserved.
|
|
18
|
+
// AMAZON PROPRIETARY/CONFIDENTIAL
|
|
19
|
+
// You may not use this file except in compliance with the terms and conditions
|
|
20
|
+
// set forth in the accompanying LICENSE.TXT file.
|
|
21
|
+
// THESE MATERIALS ARE PROVIDED ON AN "AS IS" BASIS. AMAZON SPECIFICALLY
|
|
22
|
+
// DISCLAIMS, WITH RESPECT TO THESE MATERIALS, ALL WARRANTIES, EXPRESS,
|
|
23
|
+
// IMPLIED, OR STATUTORY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
// FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
|
25
|
+
|
|
26
|
+
const stateManager = _KeplerESLintPluginStateManager.KeplerESLintPluginStateManager.getInstance();
|
|
27
|
+
stateManager.initialize();
|
|
28
|
+
module.exports = {
|
|
29
|
+
meta: {
|
|
30
|
+
name: (0, _PackageUtils.getKeplerESLintPackageJson)().name,
|
|
31
|
+
version: (0, _PackageUtils.getKeplerESLintPackageJson)().version,
|
|
32
|
+
filePatterns: ['**/*.jsx', '**/*.tsx', '**/package.json']
|
|
33
|
+
},
|
|
34
|
+
configs: {
|
|
35
|
+
kepler: {
|
|
36
|
+
plugins: ['@amazon-devices/eslint-plugin-kepler'],
|
|
37
|
+
rules: {
|
|
38
|
+
'@amazon-devices/kepler/flat-list': 'warn',
|
|
39
|
+
'@amazon-devices/kepler/check-subscription': 'warn',
|
|
40
|
+
'@amazon-devices/kepler/animated': 'error',
|
|
41
|
+
'@amazon-devices/kepler/detect-report-fully-drawn': 'warn',
|
|
42
|
+
'@amazon-devices/kepler/detect-splash-screen': 'warn',
|
|
43
|
+
'@amazon-devices/kepler/sdl-package-version-check': ['error', {
|
|
44
|
+
'semverGuidance': 'auto'
|
|
45
|
+
}],
|
|
46
|
+
'@amazon-devices/kepler/sdl-package-version-check-imports': ['warn', {
|
|
47
|
+
'semverGuidance': 'auto'
|
|
48
|
+
}],
|
|
49
|
+
'@amazon-devices/kepler/api-privileges-check': 'error',
|
|
50
|
+
'@amazon-devices/kepler/api-privilege-state-check': 'error',
|
|
51
|
+
'@amazon-devices/kepler/backward-compatibility': 'error',
|
|
52
|
+
'@amazon-devices/kepler/backward-compatibility-copy-on-pack': 'error',
|
|
53
|
+
'@amazon-devices/kepler/backward-compatibility-sysconf-check': 'error'
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
performance: {
|
|
57
|
+
plugins: ['@amazon-devices/eslint-plugin-kepler'],
|
|
58
|
+
rules: {
|
|
59
|
+
'@amazon-devices/kepler/flat-list': 'warn',
|
|
60
|
+
'@amazon-devices/kepler/check-subscription': 'warn',
|
|
61
|
+
'@amazon-devices/kepler/animated': 'error',
|
|
62
|
+
'@amazon-devices/kepler/detect-report-fully-drawn': 'warn',
|
|
63
|
+
'@amazon-devices/kepler/detect-splash-screen': 'warn'
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
'system-distributed-libs': {
|
|
67
|
+
plugins: ['@amazon-devices/eslint-plugin-kepler'],
|
|
68
|
+
rules: {
|
|
69
|
+
'@amazon-devices/kepler/sdl-package-version-check': ['error', {
|
|
70
|
+
'semverGuidance': 'auto'
|
|
71
|
+
}],
|
|
72
|
+
'@amazon-devices/kepler/sdl-package-version-check-imports': ['warn', {
|
|
73
|
+
'semverGuidance': 'auto'
|
|
74
|
+
}]
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
'api-privileges': {
|
|
78
|
+
plugins: ['@amazon-devices/eslint-plugin-kepler'],
|
|
79
|
+
rules: {
|
|
80
|
+
'@amazon-devices/kepler/api-privileges-check': 'error',
|
|
81
|
+
'@amazon-devices/kepler/api-privilege-state-check': 'error'
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
'backward-compatibility': {
|
|
85
|
+
plugins: ['@amazon-devices/eslint-plugin-kepler'],
|
|
86
|
+
rules: {
|
|
87
|
+
'@amazon-devices/kepler/backward-compatibility': 'error',
|
|
88
|
+
'@amazon-devices/kepler/backward-compatibility-copy-on-pack': 'error',
|
|
89
|
+
'@amazon-devices/kepler/backward-compatibility-sysconf-check': 'error'
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
rules: {
|
|
94
|
+
'flat-list': _FlatList.FlatList,
|
|
95
|
+
'check-subscription': _CheckSubscription.CheckSubscription,
|
|
96
|
+
'animated': _Animated.Animated,
|
|
97
|
+
'detect-report-fully-drawn': _DetectUseReportFullyDrawn.DetectUseReportFullyDrawn,
|
|
98
|
+
'detect-splash-screen': _DetectSplashScreen.DetectSplashScreen,
|
|
99
|
+
'sdl-package-version-check': _SDLPackageVersionCheck.SDLPackageVersionCheck,
|
|
100
|
+
'sdl-package-version-check-imports': _SDLPackageVersionCheckImports.SDLPackageVersionCheckImports,
|
|
101
|
+
'api-privileges-check': _ApiPrivilegesCheck.ApiPrivilegesCheck,
|
|
102
|
+
'api-privilege-state-check': _ApiPrivilegeStateCheck.ApiPrivilegeStateCheck,
|
|
103
|
+
'backward-compatibility': _BackwardCompatibility.BackwardCompatibility,
|
|
104
|
+
'backward-compatibility-copy-on-pack': _BackwardCompatibilityCopyOnPack.BackwardCompatibilityCopyOnPack,
|
|
105
|
+
'backward-compatibility-sysconf-check': _BackwardCompatibilitySysconfCheck.BackwardCompatibilitySysconfCheck
|
|
106
|
+
}
|
|
107
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.emitMetric = emitMetric;
|
|
7
|
+
var fs = _interopRequireWildcard(require("fs"));
|
|
8
|
+
var path = _interopRequireWildcard(require("path"));
|
|
9
|
+
var _uuid = require("uuid");
|
|
10
|
+
var _keplerTelemetryServiceTypescriptClient = require("@amazon-devices/kepler-telemetry-service-typescript-client");
|
|
11
|
+
var _Constants = require("../utils/Constants");
|
|
12
|
+
var _TelemetryService = require("./TelemetryService");
|
|
13
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
14
|
+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All rights reserved.
|
|
15
|
+
// AMAZON PROPRIETARY/CONFIDENTIAL
|
|
16
|
+
// You may not use this file except in compliance with the terms and conditions
|
|
17
|
+
// set forth in the accompanying LICENSE.TXT file.
|
|
18
|
+
// THESE MATERIALS ARE PROVIDED ON AN "AS IS" BASIS. AMAZON SPECIFICALLY
|
|
19
|
+
// DISCLAIMS, WITH RESPECT TO THESE MATERIALS, ALL WARRANTIES, EXPRESS,
|
|
20
|
+
// IMPLIED, OR STATUTORY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
// FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
|
22
|
+
|
|
23
|
+
let lintSessionId = undefined;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Emits the provided metric object.
|
|
27
|
+
* @param metric KeplerESLintSummaryMetric object
|
|
28
|
+
*/
|
|
29
|
+
async function emitMetric(metric) {
|
|
30
|
+
const disableTelemetry = process.env.KEPLER_ESLINT_TELEMETRY_DISABLE;
|
|
31
|
+
if (disableTelemetry && disableTelemetry.toUpperCase() === 'TRUE') {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const metricsToFile = process.env.KEPLER_ESLINT_TELEMETRY_TO_FILE;
|
|
36
|
+
if (metricsToFile && metricsToFile.toUpperCase() === 'TRUE') {
|
|
37
|
+
const filePath = path.join(_Constants.KEPLER_ESLINT_OUTPUT_DIR_PATH, 'keplerESLintMetrics.json');
|
|
38
|
+
fs.writeFileSync(filePath, JSON.stringify(metric), 'utf8');
|
|
39
|
+
} else {
|
|
40
|
+
const telemetryClient = (0, _TelemetryService.getTelemetryClient)();
|
|
41
|
+
const records = toTelemetryRecords(metric, await telemetryClient?.getMachineId());
|
|
42
|
+
for (const record of records) {
|
|
43
|
+
await telemetryClient?.publishMetric(record);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
} catch (err) {}
|
|
47
|
+
}
|
|
48
|
+
function toTelemetryRecords(metric, machineId) {
|
|
49
|
+
const lintSessionId = getLintSessionId();
|
|
50
|
+
const records = [];
|
|
51
|
+
metric.ruleMetrics.forEach(ruleMetric => {
|
|
52
|
+
const lintResultMetric = new _keplerTelemetryServiceTypescriptClient.TelemetryRecordBuilder().withOperationName('lint_result').withMetricType(_keplerTelemetryServiceTypescriptClient.MetricType.Value).withMetricValue(1).withMetricAdditionalProperty('lint_session_id', lintSessionId).withMetricAdditionalProperty('app_id', metric.project?.name ?? _Constants.UNKNOWN).withMetricAdditionalProperty('severity', ruleMetric.severity).withMetricAdditionalProperty('rule_id', ruleMetric.ruleId).withMetricAdditionalProperty('message_id', ruleMetric.messageId ?? _Constants.UNKNOWN).withMetricAdditionalProperty('message', ruleMetric.message ?? _Constants.UNKNOWN).withMetricAdditionalProperty('suppressions', ruleMetric.suppressions ? JSON.stringify(ruleMetric.suppressions) : "").withMetricAdditionalProperty('machine_id', machineId).buildBehavioralAndOperational();
|
|
53
|
+
if (lintResultMetric instanceof _keplerTelemetryServiceTypescriptClient.TelemetryRecord) {
|
|
54
|
+
records.push(lintResultMetric);
|
|
55
|
+
} else {}
|
|
56
|
+
});
|
|
57
|
+
const reportMetric = new _keplerTelemetryServiceTypescriptClient.TelemetryRecordBuilder().withOperationName('lint_html_report').withMetricType(_keplerTelemetryServiceTypescriptClient.MetricType.Error).withMetricValue(metric.reportMetric.exportSuccess ? 0 : 1).withMetricAdditionalProperty('session_id', lintSessionId).withMetricAdditionalProperty('app_id', metric.project?.name ?? _Constants.UNKNOWN).withMetricAdditionalProperty('message', metric.reportMetric.exportError ?? _Constants.UNKNOWN).withMetricAdditionalProperty('machine_id', machineId).buildBehavioralAndOperational();
|
|
58
|
+
if (reportMetric instanceof _keplerTelemetryServiceTypescriptClient.TelemetryRecord) {
|
|
59
|
+
records.push(reportMetric);
|
|
60
|
+
} else {}
|
|
61
|
+
return records;
|
|
62
|
+
}
|
|
63
|
+
function getLintSessionId() {
|
|
64
|
+
if (lintSessionId === undefined) {
|
|
65
|
+
// generate random UUID
|
|
66
|
+
lintSessionId = (0, _uuid.v4)();
|
|
67
|
+
}
|
|
68
|
+
return lintSessionId;
|
|
69
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getTelemetryClient = getTelemetryClient;
|
|
7
|
+
exports.resetTelemetryClientForTests = resetTelemetryClientForTests;
|
|
8
|
+
var _keplerTelemetryServiceTypescriptClient = require("@amazon-devices/kepler-telemetry-service-typescript-client");
|
|
9
|
+
var _PackageUtils = require("../utils/PackageUtils");
|
|
10
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
11
|
+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All rights reserved.
|
|
12
|
+
// AMAZON PROPRIETARY/CONFIDENTIAL
|
|
13
|
+
// You may not use this file except in compliance with the terms and conditions
|
|
14
|
+
// set forth in the accompanying LICENSE.TXT file.
|
|
15
|
+
// THESE MATERIALS ARE PROVIDED ON AN "AS IS" BASIS. AMAZON SPECIFICALLY
|
|
16
|
+
// DISCLAIMS, WITH RESPECT TO THESE MATERIALS, ALL WARRANTIES, EXPRESS,
|
|
17
|
+
// IMPLIED, OR STATUTORY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
// FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
|
19
|
+
|
|
20
|
+
const KIA_COMPONENT_NAME = "kepler_eslint_plugin";
|
|
21
|
+
let client = undefined;
|
|
22
|
+
class SilentLogger {
|
|
23
|
+
debug(message) {}
|
|
24
|
+
info(message) {}
|
|
25
|
+
warn(message) {}
|
|
26
|
+
error(message) {}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Returns the TelemetryClient singleton instance.
|
|
31
|
+
* @returns TelemetryClient instance, or undefined if the client could not be created.
|
|
32
|
+
*/
|
|
33
|
+
function getTelemetryClient() {
|
|
34
|
+
if (!client) {
|
|
35
|
+
client = new _keplerTelemetryServiceTypescriptClient.TelemetryClientBuilder().withLogger(new SilentLogger()).withComponentName(KIA_COMPONENT_NAME).withComponentVersion((0, _PackageUtils.getKeplerESLintPackageJson)().version).build();
|
|
36
|
+
}
|
|
37
|
+
if (client instanceof _keplerTelemetryServiceTypescriptClient.TelemetryClientError) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
return client;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Resets the TelemetryClient singleton instance for tests.
|
|
45
|
+
*/
|
|
46
|
+
function resetTelemetryClientForTests() {
|
|
47
|
+
client = undefined;
|
|
48
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ApiPrivilegeStateCheck = void 0;
|
|
7
|
+
var fs = _interopRequireWildcard(require("fs"));
|
|
8
|
+
var path = _interopRequireWildcard(require("path"));
|
|
9
|
+
var _apiPermissionsNeeded = require("./apiPermissionsNeeded");
|
|
10
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
11
|
+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All rights reserved.
|
|
12
|
+
// AMAZON PROPRIETARY/CONFIDENTIAL
|
|
13
|
+
// You may not use this file except in compliance with the terms and conditions
|
|
14
|
+
// set forth in the accompanying LICENSE.TXT file.
|
|
15
|
+
// THESE MATERIALS ARE PROVIDED ON AN "AS IS" BASIS. AMAZON SPECIFICALLY
|
|
16
|
+
// DISCLAIMS, WITH RESPECT TO THESE MATERIALS, ALL WARRANTIES, EXPRESS,
|
|
17
|
+
// IMPLIED, OR STATUTORY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
// FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* ESLint rule to check for SecurityManager usage when APIs require user prompts
|
|
22
|
+
*/
|
|
23
|
+
const ApiPrivilegeStateCheck = exports.ApiPrivilegeStateCheck = {
|
|
24
|
+
meta: {
|
|
25
|
+
type: 'problem',
|
|
26
|
+
docs: {
|
|
27
|
+
description: 'Checks that APIs requiring user prompts have SecurityManager implementation',
|
|
28
|
+
recommended: true,
|
|
29
|
+
category: 'API Privileges'
|
|
30
|
+
},
|
|
31
|
+
fixable: undefined,
|
|
32
|
+
schema: []
|
|
33
|
+
},
|
|
34
|
+
create(context) {
|
|
35
|
+
const packageRequirements = new Map();
|
|
36
|
+
_apiPermissionsNeeded.API_PRIV_NEEDED.forEach(req => {
|
|
37
|
+
if (req.requiresUserPrompt) {
|
|
38
|
+
packageRequirements.set(req.packageName, req);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Checks if SecurityManager package is in package.json dependencies
|
|
44
|
+
*/
|
|
45
|
+
const hasSecurityManagerDependency = () => {
|
|
46
|
+
try {
|
|
47
|
+
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
48
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
52
|
+
const allDeps = {
|
|
53
|
+
...packageJson.dependencies,
|
|
54
|
+
...packageJson.devDependencies
|
|
55
|
+
};
|
|
56
|
+
return !!(allDeps['@amazon-devices/security-manager-lib'] || allDeps['@amazon-devices/security-manager-lib']);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
let hasGetPrivilegeState = false;
|
|
62
|
+
let hasRequestPrivilege = false;
|
|
63
|
+
const importNodes = [];
|
|
64
|
+
return {
|
|
65
|
+
MemberExpression(node) {
|
|
66
|
+
if (node.object && node.object.name === 'SecurityManager') {
|
|
67
|
+
if (node.property && node.property.name === 'getPrivilegeState') {
|
|
68
|
+
hasGetPrivilegeState = true;
|
|
69
|
+
}
|
|
70
|
+
if (node.property && node.property.name === 'requestPrivilege') {
|
|
71
|
+
hasRequestPrivilege = true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
ImportDeclaration(node) {
|
|
76
|
+
const importSource = node.source.value;
|
|
77
|
+
const requirement = packageRequirements.get(importSource);
|
|
78
|
+
if (requirement) {
|
|
79
|
+
importNodes.push({
|
|
80
|
+
node,
|
|
81
|
+
importSource
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
'Program:exit'() {
|
|
86
|
+
const hasDependency = hasSecurityManagerDependency();
|
|
87
|
+
const hasCalls = hasGetPrivilegeState && hasRequestPrivilege;
|
|
88
|
+
importNodes.forEach(({
|
|
89
|
+
node,
|
|
90
|
+
importSource
|
|
91
|
+
}) => {
|
|
92
|
+
if (!hasDependency || !hasCalls) {
|
|
93
|
+
context.report({
|
|
94
|
+
node,
|
|
95
|
+
message: `The API ${importSource} requires you prompt the user for privilige acceptance. See the Vega documentation for this API as well as for SecurityManager.`
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ApiPrivilegesCheck = void 0;
|
|
7
|
+
var _apiPermissionsNeeded = require("./apiPermissionsNeeded");
|
|
8
|
+
var _manifestHelper = require("./manifestHelper");
|
|
9
|
+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All rights reserved.
|
|
10
|
+
// AMAZON PROPRIETARY/CONFIDENTIAL
|
|
11
|
+
// You may not use this file except in compliance with the terms and conditions
|
|
12
|
+
// set forth in the accompanying LICENSE.TXT file.
|
|
13
|
+
// THESE MATERIALS ARE PROVIDED ON AN "AS IS" BASIS. AMAZON SPECIFICALLY
|
|
14
|
+
// DISCLAIMS, WITH RESPECT TO THESE MATERIALS, ALL WARRANTIES, EXPRESS,
|
|
15
|
+
// IMPLIED, OR STATUTORY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
// FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* ESLint rule to check for API imports that require permissions in manifest.toml
|
|
20
|
+
*/
|
|
21
|
+
const ApiPrivilegesCheck = exports.ApiPrivilegesCheck = {
|
|
22
|
+
meta: {
|
|
23
|
+
type: 'problem',
|
|
24
|
+
docs: {
|
|
25
|
+
description: 'Checks that APIs requiring permissions have proper manifest.toml entries',
|
|
26
|
+
recommended: true,
|
|
27
|
+
category: 'API Privileges'
|
|
28
|
+
},
|
|
29
|
+
fixable: undefined,
|
|
30
|
+
schema: []
|
|
31
|
+
},
|
|
32
|
+
create(context) {
|
|
33
|
+
const packageRequirements = new Map();
|
|
34
|
+
_apiPermissionsNeeded.API_PRIV_NEEDED.forEach(req => {
|
|
35
|
+
packageRequirements.set(req.packageName, req);
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
ImportDeclaration(node) {
|
|
39
|
+
const importSource = node.source.value;
|
|
40
|
+
const requirement = packageRequirements.get(importSource);
|
|
41
|
+
if (requirement) {
|
|
42
|
+
// Check needs privileges first (higher priority)
|
|
43
|
+
if (requirement.needsPrivilege.length > 0) {
|
|
44
|
+
const hasAnyNeedsPrivilege = requirement.needsPrivilege.some(privilege => (0, _manifestHelper.checkManifestForPrivilege)(privilege, 'needs'));
|
|
45
|
+
if (!hasAnyNeedsPrivilege) {
|
|
46
|
+
// Report error with the first privilege as example
|
|
47
|
+
context.report({
|
|
48
|
+
node,
|
|
49
|
+
message: `Using the APIs in ${importSource} requires the [[needs.privilege]] id="${requirement.needsPrivilege[0]}" entry in the Vega manifest.toml. Please see the Vega documentation for more information.`
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
} else if (requirement.wantsPrivilege.length > 0) {
|
|
53
|
+
// Only check wants privileges if no needs privileges are defined
|
|
54
|
+
const hasAnyWantsPrivilege = requirement.wantsPrivilege.some(privilege => (0, _manifestHelper.checkManifestForPrivilege)(privilege, 'wants'));
|
|
55
|
+
if (!hasAnyWantsPrivilege) {
|
|
56
|
+
// Report error with the first privilege as example
|
|
57
|
+
context.report({
|
|
58
|
+
node,
|
|
59
|
+
message: `Using the APIs in ${importSource} requires the [[wants.privilege]] id="${requirement.wantsPrivilege[0]}" entry in the Vega manifest.toml. Please see the Vega documentation for more information.`
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.API_PRIV_NEEDED = void 0;
|
|
7
|
+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All rights reserved.
|
|
8
|
+
// AMAZON PROPRIETARY/CONFIDENTIAL
|
|
9
|
+
// You may not use this file except in compliance with the terms and conditions
|
|
10
|
+
// set forth in the accompanying LICENSE.TXT file.
|
|
11
|
+
// THESE MATERIALS ARE PROVIDED ON AN "AS IS" BASIS. AMAZON SPECIFICALLY
|
|
12
|
+
// DISCLAIMS, WITH RESPECT TO THESE MATERIALS, ALL WARRANTIES, EXPRESS,
|
|
13
|
+
// IMPLIED, OR STATUTORY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
|
14
|
+
// FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
|
15
|
+
|
|
16
|
+
// Add APIs here that require privileges.
|
|
17
|
+
|
|
18
|
+
const API_PRIV_NEEDED = exports.API_PRIV_NEEDED = [{
|
|
19
|
+
packageName: '@amazon-devices/kepler-amazon-device-messaging',
|
|
20
|
+
needsPrivilege: ['com.amazon.device-messaging.privilege.access'],
|
|
21
|
+
wantsPrivilege: [],
|
|
22
|
+
requiresUserPrompt: false
|
|
23
|
+
}, {
|
|
24
|
+
packageName: '@amazon-devices/kepler-amazon-device-messaging',
|
|
25
|
+
needsPrivilege: ['com.amazon.device-messaging.privilege.access'],
|
|
26
|
+
wantsPrivilege: [],
|
|
27
|
+
requiresUserPrompt: false
|
|
28
|
+
}, {
|
|
29
|
+
packageName: '@amazon-devices/keplerscript-audio-lib',
|
|
30
|
+
needsPrivilege: ['com.amazon.audio.privilege.settings.control', 'com.amazon.audio.privilege.microphone.access'],
|
|
31
|
+
wantsPrivilege: [],
|
|
32
|
+
requiresUserPrompt: false
|
|
33
|
+
}, {
|
|
34
|
+
packageName: '@amazon-devices/keplerscript-audio-lib',
|
|
35
|
+
needsPrivilege: ['com.amazon.audio.privilege.settings.control'],
|
|
36
|
+
wantsPrivilege: [],
|
|
37
|
+
requiresUserPrompt: false
|
|
38
|
+
}, {
|
|
39
|
+
packageName: '@amazon-devices/kepler-identifiers',
|
|
40
|
+
needsPrivilege: ['com.amazon.devconf.privilege.identifiers.device-friendly-name'],
|
|
41
|
+
wantsPrivilege: [],
|
|
42
|
+
requiresUserPrompt: true
|
|
43
|
+
}, {
|
|
44
|
+
packageName: '@amazon-devices/kepler-identifiers',
|
|
45
|
+
needsPrivilege: ['com.amazon.devconf.privilege.identifiers.device-friendly-name'],
|
|
46
|
+
wantsPrivilege: [],
|
|
47
|
+
requiresUserPrompt: true
|
|
48
|
+
}, {
|
|
49
|
+
packageName: '@amazon-devices/keplerscript-netmgr-lib',
|
|
50
|
+
needsPrivilege: [],
|
|
51
|
+
wantsPrivilege: ['com.amazon.network.privilege.net-info'],
|
|
52
|
+
requiresUserPrompt: false
|
|
53
|
+
}, {
|
|
54
|
+
packageName: '@amazon-devices/keplerscript-netmgr-lib',
|
|
55
|
+
needsPrivilege: [],
|
|
56
|
+
wantsPrivilege: ['com.amazon.network.privilege.net-info'],
|
|
57
|
+
requiresUserPrompt: false
|
|
58
|
+
}];
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.checkManifestForPrivilege = void 0;
|
|
7
|
+
var fs = _interopRequireWildcard(require("fs"));
|
|
8
|
+
var path = _interopRequireWildcard(require("path"));
|
|
9
|
+
var toml = _interopRequireWildcard(require("toml"));
|
|
10
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
11
|
+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All rights reserved.
|
|
12
|
+
// AMAZON PROPRIETARY/CONFIDENTIAL
|
|
13
|
+
// You may not use this file except in compliance with the terms and conditions
|
|
14
|
+
// set forth in the accompanying LICENSE.TXT file.
|
|
15
|
+
// THESE MATERIALS ARE PROVIDED ON AN "AS IS" BASIS. AMAZON SPECIFICALLY
|
|
16
|
+
// DISCLAIMS, WITH RESPECT TO THESE MATERIALS, ALL WARRANTIES, EXPRESS,
|
|
17
|
+
// IMPLIED, OR STATUTORY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
// FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Checks if the manifest.toml contains the required privilege in the specified section
|
|
22
|
+
*/
|
|
23
|
+
const checkManifestForPrivilege = (privilege, section) => {
|
|
24
|
+
try {
|
|
25
|
+
const manifestPath = path.join(process.cwd(), 'manifest.toml');
|
|
26
|
+
if (!fs.existsSync(manifestPath)) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
const manifestContent = fs.readFileSync(manifestPath, 'utf8');
|
|
30
|
+
const manifest = toml.parse(manifestContent);
|
|
31
|
+
if (!manifest[section] || !Array.isArray(manifest[section].privilege)) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
return manifest[section].privilege.some(entry => {
|
|
35
|
+
if (typeof entry === 'object' && entry.id === privilege) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
});
|
|
40
|
+
} catch (e) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
exports.checkManifestForPrivilege = checkManifestForPrivilege;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.BackwardCompatibility = void 0;
|
|
7
|
+
var fs = _interopRequireWildcard(require("fs"));
|
|
8
|
+
var path = _interopRequireWildcard(require("path"));
|
|
9
|
+
var _RuleUtils = require("../../utils/RuleUtils");
|
|
10
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
11
|
+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All rights reserved.
|
|
12
|
+
// AMAZON PROPRIETARY/CONFIDENTIAL
|
|
13
|
+
// You may not use this file except in compliance with the terms and conditions
|
|
14
|
+
// set forth in the accompanying LICENSE.TXT file.
|
|
15
|
+
// THESE MATERIALS ARE PROVIDED ON AN "AS IS" BASIS. AMAZON SPECIFICALLY
|
|
16
|
+
// DISCLAIMS, WITH RESPECT TO THESE MATERIALS, ALL WARRANTIES, EXPRESS,
|
|
17
|
+
// IMPLIED, OR STATUTORY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
// FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Gets the location of the version field in package.json for error reporting
|
|
22
|
+
*/
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
24
|
+
const getVersionFieldLocation = sourceCode => {
|
|
25
|
+
const text = sourceCode.getText();
|
|
26
|
+
const versionMatch = text.match(/"version"\s*:\s*"[^"]*"/);
|
|
27
|
+
if (versionMatch) {
|
|
28
|
+
const start = text.indexOf(versionMatch[0]);
|
|
29
|
+
const startPos = sourceCode.getLocFromIndex(start);
|
|
30
|
+
const endPos = sourceCode.getLocFromIndex(start + versionMatch[0].length);
|
|
31
|
+
return {
|
|
32
|
+
start: startPos,
|
|
33
|
+
end: endPos
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
start: {
|
|
38
|
+
line: 1,
|
|
39
|
+
column: 0
|
|
40
|
+
},
|
|
41
|
+
end: {
|
|
42
|
+
line: 1,
|
|
43
|
+
column: 0
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Checks for backward compatibility issues in Vega system distributed library projects
|
|
50
|
+
*/
|
|
51
|
+
const BackwardCompatibility = exports.BackwardCompatibility = {
|
|
52
|
+
meta: {
|
|
53
|
+
type: 'problem',
|
|
54
|
+
docs: {
|
|
55
|
+
description: 'Checks for backward compatibility issues in Kepler projects',
|
|
56
|
+
recommended: true,
|
|
57
|
+
category: 'Backward Compatibility'
|
|
58
|
+
},
|
|
59
|
+
schema: []
|
|
60
|
+
},
|
|
61
|
+
create(context) {
|
|
62
|
+
return {
|
|
63
|
+
Program() {
|
|
64
|
+
// do nothing if not in a Brazil repo and/or this isn't a library
|
|
65
|
+
if (!(0, _RuleUtils.isBrazilRepo)() || !(0, _RuleUtils.isSDLProject)()) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Use modern context.filename with fallback to deprecated context.getFilename()
|
|
70
|
+
const filename = context.filename || context.getFilename();
|
|
71
|
+
if (!filename.endsWith('package.json')) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Use modern context.sourceCode with fallback to deprecated context.getSourceCode()
|
|
76
|
+
const sourceCode = context.sourceCode || context.getSourceCode();
|
|
77
|
+
const text = sourceCode.getText();
|
|
78
|
+
try {
|
|
79
|
+
const packageJson = JSON.parse(text);
|
|
80
|
+
const projectRoot = process.cwd();
|
|
81
|
+
const compatibilityFilePath = path.join(projectRoot, 'kepler-compatibility.json');
|
|
82
|
+
if (!fs.existsSync(compatibilityFilePath)) {
|
|
83
|
+
context.report({
|
|
84
|
+
node: sourceCode.ast,
|
|
85
|
+
message: 'You project is missing a kepler-compatibility.json file. This file is required for Vega library development. Please add it.',
|
|
86
|
+
loc: getVersionFieldLocation(sourceCode)
|
|
87
|
+
});
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const compatibilityContent = fs.readFileSync(compatibilityFilePath, 'utf8');
|
|
92
|
+
const compatibilityData = JSON.parse(compatibilityContent);
|
|
93
|
+
const supportedVersions = Object.keys(compatibilityData.versions || {});
|
|
94
|
+
const currentVersion = packageJson.version;
|
|
95
|
+
if (currentVersion && !supportedVersions.includes(currentVersion)) {
|
|
96
|
+
context.report({
|
|
97
|
+
node: sourceCode.ast,
|
|
98
|
+
message: `This version of the library (${currentVersion}) is not found in the kepler-compatibility.json. Please add an entry for this version.`,
|
|
99
|
+
loc: getVersionFieldLocation(sourceCode)
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
} catch {
|
|
103
|
+
// If kepler-compatibility.json exists but is malformed, treat as version not found
|
|
104
|
+
const currentVersion = packageJson.version;
|
|
105
|
+
if (currentVersion) {
|
|
106
|
+
context.report({
|
|
107
|
+
node: sourceCode.ast,
|
|
108
|
+
message: `This version of the library (${currentVersion}) is not found in the kepler-compatibility.json (JSON is malformed).`,
|
|
109
|
+
loc: getVersionFieldLocation(sourceCode)
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
} catch {
|
|
114
|
+
// Ignore JSON parsing errors for package.json. Linting will be unreliable anyway.
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
};
|