UNPKG

everything-dev

Version:

A consolidated product package for building Module Federation apps with oRPC APIs.

1 lines • 5.83 kB
{"version":3,"file":"materializer.cjs","names":["Context","dirname","existsSync","readFileSync","Effect","InfraError","getSecretGroups","join","renderEnvFile","renderEnvTestFile","Layer"],"sources":["../../src/infra/materializer.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { Context, Effect, Layer } from \"effect\";\nimport { getSecretGroups, renderEnvFile, renderEnvTestFile } from \"../cli/infra\";\nimport type { RuntimeConfig } from \"../types\";\nimport { InfraError, type InfraPhase } from \"./types\";\n\nexport interface InfraMaterializerShape {\n readonly materializeTemplate: (\n configDir: string,\n runtimeConfig: RuntimeConfig,\n ) => Effect.Effect<void, InfraError>;\n readonly materializeTestInfra: (\n configDir: string,\n runtimeConfig: RuntimeConfig,\n ) => Effect.Effect<void, InfraError>;\n}\n\nexport class InfraMaterializer extends Context.Service<InfraMaterializer, InfraMaterializerShape>()(\n \"InfraMaterializer\",\n) {}\n\nfunction ensureDir(filePath: string): void {\n mkdirSync(dirname(filePath), { recursive: true });\n}\n\nfunction writeIfChanged(filePath: string, content: string): void {\n if (existsSync(filePath) && readFileSync(filePath, \"utf-8\") === content) return;\n ensureDir(filePath);\n writeFileSync(filePath, content);\n}\n\nfunction writeContentEffect(\n filePath: string,\n content: string,\n phase: InfraPhase,\n): Effect.Effect<void, InfraError> {\n return Effect.try({\n try: () => writeIfChanged(filePath, content),\n catch: (cause) =>\n new InfraError({\n phase,\n message: `failed to write ${filePath}`,\n cause,\n }),\n });\n}\n\nconst makeMaterializer = (): InfraMaterializerShape => ({\n materializeTemplate: (configDir, runtimeConfig) =>\n Effect.gen(function* () {\n const groups = getSecretGroups(runtimeConfig);\n const filePath = join(configDir, \".env.example\");\n const content = renderEnvFile(groups, { forExample: true });\n yield* writeContentEffect(filePath, content, \"materialize-env\");\n }),\n\n materializeTestInfra: (configDir, runtimeConfig) =>\n Effect.gen(function* () {\n const groups = getSecretGroups(runtimeConfig);\n const filePath = join(configDir, \".env.test\");\n const content = renderEnvTestFile(groups);\n yield* writeContentEffect(filePath, content, \"materialize-env\");\n }),\n});\n\nexport const InfraMaterializerLive: Layer.Layer<InfraMaterializer> = Layer.succeed(\n InfraMaterializer,\n makeMaterializer(),\n);\n\n/**\n * Single source of truth for \"should we persist port state?\".\n * Lives next to the only thing that still persists dev ports (the planner).\n */\nexport function shouldPersistPortState(): boolean {\n return (\n process.env.BOS_NO_PERSIST_PORTS !== \"1\" &&\n process.env.BOS_TEST !== \"1\" &&\n process.env.NODE_ENV !== \"test\"\n );\n}\n\n/**\n * True when the run is ephemeral (regression, CI, local test).\n * In ephemeral mode we must not rewrite `.env.example` because it's a\n * committed reference template — every regression run was previously\n * baking the resolved regression port into it, polluting the file.\n */\nexport function isEphemeralRun(): boolean {\n return (\n process.env.BOS_NO_PERSIST_PORTS === \"1\" ||\n process.env.BOS_TEST === \"1\" ||\n process.env.NODE_ENV === \"test\"\n );\n}\n\nexport interface MaterializeOptions {\n /**\n * Override the ephemeral detection. Defaults to the env-var check.\n * Pass `ephemeral: false` to force-template-write, e.g. for opt-in\n * smoke runs that explicitly want a deterministic template.\n */\n readonly ephemeral?: boolean;\n}\n\n/**\n * Orchestration helper: materializes the env templates in the canonical\n * order. docker-compose.yml is a static committed file — nothing here\n * generates or rewrites it.\n */\nexport async function materializeViaLayer(\n configDir: string,\n runtimeConfig: RuntimeConfig,\n options: MaterializeOptions = {},\n): Promise<void> {\n const ephemeral = options.ephemeral ?? isEphemeralRun();\n await Effect.runPromise(\n Effect.gen(function* () {\n const m = yield* InfraMaterializer;\n if (!ephemeral) {\n yield* m.materializeTemplate(configDir, runtimeConfig);\n }\n yield* m.materializeTestInfra(configDir, runtimeConfig);\n }).pipe(Effect.provide(InfraMaterializerLive)),\n );\n}\n"],"mappings":";;;;;;;AAkBA,IAAa,oBAAb,cAAuCA,eAAQ,QAAmD,CAAC,CACjG,mBACF,CAAC,CAAC,CAAC;AAEH,SAAS,UAAU,UAAwB;CACzC,2BAAUC,mBAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAClD;AAEA,SAAS,eAAe,UAAkB,SAAuB;CAC/D,QAAIC,oBAAW,QAAQ,SAAKC,sBAAa,UAAU,OAAO,MAAM,SAAS;CACzE,UAAU,QAAQ;CAClB,2BAAc,UAAU,OAAO;AACjC;AAEA,SAAS,mBACP,UACA,SACA,OACiC;CACjC,OAAOC,cAAO,IAAI;EAChB,WAAW,eAAe,UAAU,OAAO;EAC3C,QAAQ,UACN,IAAIC,yBAAW;GACb;GACA,SAAS,mBAAmB;GAC5B;EACF,CAAC;CACL,CAAC;AACH;AAEA,MAAM,0BAAkD;CACtD,sBAAsB,WAAW,kBAC/BD,cAAO,IAAI,aAAa;EACtB,MAAM,SAASE,8BAAgB,aAAa;EAG5C,OAAO,uBAFUC,gBAAK,WAAW,cAEA,GADjBC,4BAAc,QAAQ,EAAE,YAAY,KAAK,CACf,GAAG,iBAAiB;CAChE,CAAC;CAEH,uBAAuB,WAAW,kBAChCJ,cAAO,IAAI,aAAa;EACtB,MAAM,SAASE,8BAAgB,aAAa;EAG5C,OAAO,uBAFUC,gBAAK,WAAW,WAEA,GADjBE,gCAAkB,MACQ,GAAG,iBAAiB;CAChE,CAAC;AACL;AAEA,MAAa,wBAAwDC,aAAM,QACzE,mBACA,iBAAiB,CACnB;;;;;AAMA,SAAgB,yBAAkC;CAChD,OACE,QAAQ,IAAI,yBAAyB,OACrC,QAAQ,IAAI,aAAa,OACzB,QAAQ,IAAI,aAAa;AAE7B;;;;;;;AAQA,SAAgB,iBAA0B;CACxC,OACE,QAAQ,IAAI,yBAAyB,OACrC,QAAQ,IAAI,aAAa,OACzB,QAAQ,IAAI,aAAa;AAE7B;;;;;;AAgBA,eAAsB,oBACpB,WACA,eACA,UAA8B,CAAC,GAChB;CACf,MAAM,YAAY,QAAQ,aAAa,eAAe;CACtD,MAAMN,cAAO,WACXA,cAAO,IAAI,aAAa;EACtB,MAAM,IAAI,OAAO;EACjB,IAAI,CAAC,WACH,OAAO,EAAE,oBAAoB,WAAW,aAAa;EAEvD,OAAO,EAAE,qBAAqB,WAAW,aAAa;CACxD,CAAC,CAAC,CAAC,KAAKA,cAAO,QAAQ,qBAAqB,CAAC,CAC/C;AACF"}