@driveflux/env 0.0.2-develop.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,13 @@
1
+ $ bun run ./build.ts
2
+ 🔍 Scanning folder: ./dist
3
+ 📄 Found 4 JS files to process
4
+
5
+ 📊 Processing Summary:
6
+ Files processed: 4
7
+ Total exports found: 6
8
+ Duplicates removed: 0
9
+ Total processing time: 17.77ms
10
+ Average time per file: 4.44ms
11
+
12
+ ✅ No duplicate exports found in any files
13
+ ✅ Build successful
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @driveflux/env
2
+
3
+ ## 0.0.2-develop.0
4
+
5
+ ### Patch Changes
6
+
7
+ - afe41e3: Created env package
package/build.ts ADDED
@@ -0,0 +1,45 @@
1
+ import { readdirSync, rmdirSync, statSync, unlinkSync } from 'node:fs'
2
+ import path from 'node:path'
3
+ import { autoRemoveDuplicateExports } from '@driveflux/fix-builds'
4
+ import type { Target } from 'bun'
5
+
6
+ // Clean the dist directory
7
+ const outdir = './dist'
8
+ const clearDir = (dir: string) => {
9
+ try {
10
+ const files = readdirSync(dir)
11
+ for (const file of files) {
12
+ if (file.endsWith('.js') || file.endsWith('.js.map')) {
13
+ unlinkSync(path.join(dir, file))
14
+ } else {
15
+ try {
16
+ if (statSync(path.join(dir, file)).isDirectory()) {
17
+ clearDir(path.join(dir, file))
18
+ rmdirSync(path.join(dir, file))
19
+ }
20
+ } catch (_error) {
21
+ // Directory might not exist, that's fine
22
+ }
23
+ }
24
+ }
25
+ } catch (_error) {
26
+ // Directory might not exist, that's fine
27
+ }
28
+ }
29
+ clearDir(outdir)
30
+
31
+ await Bun.build({
32
+ entrypoints: ['./src/main.ts', './src/init-env.ts', './src/augment-env.ts'],
33
+ root: './src',
34
+ plugins: [],
35
+ packages: 'external',
36
+ outdir,
37
+ target: (process.env.BUILD_TARGET as Target) ?? 'bun',
38
+ splitting: true,
39
+ minify: process.env.CI === 'true' || process.env.CI === '1',
40
+ sourcemap: 'linked',
41
+ })
42
+
43
+ await autoRemoveDuplicateExports(outdir)
44
+
45
+ console.info('✅ Build successful')
@@ -0,0 +1,4 @@
1
+ {
2
+ "@types/bun": "^1.3",
3
+ "typescript": "5.9.3"
4
+ }
@@ -0,0 +1,2 @@
1
+ export declare const getAppEnv: () => string;
2
+ export declare const isProd: () => boolean;
@@ -0,0 +1 @@
1
+ export declare const augmentEnv: () => void;
@@ -0,0 +1,5 @@
1
+ import"./chunk-32b1dzdk.js";var x=()=>{if(process.env.APP_ENV)return process.env.APP_ENV;if(process.env.USE_ENV)return process.env.USE_ENV;return"development"};var b={SLACK_DEFAULT_CHANNEL_ID:"C0679V8KGSH",SLACK_RESERVATIONS_CHANNEL_ID:"C01G8B12G67",SLACK_FBC_CHANNEL:"C01L1AAKB3N",SLACK_BD_CHANNEL:"CN21PGKK8",SLACK_MAIN_FLUX_CHANNEL:"GHDPV1858",SLACK_INQUIRIES_CHANNEL_ID:"C067CSK5J5Q",SLACK_INVOICE_FAILURES_CHANNEL_ID:"C067CPUMB8T",SLACK_SST_CHANNEL_ID:"C068NH60A78",SLACK_ERROR_CHANNEL_ID:"C04N4Q7HA79",SLACK_ISSUES_CHANNEL_ID:"C0680P99AE8",SLACK_COMING_SERVICES_CHANNEL_ID:"C06SB20H2J1",SLACK_ESMS_CHANNEL_ID:"C07RPEP2BMY",SLACK_EXCESS_MILEAGE_CHANNEL_ID:"C0679URBY93",SLACK_ENGINEERING_REQUESTS_CHANNEL:"C01U8GTK3K9"},F=(g)=>({production:b,staging:Object.keys(b).reduce((m,f)=>{return m[f]="C0661UNMBQU",m},{}),development:Object.keys(b).reduce((m,f)=>{return m[f]=g?.SLACK_MY_CHANNEL_ID||"C09GJ4FJVRS",m},{})}),z=(g,m)=>{let f=F(m),j=g&&g in f?f[g]:f.staging;for(let t of Object.keys(j))if(m?.[t])j[t]=m[t];return j},w={NOTION_REQUEST_DATABASE_ID:"32332c0e-4277-43fa-b10e-7d458234f9ea",NOTION_REVIEWS_DATABASE_ID:"8a8b0df9-567d-433f-8937-583db2766176",NOTION_FBC_DATABASE_ID:"76960d4b-2b43-4019-a77e-ac46a0b3d752",NOTION_FLUXSTERS_DATABASE_ID:"4ea6953a-61c2-4673-8950-c0d0e158de0a",NOTION_BD_DATABASE_ID:"172a9182-56c0-4358-b4f1-7e8fcfa44e46",NOTION_BRANDS_LANDING_PAGES_DATABASE_ID:"e321d71a-0d29-42da-ab0b-dca2260b643e",NOTION_KNOWLEDGE_BASE_DATABASE_ID:"7a81653f-4351-4a17-aa1e-c3082c378441",NOTION_REFERRALS_DATABASE_ID:"b5599d70-b414-4aa9-9ff2-d445c8f3f0fc"},q={production:w,staging:{...w,NOTION_KNOWLEDGE_BASE_DATABASE_ID:"f95b9986-c1c9-46ca-a742-d49f3f80d7dd"}},B=(g,m)=>{let f=g&&g in q?q[g]:q.staging;for(let j of Object.keys(f))if(m?.[j])f[j]=m[j];return f};var L=()=>{let g=z(x(),process.env),m=B(x());for(let[f,j]of Object.entries({...g,...m})){if(process.env[f])continue;process.env[f]=j}};export{L as augmentEnv};
2
+ export{L as b};
3
+
4
+ //# debugId=29479D07BEA8166A64756E2164756E21
5
+ //# sourceMappingURL=augment-env.js.map
@@ -0,0 +1,12 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/app-env.ts", "../src/base-configs.ts", "../src/augment-env.ts"],
4
+ "sourcesContent": [
5
+ "export const getAppEnv = () => {\n if (process.env.APP_ENV) {\n return process.env.APP_ENV\n }\n\n // If USE_ENV is set, use it\n if (process.env.USE_ENV) {\n return process.env.USE_ENV\n }\n\n // If NODE_ENV is set, use it\n if (process.env.NODE_ENV) {\n return process.env.NODE_ENV\n }\n\n // Default to development as a last resort\n return 'development'\n}\n\nconst isAppEnv = (env: string) => getAppEnv() === env\nexport const isProd = () => isAppEnv('production')\n",
6
+ "type SlackIds = {\n -readonly [k in keyof typeof slackProductionChannels]: string\n}\ntype NotionIds = {\n -readonly [k in keyof typeof notionProductionChannels]: string\n}\n\nconst slackProductionChannels = {\n SLACK_DEFAULT_CHANNEL_ID: 'C0679V8KGSH',\n SLACK_RESERVATIONS_CHANNEL_ID: 'C01G8B12G67',\n SLACK_FBC_CHANNEL: 'C01L1AAKB3N',\n SLACK_BD_CHANNEL: 'CN21PGKK8',\n SLACK_MAIN_FLUX_CHANNEL: 'GHDPV1858',\n SLACK_INQUIRIES_CHANNEL_ID: 'C067CSK5J5Q',\n SLACK_INVOICE_FAILURES_CHANNEL_ID: 'C067CPUMB8T',\n SLACK_SST_CHANNEL_ID: 'C068NH60A78',\n SLACK_ERROR_CHANNEL_ID: 'C04N4Q7HA79',\n SLACK_ISSUES_CHANNEL_ID: 'C0680P99AE8',\n SLACK_COMING_SERVICES_CHANNEL_ID: 'C06SB20H2J1',\n SLACK_ESMS_CHANNEL_ID: 'C07RPEP2BMY',\n SLACK_EXCESS_MILEAGE_CHANNEL_ID: 'C0679URBY93',\n SLACK_ENGINEERING_REQUESTS_CHANNEL: 'C01U8GTK3K9',\n} as const\n\nconst getSlackIdsMap = (processEnv?: Record<string, string | undefined>) =>\n ({\n production: slackProductionChannels,\n staging: Object.keys(slackProductionChannels).reduce((acc, key) => {\n acc[key as keyof SlackIds] = 'C0661UNMBQU' // #platform-staging-notifications\n return acc\n }, {} as SlackIds),\n development: Object.keys(slackProductionChannels).reduce((acc, key) => {\n acc[key as keyof SlackIds] =\n processEnv?.SLACK_MY_CHANNEL_ID || 'C09GJ4FJVRS' // #platform-dev-notifications\n return acc\n }, {} as SlackIds),\n }) as const satisfies Record<string, SlackIds>\n\nexport const getSlackIds = (\n appEnv?: string,\n processEnv?: Record<string, string | undefined>,\n): SlackIds => {\n const slackIdsMap = getSlackIdsMap(processEnv)\n const envIds: SlackIds =\n appEnv && appEnv in slackIdsMap\n ? slackIdsMap[appEnv as keyof typeof slackIdsMap]\n : slackIdsMap.staging\n\n // Override the values from ENV if available\n for (const key of Object.keys(envIds)) {\n if (processEnv?.[key]) {\n envIds[key as keyof SlackIds] = processEnv[key] as string\n }\n }\n\n return envIds\n}\n\nconst notionProductionChannels = {\n NOTION_REQUEST_DATABASE_ID: '32332c0e-4277-43fa-b10e-7d458234f9ea',\n NOTION_REVIEWS_DATABASE_ID: '8a8b0df9-567d-433f-8937-583db2766176', // Seems to be unused\n NOTION_FBC_DATABASE_ID: '76960d4b-2b43-4019-a77e-ac46a0b3d752', // Seems to be unused\n NOTION_FLUXSTERS_DATABASE_ID: '4ea6953a-61c2-4673-8950-c0d0e158de0a',\n NOTION_BD_DATABASE_ID: '172a9182-56c0-4358-b4f1-7e8fcfa44e46',\n NOTION_BRANDS_LANDING_PAGES_DATABASE_ID:\n 'e321d71a-0d29-42da-ab0b-dca2260b643e',\n NOTION_KNOWLEDGE_BASE_DATABASE_ID: '7a81653f-4351-4a17-aa1e-c3082c378441',\n NOTION_REFERRALS_DATABASE_ID: 'b5599d70-b414-4aa9-9ff2-d445c8f3f0fc',\n} as const satisfies Record<string, string>\n\nconst NOTION_IDS_MAP = {\n production: notionProductionChannels,\n staging: {\n ...notionProductionChannels,\n NOTION_KNOWLEDGE_BASE_DATABASE_ID: 'f95b9986-c1c9-46ca-a742-d49f3f80d7dd',\n },\n} as const satisfies Record<string, NotionIds>\n\nexport const getNotionIds = (\n appEnv?: string,\n processEnv?: Record<string, string>,\n): NotionIds => {\n const envIds: NotionIds =\n appEnv && appEnv in NOTION_IDS_MAP\n ? NOTION_IDS_MAP[appEnv as keyof typeof NOTION_IDS_MAP]\n : NOTION_IDS_MAP.staging\n\n // Override the values from ENV if available\n for (const key of Object.keys(envIds)) {\n if (processEnv?.[key]) {\n envIds[key as keyof NotionIds] = processEnv[key] as string\n }\n }\n\n return envIds\n}\n",
7
+ "import { getAppEnv } from './app-env'\nimport { getNotionIds, getSlackIds } from './base-configs'\n\nexport const augmentEnv = () => {\n const slackIds = getSlackIds(getAppEnv(), process.env)\n const notionIds = getNotionIds(getAppEnv())\n\n for (const [key, value] of Object.entries({ ...slackIds, ...notionIds })) {\n if (process.env[key]) {\n continue\n }\n\n process.env[key] = value\n }\n}\n"
8
+ ],
9
+ "mappings": "4BAAO,IAAM,EAAY,IAAM,CAC7B,GAAI,QAAQ,IAAI,QACd,OAAO,QAAQ,IAAI,QAIrB,GAAI,QAAQ,IAAI,QACd,OAAO,QAAQ,IAAI,QAKnB,MAAO,eCLX,IAAM,EAA0B,CAC9B,yBAA0B,cAC1B,8BAA+B,cAC/B,kBAAmB,cACnB,iBAAkB,YAClB,wBAAyB,YACzB,2BAA4B,cAC5B,kCAAmC,cACnC,qBAAsB,cACtB,uBAAwB,cACxB,wBAAyB,cACzB,iCAAkC,cAClC,sBAAuB,cACvB,gCAAiC,cACjC,mCAAoC,aACtC,EAEM,EAAiB,CAAC,KACrB,CACC,WAAY,EACZ,QAAS,OAAO,KAAK,CAAuB,EAAE,OAAO,CAAC,EAAK,IAAQ,CAEjE,OADA,EAAI,GAAyB,cACtB,GACN,CAAC,CAAa,EACjB,YAAa,OAAO,KAAK,CAAuB,EAAE,OAAO,CAAC,EAAK,IAAQ,CAGrE,OAFA,EAAI,GACF,GAAY,qBAAuB,cAC9B,GACN,CAAC,CAAa,CACnB,GAEW,EAAc,CACzB,EACA,IACa,CACb,IAAM,EAAc,EAAe,CAAU,EACvC,EACJ,GAAU,KAAU,EAChB,EAAY,GACZ,EAAY,QAGlB,QAAW,KAAO,OAAO,KAAK,CAAM,EAClC,GAAI,IAAa,GACf,EAAO,GAAyB,EAAW,GAI/C,OAAO,GAGH,EAA2B,CAC/B,2BAA4B,uCAC5B,2BAA4B,uCAC5B,uBAAwB,uCACxB,6BAA8B,uCAC9B,sBAAuB,uCACvB,wCACE,uCACF,kCAAmC,uCACnC,6BAA8B,sCAChC,EAEM,EAAiB,CACrB,WAAY,EACZ,QAAS,IACJ,EACH,kCAAmC,sCACrC,CACF,EAEa,EAAe,CAC1B,EACA,IACc,CACd,IAAM,EACJ,GAAU,KAAU,EAChB,EAAe,GACf,EAAe,QAGrB,QAAW,KAAO,OAAO,KAAK,CAAM,EAClC,GAAI,IAAa,GACf,EAAO,GAA0B,EAAW,GAIhD,OAAO,GC3FF,IAAM,EAAa,IAAM,CAC9B,IAAM,EAAW,EAAY,EAAU,EAAG,QAAQ,GAAG,EAC/C,EAAY,EAAa,EAAU,CAAC,EAE1C,QAAY,EAAK,KAAU,OAAO,QAAQ,IAAK,KAAa,CAAU,CAAC,EAAG,CACxE,GAAI,QAAQ,IAAI,GACd,SAGF,QAAQ,IAAI,GAAO",
10
+ "debugId": "29479D07BEA8166A64756E2164756E21",
11
+ "names": []
12
+ }
@@ -0,0 +1,35 @@
1
+ type SlackIds = {
2
+ -readonly [k in keyof typeof slackProductionChannels]: string;
3
+ };
4
+ type NotionIds = {
5
+ -readonly [k in keyof typeof notionProductionChannels]: string;
6
+ };
7
+ declare const slackProductionChannels: {
8
+ readonly SLACK_DEFAULT_CHANNEL_ID: "C0679V8KGSH";
9
+ readonly SLACK_RESERVATIONS_CHANNEL_ID: "C01G8B12G67";
10
+ readonly SLACK_FBC_CHANNEL: "C01L1AAKB3N";
11
+ readonly SLACK_BD_CHANNEL: "CN21PGKK8";
12
+ readonly SLACK_MAIN_FLUX_CHANNEL: "GHDPV1858";
13
+ readonly SLACK_INQUIRIES_CHANNEL_ID: "C067CSK5J5Q";
14
+ readonly SLACK_INVOICE_FAILURES_CHANNEL_ID: "C067CPUMB8T";
15
+ readonly SLACK_SST_CHANNEL_ID: "C068NH60A78";
16
+ readonly SLACK_ERROR_CHANNEL_ID: "C04N4Q7HA79";
17
+ readonly SLACK_ISSUES_CHANNEL_ID: "C0680P99AE8";
18
+ readonly SLACK_COMING_SERVICES_CHANNEL_ID: "C06SB20H2J1";
19
+ readonly SLACK_ESMS_CHANNEL_ID: "C07RPEP2BMY";
20
+ readonly SLACK_EXCESS_MILEAGE_CHANNEL_ID: "C0679URBY93";
21
+ readonly SLACK_ENGINEERING_REQUESTS_CHANNEL: "C01U8GTK3K9";
22
+ };
23
+ export declare const getSlackIds: (appEnv?: string, processEnv?: Record<string, string | undefined>) => SlackIds;
24
+ declare const notionProductionChannels: {
25
+ readonly NOTION_REQUEST_DATABASE_ID: "32332c0e-4277-43fa-b10e-7d458234f9ea";
26
+ readonly NOTION_REVIEWS_DATABASE_ID: "8a8b0df9-567d-433f-8937-583db2766176";
27
+ readonly NOTION_FBC_DATABASE_ID: "76960d4b-2b43-4019-a77e-ac46a0b3d752";
28
+ readonly NOTION_FLUXSTERS_DATABASE_ID: "4ea6953a-61c2-4673-8950-c0d0e158de0a";
29
+ readonly NOTION_BD_DATABASE_ID: "172a9182-56c0-4358-b4f1-7e8fcfa44e46";
30
+ readonly NOTION_BRANDS_LANDING_PAGES_DATABASE_ID: "e321d71a-0d29-42da-ab0b-dca2260b643e";
31
+ readonly NOTION_KNOWLEDGE_BASE_DATABASE_ID: "7a81653f-4351-4a17-aa1e-c3082c378441";
32
+ readonly NOTION_REFERRALS_DATABASE_ID: "b5599d70-b414-4aa9-9ff2-d445c8f3f0fc";
33
+ };
34
+ export declare const getNotionIds: (appEnv?: string, processEnv?: Record<string, string>) => NotionIds;
35
+ export {};
@@ -0,0 +1,5 @@
1
+ import{createRequire as k}from"node:module";var g=Object.create;var{getPrototypeOf:h,defineProperty:e,getOwnPropertyNames:i}=Object;var j=Object.prototype.hasOwnProperty;var l=(a,f,b)=>{b=a!=null?g(h(a)):{};let c=f||!a||!a.__esModule?e(b,"default",{value:a,enumerable:!0}):b;for(let d of i(a))if(!j.call(c,d))e(c,d,{get:()=>a[d],enumerable:!0});return c};var n=k(import.meta.url);
2
+ export{l as c,n as d};
3
+
4
+ //# debugId=695D25ED1EB2189864756E2164756E21
5
+ //# sourceMappingURL=chunk-32b1dzdk.js.map
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [
5
+ ],
6
+ "mappings": "",
7
+ "debugId": "695D25ED1EB2189864756E2164756E21",
8
+ "names": []
9
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Dealing with env variables can be complicated. So we need to simplify the process
3
+ *
4
+ * Bun automatically loads a .env (or .env.[NODE_ENV]) file which will be detected
5
+ * here as system set env variables and dotenvx won't work properly with USE_ENV.
6
+ *
7
+ * The way to fix this behaviour is to know how to separate between env set from the shell
8
+ * and env loaded by bun.
9
+ *
10
+ * 1. Check the env loaded by bun according to its logic (load using NODE_ENV)
11
+ * 2. If USE_ENV !== NODE_ENV, load those variables
12
+ * 3. For each env loaded automatically by bun, we override the process env with the values from the loaded env.$USE_ENv files
13
+ */
14
+ export declare const initEnv: () => Promise<void>;
@@ -0,0 +1,5 @@
1
+ import"./chunk-32b1dzdk.js";import B from"@dotenvx/dotenvx";var D=async()=>{if(!process.env.USE_ENV)process.env.USE_ENV="development";let q="development",z={};if(B.config({convention:"nextjs",ignore:["MISSING_ENV_FILE"],path:[`.env.${q}.local`,`.env.${q}`,".env.local",".env"],processEnv:z,logLevel:"error"}),process.env.USE_ENV!=="development"){let A={};B.config({convention:"nextjs",ignore:["MISSING_ENV_FILE"],override:!0,path:[`.env.${process.env.USE_ENV}.local`,`.env.${process.env.USE_ENV}`],logLevel:"info",processEnv:A});for(let[j,p]of Object.entries(A)){if(!process.env[j])process.env[j]=p;if(z[j]!==p)process.env[j]=p}}};export{D as initEnv};
2
+ export{D as a};
3
+
4
+ //# debugId=FD4DA440543A58B464756E2164756E21
5
+ //# sourceMappingURL=init-env.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/init-env.ts"],
4
+ "sourcesContent": [
5
+ "import dotenv from '@dotenvx/dotenvx'\n\n/**\n * Dealing with env variables can be complicated. So we need to simplify the process\n *\n * Bun automatically loads a .env (or .env.[NODE_ENV]) file which will be detected\n * here as system set env variables and dotenvx won't work properly with USE_ENV.\n *\n * The way to fix this behaviour is to know how to separate between env set from the shell\n * and env loaded by bun.\n *\n * 1. Check the env loaded by bun according to its logic (load using NODE_ENV)\n * 2. If USE_ENV !== NODE_ENV, load those variables\n * 3. For each env loaded automatically by bun, we override the process env with the values from the loaded env.$USE_ENv files\n */\nexport const initEnv = async () => {\n if (!process.env.USE_ENV) {\n if (process.env.NODE_ENV && process.env.NODE_ENV !== 'development') {\n return\n }\n\n process.env.USE_ENV = process.env.NODE_ENV || 'development'\n }\n\n // By default bun will load the .env files, so for example, if NODE_ENV=production,\n // it will load the .env.production file even if we're in the staging env (USE_ENV=staging)\n // so we need to override that behaviour\n const nodeEnv = process.env.NODE_ENV || 'development'\n\n // For these, we won't need to load them into the env because bun did\n // however, we record them to override them in case USE_ENV is different from NODE_ENV\n const bunLoadedEnv: Record<string, string> = {}\n dotenv.config({\n convention: 'nextjs',\n ignore: ['MISSING_ENV_FILE'],\n path: [`.env.${nodeEnv}.local`, `.env.${nodeEnv}`, '.env.local', '.env'],\n processEnv: bunLoadedEnv,\n logLevel: 'error',\n })\n\n // If USE_ENV is different from NODE_ENV, we need to load the .env.${USE_ENV} file and override\n // bun's loaded env from the files\n if (process.env.USE_ENV !== process.env.NODE_ENV) {\n // Load the .env files initially\n const useEnvLoadedEnv: Record<string, string> = {}\n dotenv.config({\n convention: 'nextjs',\n ignore: ['MISSING_ENV_FILE'],\n override: true,\n path: [\n `.env.${process.env.USE_ENV}.local`,\n `.env.${process.env.USE_ENV}`,\n ],\n logLevel: 'info',\n processEnv: useEnvLoadedEnv,\n })\n\n for (const [key, value] of Object.entries(useEnvLoadedEnv)) {\n // No process env found, just set it\n if (!process.env[key]) {\n process.env[key] = value\n }\n\n if (bunLoadedEnv[key] !== value) {\n // Now we set the value in the process env to override bun's loaded env\n process.env[key] = value\n }\n\n // Here we do nothing because the env was set from the shell\n }\n }\n}\n"
6
+ ],
7
+ "mappings": "4BAAA,gCAeO,IAAM,EAAU,SAAY,CACjC,GAAI,CAAC,QAAQ,IAAI,QAKf,QAAQ,IAAI,QAAU,cAMxB,IAAM,EAAU,cAIV,EAAuC,CAAC,EAW9C,GAVA,EAAO,OAAO,CACZ,WAAY,SACZ,OAAQ,CAAC,kBAAkB,EAC3B,KAAM,CAAC,QAAQ,UAAiB,QAAQ,IAAW,aAAc,MAAM,EACvE,WAAY,EACZ,SAAU,OACZ,CAAC,EAIG,QAAQ,IAAI,UAAY,cAAsB,CAEhD,IAAM,EAA0C,CAAC,EACjD,EAAO,OAAO,CACZ,WAAY,SACZ,OAAQ,CAAC,kBAAkB,EAC3B,SAAU,GACV,KAAM,CACJ,QAAQ,QAAQ,IAAI,gBACpB,QAAQ,QAAQ,IAAI,SACtB,EACA,SAAU,OACV,WAAY,CACd,CAAC,EAED,QAAY,EAAK,KAAU,OAAO,QAAQ,CAAe,EAAG,CAE1D,GAAI,CAAC,QAAQ,IAAI,GACf,QAAQ,IAAI,GAAO,EAGrB,GAAI,EAAa,KAAS,EAExB,QAAQ,IAAI,GAAO",
8
+ "debugId": "FD4DA440543A58B464756E2164756E21",
9
+ "names": []
10
+ }
package/dist/main.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dist/main.js ADDED
@@ -0,0 +1,4 @@
1
+ import{a as A}from"./init-env.js";import{b as z}from"./augment-env.js";import{c as C,d as x}from"./chunk-32b1dzdk.js";await A().catch((k)=>{console.error("Error initializing environment:",k),process.exit(1)});z();if(x.main==x.module){let k=process.argv.slice(2);if(!k.length)console.error("No arguments provided"),process.exit(1);let{spawn:B}=await import("node:child_process"),y=k.shift();if(!y)console.error("No binary to run provided"),process.exit(1);B(y,k,{stdio:"inherit",shell:!0,env:process.env})}
2
+
3
+ //# debugId=D4E9ADD2CBDB487064756E2164756E21
4
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/main.ts"],
4
+ "sourcesContent": [
5
+ "import { augmentEnv } from './augment-env'\nimport { initEnv } from './init-env'\n\n// Init the env\nawait initEnv().catch((error: Error) => {\n console.error('Error initializing environment:', error)\n process.exit(1)\n})\n\n// Augment the env with the base configs\naugmentEnv()\n\nif (import.meta.main) {\n // When this file is called as the main, it is supposed to load the env\n // and set it in the shell calling the rest of the script from argv\n // as if it's just a pre-script to load env variables\n\n const args = process.argv.slice(2)\n if (!args.length) {\n console.error('No arguments provided')\n process.exit(1)\n }\n\n const { spawn } = await import('node:child_process')\n const binToRunRun = args.shift()\n if (!binToRunRun) {\n console.error('No binary to run provided')\n process.exit(1)\n }\n spawn(binToRunRun, args, {\n stdio: 'inherit',\n shell: true,\n env: process.env,\n })\n}\n"
6
+ ],
7
+ "mappings": "qIAIA,HAAM,JAAQ,EAAE,MAAM,CAAC,IAAiB,CACtC,QAAQ,MAAM,kCAAmC,CAAK,EACtD,QAAQ,KAAK,CAAC,EACf,EAGD,EAAW,EAEX,GAAI,iBAAkB,CAKpB,IAAM,EAAO,QAAQ,KAAK,MAAM,CAAC,EACjC,GAAI,CAAC,EAAK,OACR,QAAQ,MAAM,uBAAuB,EACrC,QAAQ,KAAK,CAAC,EAGhB,IAAQ,SAAU,KAAa,8BACzB,EAAc,EAAK,MAAM,EAC/B,GAAI,CAAC,EACH,QAAQ,MAAM,2BAA2B,EACzC,QAAQ,KAAK,CAAC,EAEhB,EAAM,EAAa,EAAM,CACvB,MAAO,UACP,MAAO,GACP,IAAK,QAAQ,GACf,CAAC",
8
+ "debugId": "D4E9ADD2CBDB487064756E2164756E21",
9
+ "names": []
10
+ }
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@driveflux/env",
3
+ "version": "0.0.2-develop.0",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "import": "./dist/main.js",
8
+ "types": "./dist/main.d.ts"
9
+ },
10
+ "./init-env": {
11
+ "import": "./dist/init-env.js",
12
+ "types": "./dist/init-env.d.ts"
13
+ },
14
+ "./augment-env": {
15
+ "import": "./dist/augment-env.js",
16
+ "types": "./dist/augment-env.d.ts"
17
+ }
18
+ },
19
+ "scripts": {
20
+ "build": "bun run ./build.ts",
21
+ "build:all": "bun tsc --emitDeclarationOnly && bun run ./build.ts"
22
+ },
23
+ "dependencies": {},
24
+ "devDependencies": {
25
+ "@types/bun": "^1.3",
26
+ "typescript": "5.9.3",
27
+ "@driveflux/fix-builds": "0.0.2-develop.12"
28
+ }
29
+ }
package/src/app-env.ts ADDED
@@ -0,0 +1,21 @@
1
+ export const getAppEnv = () => {
2
+ if (process.env.APP_ENV) {
3
+ return process.env.APP_ENV
4
+ }
5
+
6
+ // If USE_ENV is set, use it
7
+ if (process.env.USE_ENV) {
8
+ return process.env.USE_ENV
9
+ }
10
+
11
+ // If NODE_ENV is set, use it
12
+ if (process.env.NODE_ENV) {
13
+ return process.env.NODE_ENV
14
+ }
15
+
16
+ // Default to development as a last resort
17
+ return 'development'
18
+ }
19
+
20
+ const isAppEnv = (env: string) => getAppEnv() === env
21
+ export const isProd = () => isAppEnv('production')
@@ -0,0 +1,15 @@
1
+ import { getAppEnv } from './app-env'
2
+ import { getNotionIds, getSlackIds } from './base-configs'
3
+
4
+ export const augmentEnv = () => {
5
+ const slackIds = getSlackIds(getAppEnv(), process.env)
6
+ const notionIds = getNotionIds(getAppEnv())
7
+
8
+ for (const [key, value] of Object.entries({ ...slackIds, ...notionIds })) {
9
+ if (process.env[key]) {
10
+ continue
11
+ }
12
+
13
+ process.env[key] = value
14
+ }
15
+ }
@@ -0,0 +1,96 @@
1
+ type SlackIds = {
2
+ -readonly [k in keyof typeof slackProductionChannels]: string
3
+ }
4
+ type NotionIds = {
5
+ -readonly [k in keyof typeof notionProductionChannels]: string
6
+ }
7
+
8
+ const slackProductionChannels = {
9
+ SLACK_DEFAULT_CHANNEL_ID: 'C0679V8KGSH',
10
+ SLACK_RESERVATIONS_CHANNEL_ID: 'C01G8B12G67',
11
+ SLACK_FBC_CHANNEL: 'C01L1AAKB3N',
12
+ SLACK_BD_CHANNEL: 'CN21PGKK8',
13
+ SLACK_MAIN_FLUX_CHANNEL: 'GHDPV1858',
14
+ SLACK_INQUIRIES_CHANNEL_ID: 'C067CSK5J5Q',
15
+ SLACK_INVOICE_FAILURES_CHANNEL_ID: 'C067CPUMB8T',
16
+ SLACK_SST_CHANNEL_ID: 'C068NH60A78',
17
+ SLACK_ERROR_CHANNEL_ID: 'C04N4Q7HA79',
18
+ SLACK_ISSUES_CHANNEL_ID: 'C0680P99AE8',
19
+ SLACK_COMING_SERVICES_CHANNEL_ID: 'C06SB20H2J1',
20
+ SLACK_ESMS_CHANNEL_ID: 'C07RPEP2BMY',
21
+ SLACK_EXCESS_MILEAGE_CHANNEL_ID: 'C0679URBY93',
22
+ SLACK_ENGINEERING_REQUESTS_CHANNEL: 'C01U8GTK3K9',
23
+ } as const
24
+
25
+ const getSlackIdsMap = (processEnv?: Record<string, string | undefined>) =>
26
+ ({
27
+ production: slackProductionChannels,
28
+ staging: Object.keys(slackProductionChannels).reduce((acc, key) => {
29
+ acc[key as keyof SlackIds] = 'C0661UNMBQU' // #platform-staging-notifications
30
+ return acc
31
+ }, {} as SlackIds),
32
+ development: Object.keys(slackProductionChannels).reduce((acc, key) => {
33
+ acc[key as keyof SlackIds] =
34
+ processEnv?.SLACK_MY_CHANNEL_ID || 'C09GJ4FJVRS' // #platform-dev-notifications
35
+ return acc
36
+ }, {} as SlackIds),
37
+ }) as const satisfies Record<string, SlackIds>
38
+
39
+ export const getSlackIds = (
40
+ appEnv?: string,
41
+ processEnv?: Record<string, string | undefined>,
42
+ ): SlackIds => {
43
+ const slackIdsMap = getSlackIdsMap(processEnv)
44
+ const envIds: SlackIds =
45
+ appEnv && appEnv in slackIdsMap
46
+ ? slackIdsMap[appEnv as keyof typeof slackIdsMap]
47
+ : slackIdsMap.staging
48
+
49
+ // Override the values from ENV if available
50
+ for (const key of Object.keys(envIds)) {
51
+ if (processEnv?.[key]) {
52
+ envIds[key as keyof SlackIds] = processEnv[key] as string
53
+ }
54
+ }
55
+
56
+ return envIds
57
+ }
58
+
59
+ const notionProductionChannels = {
60
+ NOTION_REQUEST_DATABASE_ID: '32332c0e-4277-43fa-b10e-7d458234f9ea',
61
+ NOTION_REVIEWS_DATABASE_ID: '8a8b0df9-567d-433f-8937-583db2766176', // Seems to be unused
62
+ NOTION_FBC_DATABASE_ID: '76960d4b-2b43-4019-a77e-ac46a0b3d752', // Seems to be unused
63
+ NOTION_FLUXSTERS_DATABASE_ID: '4ea6953a-61c2-4673-8950-c0d0e158de0a',
64
+ NOTION_BD_DATABASE_ID: '172a9182-56c0-4358-b4f1-7e8fcfa44e46',
65
+ NOTION_BRANDS_LANDING_PAGES_DATABASE_ID:
66
+ 'e321d71a-0d29-42da-ab0b-dca2260b643e',
67
+ NOTION_KNOWLEDGE_BASE_DATABASE_ID: '7a81653f-4351-4a17-aa1e-c3082c378441',
68
+ NOTION_REFERRALS_DATABASE_ID: 'b5599d70-b414-4aa9-9ff2-d445c8f3f0fc',
69
+ } as const satisfies Record<string, string>
70
+
71
+ const NOTION_IDS_MAP = {
72
+ production: notionProductionChannels,
73
+ staging: {
74
+ ...notionProductionChannels,
75
+ NOTION_KNOWLEDGE_BASE_DATABASE_ID: 'f95b9986-c1c9-46ca-a742-d49f3f80d7dd',
76
+ },
77
+ } as const satisfies Record<string, NotionIds>
78
+
79
+ export const getNotionIds = (
80
+ appEnv?: string,
81
+ processEnv?: Record<string, string>,
82
+ ): NotionIds => {
83
+ const envIds: NotionIds =
84
+ appEnv && appEnv in NOTION_IDS_MAP
85
+ ? NOTION_IDS_MAP[appEnv as keyof typeof NOTION_IDS_MAP]
86
+ : NOTION_IDS_MAP.staging
87
+
88
+ // Override the values from ENV if available
89
+ for (const key of Object.keys(envIds)) {
90
+ if (processEnv?.[key]) {
91
+ envIds[key as keyof NotionIds] = processEnv[key] as string
92
+ }
93
+ }
94
+
95
+ return envIds
96
+ }
@@ -0,0 +1,72 @@
1
+ import dotenv from '@dotenvx/dotenvx'
2
+
3
+ /**
4
+ * Dealing with env variables can be complicated. So we need to simplify the process
5
+ *
6
+ * Bun automatically loads a .env (or .env.[NODE_ENV]) file which will be detected
7
+ * here as system set env variables and dotenvx won't work properly with USE_ENV.
8
+ *
9
+ * The way to fix this behaviour is to know how to separate between env set from the shell
10
+ * and env loaded by bun.
11
+ *
12
+ * 1. Check the env loaded by bun according to its logic (load using NODE_ENV)
13
+ * 2. If USE_ENV !== NODE_ENV, load those variables
14
+ * 3. For each env loaded automatically by bun, we override the process env with the values from the loaded env.$USE_ENv files
15
+ */
16
+ export const initEnv = async () => {
17
+ if (!process.env.USE_ENV) {
18
+ if (process.env.NODE_ENV && process.env.NODE_ENV !== 'development') {
19
+ return
20
+ }
21
+
22
+ process.env.USE_ENV = process.env.NODE_ENV || 'development'
23
+ }
24
+
25
+ // By default bun will load the .env files, so for example, if NODE_ENV=production,
26
+ // it will load the .env.production file even if we're in the staging env (USE_ENV=staging)
27
+ // so we need to override that behaviour
28
+ const nodeEnv = process.env.NODE_ENV || 'development'
29
+
30
+ // For these, we won't need to load them into the env because bun did
31
+ // however, we record them to override them in case USE_ENV is different from NODE_ENV
32
+ const bunLoadedEnv: Record<string, string> = {}
33
+ dotenv.config({
34
+ convention: 'nextjs',
35
+ ignore: ['MISSING_ENV_FILE'],
36
+ path: [`.env.${nodeEnv}.local`, `.env.${nodeEnv}`, '.env.local', '.env'],
37
+ processEnv: bunLoadedEnv,
38
+ logLevel: 'error',
39
+ })
40
+
41
+ // If USE_ENV is different from NODE_ENV, we need to load the .env.${USE_ENV} file and override
42
+ // bun's loaded env from the files
43
+ if (process.env.USE_ENV !== process.env.NODE_ENV) {
44
+ // Load the .env files initially
45
+ const useEnvLoadedEnv: Record<string, string> = {}
46
+ dotenv.config({
47
+ convention: 'nextjs',
48
+ ignore: ['MISSING_ENV_FILE'],
49
+ override: true,
50
+ path: [
51
+ `.env.${process.env.USE_ENV}.local`,
52
+ `.env.${process.env.USE_ENV}`,
53
+ ],
54
+ logLevel: 'info',
55
+ processEnv: useEnvLoadedEnv,
56
+ })
57
+
58
+ for (const [key, value] of Object.entries(useEnvLoadedEnv)) {
59
+ // No process env found, just set it
60
+ if (!process.env[key]) {
61
+ process.env[key] = value
62
+ }
63
+
64
+ if (bunLoadedEnv[key] !== value) {
65
+ // Now we set the value in the process env to override bun's loaded env
66
+ process.env[key] = value
67
+ }
68
+
69
+ // Here we do nothing because the env was set from the shell
70
+ }
71
+ }
72
+ }
package/src/main.ts ADDED
@@ -0,0 +1,35 @@
1
+ import { augmentEnv } from './augment-env'
2
+ import { initEnv } from './init-env'
3
+
4
+ // Init the env
5
+ await initEnv().catch((error: Error) => {
6
+ console.error('Error initializing environment:', error)
7
+ process.exit(1)
8
+ })
9
+
10
+ // Augment the env with the base configs
11
+ augmentEnv()
12
+
13
+ if (import.meta.main) {
14
+ // When this file is called as the main, it is supposed to load the env
15
+ // and set it in the shell calling the rest of the script from argv
16
+ // as if it's just a pre-script to load env variables
17
+
18
+ const args = process.argv.slice(2)
19
+ if (!args.length) {
20
+ console.error('No arguments provided')
21
+ process.exit(1)
22
+ }
23
+
24
+ const { spawn } = await import('node:child_process')
25
+ const binToRunRun = args.shift()
26
+ if (!binToRunRun) {
27
+ console.error('No binary to run provided')
28
+ process.exit(1)
29
+ }
30
+ spawn(binToRunRun, args, {
31
+ stdio: 'inherit',
32
+ shell: true,
33
+ env: process.env,
34
+ })
35
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src",
6
+ "composite": true,
7
+ "incremental": true
8
+ },
9
+ "include": ["./src/**/*.ts"],
10
+ "references": [
11
+ {
12
+ "path": "../fix-builds"
13
+ }
14
+ ]
15
+ }