Skip to content

Commit

Permalink
Merge branch 'main' of github.com:blockscout/frontend into tom2drum/i…
Browse files Browse the repository at this point in the history
…ssue-1250
  • Loading branch information
tom2drum committed Oct 18, 2023
2 parents 426e0b4 + 4b42b71 commit 16da427
Show file tree
Hide file tree
Showing 43 changed files with 415 additions and 151 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ NEXT_PUBLIC_RE_CAPTCHA_APP_SITE_KEY=xxx
NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID=UA-XXXXXX-X
NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN=xxx
NEXT_PUBLIC_AUTH0_CLIENT_ID=xxx
NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY=xxx
FAVICON_GENERATOR_API_KEY=xxx
3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ node_modules_linux
playwright/envs.js
deploy/tools/envs-validator/index.js
deploy/tools/feature-reporter/build/**
deploy/tools/feature-reporter/index.js
deploy/tools/feature-reporter/index.js
public/**
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ module.exports = {
},
},
{
files: [ 'configs/**/*.js', 'configs/**/*.ts', '*.config.ts', 'playwright/**/*.ts', 'deploy/tools/**' ],
files: [ '*.config.ts', 'playwright/**', 'deploy/tools/**', 'middleware.ts', 'nextjs/**' ],
rules: {
// for configs allow to consume env variables from process.env directly
'no-restricted-properties': [ 0 ],
Expand Down
10 changes: 4 additions & 6 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ on:
- 'docs/**'
- 'public/**'
- 'stub/**'
- 'tools/**'

# concurrency:
# group: ${{ github.workflow }}__${{ github.job }}__${{ github.ref }}
Expand Down Expand Up @@ -51,7 +52,7 @@ jobs:
run: yarn lint:tsc

envs_validation:
name: ENV variables presets validation
name: ENV variables validation
runs-on: ubuntu-latest
needs: [ code_quality ]
steps:
Expand Down Expand Up @@ -79,13 +80,10 @@ jobs:
- name: Install script dependencies
run: cd ./deploy/tools/envs-validator && yarn --frozen-lockfile --ignore-optional

- name: Copy secrets file
run: cp ./.env.example ./configs/envs/.env.secrets

- name: Run validation script
- name: Run validation tests
run: |
set +e
cd ./deploy/tools/envs-validator && yarn dev
cd ./deploy/tools/envs-validator && yarn test
exitcode="$?"
echo "exitcode=$exitcode" >> $GITHUB_OUTPUT
exit "$exitcode"
Expand Down
2 changes: 2 additions & 0 deletions configs/app/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ const socketEndpoint = [

const api = Object.freeze({
host: apiHost,
protocol: apiSchema,
port: apiPort,
endpoint: apiEndpoint,
socket: socketEndpoint,
basePath: stripTrailingSlash(getEnvValue('NEXT_PUBLIC_API_BASE_PATH') || ''),
Expand Down
2 changes: 1 addition & 1 deletion configs/app/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const baseUrl = [
appHost,
appPort && ':' + appPort,
].filter(Boolean).join('');
const isDev = process.env.NODE_ENV === 'development';
const isDev = getEnvValue('NODE_ENV') === 'development';

const app = Object.freeze({
isDev,
Expand Down
16 changes: 0 additions & 16 deletions configs/app/features/sentry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,10 @@ const instance = (() => {
})();
const environment = getEnvValue('NEXT_PUBLIC_APP_ENV') || 'production';
const release = getEnvValue('NEXT_PUBLIC_GIT_TAG');
const cspReportUrl = (() => {
try {
const url = new URL(getEnvValue('SENTRY_CSP_REPORT_URI') || '');

// https://docs.sentry.io/product/security-policy-reporting/#additional-configuration
url.searchParams.set('sentry_environment', environment);
release && url.searchParams.set('sentry_release', release);

return url.toString();
} catch (error) {
return;
}
})();

const title = 'Sentry error monitoring';

const config: Feature<{
dsn: string;
cspReportUrl: string | undefined;
instance: string;
release: string | undefined;
environment: string;
Expand All @@ -42,7 +27,6 @@ const config: Feature<{
title,
isEnabled: true,
dsn,
cspReportUrl,
instance,
release,
environment,
Expand Down
18 changes: 17 additions & 1 deletion configs/app/ui.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
import type { NavItemExternal } from 'types/client/navigation-items';
import { NAVIGATION_LINK_IDS, type NavItemExternal, type NavigationLinkId } from 'types/client/navigation-items';
import type { ChainIndicatorId } from 'types/homepage';
import type { NetworkExplorer } from 'types/networks';

import * as views from './ui/views';
import { getEnvValue, getExternalAssetFilePath, parseEnvJson } from './utils';

const hiddenLinks = (() => {
const parsedValue = parseEnvJson<Array<NavigationLinkId>>(getEnvValue('NEXT_PUBLIC_NAVIGATION_HIDDEN_LINKS')) || [];

if (!Array.isArray(parsedValue)) {
return undefined;
}

const result = NAVIGATION_LINK_IDS.reduce((result, item) => {
result[item] = parsedValue.includes(item);
return result;
}, {} as Record<NavigationLinkId, boolean>);

return result;
})();

// eslint-disable-next-line max-len
const HOMEPAGE_PLATE_BACKGROUND_DEFAULT = 'radial-gradient(103.03% 103.03% at 0% 0%, rgba(183, 148, 244, 0.8) 0%, rgba(0, 163, 196, 0.8) 100%), var(--chakra-colors-blue-400)';

Expand All @@ -18,6 +33,7 @@ const UI = Object.freeze({
'default': getExternalAssetFilePath('NEXT_PUBLIC_NETWORK_ICON'),
dark: getExternalAssetFilePath('NEXT_PUBLIC_NETWORK_ICON_DARK'),
},
hiddenLinks,
otherLinks: parseEnvJson<Array<NavItemExternal>>(getEnvValue('NEXT_PUBLIC_OTHER_LINKS')) || [],
featuredNetworks: getExternalAssetFilePath('NEXT_PUBLIC_FEATURED_NETWORKS'),
},
Expand Down
13 changes: 9 additions & 4 deletions configs/app/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as regexp from 'lib/regexp';
export const replaceQuotes = (value: string | undefined) => value?.replaceAll('\'', '"');

export const getEnvValue = (envName: string) => {
// eslint-disable-next-line no-restricted-properties
const envs = isBrowser() ? window.__envs : process.env;

if (isBrowser() && envs.NEXT_PUBLIC_APP_INSTANCE === 'pw') {
Expand Down Expand Up @@ -36,8 +37,12 @@ export const getExternalAssetFilePath = (envName: string) => {
};

export const buildExternalAssetFilePath = (name: string, value: string) => {
const fileName = name.replace(/^NEXT_PUBLIC_/, '').replace(/_URL$/, '').toLowerCase();
const fileExtension = value.match(regexp.FILE_EXTENSION)?.[1];

return `/assets/${ fileName }.${ fileExtension }`;
try {
const fileName = name.replace(/^NEXT_PUBLIC_/, '').replace(/_URL$/, '').toLowerCase();
const url = new URL(value);
const fileExtension = url.pathname.match(regexp.FILE_EXTENSION)?.[1];
return `/assets/${ fileName }.${ fileExtension }`;
} catch (error) {
return;
}
};
10 changes: 8 additions & 2 deletions deploy/scripts/download_assets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,14 @@ get_target_filename() {
local name_suffix="${name_prefix%_URL}"
local name_lc="$(echo "$name_suffix" | tr '[:upper:]' '[:lower:]')"

# Extract the extension from the URL
local extension="${url##*.}"
# Remove query parameters from the URL and get the filename
local filename=$(basename "${url%%\?*}")

# Extract the extension from the filename
local extension="${filename##*.}"

# Convert the extension to lowercase
extension=$(echo "$extension" | tr '[:upper:]' '[:lower:]')

# Construct the custom file name
echo "$name_lc.$extension"
Expand Down
2 changes: 1 addition & 1 deletion deploy/scripts/favicon_generator.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

master_url="${NEXT_PUBLIC_FAVICON_MASTER_URL:-$NEXT_PUBLIC_NETWORK_ICON}"
master_url="${FAVICON_MASTER_URL:-$NEXT_PUBLIC_NETWORK_ICON}"
export MASTER_URL="$master_url"

cd ./deploy/tools/favicon-generator
Expand Down
1 change: 1 addition & 0 deletions deploy/tools/envs-validator/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
/public
.env
.env.registry
.env.secrets
index.js
51 changes: 0 additions & 51 deletions deploy/tools/envs-validator/dev.sh

This file was deleted.

43 changes: 20 additions & 23 deletions deploy/tools/envs-validator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ import fs from 'fs';
import path from 'path';
import type { ValidationError } from 'yup';

import { buildExternalAssetFilePath } from '../../../configs/app/utils';
import schema from './schema';

const silent = process.argv.includes('--silent');

run();

async function run() {
console.log();
!silent && console.log();
try {
const appEnvs = Object.entries(process.env)
.filter(([ key ]) => key.startsWith('NEXT_PUBLIC_'))
Expand All @@ -26,25 +29,22 @@ async function run() {
}

async function validateEnvs(appEnvs: Record<string, string>) {
console.log(`🌀 Validating ENV variables values...`);
!silent && console.log(`🌀 Validating ENV variables values...`);

try {
// replace ENVs with external JSON files content
appEnvs.NEXT_PUBLIC_FEATURED_NETWORKS = await getExternalJsonContent(
'./public/assets/featured_networks.json',
appEnvs.NEXT_PUBLIC_FEATURED_NETWORKS,
) || '[]';
appEnvs.NEXT_PUBLIC_MARKETPLACE_CONFIG_URL = await getExternalJsonContent(
'./public/assets/marketplace_config.json',
appEnvs.NEXT_PUBLIC_MARKETPLACE_CONFIG_URL,
) || '[]';
appEnvs.NEXT_PUBLIC_FOOTER_LINKS = await getExternalJsonContent(
'./public/assets/footer_links.json',
appEnvs.NEXT_PUBLIC_FOOTER_LINKS,
) || '[]';
const envsWithJsonConfig = [
'NEXT_PUBLIC_FEATURED_NETWORKS',
'NEXT_PUBLIC_MARKETPLACE_CONFIG_URL',
'NEXT_PUBLIC_FOOTER_LINKS',
];

for await (const envName of envsWithJsonConfig) {
appEnvs[envName] = await(appEnvs[envName] ? getExternalJsonContent(envName) : Promise.resolve()) || '[]';
}

await schema.validate(appEnvs, { stripUnknown: false, abortEarly: false });
console.log('👍 All good!');
!silent && console.log('👍 All good!');
} catch (_error) {
if (typeof _error === 'object' && _error !== null && 'errors' in _error) {
console.log('🚨 ENVs validation failed with the following errors:');
Expand All @@ -59,15 +59,12 @@ async function validateEnvs(appEnvs: Record<string, string>) {
throw _error;
}

console.log();
!silent && console.log();
}

async function getExternalJsonContent(fileName: string, envValue: string): Promise<string | void> {
async function getExternalJsonContent(envName: string): Promise<string | void> {
return new Promise((resolve, reject) => {
if (!envValue) {
resolve();
return;
}
const fileName = `./public${ buildExternalAssetFilePath(envName, '.json') }`;

fs.readFile(path.resolve(__dirname, fileName), 'utf8', (err, data) => {
if (err) {
Expand All @@ -83,7 +80,7 @@ async function getExternalJsonContent(fileName: string, envValue: string): Promi

async function checkPlaceholdersCongruity(envsMap: Record<string, string>) {
try {
console.log(`🌀 Checking environment variables and their placeholders congruity...`);
!silent && console.log(`🌀 Checking environment variables and their placeholders congruity...`);

const runTimeEnvs = await getEnvsPlaceholders(path.resolve(__dirname, '.env.registry'));
const buildTimeEnvs = await getEnvsPlaceholders(path.resolve(__dirname, '.env'));
Expand All @@ -108,7 +105,7 @@ async function checkPlaceholdersCongruity(envsMap: Record<string, string>) {
throw new Error();
}

console.log('👍 All good!\n');
!silent && console.log('👍 All good!\n');
} catch (error) {
console.log('🚨 Congruity check failed.\n');
throw error;
Expand Down
2 changes: 1 addition & 1 deletion deploy/tools/envs-validator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"build": "yarn webpack-cli -c ./webpack.config.js",
"validate": "node ./index.js",
"dev": "./dev.sh"
"test": "./test.sh"
},
"dependencies": {
"ts-loader": "^9.4.4",
Expand Down
9 changes: 7 additions & 2 deletions deploy/tools/envs-validator/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import type { AdButlerConfig } from '../../../types/client/adButlerConfig';
import { SUPPORTED_AD_TEXT_PROVIDERS, SUPPORTED_AD_BANNER_PROVIDERS } from '../../../types/client/adProviders';
import type { AdTextProviders, AdBannerProviders } from '../../../types/client/adProviders';
import type { MarketplaceAppOverview } from '../../../types/client/marketplace';
import type { NavItemExternal } from '../../../types/client/navigation-items';
import { NAVIGATION_LINK_IDS } from '../../../types/client/navigation-items';
import type { NavItemExternal, NavigationLinkId } from '../../../types/client/navigation-items';
import type { BridgedTokenChain, TokenBridge } from '../../../types/client/token';
import type { WalletType } from '../../../types/client/wallets';
import { SUPPORTED_WALLETS } from '../../../types/client/wallets';
Expand Down Expand Up @@ -354,6 +355,11 @@ const schema = yup
.transform(replaceQuotes)
.json()
.of(navItemExternalSchema),
NEXT_PUBLIC_NAVIGATION_HIDDEN_LINKS: yup
.array()
.transform(replaceQuotes)
.json()
.of(yup.string<NavigationLinkId>().oneOf(NAVIGATION_LINK_IDS)),
NEXT_PUBLIC_NETWORK_LOGO: yup.string().test(urlTest),
NEXT_PUBLIC_NETWORK_LOGO_DARK: yup.string().test(urlTest),
NEXT_PUBLIC_NETWORK_ICON: yup.string().test(urlTest),
Expand Down Expand Up @@ -432,7 +438,6 @@ const schema = yup
NEXT_PUBLIC_RE_CAPTCHA_APP_SITE_KEY: yup.string(),
NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: yup.string(),
NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN: yup.string(),
NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY: yup.string(),

// Misc
NEXT_PUBLIC_USE_NEXT_JS_PROXY: yup.boolean(),
Expand Down
Loading

0 comments on commit 16da427

Please sign in to comment.