diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4148966..ee48b2f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- [#40](https://github.com/green-code-initiative/creedengo-javascript/pull/40) Add rule `@creedengo/avoid-autoplay` (GCI36)
+- [#45](https://github.com/green-code-initiative/creedengo-javascript/pull/45) Add rule `@creedengo/avoid-keep-awake` (GCI505)
- [#46](https://github.com/green-code-initiative/creedengo-javascript/pull/46) Add rule `@creedengo/prefer-lighter-formats-for-image-files` (GCI31)
## [2.0.0] - 2025-01-22
diff --git a/eslint-plugin/README.md b/eslint-plugin/README.md
index 35086e1..0504ba6 100644
--- a/eslint-plugin/README.md
+++ b/eslint-plugin/README.md
@@ -80,6 +80,7 @@ Add `@creedengo` to the `plugins` section of your `.eslintrc`, followed by rules
| [avoid-brightness-override](docs/rules/avoid-brightness-override.md) | Should avoid to override brightness | ✅ |
| [avoid-css-animations](docs/rules/avoid-css-animations.md) | Avoid usage of CSS animations | ✅ |
| [avoid-high-accuracy-geolocation](docs/rules/avoid-high-accuracy-geolocation.md) | Avoid using high accuracy geolocation in web applications | ✅ |
+| [avoid-keep-awake](docs/rules/avoid-keep-awake.md) | Avoid screen keep awake | ✅ |
| [limit-db-query-results](docs/rules/limit-db-query-results.md) | Should limit the number of returns for a SQL query | ✅ |
| [no-empty-image-src-attribute](docs/rules/no-empty-image-src-attribute.md) | Disallow usage of image with empty source attribute | ✅ |
| [no-import-all-from-library](docs/rules/no-import-all-from-library.md) | Should not import all from library | ✅ |
diff --git a/eslint-plugin/docs/rules/avoid-keep-awake.md b/eslint-plugin/docs/rules/avoid-keep-awake.md
new file mode 100644
index 0000000..056ccf2
--- /dev/null
+++ b/eslint-plugin/docs/rules/avoid-keep-awake.md
@@ -0,0 +1,40 @@
+# Avoid screen keep awake (`@creedengo/avoid-keep-awake`)
+
+⚠️ This rule _warns_ in the ✅ `recommended` config.
+
+
+
+## Why is this an issue?
+
+To avoid draining the battery, an Android device that is left idle quickly falls asleep.
+Hence, keeping the screen on should be avoided, unless it is absolutely necessary.
+
+> **Note**: This rule currently only supports detecting `expo-keep-awake` package usage. Support for other keep-awake packages may be added in future versions.
+
+```js
+import { useKeepAwake } from "expo-keep-awake";
+
+export default function KeepAwakeExample() {
+ useKeepAwake(); // Non compliant
+ return (
+
+ This screen will never sleep!
+
+ );
+}
+```
+
+```js
+import { activateKeepAwake } from "expo-keep-awake";
+
+_activate = () => {
+ activateKeepAwake(); // Non-compliant
+ alert("Activated!");
+};
+```
+
+## Resources
+
+### Documentation
+
+- [Expo Docs](https://docs.expo.dev/versions/latest/sdk/keep-awake/) - Expo KeepAwake
diff --git a/eslint-plugin/lib/rules/avoid-keep-awake.js b/eslint-plugin/lib/rules/avoid-keep-awake.js
new file mode 100644
index 0000000..06f3737
--- /dev/null
+++ b/eslint-plugin/lib/rules/avoid-keep-awake.js
@@ -0,0 +1,65 @@
+/*
+ * creedengo JavaScript plugin - Provides rules to reduce the environmental footprint of your JavaScript programs
+ * Copyright © 2023 Green Code Initiative (https://green-code-initiative.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+"use strict";
+
+const keepAwakeLibrariesMethods = {
+ "expo-keep-awake": ["activateKeepAwake", "useKeepAwake"],
+};
+
+/** @type {import("eslint").Rule.RuleModule} */
+module.exports = {
+ meta: {
+ type: "suggestion",
+ docs: {
+ description: "Avoid screen keep awake",
+ category: "eco-design",
+ recommended: "warn",
+ },
+ messages: {
+ AvoidKeepAwake: "Avoid screen keep awake",
+ },
+ schema: [],
+ },
+ create: function (context) {
+ const librariesFoundInImports = [];
+
+ return {
+ ImportDeclaration(node) {
+ const currentLibrary = node.source.value;
+
+ if (keepAwakeLibrariesMethods[currentLibrary]) {
+ librariesFoundInImports.push(currentLibrary);
+ }
+ },
+ CallExpression(node) {
+ if (librariesFoundInImports.length === 0) {
+ return;
+ }
+
+ if (
+ librariesFoundInImports.some((library) =>
+ keepAwakeLibrariesMethods[library].includes(node.callee.name),
+ )
+ ) {
+ context.report({ node, messageId: "AvoidKeepAwake" });
+ }
+ },
+ };
+ },
+};
diff --git a/eslint-plugin/tests/lib/rules/avoid-keep-awake.js b/eslint-plugin/tests/lib/rules/avoid-keep-awake.js
new file mode 100644
index 0000000..6bea138
--- /dev/null
+++ b/eslint-plugin/tests/lib/rules/avoid-keep-awake.js
@@ -0,0 +1,127 @@
+/*
+ * creedengo JavaScript plugin - Provides rules to reduce the environmental footprint of your JavaScript programs
+ * Copyright © 2023 Green Code Initiative (https://green-code-initiative.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const rule = require("../../../lib/rules/avoid-keep-awake");
+const RuleTester = require("eslint").RuleTester;
+
+//------------------------------------------------------------------------------
+// Tests
+//------------------------------------------------------------------------------
+
+const ruleTester = new RuleTester({
+ parserOptions: {
+ ecmaVersion: 2022,
+ sourceType: "module",
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+});
+
+const expectedErrorHook = {
+ messageId: "AvoidKeepAwake",
+ type: "CallExpression",
+};
+
+const expectedErrorFunction = {
+ messageId: "AvoidKeepAwake",
+ type: "CallExpression",
+};
+
+ruleTester.run("avoid-keep-awake", rule, {
+ valid: [
+ {
+ code: `
+ import React from 'react';
+ import { Text, View } from 'react-native';
+
+ export default function ValidExample() {
+ return (
+
+ This screen will sleep!
+
+ );
+ }
+ `,
+ },
+ {
+ code: `
+ import React from 'react';
+ import { useKeepAwake } from 'other-library';
+ import { Button, View } from 'react-native';
+
+ export default class ValidExample extends React.Component {
+ render() {
+ useKeepAwake();
+ return (
+
+
+ );
+ }
+ }
+ `,
+ },
+ ],
+ invalid: [
+ {
+ code: `
+ import { useKeepAwake } from 'expo-keep-awake';
+ import React from 'react';
+ import { Text, View } from 'react-native';
+
+ export default function KeepAwakeExample() {
+ useKeepAwake();
+ return (
+
+ This screen will never sleep!
+
+ );
+ }
+ `,
+ errors: [expectedErrorHook],
+ },
+ {
+ code: `
+ import { activateKeepAwake } from 'expo-keep-awake';
+ import React from 'react';
+ import { Button, View } from 'react-native';
+
+ export default class KeepAwakeExample extends React.Component {
+ render() {
+ return (
+
+
+
+ );
+ }
+
+ _activate = () => {
+ activateKeepAwake();
+ alert('Activated!');
+ };
+ }`,
+ errors: [expectedErrorFunction],
+ },
+ ],
+});
diff --git a/sonar-plugin/pom.xml b/sonar-plugin/pom.xml
index 03cd541..4a65e3e 100644
--- a/sonar-plugin/pom.xml
+++ b/sonar-plugin/pom.xml
@@ -49,7 +49,7 @@
${encoding}
${encoding}
- 2.2.1
+ 2.2.2
9.14.0.375
9.13.0.20537
1.23.0.740
diff --git a/sonar-plugin/src/main/java/org/greencodeinitiative/creedengo/javascript/CheckList.java b/sonar-plugin/src/main/java/org/greencodeinitiative/creedengo/javascript/CheckList.java
index 6fb8973..8ed5b81 100644
--- a/sonar-plugin/src/main/java/org/greencodeinitiative/creedengo/javascript/CheckList.java
+++ b/sonar-plugin/src/main/java/org/greencodeinitiative/creedengo/javascript/CheckList.java
@@ -38,6 +38,7 @@ public static List> getAllChecks() {
AvoidBrightnessOverride.class,
AvoidCSSAnimations.class,
AvoidHighAccuracyGeolocation.class,
+ AvoidKeepAwake.class,
LimitDbQueryResult.class,
NoEmptyImageSrcAttribute.class,
NoImportAllFromLibrary.class,
diff --git a/sonar-plugin/src/main/java/org/greencodeinitiative/creedengo/javascript/checks/AvoidKeepAwake.java b/sonar-plugin/src/main/java/org/greencodeinitiative/creedengo/javascript/checks/AvoidKeepAwake.java
new file mode 100644
index 0000000..d9e5229
--- /dev/null
+++ b/sonar-plugin/src/main/java/org/greencodeinitiative/creedengo/javascript/checks/AvoidKeepAwake.java
@@ -0,0 +1,37 @@
+/*
+ * Creedengo JavaScript plugin - Provides rules to reduce the environmental footprint of your JavaScript programs
+ * Copyright © 2023 Green Code Initiative (https://green-code-initiative.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.greencodeinitiative.creedengo.javascript.checks;
+
+import org.sonar.check.Rule;
+import org.sonar.plugins.javascript.api.EslintBasedCheck;
+import org.sonar.plugins.javascript.api.JavaScriptRule;
+import org.sonar.plugins.javascript.api.TypeScriptRule;
+
+@JavaScriptRule
+@TypeScriptRule
+@Rule(key = AvoidKeepAwake.RULE_KEY)
+public class AvoidKeepAwake implements EslintBasedCheck {
+
+ public static final String RULE_KEY = "GCI505";
+
+ @Override
+ public String eslintKey() {
+ return "@creedengo/avoid-keep-awake";
+ }
+
+}
diff --git a/sonar-plugin/src/main/resources/org/greencodeinitiative/creedengo/profiles/javascript_profile.json b/sonar-plugin/src/main/resources/org/greencodeinitiative/creedengo/profiles/javascript_profile.json
index 8be08f9..af1a0b3 100644
--- a/sonar-plugin/src/main/resources/org/greencodeinitiative/creedengo/profiles/javascript_profile.json
+++ b/sonar-plugin/src/main/resources/org/greencodeinitiative/creedengo/profiles/javascript_profile.json
@@ -11,6 +11,7 @@
"GCI30",
"GCI31",
"GCI36",
+ "GCI505",
"GCI523",
"GCI530"
]