Skip to content

Commit

Permalink
feat: add global-config-scripts (#270)
Browse files Browse the repository at this point in the history
* feat: add global-config-scripts

* feat: add global-config-scripts

* feat: increase version

* feat: increase version
  • Loading branch information
sgimama authored Oct 28, 2024
1 parent f75b00f commit cd42933
Show file tree
Hide file tree
Showing 9 changed files with 308 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/new-seas-check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'gdu': minor
---

Add scripts for tokens mfe
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@manypkg/cli": "^0.21.4",
"@types/node": "^16.4.13",
"browserslist-config-autoguru": "*",
"dotenv": "^16.4.5",
"eslint": "^7.28.0",
"eslint-plugin-jest": "^24.3.6",
"glob": "^7.1.6",
Expand Down
134 changes: 134 additions & 0 deletions packages/gdu/commands/global-configs/config-tenants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import * as fs from 'fs';
import * as path from 'path';

import * as dotenv from 'dotenv';

import { getTokens } from '../../lib/globalConfigs';

const envs = ['uat', 'preprod', 'dev', 'prod', 'test', 'tokens'];
const tenants = ['au', 'nz', 'au-legacy'];
type ENV = (typeof envs)[number];
type TENANT = (typeof tenants)[number] ;

export default async () => {
console.log('Global config tenants started');
const TOKENS = await getTokens();

const mfeListFile = path.resolve(
process.cwd(),
'.mfe-data',
'mfe-list.json',
);
const mfeList = JSON.parse(fs.readFileSync(mfeListFile, 'utf-8'));
let mfeProjects = [];

for (const category in mfeList) {
const categoryKeys = Object.keys(mfeList[category]);
mfeProjects = mfeProjects.concat(categoryKeys);
}

const destinationFolder = path.join(
process.cwd(),
'.mfe-data',
'app-configs',
);

const copyTokens = (mfe) => {
const prodFile = path.join(
process.cwd(),
'apps',
mfe,
'.gdu_app_config',
'.env.prod',
);
if (fs.existsSync(prodFile)) {
const tokensFile = path.join(
process.cwd(),
'apps',
mfe,
'.gdu_app_config',
'.env.tokens',
);

// Extract text from prod file
const prodText = fs.readFileSync(prodFile, 'utf8');
// replace #{*****} with "#{*****}" where ***** can be any value with any length
const tokensText = prodText.replace(/#{(.*?)}/g, '"#{$1}"');

// Write the tokens file
fs.writeFileSync(
tokensFile,
`# This file automatically generated from .env.prod file. \r${tokensText}`,
);
}
};

// force delete destination folder if it exists
if (fs.existsSync(destinationFolder)) {
fs.rmSync(destinationFolder, { recursive: true });
}
// create destination folder
if (!fs.existsSync(destinationFolder)) {
fs.mkdirSync(destinationFolder, { recursive: true });
}
const getEnvFile = (mfe, env: ENV, tenant?: TENANT) =>
path.join(
process.cwd(),
'apps',
mfe,
'.gdu_app_config',
tenant ? `.env.${env}_${tenant}` : `.env.${env}`,
);

const generateTokens = (envFile, mfe, env: ENV, tenant?: TENANT) => {
const fileStats = fs.statSync(envFile);
const dirPathMfeApp = path.join(destinationFolder, `${mfe}`);
if (!fs.existsSync(dirPathMfeApp)) {
fs.mkdirSync(dirPathMfeApp);
}
let data = '';

// Check if the file is empty
if (fileStats.size > 0) {
dotenv.config({ path: envFile, override: true });

const fileContent = fs.readFileSync(envFile, 'utf8');
const FILTERED_TOKENS = Object.keys(TOKENS).reduce((acc, key) => {
if (fileContent.includes(key)) {
acc[key] = process.env[key];
}
return acc;
}, {});

data = JSON.stringify(FILTERED_TOKENS, null, 2);
}

fs.writeFileSync(
path.join(
dirPathMfeApp,
tenant ? `${env}_${tenant}.json` : `${env}.json`,
),
data,
);
};

mfeProjects.forEach((mfe) => {
envs.forEach((env) => {
if (env === 'tokens') {
const envFile = getEnvFile(mfe, env);
copyTokens(mfe);
if (fs.existsSync(envFile)) {
generateTokens(envFile, mfe, env);
}
}
tenants.forEach((tenant) => {
const envFile = getEnvFile(mfe, env, tenant);
if (fs.existsSync(envFile)) {
generateTokens(envFile, mfe, env, tenant);
}
});
});
});
console.log('Global config tokens finished');

}
103 changes: 103 additions & 0 deletions packages/gdu/commands/global-configs/config-tokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import * as fs from 'fs';
import * as path from 'path';

import * as dotenv from 'dotenv';

import { getTokens } from '../../lib/globalConfigs';

const envs = ['uat', 'preprod', 'dev', 'prod_build', 'test', 'tokens'];
const tenants = ['au', 'nz', 'au-legacy'];
type ENV = (typeof envs)[number];
type TENANT = (typeof tenants)[number] ;


export default async () => {
console.log('Global config tokens started');
const TOKENS = await getTokens();

// eslint-disable-next-line unicorn/consistent-function-scoping
const getFileName = (env: ENV) => {
switch (env) {
case 'prod_build':
return 'prod';
default:
return env;
}
};

const defaultsFile = path.join(
process.cwd(),
'.gdu_config',
'.env.defaults',
);

const destinationFolder = path.join(
process.cwd(),
'.mfe-data',
'env-configs',
);

const copyTokens = () => {
const prodFile = path.join(
process.cwd(),
'.gdu_config',
'.env.prod',
);
const tokensFile = path.join(
process.cwd(),
'.gdu_config',
'.env.tokens',
);

// Extract text from prod file
const prodText = fs.readFileSync(prodFile, 'utf8');
// replace #{*****} with "#{*****}" where ***** can be any value with any length
const tokensText = prodText.replace(/#{(.*?)}/g, '"#{$1}"');
// Write the tokens file
fs.writeFileSync(
tokensFile,
`# This file automatically generated from .env.prod file. \r${tokensText}`,
);
};

const generateTokens = (env: ENV, tenant?: TENANT) => {
if (env === 'tokens') {
copyTokens();
}
const envFile = path.join(
process.cwd(),
'.gdu_config',
tenant ? `.env.${env}_${tenant}` : `.env.${env}`,
);
dotenv.config({ path: [defaultsFile, envFile], override: true });

const FILTERED_TOKENS = Object.keys(TOKENS).reduce((acc, key) => {
if (process.env[key])
acc[key] = process.env[key];
return acc;
}, {});

const data = JSON.stringify(FILTERED_TOKENS, null, 2);

fs.writeFileSync(
path.join(
destinationFolder,
tenant
? `${getFileName(env)}_${tenant}.json`
: `${getFileName(env)}.json`,
),
data,
);
};

envs.forEach((env: ENV) => {
if (env !== 'tokens') {
tenants.forEach((tenant: TENANT) => {
generateTokens(env, tenant);
});
}
generateTokens(env);
});
console.log('Global config tokens finished');

}
28 changes: 28 additions & 0 deletions packages/gdu/commands/global-configs/generate-tokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as fs from 'fs';
import * as path from 'path';
export default async () => {
console.log('Global config generate tokens started');

const typeFilePath = path.resolve( 'packages', 'global-configs', 'processEnvs.d.ts');
const fileContent: string = fs.readFileSync(typeFilePath, 'utf-8');
type ProcessEnvs = any;

const regex = /readonly\s+(\w+):/g;
let match: RegExpExecArray | null;
const keys: (keyof ProcessEnvs)[] = [];

while ((match = regex.exec(fileContent)) !== null) {
keys.push(match[1] as keyof ProcessEnvs);
}

const TOKENS: Record<keyof ProcessEnvs, string | undefined> = keys.reduce((acc, key) => {
acc[key] = `process.env.${key.toString()}`;
return acc;
}, {} as Record<keyof ProcessEnvs, string | undefined>);

const tokensContent: string = `export const TOKENS = ${JSON.stringify(TOKENS, null, 2).replace(/"process\.env\.(\w+)"/g, 'process.env.$1')};\n`;
const tokensFilePath = path.resolve('packages', 'global-configs', '__generated__', 'tokens.ts');
fs.writeFileSync(tokensFilePath, tokensContent);

console.log('tokens.ts has been created with the TOKENS object.');
}
10 changes: 10 additions & 0 deletions packages/gdu/commands/global-configs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

import configTenants from './config-tenants';
import configTokents from './config-tokens';
import configGenerateTokens from './generate-tokens';

export default async () => {
await configGenerateTokens();
await configTokents();
await configTenants();
};
4 changes: 4 additions & 0 deletions packages/gdu/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ export default (app: Sade) => {
app.command('gh-actions')
.describe('A command to create GitHub actions things')
.action(deferredAction(async () => import('./gh-actions')));

app.command('generate-global-configs')
.describe('Generate global configs')
.action(deferredAction(async () => import('./global-configs'), IS_NOT_ROOT));
};

const NOT_READY = wrapAction(() => {
Expand Down
15 changes: 15 additions & 0 deletions packages/gdu/lib/globalConfigs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { join } from 'path';

import { register } from 'ts-node';

import { PROJECT_ROOT } from './roots';


export const getTokens = async () => {
register();

const tokensFile = join(PROJECT_ROOT, 'packages/global-configs/__generated__/tokens.ts');
const fileTokens = await import(tokensFile);
return fileTokens.TOKENS

};
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8487,6 +8487,13 @@ __metadata:
languageName: node
linkType: hard

"dotenv@npm:^16.4.5":
version: 16.4.5
resolution: "dotenv@npm:16.4.5"
checksum: 301a12c3d44fd49888b74eb9ccf9f07a1f5df43f489e7fcb89647a2edcd84c42d6bc349dc8df099cd18f07c35c7b04685c1a4f3e6a6a9e6b30f8d48c15b7f49c
languageName: node
linkType: hard

"dotenv@npm:^8.2.0":
version: 8.6.0
resolution: "dotenv@npm:8.6.0"
Expand Down Expand Up @@ -15124,6 +15131,7 @@ __metadata:
"@manypkg/cli": ^0.21.4
"@types/node": ^16.4.13
browserslist-config-autoguru: "*"
dotenv: ^16.4.5
eslint: ^7.28.0
eslint-plugin-jest: ^24.3.6
glob: ^7.1.6
Expand Down

0 comments on commit cd42933

Please sign in to comment.