Skip to content

Commit

Permalink
refactor: Use env file instead of process.env everywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
ptbrowne committed Jul 29, 2024
1 parent c3ab760 commit fc39b8c
Show file tree
Hide file tree
Showing 17 changed files with 144 additions and 53 deletions.
5 changes: 4 additions & 1 deletion .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ I18N_DOMAINS={"de": "www.elcom.local", "fr": "fr.elcom.local", "it": "it.elcom.l
BASIC_AUTH_CREDENTIALS=
EIAM_CERTIFICATE_PASSWORD=
# EIAM_CERTIFICATE_PATH=
EIAM_CERTIFICATE_CONTENT=
EIAM_CERTIFICATE_CONTENT=
FIRST_PERIOD=2009
CURRENT_PERIOD=2025
DEPLOYMENT=dev
15 changes: 4 additions & 11 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,13 @@ const withMDX = require("@next/mdx")();
const pkg = require("./package.json");
const { locales, defaultLocale } = require("./src/locales/locales.json");

const {
I18N_DOMAINS,
WEBPACK_ASSET_PREFIX,
CURRENT_PERIOD = "2025",
FIRST_PERIOD = "2009",
DEPLOYMENT,
MATOMO_ID,
} = process.env;
const { I18N_DOMAINS, WEBPACK_ASSET_PREFIX, MATOMO_ID } = process.env;

const buildEnv = {
VERSION: `v${pkg.version}`,
DEPLOYMENT: DEPLOYMENT,
CURRENT_PERIOD: CURRENT_PERIOD,
FIRST_PERIOD: FIRST_PERIOD,
DEPLOYMENT: process.env.DEPLOYMENT,
CURRENT_PERIOD: process.env.CURRENT_PERIOD,
FIRST_PERIOD: process.env.CURRENT_PERIOD,
};

console.log("Build Environment:", buildEnv);
Expand Down
6 changes: 4 additions & 2 deletions src/components/header.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Trans } from "@lingui/macro";
import { Box, Flex, Text } from "theme-ui";

import { buildEnv } from "src/domain/env";

import { LanguageMenu } from "./language-menu";
import { HomeLink } from "./links";
import { LogoDesktop, LogoMobile } from "./logo";
Expand Down Expand Up @@ -95,8 +97,8 @@ export const Logo = () => {
sx={{ pl: [0, 6], textDecoration: "none", color: "monochrome800" }}
>
<Trans id="site.title">Strompreise Schweiz</Trans>
{process.env.DEPLOYMENT &&
` [${process.env.DEPLOYMENT.toLocaleUpperCase()}]`}
{buildEnv.DEPLOYMENT &&
` [${buildEnv.DEPLOYMENT.toLocaleUpperCase()}]`}
</Text>
</Flex>
</HomeLink>
Expand Down
7 changes: 4 additions & 3 deletions src/domain/data.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { scaleThreshold, range } from "d3";
import { useMemo } from "react";

import { buildEnv } from "src/domain/env";
import { Observation as QueryObservation } from "src/graphql/queries";

import { useTheme } from "../themes";
Expand Down Expand Up @@ -67,15 +68,15 @@ export const useColorScale = ({

export type Entity = "municipality" | "operator" | "canton";

if (!process.env.FIRST_PERIOD || !process.env.CURRENT_PERIOD) {
if (!buildEnv.FIRST_PERIOD || !buildEnv.CURRENT_PERIOD) {
throw Error(
`Please configure FIRST_PERIOD and CURRENT_PERIOD in next.config.js`
);
}

export const periods = range(
parseInt(process.env.CURRENT_PERIOD, 10),
parseInt(process.env.FIRST_PERIOD, 10) - 1,
parseInt(buildEnv.CURRENT_PERIOD, 10),
parseInt(buildEnv.FIRST_PERIOD, 10) - 1,
-1
).map((d) => d.toString());

Expand Down
56 changes: 56 additions & 0 deletions src/domain/env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const { z } = require("zod");

const buildSchema = z.object({
// Used to display a mention of the current deployment in development mode
DEPLOYMENT: z.string().optional(),
CURRENT_PERIOD: z.string().default("2025"),
FIRST_PERIOD: z.string().default("2009"),
VERSION: z.string().optional(),
});

// Define the schema for server-side variables
const serverSchema = z.object({
// Gever document download
EIAM_CERTIFICATE_CONTENT: z.string().optional(),
EIAM_CERTIFICATE_PASSWORD: z.string(),
EIAM_CERTIFICATE_PATH: z.string(),
GEVER_BINDING_IPSTS: z.string(),
GEVER_BINDING_RPSTS: z.string(),
GEVER_BINDING_SERVICE: z.string(),
DEBUG_DOWNLOAD_SECRET: z
.string()
.default("GqQF$t$Fm^oddinivkY8TT8F^kRuRUJ$NJ5Jt%vQ"),

ELCOM_ENV: z.string(),

// Gitlab as CMS
GITLAB_WIKI_TOKEN: z.string(),
GITLAB_WIKI_URL: z.string(),

// Tracking
MATOMO_ID: z.string(),

// Apollo plugin
METRICS_PLUGIN_ENABLED: z.string(),

NODE_ENV: z.string(),

// Sparql
SPARQL_EDITOR: z.string().optional(),
SPARQL_ENDPOINT: z.string().default("https://test.lindas.admin.ch/query"),
});

module.exports = {
serverEnv:
typeof window !== "undefined" ? serverSchema.parse(process.env) : null,

// Need to inline variables here so that they are replaced at build time
buildEnv: buildSchema.parse({
DEPLOYMENT: process.env.DEPLOYMENT,
CURRENT_PERIOD: process.env.CURRENT_PERIOD,
FIRST_PERIOD: process.env.CURRENT_PERIOD,
VERSION: process.env.VERSION,
}),

buildSchema: buildSchema,
};
10 changes: 7 additions & 3 deletions src/domain/gever/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import fs from "fs";
import { memoize } from "lodash";
import z from "zod";

import { serverEnv } from "src/domain/env";
import { OperatorDocumentCategory } from "src/graphql/queries";
import assert from "src/lib/assert";
import { truthy } from "src/lib/truthy";

import { decrypt, encrypt } from "./encrypt";
Expand All @@ -25,15 +27,17 @@ import {
$$,
} from "./utils";

assert(!!serverEnv, "serverEnv must be defined");

const bindings = {
ipsts:
process.env.GEVER_BINDING_IPSTS ||
serverEnv.GEVER_BINDING_IPSTS ||
"https://idp-cert.gate-r.eiam.admin.ch/auth/sts/v14/certificatetransport",
rpsts:
process.env.GEVER_BINDING_RPSTS ||
serverEnv.GEVER_BINDING_RPSTS ||
"https://feds-r.eiam.admin.ch/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256",
service:
process.env.GEVER_BINDING_SERVICE ||
serverEnv.GEVER_BINDING_SERVICE ||
"https://api-bv.egov-abn.uvek.admin.ch/BusinessManagement/GeverService/GeverServiceAdvanced.svc",
};

Expand Down
11 changes: 8 additions & 3 deletions src/domain/gever/soap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ import https from "https";

import fetch from "node-fetch";

import { serverEnv } from "src/domain/env";

const getCertificateContent = () => {
const CERTIFICATE_PATH = process.env.EIAM_CERTIFICATE_PATH;
const CERTIFICATE_CONTENT = process.env.EIAM_CERTIFICATE_CONTENT;
if (!serverEnv) {
throw new Error("serverEnv must be defined");
}
const CERTIFICATE_PATH = serverEnv?.EIAM_CERTIFICATE_PATH;
const CERTIFICATE_CONTENT = serverEnv?.EIAM_CERTIFICATE_CONTENT;
if (CERTIFICATE_PATH) {
if (!fs.existsSync(CERTIFICATE_PATH)) {
throw new Error(`Certificate file does not exist ${CERTIFICATE_PATH}`);
Expand All @@ -22,7 +27,7 @@ const getCertificateContent = () => {

export const makeSslConfiguredAgent = () => {
const pfx = getCertificateContent();
const CERTIFICATE_PASSWORD = process.env.EIAM_CERTIFICATE_PASSWORD;
const CERTIFICATE_PASSWORD = serverEnv?.EIAM_CERTIFICATE_PASSWORD;

if (!CERTIFICATE_PASSWORD) {
throw new Error("EIAM_CERTIFICATE_PASSWORD must be defined in env");
Expand Down
14 changes: 8 additions & 6 deletions src/domain/gitlab-wiki-api.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import https from 'https'
import https from "https";
import os from "os";
import path from "path";

import fs from "fs-extra";

import { serverEnv } from "src/domain/env";

import { getWikiPage as getStaticWikiPage } from "./gitlab-wiki-static";

type WikiPage = {
Expand All @@ -24,7 +26,7 @@ const CACHE_TTL = 1000;

const fetchWithTimeout = async (
url: string,
options: RequestInit & { timeout?: number, agent?: https.Agent } = {}
options: RequestInit & { timeout?: number; agent?: https.Agent } = {}
) => {
const { timeout } = options;

Expand Down Expand Up @@ -65,7 +67,7 @@ const getCachedWikiPages = async (

// This is necessary for GLOBAL_AGENT to correctly override the agent while
// the GLOBAL_AGENT_FORCE_GLOBAL_AGENT variable is set
agent: https.globalAgent
agent: https.globalAgent,
});
const pages: WikiPages = await res.json();

Expand All @@ -78,16 +80,16 @@ const getCachedWikiPages = async (
export const getWikiPage = async (
slug: string
): Promise<WikiPage | undefined> => {
if (!process.env.GITLAB_WIKI_URL || !process.env.GITLAB_WIKI_TOKEN) {
if (!serverEnv?.GITLAB_WIKI_URL || !serverEnv.GITLAB_WIKI_TOKEN) {
throw Error(
"Please set GITLAB_WIKI_URL and GITLAB_WIKI_TOKEN environment variables to fetch content from GitLab Wiki."
);
}

try {
const wikiPages = await getCachedWikiPages(
`${process.env.GITLAB_WIKI_URL}?with_content=1`,
process.env.GITLAB_WIKI_TOKEN
`${serverEnv.GITLAB_WIKI_URL}?with_content=1`,
serverEnv.GITLAB_WIKI_TOKEN
);

return wikiPages.find((page) => page.slug === slug);
Expand Down
7 changes: 7 additions & 0 deletions src/lib/assert.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function assert(predicate: boolean, message: string): asserts predicate {
if (!predicate) {
throw new Error(message);
}
}

export default assert;
3 changes: 2 additions & 1 deletion src/lib/use-query-state.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useRouter } from "next/router";
import { useCallback } from "react";

import { buildEnv } from "src/domain/env";

const ensureArray = (input: string | string[]): string[] =>
Array.isArray(input) ? input : [input];
Expand All @@ -22,7 +23,7 @@ const queryStateKeys = [

const queryStateDefaults = {
id: "261",
period: process.env.CURRENT_PERIOD,
period: buildEnv.CURRENT_PERIOD,
category: "H4",
priceComponent: "total",
product: "standard",
Expand Down
11 changes: 4 additions & 7 deletions src/pages/_document.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import Document, {
Html,
Head,
Main,
NextScript,
} from "next/document";
import Document, { Html, Head, Main, NextScript } from "next/document";

import { buildEnv } from "src/domain/env";

class MyDocument extends Document {
render() {
return (
<Html
data-app-version={`${process.env.VERSION}`}
data-app-version={`${buildEnv.VERSION}`}
// lang={this.props.locale}
>
<Head></Head>
Expand Down
3 changes: 2 additions & 1 deletion src/pages/api/data-export.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { csvFormat } from "d3";
import { NextApiRequest, NextApiResponse } from "next";

import { buildEnv } from "src/domain/env";
import { parseLocaleString } from "src/locales/locales";

import {
Expand All @@ -11,7 +12,7 @@ import {

export default async (req: NextApiRequest, res: NextApiResponse) => {
const locale = parseLocaleString(req.query.locale?.toString());
const period = req.query.period?.toString() ?? process.env.CURRENT_PERIOD!;
const period = req.query.period?.toString() ?? buildEnv.CURRENT_PERIOD!;

const cube = await getObservationsCube();

Expand Down
9 changes: 6 additions & 3 deletions src/pages/api/debug-download.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { InferAPIResponse } from "nextkit";

import { serverEnv } from "src/domain/env";
import assert from "src/lib/assert";

import { searchGeverDocuments } from "../../domain/gever";
import { fetchOperatorInfo } from "../../rdf/search-queries";
import { endpointUrl } from "../../rdf/sparql-client";
import { api } from "../../server/nextkit";

const secret =
process.env.DEBUG_DOWNLOAD_SECRET ||
"GqQF$t$Fm^oddinivkY8TT8F^kRuRUJ$NJ5Jt%vQ";
assert(!!serverEnv, "serverEnv is not defined");

const secret = serverEnv.DEBUG_DOWNLOAD_SECRET;

const handler = api({
GET: async ({ req }) => {
Expand Down
12 changes: 8 additions & 4 deletions src/pages/api/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,28 @@ import responseCachePlugin from "@apollo/server-plugin-response-cache";
import { startServerAndCreateNextHandler } from "@as-integrations/next";
import { NextApiHandler } from "next";

import { serverEnv } from "src/domain/env";
import { resolvers } from "src/graphql/resolvers";
import typeDefs from "src/graphql/schema.graphql";
import { context } from "src/graphql/server-context";
import assert from "src/lib/assert";

import { metricsPlugin } from "./metricsPlugin";

assert(!!serverEnv, "serverEnv is not defined");

const server = new ApolloServer({
typeDefs,
resolvers,
apollo: {},
introspection: process.env.NODE_ENV === "development",
introspection: serverEnv.NODE_ENV === "development",
plugins: [
metricsPlugin({
enabled:
process.env.NODE_ENV === "development" ||
process.env.METRICS_PLUGIN_ENABLED === "true",
serverEnv.NODE_ENV === "development" ||
serverEnv.METRICS_PLUGIN_ENABLED === "true",
}),
process.env.NODE_ENV === "development"
serverEnv.NODE_ENV === "development"
? ApolloServerPluginLandingPageLocalDefault({ embed: false })
: ApolloServerPluginLandingPageDisabled(),
ApolloServerPluginCacheControl({
Expand Down
6 changes: 5 additions & 1 deletion src/pages/api/matomo-id.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { NextApiRequest, NextApiResponse } from "next";

import { serverEnv } from "src/domain/env";
import assert from "src/lib/assert";

export default async (req: NextApiRequest, res: NextApiResponse) => {
res.json({ matomoId: process.env.MATOMO_ID });
assert(!!serverEnv, "serverEnv is not defined");
res.json({ matomoId: serverEnv.MATOMO_ID });
};
6 changes: 5 additions & 1 deletion src/pages/api/municipalities-data.csv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { mapValues } from "lodash";
import { NextApiHandler } from "next";
import { z } from "zod";

import { buildEnv } from "src/domain/env";

const MunicipalityInfo = z
.object({
netzbetreiber: z.string(),
Expand Down Expand Up @@ -135,7 +137,9 @@ WHERE {
};

const handler: NextApiHandler = async (req, res) => {
const period = Number(req.query.period?.toString() ?? 2024!);
const period = Number(
req.query.period?.toString() ?? buildEnv.CURRENT_PERIOD
);
const data = await fetchMunicipalitiesInfo(period);
const filename = `municipalities-data-${period}.csv`;
const csv = csvFormat(data, [
Expand Down
Loading

0 comments on commit fc39b8c

Please sign in to comment.