Skip to content

Commit

Permalink
[DEV-1364] Remove config file and create BrowserConfig (#613)
Browse files Browse the repository at this point in the history
  • Loading branch information
kin0992 authored Feb 7, 2024
1 parent 4caeaaf commit 1352c9e
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 92 deletions.
5 changes: 5 additions & 0 deletions .changeset/famous-candles-clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"nextjs-website": patch
---

[DEV-1364] Remove AppEnv and Config in favor of the BrowserEnv and BrowserConfig
47 changes: 0 additions & 47 deletions apps/nextjs-website/src/AppEnv.ts

This file was deleted.

39 changes: 39 additions & 0 deletions apps/nextjs-website/src/BrowserConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as t from 'io-ts';
import { pipe } from 'fp-ts/lib/function';
import * as E from 'fp-ts/lib/Either';
import * as PR from 'io-ts/lib/PathReporter';
import * as tt from 'io-ts-types';

const BrowserConfigCodec = t.type({
NEXT_PUBLIC_COGNITO_REGION: t.string,
NEXT_PUBLIC_COGNITO_USER_POOL_ID: t.string,
NEXT_PUBLIC_COGNITO_IDENTITY_POOL_ID: t.string,
NEXT_PUBLIC_WEBINAR_QUESTION_LIFETIME_IN_SECONDS: t.string.pipe(
tt.NumberFromString
),
});

export type BrowserConfig = t.TypeOf<typeof BrowserConfigCodec>;

// TODO: Migrate all the above environment
// publicEnv exists to allow nextjs to correctly replace environments at build
// time, without this copy in some cases some NEXT_PUBLIC environments will be
// undefined
// https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#bundling-environment-variables-for-the-browser
export const publicEnv = {
NEXT_PUBLIC_COGNITO_REGION: process.env.NEXT_PUBLIC_COGNITO_REGION,
NEXT_PUBLIC_COGNITO_USER_POOL_ID:
process.env.NEXT_PUBLIC_COGNITO_USER_POOL_ID,
NEXT_PUBLIC_COGNITO_IDENTITY_POOL_ID:
process.env.NEXT_PUBLIC_COGNITO_IDENTITY_POOL_ID,
NEXT_PUBLIC_WEBINAR_QUESTION_LIFETIME_IN_SECONDS:
process.env.NEXT_PUBLIC_WEBINAR_QUESTION_LIFETIME_IN_SECONDS,
};

export const makeBrowserConfig = (
env: Record<string, undefined | string>
): E.Either<string, BrowserConfig> =>
pipe(
BrowserConfigCodec.decode(env),
E.mapLeft((errors) => PR.failure(errors).join('\n'))
);
28 changes: 28 additions & 0 deletions apps/nextjs-website/src/BrowserEnv.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { WebinarEnv } from './lib/webinars/webinarQuestions';
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import { makeAwsCredentialsFromCognito } from './lib/makeAwsCredentialsFromCognito';
import { Auth } from 'aws-amplify';
import { BrowserConfig } from '@/BrowserConfig';

// This type represents the environment of the browser.
// Contains all dependencies required to run the application on the browser.
export type BrowserEnv = {
readonly config: BrowserConfig;
} & WebinarEnv;

// given environment variables produce an BrowserEnv
export const makeBrowserEnv = (config: BrowserConfig): BrowserEnv => ({
config,
questionLifetimeInSeconds:
config.NEXT_PUBLIC_WEBINAR_QUESTION_LIFETIME_IN_SECONDS,
nowDate: () => new Date(),
dynamoDBClient: new DynamoDBClient({
region: config.NEXT_PUBLIC_COGNITO_REGION,
credentials: makeAwsCredentialsFromCognito(
config,
// passing Auth.currentSession raise an error because
// Auth.currentSession is not able to retrieve all the information
() => Auth.currentSession()
),
}),
});
46 changes: 6 additions & 40 deletions apps/nextjs-website/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import * as t from 'io-ts';
import * as tt from 'io-ts-types';
import { pipe } from 'fp-ts/lib/function';
import * as E from 'fp-ts/lib/Either';
import * as PR from 'io-ts/lib/PathReporter';
/**
This file is going to be removed after few refactoring phases.
The following environments are going to be moved in dedicated config files or environments.
See BrowserConfig.ts and BrowserEnv.ts as examples.
@deprecated
*/
// TODO: Add environment parser
export const docsPath = process.env.PATH_TO_GITBOOK_DOCS;
export const cookieDomainScript = process.env.NEXT_PUBLIC_COOKIE_DOMAIN_SCRIPT;
Expand Down Expand Up @@ -55,38 +56,3 @@ export const timeOptions: Intl.DateTimeFormatOptions = {
hour: '2-digit',
minute: '2-digit',
};

// TODO: Migrate all the above environment
// publicenv exists to allow nextjs to correctly replace environments at build
// time, without this copy in some cases some NEXT_PUBLIC environments will be
// undefined
// https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#bundling-environment-variables-for-the-browser
export const publicEnv = {
NEXT_PUBLIC_COGNITO_REGION: process.env.NEXT_PUBLIC_COGNITO_REGION,
NEXT_PUBLIC_COGNITO_USER_POOL_ID:
process.env.NEXT_PUBLIC_COGNITO_USER_POOL_ID,
NEXT_PUBLIC_COGNITO_IDENTITY_POOL_ID:
process.env.NEXT_PUBLIC_COGNITO_IDENTITY_POOL_ID,
NEXT_PUBLIC_WEBINAR_QUESTION_LIFETIME_IN_SECONDS:
process.env.NEXT_PUBLIC_WEBINAR_QUESTION_LIFETIME_IN_SECONDS,
};

const ConfigCodec = t.type({
NEXT_PUBLIC_COGNITO_REGION: t.string,
NEXT_PUBLIC_COGNITO_USER_POOL_ID: t.string,
NEXT_PUBLIC_COGNITO_IDENTITY_POOL_ID: t.string,
NEXT_PUBLIC_WEBINAR_QUESTION_LIFETIME_IN_SECONDS: t.string.pipe(
tt.NumberFromString
),
});

export type Config = t.TypeOf<typeof ConfigCodec>;

// parse config from environment variables
export const makeConfig = (
env: Record<string, undefined | string>
): E.Either<string, Config> =>
pipe(
ConfigCodec.decode(env),
E.mapLeft((errors) => PR.failure(errors).join('\n'))
);
4 changes: 2 additions & 2 deletions apps/nextjs-website/src/lib/makeAwsCredentialsFromCognito.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Config } from '@/config';
import { fromCognitoIdentityPool } from '@aws-sdk/credential-providers';
import { Auth } from 'aws-amplify';
import { BrowserConfig } from '@/BrowserConfig';

// Create a aws credentials provider given a cognito user
export const makeAwsCredentialsFromCognito = (
config: Config,
config: BrowserConfig,
getCurrentSession: typeof Auth.currentSession
) => {
const providerName = `cognito-idp.${config.NEXT_PUBLIC_COGNITO_REGION}.amazonaws.com/${config.NEXT_PUBLIC_COGNITO_USER_POOL_ID}`;
Expand Down
18 changes: 15 additions & 3 deletions apps/nextjs-website/src/lib/webinarApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,25 @@
// or components within the app and components folders, e.g.: provide a valid
// application environment (AppEnv) and transform TaskEither to Promise
import { pipe } from 'fp-ts/function';
import * as E from 'fp-ts/Either';
import * as TE from 'fp-ts/TaskEither';
import { appEnv } from '@/AppEnv';
import { makeBrowserEnv } from '@/BrowserEnv';
import {
InsertWebinarQuestion,
insertWebinarQuestion,
listWebinarQuestions,
} from './webinars/webinarQuestions';
import { makeBrowserConfig, publicEnv } from '@/BrowserConfig';

// a BrowserEnv instance ready to be used
const browserEnv = pipe(
makeBrowserConfig(publicEnv),
E.map(makeBrowserEnv),
E.getOrElseW((errors) => {
// eslint-disable-next-line functional/no-throw-statements
throw errors;
})
);

const makePromiseFromTE = <E, A>(input: TE.TaskEither<E, A>) =>
pipe(
Expand All @@ -21,7 +33,7 @@ const makePromiseFromTE = <E, A>(input: TE.TaskEither<E, A>) =>
);

export const sendWebinarQuestion = (question: InsertWebinarQuestion) =>
pipe(insertWebinarQuestion(question)(appEnv), makePromiseFromTE)();
pipe(insertWebinarQuestion(question)(browserEnv), makePromiseFromTE)();

export const getWebinarQuestionList = (webinarId: string) =>
pipe(listWebinarQuestions(webinarId)(appEnv), makePromiseFromTE)();
pipe(listWebinarQuestions(webinarId)(browserEnv), makePromiseFromTE)();

0 comments on commit 1352c9e

Please sign in to comment.