Skip to content

Commit 635ee09

Browse files
committed
Configures environment variables for client app
Introduces environment variable configuration for the client application. Adds an `.env.example` file to serve as a template for configuration. Moves environment variable loading and checking to a dedicated module for better organization and reusability. Modifies build and server tasks to utilize the new environment variable handling. Updates the README to include instructions on configuring the environment. Fix #43
1 parent c1fd4d0 commit 635ee09

File tree

7 files changed

+143
-24
lines changed

7 files changed

+143
-24
lines changed

packages/client/.env.example

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# =============================================
2+
# STAC Manager Environment Example File
3+
# =============================================
4+
# IMPORTANT: DO NOT MODIFY THIS FILE!
5+
# Instead, create a copy named '.env' and modify that file.
6+
# This example file serves as a template and documentation.
7+
# =============================================
8+
9+
# =================
10+
# App Configuration
11+
# =================
12+
13+
# The title of the application shown in browser tab and headers
14+
APP_TITLE=STAC Manager
15+
16+
# A brief description of the application for metadata purposes
17+
APP_DESCRIPTION=Plugin based STAC editor
18+
19+
# The base URL where the app is being served from
20+
# DO NOT set this in the .env file. Set it as an environment variable before building.
21+
# See the README for instructions.
22+
# PUBLIC_URL= Do not set here
23+
24+
# ===============
25+
# API Integration
26+
# ===============
27+
28+
# URL of the STAC Browser instance (optional)
29+
# If not set, will default to Radiant Earth's STAC Browser
30+
REACT_APP_STAC_BROWSER=
31+
32+
# URL of the STAC API endpoint (required)
33+
# This is the API the app will interact with for STAC operations
34+
REACT_APP_STAC_API=
35+
36+
# ====================
37+
# Keycloak Auth Config
38+
# ====================
39+
# If not provided, authentication will be disabled.
40+
41+
# Base URL of the Keycloak server
42+
REACT_APP_KEYCLOAK_URL=
43+
44+
# Client ID registered in Keycloak
45+
REACT_APP_KEYCLOAK_CLIENT_ID=
46+
47+
# Realm name in Keycloak
48+
REACT_APP_KEYCLOAK_REALM=
49+
50+
# =================
51+
# Theme Customization
52+
# =================
53+
54+
# Primary color for the application theme (hex color code)
55+
# Default: #6A5ACD (SlateBlue)
56+
# REACT_APP_THEME_PRIMARY_COLOR='#6A5ACD'
57+
58+
# Secondary color for the application theme (hex color code)
59+
# Default: #048A81 (Teal)
60+
# REACT_APP_THEME_SECONDARY_COLOR='#048A81'

packages/client/.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
# Environment
33
################################################
44

5-
.env.*
5+
.env*
6+
!.env.example

packages/client/README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ See root README.md for instructions on how to install and run the project.
88

99
## Client specific instructions
1010

11+
### Environment Configuration
12+
13+
The application uses environment variables for configuration. A template file `.env.example` is provided as a template.
14+
15+
To configure the application:
16+
1. Copy `.env.example` to `.env`
17+
2. Modify the `.env` file with your specific configuration values
18+
3. Never modify `.env.example` directly as it serves as documentation
19+
1120
Some client options are controlled by environment variables. These are:
1221
```
1322
# App config
@@ -66,4 +75,4 @@ icon-512.png 512x512
6675
favicon.png 32x32
6776
apple-touch-icon.png 360x360
6877
meta-image.png 1920x1080
69-
```
78+
```

packages/client/posthtml.config.js

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,5 @@
1+
/* global process, module */
12
// https://github.com/parcel-bundler/parcel/issues/1209#issuecomment-942927265
2-
const dotenv = require('dotenv');
3-
4-
const NODE_ENV = process.env.NODE_ENV;
5-
6-
const dotenvFiles = [
7-
'.env',
8-
// Don't include `.env.local` for `test` environment
9-
// since normally you expect tests to produce the same
10-
// results for everyone
11-
NODE_ENV === 'test' ? null : '.env.local',
12-
`.env.${NODE_ENV}`,
13-
`.env.${NODE_ENV}.local`
14-
].filter(Boolean);
15-
16-
const env = {};
17-
18-
for (let dotenvFile of dotenvFiles) {
19-
const config = dotenv.config({ path: dotenvFile });
20-
if (config.parsed) {
21-
Object.assign(env, config.parsed);
22-
}
23-
}
243

254
module.exports = {
265
plugins: {

packages/client/tasks/build.mjs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,17 @@ import fs from 'fs-extra';
55
import log from 'fancy-log';
66
import { Parcel } from '@parcel/core';
77

8+
import {
9+
checkRequiredEnvVars,
10+
loadEnvironmentVariables
11+
} from './check-env-vars.mjs';
12+
813
const __filename = fileURLToPath(import.meta.url);
914
const __dirname = path.dirname(__filename);
1015

16+
loadEnvironmentVariables();
17+
checkRequiredEnvVars(['REACT_APP_STAC_API', 'PUBLIC_URL']);
18+
1119
// /////////////////////////////////////////////////////////////////////////////
1220
// --------------------------- Variables -------------------------------------//
1321
// ---------------------------------------------------------------------------//
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/* global process */
2+
import log from 'fancy-log';
3+
import dotenv from 'dotenv';
4+
5+
/**
6+
* Check if required environment variables are set
7+
* @param {string[]} requiredVars - Array of required environment variable names
8+
* @throws {Error} - If any required variables are missing
9+
*/
10+
export function checkRequiredEnvVars(requiredVars) {
11+
const missingVars = requiredVars.filter((varName) => !process.env[varName]);
12+
13+
if (missingVars.length > 0) {
14+
log.error('ERROR: Missing required environment variables:');
15+
missingVars.forEach((v) => log.error(` - ${v}`));
16+
console.log(); // eslint-disable-line no-console
17+
log.info('Make sure to:');
18+
log.info('1. Copy .env.example to .env');
19+
log.info('2. Fill in all required values in .env');
20+
console.log(); // eslint-disable-line no-console
21+
process.exit(1);
22+
}
23+
}
24+
25+
/**
26+
* Loads environment variables from `.env` files based on the current
27+
* `NODE_ENV`.
28+
*
29+
* The function determines the appropriate `.env` files to load in the following
30+
* order:
31+
* 1. `.env` - Always included.
32+
* 2. `.env.local` - Included unless the `NODE_ENV` is `test`.
33+
* 3. `.env.<NODE_ENV>` - Included based on the current `NODE_ENV`.
34+
* 4. `.env.<NODE_ENV>.local` - Included based on the current `NODE_ENV`.
35+
*
36+
* Files are loaded in the order specified above, and later files override
37+
* variables from earlier ones. The `.env.local` file is skipped for the `test`
38+
* environment to ensure consistent test results across different environments.
39+
*/
40+
export function loadEnvironmentVariables() {
41+
const dotenvFiles = [
42+
'.env',
43+
// Don't include `.env.local` for `test` environment
44+
// since normally you expect tests to produce the same
45+
// results for everyone
46+
process.env.NODE_ENV === 'test' ? null : '.env.local',
47+
`.env.${process.env.NODE_ENV}`,
48+
`.env.${process.env.NODE_ENV}.local`
49+
].filter(Boolean);
50+
51+
dotenvFiles.forEach((dotenvFile) => {
52+
dotenv.config({ path: dotenvFile });
53+
});
54+
}

packages/client/tasks/server.mjs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,18 @@ import portscanner from 'portscanner';
77
import log from 'fancy-log';
88
import { Parcel } from '@parcel/core';
99

10+
import {
11+
checkRequiredEnvVars,
12+
loadEnvironmentVariables
13+
} from './check-env-vars.mjs';
14+
1015
const __filename = fileURLToPath(import.meta.url);
1116
const __dirname = path.dirname(__filename);
1217
const __appRoot = path.join(__dirname, '..');
1318

19+
loadEnvironmentVariables();
20+
checkRequiredEnvVars(['REACT_APP_STAC_API']);
21+
1422
// /////////////////////////////////////////////////////////////////////////////
1523
// --------------------------- Variables -------------------------------------//
1624
// ---------------------------------------------------------------------------//

0 commit comments

Comments
 (0)