mirror of
https://github.com/hanzonet/explore.git
synced 2026-10-30 18:16:57 +00:00
* operation lifecycle accordion * operation entity * adapt layout to mobile device * basic operations view * pass response data to operation details * update types package * tac operation status and links to tx on ton * feature config, docs and operation badge * add info to tx page * add operations to search * search input on operations page * tests * update tooltips and temporary fix of ts * add InterFallback typeface with → glyph * design and api updates * support new API version * add time format toggle * add shield to entity icon * minor fixes * update screenshots * clean up * fix screenshot
156 lines
4.7 KiB
TypeScript
Executable File
156 lines
4.7 KiB
TypeScript
Executable File
import fs from 'fs';
|
|
import path from 'path';
|
|
|
|
/* eslint-disable no-console */
|
|
const PRESETS = {
|
|
arbitrum: 'https://arbitrum.blockscout.com',
|
|
arbitrum_sepolia: 'https://arbitrum-sepolia.blockscout.com',
|
|
base: 'https://base.blockscout.com',
|
|
blackfort_testnet: 'https://blackfort-testnet.blockscout.com',
|
|
celo_alfajores: 'https://celo-alfajores.blockscout.com',
|
|
eth: 'https://eth.blockscout.com',
|
|
eth_goerli: 'https://eth-goerli.blockscout.com',
|
|
eth_sepolia: 'https://eth-sepolia.blockscout.com',
|
|
filecoin: 'https://filecoin.blockscout.com',
|
|
garnet: 'https://explorer.garnetchain.com',
|
|
gnosis: 'https://gnosis.blockscout.com',
|
|
immutable: 'https://explorer.immutable.com',
|
|
mekong: 'https://mekong.blockscout.com',
|
|
neon_devnet: 'https://neon-devnet.blockscout.com',
|
|
optimism: 'https://optimism.blockscout.com',
|
|
optimism_interop_0: 'https://optimism-interop-alpha-0.blockscout.com',
|
|
optimism_sepolia: 'https://optimism-sepolia.blockscout.com',
|
|
polygon: 'https://polygon.blockscout.com',
|
|
rari_testnet: 'https://rari-testnet.cloud.blockscout.com',
|
|
rootstock_testnet: 'https://rootstock-testnet.blockscout.com',
|
|
scroll_sepolia: 'https://scroll-sepolia.blockscout.com',
|
|
shibarium: 'https://www.shibariumscan.io',
|
|
stability_testnet: 'https://stability-testnet.blockscout.com',
|
|
tac_turin: 'https://tac-turin.blockscout.com',
|
|
zkevm: 'https://zkevm.blockscout.com',
|
|
zksync: 'https://zksync.blockscout.com',
|
|
zilliqa_prototestnet: 'https://zilliqa-prototestnet.blockscout.com',
|
|
zora: 'https://explorer.zora.energy',
|
|
// main === staging
|
|
main: 'https://eth-sepolia.k8s-dev.blockscout.com',
|
|
};
|
|
|
|
const LOCAL_ENVS = {
|
|
NEXT_PUBLIC_APP_PROTOCOL: 'http',
|
|
NEXT_PUBLIC_APP_HOST: 'localhost',
|
|
NEXT_PUBLIC_APP_PORT: '3000',
|
|
NEXT_PUBLIC_APP_ENV: 'development',
|
|
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL: 'ws',
|
|
};
|
|
|
|
const IGNORED_ENVS = [
|
|
'NEXT_PUBLIC_GIT_COMMIT_SHA',
|
|
'NEXT_PUBLIC_GIT_TAG',
|
|
'NEXT_PUBLIC_ICON_SPRITE_HASH',
|
|
];
|
|
|
|
function parseScriptArgs() {
|
|
const args = process.argv.slice(2);
|
|
|
|
const result: Record<string, string> = {};
|
|
args.forEach(arg => {
|
|
const [ key, value ] = arg.split('=');
|
|
if (key && value) {
|
|
result[key.replace(/^--/, '') as keyof typeof result] = value;
|
|
}
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
function getSecretEnvsList() {
|
|
const fileContent = fs.readFileSync(path.resolve(__dirname, '../../.env.example'), 'utf8');
|
|
const result = fileContent.split('\n').map((line) => line.split('=')[0]);
|
|
return result;
|
|
}
|
|
|
|
function updateFileContent(envsEntries: Array<[ string, string ]>, presetId: keyof typeof PRESETS) {
|
|
const presetEnvsContent = envsEntries
|
|
.map(([ key, value ]) => `${ key }=${ value }`)
|
|
.join('\n');
|
|
|
|
const chainName = envsEntries.find(([ key ]) => key === 'NEXT_PUBLIC_NETWORK_NAME')?.[1] ?? 'Unknown';
|
|
|
|
const explorerUrl = PRESETS[presetId];
|
|
|
|
const localEnvsContent = Object.entries(LOCAL_ENVS)
|
|
.map(([ key, value ]) => `${ key }=${ value }`)
|
|
.join('\n');
|
|
|
|
const content =
|
|
`# Set of ENVs for ${ chainName } network explorer\n` +
|
|
'# ' + explorerUrl + '\n' +
|
|
`# This is an auto-generated file. To update all values, run "yarn dev:preset:sync --name=${ presetId }"\n` +
|
|
'\n' +
|
|
'# Local ENVs\n' +
|
|
localEnvsContent + '\n' +
|
|
'\n' +
|
|
'# Instance ENVs\n' +
|
|
presetEnvsContent;
|
|
|
|
fs.writeFileSync(path.resolve(__dirname, `../../configs/envs/.env.${ presetId }`), content);
|
|
}
|
|
|
|
async function updatePresetFile(presetId: keyof typeof PRESETS) {
|
|
const secretEnvs = getSecretEnvsList();
|
|
|
|
const instanceUrl = PRESETS[presetId];
|
|
const response = await fetch(`${ instanceUrl }/node-api/config`);
|
|
const instanceConfig = await response.json() as Record<'envs', Record<string, string>>;
|
|
|
|
const ignoredEnvs = [
|
|
...Object.keys(LOCAL_ENVS),
|
|
...IGNORED_ENVS,
|
|
...secretEnvs,
|
|
];
|
|
|
|
const presetEnvsEntries = Object.entries(instanceConfig.envs)
|
|
.filter(([ key ]) => !ignoredEnvs.includes(key));
|
|
|
|
updateFileContent(presetEnvsEntries, presetId);
|
|
}
|
|
|
|
async function run() {
|
|
const args = parseScriptArgs();
|
|
if (!args.name) {
|
|
console.log('🚨 No "--name" argument is provided. Exiting...');
|
|
return;
|
|
}
|
|
|
|
const name = args.name;
|
|
|
|
if (name === 'all') {
|
|
console.log(`🌀 Syncing all presets configuration files...`);
|
|
|
|
for (const presetId in PRESETS) {
|
|
await updatePresetFile(presetId as keyof typeof PRESETS);
|
|
console.log(` - [v] "${ presetId }" is ready`);
|
|
}
|
|
|
|
console.log(`✅ Done!`);
|
|
|
|
return;
|
|
}
|
|
|
|
const presetId = name as keyof typeof PRESETS;
|
|
|
|
const instanceUrl = PRESETS[presetId];
|
|
if (!instanceUrl) {
|
|
console.log(`🚨 No preset with name "${ presetId }" found. Exiting...`);
|
|
return;
|
|
}
|
|
|
|
console.log(`🌀 Syncing preset configuration file...`);
|
|
|
|
await updatePresetFile(presetId);
|
|
|
|
console.log(`✅ Done!`);
|
|
}
|
|
|
|
run();
|