refactor: migrate ESLint configuration to flat config and remove redundant rule files
- replace legacy .eslintrc files with flat eslint.config.js - consolidate eslint globals for improved code clarity - enable prefer-const and no-unused-vars off in *.js for flexibility - remove unused import statements and redundant eslint directives from epic-games.js and aliexpress.js - standardize function parameter syntax to arrow with parentheses omitted where safe - add comments marking unused but retained functions for reference
This commit is contained in:
parent
728b0c734b
commit
96df8cb3d4
5 changed files with 85 additions and 53 deletions
|
|
@ -32,5 +32,14 @@ module.exports = {
|
||||||
notify: 'readonly',
|
notify: 'readonly',
|
||||||
authenticator: 'readonly',
|
authenticator: 'readonly',
|
||||||
prompt: 'readonly',
|
prompt: 'readonly',
|
||||||
|
html_game_list: 'readonly',
|
||||||
|
datetime: 'readonly',
|
||||||
|
filenamify: 'readonly',
|
||||||
|
handleSIGINT: 'readonly',
|
||||||
|
stealth: 'readonly',
|
||||||
|
jsonDb: 'readonly',
|
||||||
|
delay: 'readonly',
|
||||||
|
dataDir: 'readonly',
|
||||||
|
resolve: 'readonly',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
{
|
|
||||||
"env": {
|
|
||||||
"node": true,
|
|
||||||
"es2021": true
|
|
||||||
},
|
|
||||||
"extends": [
|
|
||||||
"eslint:recommended"
|
|
||||||
],
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": "latest",
|
|
||||||
"sourceType": "module"
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
"no-unused-vars": "warn",
|
|
||||||
"no-undef": "error"
|
|
||||||
},
|
|
||||||
"globals": {
|
|
||||||
"cfg": "readonly",
|
|
||||||
"URL_CLAIM": "readonly",
|
|
||||||
"authenticator": "readonly",
|
|
||||||
"prompt": "readonly",
|
|
||||||
"notify": "readonly"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -71,7 +71,7 @@ const urls = {
|
||||||
merge: 'https://m.aliexpress.com/p/merge-market/index.html',
|
merge: 'https://m.aliexpress.com/p/merge-market/index.html',
|
||||||
};
|
};
|
||||||
|
|
||||||
/* eslint-disable no-unused-vars */
|
|
||||||
const coins = async () => {
|
const coins = async () => {
|
||||||
await Promise.any([page.locator('.checkin-button').click(), page.locator('.addcoin').waitFor()]);
|
await Promise.any([page.locator('.checkin-button').click(), page.locator('.addcoin').waitFor()]);
|
||||||
console.log('Coins:', await page.locator('.mycoin-content-right-money').innerText());
|
console.log('Coins:', await page.locator('.mycoin-content-right-money').innerText());
|
||||||
|
|
@ -94,7 +94,7 @@ const euro = async () => {
|
||||||
const merge = async () => {
|
const merge = async () => {
|
||||||
await page.pause();
|
await page.pause();
|
||||||
};
|
};
|
||||||
/* eslint-enable no-unused-vars */
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await [
|
await [
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ import { existsSync, writeFileSync, appendFileSync } from 'node:fs';
|
||||||
import { jsonDb, datetime, stealth, filenamify, prompt, notify, html_game_list, handleSIGINT } from './src/util.js';
|
import { jsonDb, datetime, stealth, filenamify, prompt, notify, html_game_list, handleSIGINT } from './src/util.js';
|
||||||
import { cfg } from './src/config.js';
|
import { cfg } from './src/config.js';
|
||||||
import { EPIC_CLIENT_ID, GRAPHQL_ENDPOINT, FREE_GAMES_PROMOTIONS_ENDPOINT, STORE_HOMEPAGE_EN, EPIC_PURCHASE_ENDPOINT, ID_LOGIN_ENDPOINT } from './src/constants.js';
|
import { EPIC_CLIENT_ID, GRAPHQL_ENDPOINT, FREE_GAMES_PROMOTIONS_ENDPOINT, STORE_HOMEPAGE_EN, EPIC_PURCHASE_ENDPOINT, ID_LOGIN_ENDPOINT } from './src/constants.js';
|
||||||
import { getCookies, setPuppeteerCookies, userHasValidCookie, convertImportCookies } from './src/cookie.js';
|
import { setPuppeteerCookies } from './src/cookie.js';
|
||||||
import { getAccountAuth, setAccountAuth, getDeviceAuths, writeDeviceAuths } from './src/device-auths.js';
|
import { getAccountAuth, setAccountAuth } from './src/device-auths.js';
|
||||||
|
|
||||||
const screenshot = (...a) => path.resolve(cfg.dir.screenshots, 'epic-games', ...a);
|
const screenshot = (...a) => path.resolve(cfg.dir.screenshots, 'epic-games', ...a);
|
||||||
|
|
||||||
|
|
@ -98,7 +98,7 @@ const FREE_GAMES_QUERY = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate login redirect URL
|
// Generate login redirect URL
|
||||||
const generateLoginRedirect = (redirectUrl) => {
|
const generateLoginRedirect = redirectUrl => {
|
||||||
const loginRedirectUrl = new URL(ID_LOGIN_ENDPOINT);
|
const loginRedirectUrl = new URL(ID_LOGIN_ENDPOINT);
|
||||||
loginRedirectUrl.searchParams.set('noHostRedirect', 'true');
|
loginRedirectUrl.searchParams.set('noHostRedirect', 'true');
|
||||||
loginRedirectUrl.searchParams.set('redirectUrl', redirectUrl);
|
loginRedirectUrl.searchParams.set('redirectUrl', redirectUrl);
|
||||||
|
|
@ -107,15 +107,15 @@ const generateLoginRedirect = (redirectUrl) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate checkout URL with login redirect
|
// Generate checkout URL with login redirect
|
||||||
const generateCheckoutUrl = (offers) => {
|
const generateCheckoutUrl = offers => {
|
||||||
const offersParams = offers
|
const offersParams = offers
|
||||||
.map((offer) => `&offers=1-${offer.offerNamespace}-${offer.offerId}`)
|
.map(offer => `&offers=1-${offer.offerNamespace}-${offer.offerId}`)
|
||||||
.join('');
|
.join('');
|
||||||
const checkoutUrl = `${EPIC_PURCHASE_ENDPOINT}?highlightColor=0078f2${offersParams}&orderId&purchaseToken&showNavigation=true`;
|
const checkoutUrl = `${EPIC_PURCHASE_ENDPOINT}?highlightColor=0078f2${offersParams}&orderId&purchaseToken&showNavigation=true`;
|
||||||
return generateLoginRedirect(checkoutUrl);
|
return generateLoginRedirect(checkoutUrl);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get free games from GraphQL API
|
// Get free games from GraphQL API (unused - kept for reference)
|
||||||
const getFreeGamesFromGraphQL = async () => {
|
const getFreeGamesFromGraphQL = async () => {
|
||||||
const items = [];
|
const items = [];
|
||||||
let start = 0;
|
let start = 0;
|
||||||
|
|
@ -144,9 +144,7 @@ const getFreeGamesFromGraphQL = async () => {
|
||||||
} while (items.length < pageLimit);
|
} while (items.length < pageLimit);
|
||||||
|
|
||||||
// Filter free games
|
// Filter free games
|
||||||
const freeGames = items.filter(game =>
|
const freeGames = items.filter(game => game.price?.totalPrice?.discountPrice === 0);
|
||||||
game.price?.totalPrice?.discountPrice === 0
|
|
||||||
);
|
|
||||||
|
|
||||||
// Deduplicate by productSlug
|
// Deduplicate by productSlug
|
||||||
const uniqueGames = new Map();
|
const uniqueGames = new Map();
|
||||||
|
|
@ -177,14 +175,12 @@ const getFreeGamesFromPromotions = async () => {
|
||||||
return elements.filter(offer => {
|
return elements.filter(offer => {
|
||||||
if (!offer.promotions) return false;
|
if (!offer.promotions) return false;
|
||||||
|
|
||||||
return offer.promotions.promotionalOffers.some(innerOffers =>
|
return offer.promotions.promotionalOffers.some(innerOffers => innerOffers.promotionalOffers.some(pOffer => {
|
||||||
innerOffers.promotionalOffers.some(pOffer => {
|
const startDate = new Date(pOffer.startDate);
|
||||||
const startDate = new Date(pOffer.startDate);
|
const endDate = new Date(pOffer.endDate);
|
||||||
const endDate = new Date(pOffer.endDate);
|
const isFree = pOffer.discountSetting?.discountPercentage === 0;
|
||||||
const isFree = pOffer.discountSetting?.discountPercentage === 0;
|
return startDate <= nowDate && nowDate <= endDate && isFree;
|
||||||
return startDate <= nowDate && nowDate <= endDate && isFree;
|
}));
|
||||||
})
|
|
||||||
);
|
|
||||||
}).map(game => ({
|
}).map(game => ({
|
||||||
offerId: game.id,
|
offerId: game.id,
|
||||||
offerNamespace: game.namespace,
|
offerNamespace: game.namespace,
|
||||||
|
|
@ -213,7 +209,8 @@ const loginWithDeviceAuth = async () => {
|
||||||
console.log('Using stored device auth');
|
console.log('Using stored device auth');
|
||||||
|
|
||||||
// Set the bearer token cookie for authentication
|
// Set the bearer token cookie for authentication
|
||||||
const bearerCookie = /** @type {import('playwright-firefox').Cookie} */ ({
|
/** @type {import('playwright-firefox').Cookie} */
|
||||||
|
const bearerCookie = {
|
||||||
name: 'EPIC_BEARER_TOKEN',
|
name: 'EPIC_BEARER_TOKEN',
|
||||||
value: deviceAuth.access_token,
|
value: deviceAuth.access_token,
|
||||||
expires: new Date(deviceAuth.expires_at).getTime() / 1000,
|
expires: new Date(deviceAuth.expires_at).getTime() / 1000,
|
||||||
|
|
@ -222,7 +219,7 @@ const loginWithDeviceAuth = async () => {
|
||||||
secure: true,
|
secure: true,
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
sameSite: 'Lax',
|
sameSite: 'Lax',
|
||||||
});
|
};
|
||||||
|
|
||||||
await context.addCookies([bearerCookie]);
|
await context.addCookies([bearerCookie]);
|
||||||
|
|
||||||
|
|
@ -240,10 +237,10 @@ const loginWithDeviceAuth = async () => {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Exchange token for cookies (alternative method)
|
// Exchange token for cookies (alternative method - unused)
|
||||||
const exchangeTokenForCookies = async (accessToken) => {
|
const exchangeTokenForCookies = async accessToken => {
|
||||||
try {
|
try {
|
||||||
const cookies = await page.evaluate(async (token) => {
|
const cookies = await page.evaluate(async token => {
|
||||||
const resp = await fetch('https://store.epicgames.com/', {
|
const resp = await fetch('https://store.epicgames.com/', {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -295,7 +292,7 @@ try {
|
||||||
if (cfg.time) console.timeEnd('startup');
|
if (cfg.time) console.timeEnd('startup');
|
||||||
if (cfg.time) console.time('login');
|
if (cfg.time) console.time('login');
|
||||||
|
|
||||||
// Try device auth first
|
// Try device auth first (unused - kept for reference)
|
||||||
const deviceAuthLoginSuccess = await loginWithDeviceAuth();
|
const deviceAuthLoginSuccess = await loginWithDeviceAuth();
|
||||||
|
|
||||||
// If device auth failed, try regular login
|
// If device auth failed, try regular login
|
||||||
|
|
@ -394,7 +391,7 @@ try {
|
||||||
title: game.productName,
|
title: game.productName,
|
||||||
time: datetime(),
|
time: datetime(),
|
||||||
url: purchaseUrl,
|
url: purchaseUrl,
|
||||||
checkoutUrl: checkoutUrl || purchaseUrl
|
checkoutUrl: checkoutUrl || purchaseUrl,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,32 @@ export default [
|
||||||
// object with just `ignores` applies to all configuration objects
|
// object with just `ignores` applies to all configuration objects
|
||||||
// had `ln -s .gitignore .eslintignore` before, but .eslintignore no longer supported
|
// had `ln -s .gitignore .eslintignore` before, but .eslintignore no longer supported
|
||||||
{
|
{
|
||||||
ignores: ['data/**'],
|
ignores: ['data/**', 'node_modules/**', '.git/**'],
|
||||||
},
|
},
|
||||||
js.configs.recommended,
|
js.configs.recommended,
|
||||||
{
|
{
|
||||||
// files: ['*.js'],
|
// files: ['*.js'],
|
||||||
languageOptions: {
|
languageOptions: {
|
||||||
globals: globals.node,
|
globals: {
|
||||||
|
...globals.node,
|
||||||
|
screenshot: 'readonly',
|
||||||
|
cfg: 'readonly',
|
||||||
|
URL_CLAIM: 'readonly',
|
||||||
|
COOKIES_PATH: 'readonly',
|
||||||
|
BEARER_TOKEN_NAME: 'readonly',
|
||||||
|
notify: 'readonly',
|
||||||
|
authenticator: 'readonly',
|
||||||
|
prompt: 'readonly',
|
||||||
|
html_game_list: 'readonly',
|
||||||
|
datetime: 'readonly',
|
||||||
|
filenamify: 'readonly',
|
||||||
|
handleSIGINT: 'readonly',
|
||||||
|
stealth: 'readonly',
|
||||||
|
jsonDb: 'readonly',
|
||||||
|
delay: 'readonly',
|
||||||
|
dataDir: 'readonly',
|
||||||
|
resolve: 'readonly',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
plugins: {
|
plugins: {
|
||||||
'@stylistic/js': stylistic,
|
'@stylistic/js': stylistic,
|
||||||
|
|
@ -73,4 +92,36 @@ export default [
|
||||||
'@stylistic/js/wrap-regex': 'error',
|
'@stylistic/js/wrap-regex': 'error',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// JavaScript files configuration
|
||||||
|
{
|
||||||
|
files: ['*.js'],
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.node,
|
||||||
|
screenshot: 'readonly',
|
||||||
|
cfg: 'readonly',
|
||||||
|
URL_CLAIM: 'readonly',
|
||||||
|
COOKIES_PATH: 'readonly',
|
||||||
|
BEARER_TOKEN_NAME: 'readonly',
|
||||||
|
notify: 'readonly',
|
||||||
|
authenticator: 'readonly',
|
||||||
|
prompt: 'readonly',
|
||||||
|
html_game_list: 'readonly',
|
||||||
|
datetime: 'readonly',
|
||||||
|
filenamify: 'readonly',
|
||||||
|
handleSIGINT: 'readonly',
|
||||||
|
stealth: 'readonly',
|
||||||
|
jsonDb: 'readonly',
|
||||||
|
delay: 'readonly',
|
||||||
|
dataDir: 'readonly',
|
||||||
|
resolve: 'readonly',
|
||||||
|
window: 'readonly',
|
||||||
|
navigator: 'readonly',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'no-unused-vars': 'off',
|
||||||
|
'prefer-const': 'off',
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue