Skip to content
Open

Ofero #206

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-docker-image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: multiversx/mx-explorer-dapp
images: gioviboy/mx-explorer-dapp

- name: Build and push Docker image
id: push
Expand Down
28 changes: 27 additions & 1 deletion entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,36 @@ if [ -n "$START_API_ADDRESS_STOP" ]; then
fi

if [ -n "$START_IS_SOVEREIGN_STOP" ]; then
# normalizează la true/false
case "$(printf '%s' "$START_IS_SOVEREIGN_STOP" | tr '[:upper:]' '[:lower:]')" in
1|true|yes|y|on) START_IS_SOVEREIGN_STOP=true ;;
0|false|no|n|off|"") START_IS_SOVEREIGN_STOP=false ;;
*) START_IS_SOVEREIGN_STOP=true ;;
esac

echo "IS Sovereign defined: ${START_IS_SOVEREIGN_STOP}, replacing in config"
find /usr/share/nginx/html/ -type f -exec sed -i 's|START_IS_SOVEREIGN_STOP|'${START_IS_SOVEREIGN_STOP}'|g' {} +
find /usr/share/nginx/html/ -type f -exec sed -i \
-e "s|'START_IS_SOVEREIGN_STOP'|${START_IS_SOVEREIGN_STOP}|g" \
-e "s|\"START_IS_SOVEREIGN_STOP\"|${START_IS_SOVEREIGN_STOP}|g" \
-e "s|START_IS_SOVEREIGN_STOP|${START_IS_SOVEREIGN_STOP}|g" {} +
fi

if [ -n "$START_IS_ACCESSTOKEN_STOP" ]; then
# normalizează la true/false
case "$(printf '%s' "$START_IS_ACCESSTOKEN_STOP" | tr '[:upper:]' '[:lower:]')" in
1|true|yes|y|on) START_IS_ACCESSTOKEN_STOP=true ;;
0|false|no|n|off|"") START_IS_ACCESSTOKEN_STOP=false ;;
*) START_IS_ACCESSTOKEN_STOP=true ;;
esac

echo "IS Sovereign defined: ${START_IS_ACCESSTOKEN_STOP}, replacing in config"
find /usr/share/nginx/html/ -type f -exec sed -i \
-e "s|'START_IS_ACCESSTOKEN_STOP'|${START_IS_ACCESSTOKEN_STOP}|g" \
-e "s|\"START_IS_ACCESSTOKEN_STOP\"|${START_IS_ACCESSTOKEN_STOP}|g" \
-e "s|START_IS_ACCESSTOKEN_STOP|${START_IS_ACCESSTOKEN_STOP}|g" {} +
fi


# FIX NGINX
sed -i '/location \/ {/,/}/d' /etc/nginx/conf.d/default.conf
sed -i '/#access_log/a\
Expand Down
37 changes: 25 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,29 @@
"yup": "0.32.11"
},
"scripts": {
"start": "cross-env VITE_APP_CACHE_BUST=$(git rev-parse --short HEAD || echo 'local') vite",
"start-devnet": "yarn run copy-devnet-config & cross-env VITE_APP_SHARE_PREFIX=devnet- yarn run start",
"start-mainnet": "yarn run copy-mainnet-config & yarn run start",
"start-testnet": "yarn run copy-testnet-config & cross-env VITE_APP_SHARE_PREFIX=testnet- yarn run start",
"build-devnet": "yarn run copy-devnet-config & cross-env VITE_APP_SHARE_PREFIX=devnet- VITE_APP_GA_ID=G-QE38EW59B8 yarn run build",
"build-mainnet": "yarn run copy-mainnet-config & cross-env VITE_APP_SHARE_PREFIX= VITE_APP_GA_ID=G-EFN7QYSMQS yarn run build",
"build-testnet": "yarn run copy-testnet-config & cross-env VITE_APP_SHARE_PREFIX=testnet- VITE_APP_GA_ID=G-EFN7QYSMQS yarn run build",
"build-staging": "yarn run copy-mainnet-config & cross-env VITE_APP_SHARE_PREFIX=staging- VITE_APP_GA_ID=G-EFN7QYSMQS VITE_APP_IS_STAGING=true yarn run build",
"build-internal": "yarn run copy-multiple-config & cross-env VITE_APP_SHARE_PREFIX=internal- VITE_APP_GA_ID=G-EFN7QYSMQS yarn run build",
"build-next": "yarn run copy-multiple-config & cross-env VITE_APP_SHARE_PREFIX=next- VITE_APP_GA_ID=G-EFN7QYSMQS yarn run build",
"build": "cross-env VITE_APP_CACHE_BUST=$(git rev-parse --short HEAD || echo 'local') vite build && yarn version:make",
"start-local": "yarn run config:from-env && node scripts/start.js",
"build-local": "yarn run config:from-env && node scripts/build.js",
"config:from-env": "node scripts/config-from-env.js",
"start": "node scripts/start.js",
"prestart-mainnet": "yarn run copy-mainnet-config",
"start-mainnet": "node scripts/start.js --share-prefix=",
"prestart-devnet": "yarn run copy-devnet-config",
"start-devnet": "node scripts/start.js --share-prefix=devnet-",
"prestart-testnet": "yarn run copy-testnet-config",
"start-testnet": "node scripts/start.js --share-prefix=testnet-",
"build": "node scripts/build.js",
"prebuild-mainnet": "yarn run copy-mainnet-config",
"build-mainnet": "node scripts/build.js --share-prefix= --ga=G-EFN7QYSMQS",
"prebuild-devnet": "yarn run copy-devnet-config",
"build-devnet": "node scripts/build.js --share-prefix=devnet- --ga=G-QE38EW59B8",
"prebuild-testnet": "yarn run copy-testnet-config",
"build-testnet": "node scripts/build.js --share-prefix=testnet- --ga=G-EFN7QYSMQS",
"prebuild-staging": "yarn run copy-mainnet-config",
"build-staging": "node scripts/build.js --share-prefix=staging- --ga=G-EFN7QYSMQS --staging=true",
"prebuild-internal": "yarn run copy-multiple-config",
"build-internal": "node scripts/build.js --share-prefix=internal- --ga=G-EFN7QYSMQS",
"prebuild-next": "yarn run copy-multiple-config",
"build-next": "node scripts/build.js --share-prefix=next- --ga=G-EFN7QYSMQS",
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"copy-placeholder-config": "run-script-os",
Expand All @@ -86,7 +98,7 @@
"copy-testnet-config:windows": "copy .\\src\\config\\config.testnet.ts .\\src\\config\\index.ts",
"copy-multiple-config:windows": "copy .\\src\\config\\config.multiple.ts .\\src\\config\\index.ts",
"copy-base-interceptor:windows": "copy .\\src\\interceptors\\Interceptor.tsx .\\src\\interceptors\\index.tsx",
"version:make": "git rev-parse --short HEAD | sed 's/^/\"/;s/$/\"/' > build/version.json",
"version:make": "node scripts/version-make.js",
"prepare": "yarn run prepare-free-icons && yarn run copy-base-interceptor",
"prepare-free-icons": "run-script-os",
"prepare-free-icons:nix": "cp ./src/icons/duotone/fontawesomeFree.ts ./src/icons/duotone/index.ts && cp ./src/icons/light/fontawesomeFree.ts ./src/icons/light/index.ts && cp ./src/icons/regular/fontawesomeFree.ts ./src/icons/regular/index.ts && cp ./src/icons/solid/fontawesomeFree.ts ./src/icons/solid/index.ts",
Expand All @@ -113,6 +125,7 @@
"cross-env": "7.0.3",
"cypress": "13.6.3",
"cypress-mochawesome-reporter": "3.7.0",
"dotenv": "^17.2.1",
"eslint": "8.57.0",
"eslint-config-prettier": "8.8.0",
"eslint-plugin-import": "2.28.1",
Expand Down
54 changes: 54 additions & 0 deletions scripts/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// scripts/build.js
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');

// 1) SHA pentru cache-bust
let sha = 'local';
try {
sha = execSync('git rev-parse --short HEAD', { stdio: ['ignore', 'pipe', 'ignore'] })
.toString()
.trim();
} catch { /* fără git -> 'local' */ }

// 2) Parsează argumente CLI ca să nu mai depindem de cross-env
// ex: node scripts/build.js --share-prefix=devnet- --ga=G-XXXX --staging=true
const argv = process.argv.slice(2);
for (const a of argv) {
if (a.startsWith('--share-prefix=')) {
process.env.VITE_APP_SHARE_PREFIX = a.split('=')[1];
} else if (a.startsWith('--ga=')) {
process.env.VITE_APP_GA_ID = a.split('=')[1];
} else if (a.startsWith('--staging=')) {
process.env.VITE_APP_IS_STAGING = a.split('=')[1];
}
}

// 3) Setează cache-bust
process.env.VITE_APP_CACHE_BUST = sha;

// 4) Rulează Vite cu API-ul oficial (nu prin npx)
(async () => {
try {
const { build } = require('vite');
await build(); // Vite va afișa logurile: "vite vX building for production..."
} catch (err) {
// fallback (dacă nu există vite în deps)
try {
const { spawnSync } = require('child_process');
const nodeCmd = process.platform === 'win32' ? 'node.exe' : 'node';
const res = spawnSync(nodeCmd, [path.join('node_modules', 'vite', 'bin', 'vite.js'), 'build'], {
stdio: 'inherit',
env: process.env,
});
if (res.status !== 0) process.exit(res.status ?? 1);
} catch (e2) {
console.error('Build failed:', err);
process.exit(1);
}
}

// 5) Scrie build/version.json cu SHA
fs.mkdirSync(path.join('build'), { recursive: true });
fs.writeFileSync(path.join('build', 'version.json'), JSON.stringify(sha));
})();
67 changes: 67 additions & 0 deletions scripts/config-from-env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// scripts/config-from-env.js
const fs = require('fs');
const path = require('path');
const dotenv = require('dotenv');

dotenv.config({ path: path.resolve(process.cwd(), '.env.local') });

const placeholderPath = path.resolve('src', 'config', 'config.placeholder.ts');
const targetPath = path.resolve('src', 'config', 'index.ts');

if (!fs.existsSync(placeholderPath)) {
console.error(`Nu găsesc ${placeholderPath}. Verifică calea.`);
process.exit(1);
}

let content = fs.readFileSync(placeholderPath, 'utf8');

// Token-urile suportate (completează dacă apar altele)
const ALL_KEYS = [
'START_NAME_STOP',
'START_CHAIN_ID_STOP',
'START_EGLD_LABEL_STOP',
'START_WALLET_ADDRESS_STOP',
'START_EXPLORER_ADDRESS_STOP',
'START_NFT_EXPLORER_ADDRESS_STOP',
'START_API_ADDRESS_STOP',
'START_IS_SOVEREIGN_STOP'
];

// Chei booleene care trebuie injectate ca true/false fără ghilimele
const BOOL_KEYS = [
'START_IS_SOVEREIGN_STOP'
];

const STR_KEYS = ALL_KEYS.filter(k => !BOOL_KEYS.includes(k));

function parseBool(v) {
if (v == null) return false;
const s = String(v).trim().toLowerCase();
if (['1', 'true', 'yes', 'y', 'on'].includes(s)) return true;
if (['0', 'false', 'no', 'n', 'off'].includes(s)) return false;
// fallback: orice altceva non-empty => true
return Boolean(s);
}

// 1) Booleene: înlocuiește 'TOKEN' / "TOKEN" cu true/false (fără ghilimele)
// și acoperă și cazul când TOKEN apare ne-ghilimat.
for (const k of BOOL_KEYS) {
if (!(k in process.env)) continue;
const b = parseBool(process.env[k]);
// quote-agnostic: 'TOKEN' sau "TOKEN"
const rxQuoted = new RegExp(`(['"])${k}\\1`, 'g');
content = content.replace(rxQuoted, String(b));
// fallback: TOKEN fără ghilimele
content = content.split(k).join(String(b));
}

// 2) Stringuri: înlocuire textuală; dacă placeholderul are ghilimele,
// valoarea rămâne string valid în TS.
for (const k of STR_KEYS) {
if (!(k in process.env)) continue;
const v = process.env[k] ?? '';
content = content.split(k).join(v);
}

fs.writeFileSync(targetPath, content);
console.log(`Config generat în ${path.relative(process.cwd(), targetPath)} din .env.local`);
82 changes: 82 additions & 0 deletions scripts/start.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// scripts/start.js
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
require('dotenv').config({ path: path.resolve(process.cwd(), '.env.local') });

// 1) Cache-bust cu SHA
let sha = 'local';
try {
sha = execSync('git rev-parse --short HEAD', { stdio: ['ignore', 'pipe', 'ignore'] })
.toString()
.trim();
} catch {}
process.env.VITE_APP_CACHE_BUST = process.env.VITE_APP_CACHE_BUST || sha;
process.env.NODE_ENV = process.env.NODE_ENV || 'development';

// 2) Permite override prin CLI: --share-prefix= --ga= --staging=true
for (const a of process.argv.slice(2)) {
if (a.startsWith('--share-prefix=')) process.env.VITE_APP_SHARE_PREFIX = a.split('=')[1];
else if (a.startsWith('--ga=')) process.env.VITE_APP_GA_ID = a.split('=')[1];
else if (a.startsWith('--staging=')) process.env.VITE_APP_IS_STAGING = a.split('=')[1];
}

// 3) Construiește map-ul pentru token-urile START_* (din .env.local)
const startTokens = Object.fromEntries(
Object.entries(process.env)
.filter(([k]) => k.startsWith('START_'))
.map(([k, v]) => [k, v ?? ''])
);

// Plugin simplu care înlocuiește token-urile în sursele TS/JS/TSX/JSX
function tokenReplacePlugin() {
const exts = /\.(ts|tsx|js|jsx)$/i;
const keys = Object.keys(startTokens);
if (!keys.length) return { name: 'token-replace', transform: code => ({ code, map: null }) };

return {
name: 'token-replace',
enforce: 'pre',
transform(code, id) {
if (!exts.test(id)) return null;
let out = code;
for (const k of keys) {
// Înlocuire textuală; dacă în cod e "START_XXX", îl schimbăm în stringul real
const val = JSON.stringify(startTokens[k]);
out = out.split(k).join(val);
}
return { code: out, map: null };
},
// Înlocuire și în index.html
transformIndexHtml(html) {
let out = html;
for (const k of keys) {
out = out.split(k).join(startTokens[k] ?? '');
}
return out;
}
};
}

(async () => {
try {
const { createServer } = require('vite');

const server = await createServer({
plugins: [tokenReplacePlugin()],
});

await server.listen();
server.printUrls();

const shutdown = async () => {
try { await server.close(); } catch {}
process.exit(0);
};
process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);
} catch (err) {
console.error('Failed to start Vite dev server:', err);
process.exit(1);
}
})();
11 changes: 11 additions & 0 deletions scripts/version-make.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// scripts/version-make.js
const { execSync } = require('child_process');
const fs = require('fs');
let sha = 'local';
try {
sha = execSync('git rev-parse --short HEAD', { stdio: ['ignore', 'pipe', 'ignore'] })
.toString()
.trim();
} catch {}
fs.mkdirSync('build', { recursive: true });
fs.writeFileSync('build/version.json', JSON.stringify(sha));
1 change: 1 addition & 0 deletions src/config/config.placeholder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const networks: NetworkType[] = [
explorerAddress: 'START_EXPLORER_ADDRESS_STOP',
nftExplorerAddress: 'START_NFT_EXPLORER_ADDRESS_STOP',
isSovereign: 'START_IS_SOVEREIGN_STOP',
accessToken: 'START_IS_ACCESSTOKEN_STOP',
apiAddress: 'START_API_ADDRESS_STOP'
},

Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3703,6 +3703,11 @@ dot-case@^3.0.4:
no-case "^3.0.4"
tslib "^2.0.3"

dotenv@^17.2.1:
version "17.2.1"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-17.2.1.tgz#6f32e10faf014883515538dc922a0fb8765d9b32"
integrity sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ==

draco3d@^1.4.1:
version "1.5.7"
resolved "https://registry.yarnpkg.com/draco3d/-/draco3d-1.5.7.tgz#94f9bce293eb8920c159dc91a4ce9124a9e899e0"
Expand Down