@ankhorage/infra 7.1.1 → 7.1.3

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.
Files changed (40) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cli/commands/up.d.ts.map +1 -1
  3. package/dist/cli/commands/up.js +1 -0
  4. package/dist/cli/commands/up.js.map +1 -1
  5. package/dist/cli/runInfraCliAsync.d.ts.map +1 -1
  6. package/dist/cli/runInfraCliAsync.js +8 -6
  7. package/dist/cli/runInfraCliAsync.js.map +1 -1
  8. package/dist/constants.d.ts +1 -0
  9. package/dist/constants.d.ts.map +1 -1
  10. package/dist/constants.js +1 -0
  11. package/dist/constants.js.map +1 -1
  12. package/dist/features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.d.ts +5 -0
  13. package/dist/features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.d.ts.map +1 -0
  14. package/dist/features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.js +70 -0
  15. package/dist/features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.js.map +1 -0
  16. package/dist/features/environment-lifecycle/composition/createInfraCommandServices.d.ts.map +1 -1
  17. package/dist/features/environment-lifecycle/composition/createInfraCommandServices.js +2 -0
  18. package/dist/features/environment-lifecycle/composition/createInfraCommandServices.js.map +1 -1
  19. package/dist/features/environment-lifecycle/composition/createProjectInfraLifecycle.d.ts.map +1 -1
  20. package/dist/features/environment-lifecycle/composition/createProjectInfraLifecycle.js +1 -0
  21. package/dist/features/environment-lifecycle/composition/createProjectInfraLifecycle.js.map +1 -1
  22. package/dist/types/infraCli.d.ts +2 -0
  23. package/dist/types/infraCli.d.ts.map +1 -1
  24. package/dist/types/infraCli.js.map +1 -1
  25. package/package.json +3 -3
  26. package/src/cli/cli.test.ts +21 -5
  27. package/src/cli/commands/up.ts +5 -0
  28. package/src/cli/runInfraCliAsync.ts +11 -7
  29. package/src/commands.test.ts +8 -2
  30. package/src/constants.ts +1 -0
  31. package/src/features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.ts +84 -0
  32. package/src/features/environment-lifecycle/composition/createInfraCommandServices.ts +3 -0
  33. package/src/features/environment-lifecycle/composition/createProjectInfraLifecycle.ts +5 -0
  34. package/src/projectEnvironmentOutputs.test.ts +225 -0
  35. package/src/types/infraCli.ts +2 -0
  36. package/dist/cli/renderInfraRootHelp.d.ts +0 -3
  37. package/dist/cli/renderInfraRootHelp.d.ts.map +0 -1
  38. package/dist/cli/renderInfraRootHelp.js +0 -21
  39. package/dist/cli/renderInfraRootHelp.js.map +0 -1
  40. package/src/cli/renderInfraRootHelp.ts +0 -23
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @ankhorage/infra
2
2
 
3
+ ## 7.1.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 2da5618: Materialize public local Infra outputs that declare environment-variable names into the generated app `.env.local`, preserving unrelated entries while keeping secret outputs as references.
8
+
9
+ ## 7.1.2
10
+
11
+ ### Patch Changes
12
+
13
+ - e707284: Render standalone Infra help from the canonical provider manifest through the shared Ankh CLI help runtime.
14
+
3
15
  ## 7.1.1
4
16
 
5
17
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"up.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/up.ts"],"names":[],"mappings":"AAMA,kEAAkE;AAClE,eAAO,MAAM,EAAE;;;;;;;;CAqB4B,CAAC"}
1
+ {"version":3,"file":"up.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/up.ts"],"names":[],"mappings":"AAMA,kEAAkE;AAClE,eAAO,MAAM,EAAE;;;;;;;;CA0B4B,CAAC"}
@@ -17,6 +17,7 @@ export const up = {
17
17
  desired: operation.desired,
18
18
  ledger: result.value.ledger,
19
19
  });
20
+ await services.writeEnvironmentOutputs(operation.project.projectPath, result.value.environment, result.value.outputs);
20
21
  writeInfraStructured(request.context, request.arguments.format, {
21
22
  environment: result.value.environment,
22
23
  resources: result.value.resources.length,
@@ -1 +1 @@
1
- {"version":3,"file":"up.js","sourceRoot":"","sources":["../../../src/cli/commands/up.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EAAE,iCAAiC,EAAE,MAAM,+CAA+C,CAAC;AAClG,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAExE,kEAAkE;AAClE,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,cAAc,EAAE,IAAI;IACpB,IAAI,EAAE,CAAC,IAAI,CAAC;IACZ,UAAU,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACjC,OAAO,EAAE,6DAA6D;IACtE,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ;QACzB,MAAM,SAAS,GAAG,MAAM,iCAAiC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC7E,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;QACzF,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7C,MAAM,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE;YACvD,aAAa,EAAE,CAAC;YAChB,OAAO,EAAE,SAAS,CAAC,OAAO;YAC1B,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;SAC5B,CAAC,CAAC;QACH,oBAAoB,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE;YAC9D,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW;YACrC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM;YACxC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO;SAC9B,CAAC,CAAC;QACH,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACzB,CAAC;CACwC,CAAC","sourcesContent":["import { INFRA_CAPABILITIES } from '../../constants.js';\nimport type { InfraCommandDefinition } from '../../types/infraCli.js';\nimport { prepareInfraCommandOperationAsync } from '../utils/prepareInfraCommandOperationAsync.js';\nimport { requireInfraSuccess } from '../utils/requireInfraSuccess.js';\nimport { writeInfraStructured } from '../utils/writeInfraStructured.js';\n\n/*** Define idempotent environment creation and reconciliation. */\nexport const up = {\n standaloneName: 'up',\n path: ['up'],\n capability: INFRA_CAPABILITIES[3],\n summary: 'Idempotently ensure and reconcile the selected environment.',\n async run(request, services) {\n const operation = await prepareInfraCommandOperationAsync(request, services);\n const result = await services.operations.up(operation.operation, operation.dependencies);\n requireInfraSuccess(result, request.context);\n await services.writeState(operation.project.projectPath, {\n schemaVersion: 1,\n desired: operation.desired,\n ledger: result.value.ledger,\n });\n writeInfraStructured(request.context, request.arguments.format, {\n environment: result.value.environment,\n resources: result.value.resources.length,\n outputs: result.value.outputs,\n });\n return { exitCode: 0 };\n },\n} as const satisfies InfraCommandDefinition;\n"]}
1
+ {"version":3,"file":"up.js","sourceRoot":"","sources":["../../../src/cli/commands/up.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EAAE,iCAAiC,EAAE,MAAM,+CAA+C,CAAC;AAClG,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAExE,kEAAkE;AAClE,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,cAAc,EAAE,IAAI;IACpB,IAAI,EAAE,CAAC,IAAI,CAAC;IACZ,UAAU,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACjC,OAAO,EAAE,6DAA6D;IACtE,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ;QACzB,MAAM,SAAS,GAAG,MAAM,iCAAiC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC7E,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;QACzF,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7C,MAAM,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE;YACvD,aAAa,EAAE,CAAC;YAChB,OAAO,EAAE,SAAS,CAAC,OAAO;YAC1B,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;SAC5B,CAAC,CAAC;QACH,MAAM,QAAQ,CAAC,uBAAuB,CACpC,SAAS,CAAC,OAAO,CAAC,WAAW,EAC7B,MAAM,CAAC,KAAK,CAAC,WAAW,EACxB,MAAM,CAAC,KAAK,CAAC,OAAO,CACrB,CAAC;QACF,oBAAoB,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE;YAC9D,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW;YACrC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM;YACxC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO;SAC9B,CAAC,CAAC;QACH,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACzB,CAAC;CACwC,CAAC","sourcesContent":["import { INFRA_CAPABILITIES } from '../../constants.js';\nimport type { InfraCommandDefinition } from '../../types/infraCli.js';\nimport { prepareInfraCommandOperationAsync } from '../utils/prepareInfraCommandOperationAsync.js';\nimport { requireInfraSuccess } from '../utils/requireInfraSuccess.js';\nimport { writeInfraStructured } from '../utils/writeInfraStructured.js';\n\n/*** Define idempotent environment creation and reconciliation. */\nexport const up = {\n standaloneName: 'up',\n path: ['up'],\n capability: INFRA_CAPABILITIES[3],\n summary: 'Idempotently ensure and reconcile the selected environment.',\n async run(request, services) {\n const operation = await prepareInfraCommandOperationAsync(request, services);\n const result = await services.operations.up(operation.operation, operation.dependencies);\n requireInfraSuccess(result, request.context);\n await services.writeState(operation.project.projectPath, {\n schemaVersion: 1,\n desired: operation.desired,\n ledger: result.value.ledger,\n });\n await services.writeEnvironmentOutputs(\n operation.project.projectPath,\n result.value.environment,\n result.value.outputs,\n );\n writeInfraStructured(request.context, request.arguments.format, {\n environment: result.value.environment,\n resources: result.value.resources.length,\n outputs: result.value.outputs,\n });\n return { exitCode: 0 };\n },\n} as const satisfies InfraCommandDefinition;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"runInfraCliAsync.d.ts","sourceRoot":"","sources":["../../src/cli/runInfraCliAsync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,sBAAsB,CAAC;AAO9B,iGAAiG;AACjG,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CAkBhC;AAED,UAAU,eAAe;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,cAAc,CAAC,EAAE,mBAAmB,CAAC;IAC9C,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;CACnD"}
1
+ {"version":3,"file":"runInfraCliAsync.d.ts","sourceRoot":"","sources":["../../src/cli/runInfraCliAsync.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,sBAAsB,CAAC;AAO9B,iGAAiG;AACjG,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CAwBhC;AAED,UAAU,eAAe;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,cAAc,CAAC,EAAE,mBAAmB,CAAC;IAC9C,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;CACnD"}
@@ -1,6 +1,8 @@
1
+ import { isHelpToken, renderProviderHelp } from '@ankhorage/ankh';
2
+ import { INFRA_PACKAGE_DESCRIPTION } from '../constants.js';
1
3
  import { createDefaultInfraCommandContext } from './createDefaultInfraCommandContext.js';
4
+ import { createInfraRuntimeProvider } from './createInfraRuntimeProvider.js';
2
5
  import { findInfraCommand } from './findInfraCommand.js';
3
- import { renderInfraRootHelp } from './renderInfraRootHelp.js';
4
6
  import { renderUnknownInfraCommand } from './renderUnknownInfraCommand.js';
5
7
  import { runInfraCommandAsync } from './runInfraCommandAsync.js';
6
8
  /*** Dispatch the standalone executable arguments through the canonical Infra command surface. */
@@ -9,7 +11,11 @@ export async function runInfraCliAsync(argv, options = {}) {
9
11
  const runCommand = options.runCommandImpl ?? runInfraCommandAsync;
10
12
  const [firstToken, ...restTokens] = argv;
11
13
  if (firstToken === undefined || isHelpToken(firstToken)) {
12
- context.writeStdout(renderInfraRootHelp(context.version));
14
+ context.writeStdout(renderProviderHelp({
15
+ commandPrefix: ['ankhorage-infra'],
16
+ description: INFRA_PACKAGE_DESCRIPTION,
17
+ manifest: createInfraRuntimeProvider(),
18
+ }));
13
19
  return { exitCode: 0 };
14
20
  }
15
21
  if (isVersionToken(firstToken)) {
@@ -23,10 +29,6 @@ export async function runInfraCliAsync(argv, options = {}) {
23
29
  }
24
30
  return runCommand({ argv: restTokens, command, context }, { services: options.services });
25
31
  }
26
- /*** Recognize standalone help tokens. */
27
- function isHelpToken(value) {
28
- return value === '--help' || value === '-h' || value === 'help';
29
- }
30
32
  /*** Recognize standalone version tokens. */
31
33
  function isVersionToken(value) {
32
34
  return value === '--version' || value === '-v' || value === 'version';
@@ -1 +1 @@
1
- {"version":3,"file":"runInfraCliAsync.js","sourceRoot":"","sources":["../../src/cli/runInfraCliAsync.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gCAAgC,EAAE,MAAM,uCAAuC,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,iGAAiG;AACjG,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAuB,EACvB,UAA2B,EAAE;IAE7B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,gCAAgC,EAAE,CAAC;IACtE,MAAM,UAAU,GAAG,OAAO,CAAC,cAAc,IAAI,oBAAoB,CAAC;IAClE,MAAM,CAAC,UAAU,EAAE,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC;IACzC,IAAI,UAAU,KAAK,SAAS,IAAI,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC;QACxD,OAAO,CAAC,WAAW,CAAC,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QAC1D,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACzB,CAAC;IACD,IAAI,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC;QAC5C,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACzB,CAAC;IACD,MAAM,OAAO,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAC7C,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,OAAO,CAAC,WAAW,CAAC,yBAAyB,CAAC,UAAU,CAAC,CAAC,CAAC;QAC3D,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACzB,CAAC;IACD,OAAO,UAAU,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC5F,CAAC;AAQD,yCAAyC;AACzC,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,CAAC;AAClE,CAAC;AAED,4CAA4C;AAC5C,SAAS,cAAc,CAAC,KAAa;IACnC,OAAO,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC;AACxE,CAAC","sourcesContent":["import type {\n InfraCommandContext,\n InfraCommandRunResult,\n InfraCommandServices,\n RunInfraCommandImpl,\n} from '../types/infraCli.js';\nimport { createDefaultInfraCommandContext } from './createDefaultInfraCommandContext.js';\nimport { findInfraCommand } from './findInfraCommand.js';\nimport { renderInfraRootHelp } from './renderInfraRootHelp.js';\nimport { renderUnknownInfraCommand } from './renderUnknownInfraCommand.js';\nimport { runInfraCommandAsync } from './runInfraCommandAsync.js';\n\n/*** Dispatch the standalone executable arguments through the canonical Infra command surface. */\nexport async function runInfraCliAsync(\n argv: readonly string[],\n options: InfraCliOptions = {},\n): Promise<InfraCommandRunResult> {\n const context = options.context ?? createDefaultInfraCommandContext();\n const runCommand = options.runCommandImpl ?? runInfraCommandAsync;\n const [firstToken, ...restTokens] = argv;\n if (firstToken === undefined || isHelpToken(firstToken)) {\n context.writeStdout(renderInfraRootHelp(context.version));\n return { exitCode: 0 };\n }\n if (isVersionToken(firstToken)) {\n context.writeStdout(`${context.version}\\n`);\n return { exitCode: 0 };\n }\n const command = findInfraCommand(firstToken);\n if (command === null) {\n context.writeStderr(renderUnknownInfraCommand(firstToken));\n return { exitCode: 1 };\n }\n return runCommand({ argv: restTokens, command, context }, { services: options.services });\n}\n\ninterface InfraCliOptions {\n readonly context?: InfraCommandContext;\n readonly runCommandImpl?: RunInfraCommandImpl;\n readonly services?: Partial<InfraCommandServices>;\n}\n\n/*** Recognize standalone help tokens. */\nfunction isHelpToken(value: string): boolean {\n return value === '--help' || value === '-h' || value === 'help';\n}\n\n/*** Recognize standalone version tokens. */\nfunction isVersionToken(value: string): boolean {\n return value === '--version' || value === '-v' || value === 'version';\n}\n"]}
1
+ {"version":3,"file":"runInfraCliAsync.js","sourceRoot":"","sources":["../../src/cli/runInfraCliAsync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAElE,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAO5D,OAAO,EAAE,gCAAgC,EAAE,MAAM,uCAAuC,CAAC;AACzF,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,iGAAiG;AACjG,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAuB,EACvB,UAA2B,EAAE;IAE7B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,gCAAgC,EAAE,CAAC;IACtE,MAAM,UAAU,GAAG,OAAO,CAAC,cAAc,IAAI,oBAAoB,CAAC;IAClE,MAAM,CAAC,UAAU,EAAE,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC;IACzC,IAAI,UAAU,KAAK,SAAS,IAAI,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC;QACxD,OAAO,CAAC,WAAW,CACjB,kBAAkB,CAAC;YACjB,aAAa,EAAE,CAAC,iBAAiB,CAAC;YAClC,WAAW,EAAE,yBAAyB;YACtC,QAAQ,EAAE,0BAA0B,EAAE;SACvC,CAAC,CACH,CAAC;QACF,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACzB,CAAC;IACD,IAAI,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC;QAC5C,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACzB,CAAC;IACD,MAAM,OAAO,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAC7C,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,OAAO,CAAC,WAAW,CAAC,yBAAyB,CAAC,UAAU,CAAC,CAAC,CAAC;QAC3D,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACzB,CAAC;IACD,OAAO,UAAU,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC5F,CAAC;AAQD,4CAA4C;AAC5C,SAAS,cAAc,CAAC,KAAa;IACnC,OAAO,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC;AACxE,CAAC","sourcesContent":["import { isHelpToken, renderProviderHelp } from '@ankhorage/ankh';\n\nimport { INFRA_PACKAGE_DESCRIPTION } from '../constants.js';\nimport type {\n InfraCommandContext,\n InfraCommandRunResult,\n InfraCommandServices,\n RunInfraCommandImpl,\n} from '../types/infraCli.js';\nimport { createDefaultInfraCommandContext } from './createDefaultInfraCommandContext.js';\nimport { createInfraRuntimeProvider } from './createInfraRuntimeProvider.js';\nimport { findInfraCommand } from './findInfraCommand.js';\nimport { renderUnknownInfraCommand } from './renderUnknownInfraCommand.js';\nimport { runInfraCommandAsync } from './runInfraCommandAsync.js';\n\n/*** Dispatch the standalone executable arguments through the canonical Infra command surface. */\nexport async function runInfraCliAsync(\n argv: readonly string[],\n options: InfraCliOptions = {},\n): Promise<InfraCommandRunResult> {\n const context = options.context ?? createDefaultInfraCommandContext();\n const runCommand = options.runCommandImpl ?? runInfraCommandAsync;\n const [firstToken, ...restTokens] = argv;\n if (firstToken === undefined || isHelpToken(firstToken)) {\n context.writeStdout(\n renderProviderHelp({\n commandPrefix: ['ankhorage-infra'],\n description: INFRA_PACKAGE_DESCRIPTION,\n manifest: createInfraRuntimeProvider(),\n }),\n );\n return { exitCode: 0 };\n }\n if (isVersionToken(firstToken)) {\n context.writeStdout(`${context.version}\\n`);\n return { exitCode: 0 };\n }\n const command = findInfraCommand(firstToken);\n if (command === null) {\n context.writeStderr(renderUnknownInfraCommand(firstToken));\n return { exitCode: 1 };\n }\n return runCommand({ argv: restTokens, command, context }, { services: options.services });\n}\n\ninterface InfraCliOptions {\n readonly context?: InfraCommandContext;\n readonly runCommandImpl?: RunInfraCommandImpl;\n readonly services?: Partial<InfraCommandServices>;\n}\n\n/*** Recognize standalone version tokens. */\nfunction isVersionToken(value: string): boolean {\n return value === '--version' || value === '-v' || value === 'version';\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  export declare const INFRA_PACKAGE_NAME: string;
2
2
  export declare const INFRA_PACKAGE_VERSION: string;
3
+ export declare const INFRA_PACKAGE_DESCRIPTION: string;
3
4
  export declare const INFRA_COMMAND_CATEGORY: "infra";
4
5
  export declare const INFRA_CAPABILITIES: readonly ["infra.validate", "infra.plan", "infra.generate", "infra.up", "infra.status", "infra.outputs", "infra.down", "infra.destroy"];
5
6
  export declare const INFRA_PACKAGE_METADATA: {
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,kBAAkB,QAAmB,CAAC;AACnD,eAAO,MAAM,qBAAqB,QAAsB,CAAC;AACzD,eAAO,MAAM,sBAAsB,SAAiD,CAAC;AACrF,eAAO,MAAM,kBAAkB,yIASiB,CAAC;AAEjD,eAAO,MAAM,sBAAsB;;;;CAIK,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,kBAAkB,QAAmB,CAAC;AACnD,eAAO,MAAM,qBAAqB,QAAsB,CAAC;AACzD,eAAO,MAAM,yBAAyB,QAA0B,CAAC;AACjE,eAAO,MAAM,sBAAsB,SAAiD,CAAC;AACrF,eAAO,MAAM,kBAAkB,yIASiB,CAAC;AAEjD,eAAO,MAAM,sBAAsB;;;;CAIK,CAAC"}
package/dist/constants.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import packageJson from '../package.json';
2
2
  export const INFRA_PACKAGE_NAME = packageJson.name;
3
3
  export const INFRA_PACKAGE_VERSION = packageJson.version;
4
+ export const INFRA_PACKAGE_DESCRIPTION = packageJson.description;
4
5
  export const INFRA_COMMAND_CATEGORY = 'infra';
5
6
  export const INFRA_CAPABILITIES = [
6
7
  'infra.validate',
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAMA,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAE1C,MAAM,CAAC,MAAM,kBAAkB,GAAG,WAAW,CAAC,IAAI,CAAC;AACnD,MAAM,CAAC,MAAM,qBAAqB,GAAG,WAAW,CAAC,OAAO,CAAC;AACzD,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAA8C,CAAC;AACrF,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,gBAAgB;IAChB,YAAY;IACZ,gBAAgB;IAChB,UAAU;IACV,cAAc;IACd,eAAe;IACf,YAAY;IACZ,eAAe;CAC+B,CAAC;AAEjD,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,QAAQ,EAAE,sBAAsB;IAChC,QAAQ,EAAE,qBAAqB;IAC/B,YAAY,EAAE,kBAAkB;CACM,CAAC","sourcesContent":["import type {\n AnkhCapabilityId,\n AnkhCommandCategory,\n AnkhPackageMetadata,\n} from '@ankhorage/contracts/cli';\n\nimport packageJson from '../package.json';\n\nexport const INFRA_PACKAGE_NAME = packageJson.name;\nexport const INFRA_PACKAGE_VERSION = packageJson.version;\nexport const INFRA_COMMAND_CATEGORY = 'infra' as const satisfies AnkhCommandCategory;\nexport const INFRA_CAPABILITIES = [\n 'infra.validate',\n 'infra.plan',\n 'infra.generate',\n 'infra.up',\n 'infra.status',\n 'infra.outputs',\n 'infra.down',\n 'infra.destroy',\n] as const satisfies readonly AnkhCapabilityId[];\n\nexport const INFRA_PACKAGE_METADATA = {\n category: INFRA_COMMAND_CATEGORY,\n provider: './dist/cli/index.js',\n capabilities: INFRA_CAPABILITIES,\n} as const satisfies AnkhPackageMetadata;\n"]}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAMA,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAE1C,MAAM,CAAC,MAAM,kBAAkB,GAAG,WAAW,CAAC,IAAI,CAAC;AACnD,MAAM,CAAC,MAAM,qBAAqB,GAAG,WAAW,CAAC,OAAO,CAAC;AACzD,MAAM,CAAC,MAAM,yBAAyB,GAAG,WAAW,CAAC,WAAW,CAAC;AACjE,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAA8C,CAAC;AACrF,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,gBAAgB;IAChB,YAAY;IACZ,gBAAgB;IAChB,UAAU;IACV,cAAc;IACd,eAAe;IACf,YAAY;IACZ,eAAe;CAC+B,CAAC;AAEjD,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,QAAQ,EAAE,sBAAsB;IAChC,QAAQ,EAAE,qBAAqB;IAC/B,YAAY,EAAE,kBAAkB;CACM,CAAC","sourcesContent":["import type {\n AnkhCapabilityId,\n AnkhCommandCategory,\n AnkhPackageMetadata,\n} from '@ankhorage/contracts/cli';\n\nimport packageJson from '../package.json';\n\nexport const INFRA_PACKAGE_NAME = packageJson.name;\nexport const INFRA_PACKAGE_VERSION = packageJson.version;\nexport const INFRA_PACKAGE_DESCRIPTION = packageJson.description;\nexport const INFRA_COMMAND_CATEGORY = 'infra' as const satisfies AnkhCommandCategory;\nexport const INFRA_CAPABILITIES = [\n 'infra.validate',\n 'infra.plan',\n 'infra.generate',\n 'infra.up',\n 'infra.status',\n 'infra.outputs',\n 'infra.down',\n 'infra.destroy',\n] as const satisfies readonly AnkhCapabilityId[];\n\nexport const INFRA_PACKAGE_METADATA = {\n category: INFRA_COMMAND_CATEGORY,\n provider: './dist/cli/index.js',\n capabilities: INFRA_CAPABILITIES,\n} as const satisfies AnkhPackageMetadata;\n"]}
@@ -0,0 +1,5 @@
1
+ import type { AppEnvironmentId } from '@ankhorage/contracts/environments';
2
+ import type { InfraOutput } from '@ankhorage/contracts/infra';
3
+ /*** Materialize public local Infra outputs into the project app environment while preserving unrelated entries. */
4
+ export declare function writeProjectEnvironmentOutputsAsync(projectPath: string, environment: AppEnvironmentId, outputs: readonly InfraOutput[]): Promise<void>;
5
+ //# sourceMappingURL=writeProjectEnvironmentOutputsAsync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writeProjectEnvironmentOutputsAsync.d.ts","sourceRoot":"","sources":["../../../../../src/features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAM9D,mHAAmH;AACnH,wBAAsB,mCAAmC,CACvD,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,gBAAgB,EAC7B,OAAO,EAAE,SAAS,WAAW,EAAE,GAC9B,OAAO,CAAC,IAAI,CAAC,CAef"}
@@ -0,0 +1,70 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { pathExists } from '@ankhorage/utility/node/fs';
4
+ const ENVIRONMENT_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/u;
5
+ const ENVIRONMENT_ASSIGNMENT_PATTERN = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/u;
6
+ /*** Materialize public local Infra outputs into the project app environment while preserving unrelated entries. */
7
+ export async function writeProjectEnvironmentOutputsAsync(projectPath, environment, outputs) {
8
+ if (environment !== 'local')
9
+ return;
10
+ const values = collectEnvironmentValues(outputs);
11
+ if (values.size === 0)
12
+ return;
13
+ const environmentPath = path.join(projectPath, '.env.local');
14
+ const current = (await pathExists(environmentPath))
15
+ ? await fs.readFile(environmentPath, 'utf8')
16
+ : '';
17
+ const next = mergeEnvironmentFile(current, values);
18
+ if (next === current)
19
+ return;
20
+ await fs.mkdir(projectPath, { recursive: true });
21
+ await fs.writeFile(environmentPath, next, 'utf8');
22
+ }
23
+ /*** Collect only browser-safe public outputs that explicitly declare an environment variable. */
24
+ function collectEnvironmentValues(outputs) {
25
+ const values = new Map();
26
+ for (const output of outputs) {
27
+ if (output.visibility !== 'public' || output.environmentVariable === undefined)
28
+ continue;
29
+ if (!ENVIRONMENT_NAME_PATTERN.test(output.environmentVariable)) {
30
+ throw new Error(`Invalid Infra environment variable name: ${output.environmentVariable}`);
31
+ }
32
+ values.set(output.environmentVariable, String(output.value));
33
+ }
34
+ return values;
35
+ }
36
+ /*** Merge managed environment values without changing unrelated lines or retaining duplicate managed keys. */
37
+ function mergeEnvironmentFile(current, values) {
38
+ const normalized = current.replaceAll('\r\n', '\n');
39
+ const lines = normalized.length === 0 ? [] : normalized.split('\n');
40
+ if (lines.at(-1) === '')
41
+ lines.pop();
42
+ const written = new Set();
43
+ const nextLines = [];
44
+ for (const line of lines) {
45
+ const name = readEnvironmentAssignmentName(line);
46
+ if (name !== undefined && values.has(name)) {
47
+ if (!written.has(name)) {
48
+ nextLines.push(`${name}=${serializeEnvironmentValue(values.get(name) ?? '')}`);
49
+ written.add(name);
50
+ }
51
+ continue;
52
+ }
53
+ nextLines.push(line);
54
+ }
55
+ for (const [name, value] of [...values.entries()].sort(([left], [right]) => left.localeCompare(right))) {
56
+ if (written.has(name))
57
+ continue;
58
+ nextLines.push(`${name}=${serializeEnvironmentValue(value)}`);
59
+ }
60
+ return nextLines.length === 0 ? '' : `${nextLines.join('\n')}\n`;
61
+ }
62
+ /*** Read an environment assignment name without interpreting or mutating its value. */
63
+ function readEnvironmentAssignmentName(line) {
64
+ return ENVIRONMENT_ASSIGNMENT_PATTERN.exec(line)?.[1];
65
+ }
66
+ /*** Serialize one primitive Infra output as a quoted dotenv value. */
67
+ function serializeEnvironmentValue(value) {
68
+ return JSON.stringify(value);
69
+ }
70
+ //# sourceMappingURL=writeProjectEnvironmentOutputsAsync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writeProjectEnvironmentOutputsAsync.js","sourceRoot":"","sources":["../../../../../src/features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\n\nimport type { AppEnvironmentId } from '@ankhorage/contracts/environments';\nimport type { InfraOutput } from '@ankhorage/contracts/infra';\nimport { pathExists } from '@ankhorage/utility/node/fs';\n\nconst ENVIRONMENT_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/u;\nconst ENVIRONMENT_ASSIGNMENT_PATTERN = /^\\s*(?:export\\s+)?([A-Za-z_][A-Za-z0-9_]*)\\s*=/u;\n\n/*** Materialize public local Infra outputs into the project app environment while preserving unrelated entries. */\nexport async function writeProjectEnvironmentOutputsAsync(\n projectPath: string,\n environment: AppEnvironmentId,\n outputs: readonly InfraOutput[],\n): Promise<void> {\n if (environment !== 'local') return;\n\n const values = collectEnvironmentValues(outputs);\n if (values.size === 0) return;\n\n const environmentPath = path.join(projectPath, '.env.local');\n const current = (await pathExists(environmentPath))\n ? await fs.readFile(environmentPath, 'utf8')\n : '';\n const next = mergeEnvironmentFile(current, values);\n if (next === current) return;\n\n await fs.mkdir(projectPath, { recursive: true });\n await fs.writeFile(environmentPath, next, 'utf8');\n}\n\n/*** Collect only browser-safe public outputs that explicitly declare an environment variable. */\nfunction collectEnvironmentValues(outputs: readonly InfraOutput[]): ReadonlyMap<string, string> {\n const values = new Map<string, string>();\n for (const output of outputs) {\n if (output.visibility !== 'public' || output.environmentVariable === undefined) continue;\n if (!ENVIRONMENT_NAME_PATTERN.test(output.environmentVariable)) {\n throw new Error(`Invalid Infra environment variable name: ${output.environmentVariable}`);\n }\n values.set(output.environmentVariable, String(output.value));\n }\n return values;\n}\n\n/*** Merge managed environment values without changing unrelated lines or retaining duplicate managed keys. */\nfunction mergeEnvironmentFile(current: string, values: ReadonlyMap<string, string>): string {\n const normalized = current.replaceAll('\\r\\n', '\\n');\n const lines = normalized.length === 0 ? [] : normalized.split('\\n');\n if (lines.at(-1) === '') lines.pop();\n\n const written = new Set<string>();\n const nextLines: string[] = [];\n for (const line of lines) {\n const name = readEnvironmentAssignmentName(line);\n if (name !== undefined && values.has(name)) {\n if (!written.has(name)) {\n nextLines.push(`${name}=${serializeEnvironmentValue(values.get(name) ?? '')}`);\n written.add(name);\n }\n continue;\n }\n nextLines.push(line);\n }\n\n for (const [name, value] of [...values.entries()].sort(([left], [right]) =>\n left.localeCompare(right),\n )) {\n if (written.has(name)) continue;\n nextLines.push(`${name}=${serializeEnvironmentValue(value)}`);\n }\n\n return nextLines.length === 0 ? '' : `${nextLines.join('\\n')}\\n`;\n}\n\n/*** Read an environment assignment name without interpreting or mutating its value. */\nfunction readEnvironmentAssignmentName(line: string): string | undefined {\n return ENVIRONMENT_ASSIGNMENT_PATTERN.exec(line)?.[1];\n}\n\n/*** Serialize one primitive Infra output as a quoted dotenv value. */\nfunction serializeEnvironmentValue(value: string): string {\n return JSON.stringify(value);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"createInfraCommandServices.d.ts","sourceRoot":"","sources":["../../../../src/features/environment-lifecycle/composition/createInfraCommandServices.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAmBvE,mGAAmG;AACnG,wBAAgB,0BAA0B,CACxC,SAAS,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAC5C,oBAAoB,CA8BtB"}
1
+ {"version":3,"file":"createInfraCommandServices.d.ts","sourceRoot":"","sources":["../../../../src/features/environment-lifecycle/composition/createInfraCommandServices.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAoBvE,mGAAmG;AACnG,wBAAgB,0BAA0B,CACxC,SAAS,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAC5C,oBAAoB,CAgCtB"}
@@ -6,6 +6,7 @@ import { removeStoredInfraCredentialsAsync } from '../adapters/outbound/removeSt
6
6
  import { removeStoredInfraStateAsync } from '../adapters/outbound/removeStoredInfraStateAsync.js';
7
7
  import { resolveInfraProjectAsync } from '../adapters/outbound/resolveInfraProjectAsync.js';
8
8
  import { writeInfraGeneratedArtifactsAsync } from '../adapters/outbound/writeInfraGeneratedArtifactsAsync.js';
9
+ import { writeProjectEnvironmentOutputsAsync } from '../adapters/outbound/writeProjectEnvironmentOutputsAsync.js';
9
10
  import { writeStoredInfraStateAsync } from '../adapters/outbound/writeStoredInfraStateAsync.js';
10
11
  import { destroyInfraEnvironmentAsync } from '../application/use-cases/destroyInfraEnvironmentAsync.js';
11
12
  import { downInfraEnvironmentAsync } from '../application/use-cases/downInfraEnvironmentAsync.js';
@@ -24,6 +25,7 @@ export function createInfraCommandServices(overrides = {}) {
24
25
  removeState: overrides.removeState ?? removeStoredInfraStateAsync,
25
26
  removeCredentials: overrides.removeCredentials ?? removeStoredInfraCredentialsAsync,
26
27
  writeArtifacts: overrides.writeArtifacts ?? writeInfraGeneratedArtifactsAsync,
28
+ writeEnvironmentOutputs: overrides.writeEnvironmentOutputs ?? writeProjectEnvironmentOutputsAsync,
27
29
  operations: overrides.operations ?? {
28
30
  validate: validateInfraEnvironmentAsync,
29
31
  plan: planInfraEnvironmentAsync,
@@ -1 +1 @@
1
- {"version":3,"file":"createInfraCommandServices.js","sourceRoot":"","sources":["../../../../src/features/environment-lifecycle/composition/createInfraCommandServices.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gCAAgC,EAAE,MAAM,0DAA0D,CAAC;AAC5G,OAAO,EAAE,qCAAqC,EAAE,MAAM,+DAA+D,CAAC;AACtH,OAAO,EAAE,gCAAgC,EAAE,MAAM,0DAA0D,CAAC;AAC5G,OAAO,EAAE,yBAAyB,EAAE,MAAM,mDAAmD,CAAC;AAC9F,OAAO,EAAE,iCAAiC,EAAE,MAAM,2DAA2D,CAAC;AAC9G,OAAO,EAAE,2BAA2B,EAAE,MAAM,qDAAqD,CAAC;AAClG,OAAO,EAAE,wBAAwB,EAAE,MAAM,kDAAkD,CAAC;AAC5F,OAAO,EAAE,iCAAiC,EAAE,MAAM,2DAA2D,CAAC;AAC9G,OAAO,EAAE,0BAA0B,EAAE,MAAM,oDAAoD,CAAC;AAChG,OAAO,EAAE,4BAA4B,EAAE,MAAM,0DAA0D,CAAC;AACxG,OAAO,EAAE,yBAAyB,EAAE,MAAM,uDAAuD,CAAC;AAClG,OAAO,EAAE,6BAA6B,EAAE,MAAM,2DAA2D,CAAC;AAC1G,OAAO,EAAE,0BAA0B,EAAE,MAAM,wDAAwD,CAAC;AACpG,OAAO,EAAE,yBAAyB,EAAE,MAAM,uDAAuD,CAAC;AAClG,OAAO,EAAE,2BAA2B,EAAE,MAAM,yDAAyD,CAAC;AACtG,OAAO,EAAE,uBAAuB,EAAE,MAAM,qDAAqD,CAAC;AAC9F,OAAO,EAAE,6BAA6B,EAAE,MAAM,2DAA2D,CAAC;AAE1G,mGAAmG;AACnG,MAAM,UAAU,0BAA0B,CACxC,YAA2C,EAAE;IAE7C,OAAO;QACL,cAAc,EAAE,SAAS,CAAC,cAAc,IAAI,wBAAwB;QACpE,SAAS,EAAE,SAAS,CAAC,SAAS,IAAI,yBAAyB;QAC3D,UAAU,EAAE,SAAS,CAAC,UAAU,IAAI,0BAA0B;QAC9D,WAAW,EAAE,SAAS,CAAC,WAAW,IAAI,2BAA2B;QACjE,iBAAiB,EAAE,SAAS,CAAC,iBAAiB,IAAI,iCAAiC;QACnF,cAAc,EAAE,SAAS,CAAC,cAAc,IAAI,iCAAiC;QAC7E,UAAU,EAAE,SAAS,CAAC,UAAU,IAAI;YAClC,QAAQ,EAAE,6BAA6B;YACvC,IAAI,EAAE,yBAAyB;YAC/B,QAAQ,EAAE,6BAA6B;YACvC,EAAE,EAAE,uBAAuB;YAC3B,MAAM,EAAE,2BAA2B;YACnC,OAAO,EAAE,0BAA0B;YACnC,IAAI,EAAE,yBAAyB;YAC/B,OAAO,EAAE,4BAA4B;SACtC;QACD,kBAAkB,EAChB,SAAS,CAAC,kBAAkB;YAC5B,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;gBACpB,eAAe,EAAE,qCAAqC,EAAE;gBACxD,WAAW,EAAE,gCAAgC,CAAC;oBAC5C,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,kBAAkB,EAAE,OAAO,CAAC,GAAG;iBAChC,CAAC;gBACF,OAAO,EAAE,gCAAgC,CAAC,OAAO,CAAC,GAAG,CAAC;aACvD,CAAC,CAAC;KACN,CAAC;AACJ,CAAC","sourcesContent":["import type { InfraCommandServices } from '../../../types/infraCli.js';\nimport { createEnvironmentInfraSecretPort } from '../adapters/outbound/createEnvironmentInfraSecretPort.js';\nimport { createNodeInfraAdapterPackageResolver } from '../adapters/outbound/createNodeInfraAdapterPackageResolver.js';\nimport { createProjectInfraCredentialPort } from '../adapters/outbound/createProjectInfraCredentialPort.js';\nimport { readStoredInfraStateAsync } from '../adapters/outbound/readStoredInfraStateAsync.js';\nimport { removeStoredInfraCredentialsAsync } from '../adapters/outbound/removeStoredInfraCredentialsAsync.js';\nimport { removeStoredInfraStateAsync } from '../adapters/outbound/removeStoredInfraStateAsync.js';\nimport { resolveInfraProjectAsync } from '../adapters/outbound/resolveInfraProjectAsync.js';\nimport { writeInfraGeneratedArtifactsAsync } from '../adapters/outbound/writeInfraGeneratedArtifactsAsync.js';\nimport { writeStoredInfraStateAsync } from '../adapters/outbound/writeStoredInfraStateAsync.js';\nimport { destroyInfraEnvironmentAsync } from '../application/use-cases/destroyInfraEnvironmentAsync.js';\nimport { downInfraEnvironmentAsync } from '../application/use-cases/downInfraEnvironmentAsync.js';\nimport { generateInfraEnvironmentAsync } from '../application/use-cases/generateInfraEnvironmentAsync.js';\nimport { getInfraEnvironmentOutputs } from '../application/use-cases/getInfraEnvironmentOutputs.js';\nimport { planInfraEnvironmentAsync } from '../application/use-cases/planInfraEnvironmentAsync.js';\nimport { statusInfraEnvironmentAsync } from '../application/use-cases/statusInfraEnvironmentAsync.js';\nimport { upInfraEnvironmentAsync } from '../application/use-cases/upInfraEnvironmentAsync.js';\nimport { validateInfraEnvironmentAsync } from '../application/use-cases/validateInfraEnvironmentAsync.js';\n\n/*** Compose command use cases with filesystem, environment-value and package-resolver adapters. */\nexport function createInfraCommandServices(\n overrides: Partial<InfraCommandServices> = {},\n): InfraCommandServices {\n return {\n resolveProject: overrides.resolveProject ?? resolveInfraProjectAsync,\n readState: overrides.readState ?? readStoredInfraStateAsync,\n writeState: overrides.writeState ?? writeStoredInfraStateAsync,\n removeState: overrides.removeState ?? removeStoredInfraStateAsync,\n removeCredentials: overrides.removeCredentials ?? removeStoredInfraCredentialsAsync,\n writeArtifacts: overrides.writeArtifacts ?? writeInfraGeneratedArtifactsAsync,\n operations: overrides.operations ?? {\n validate: validateInfraEnvironmentAsync,\n plan: planInfraEnvironmentAsync,\n generate: generateInfraEnvironmentAsync,\n up: upInfraEnvironmentAsync,\n status: statusInfraEnvironmentAsync,\n outputs: getInfraEnvironmentOutputs,\n down: downInfraEnvironmentAsync,\n destroy: destroyInfraEnvironmentAsync,\n },\n createDependencies:\n overrides.createDependencies ??\n ((context, scope) => ({\n adapterResolver: createNodeInfraAdapterPackageResolver(),\n credentials: createProjectInfraCredentialPort({\n projectPath: scope.projectPath,\n environment: scope.environment,\n processEnvironment: context.env,\n }),\n secrets: createEnvironmentInfraSecretPort(context.env),\n })),\n };\n}\n"]}
1
+ {"version":3,"file":"createInfraCommandServices.js","sourceRoot":"","sources":["../../../../src/features/environment-lifecycle/composition/createInfraCommandServices.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gCAAgC,EAAE,MAAM,0DAA0D,CAAC;AAC5G,OAAO,EAAE,qCAAqC,EAAE,MAAM,+DAA+D,CAAC;AACtH,OAAO,EAAE,gCAAgC,EAAE,MAAM,0DAA0D,CAAC;AAC5G,OAAO,EAAE,yBAAyB,EAAE,MAAM,mDAAmD,CAAC;AAC9F,OAAO,EAAE,iCAAiC,EAAE,MAAM,2DAA2D,CAAC;AAC9G,OAAO,EAAE,2BAA2B,EAAE,MAAM,qDAAqD,CAAC;AAClG,OAAO,EAAE,wBAAwB,EAAE,MAAM,kDAAkD,CAAC;AAC5F,OAAO,EAAE,iCAAiC,EAAE,MAAM,2DAA2D,CAAC;AAC9G,OAAO,EAAE,mCAAmC,EAAE,MAAM,6DAA6D,CAAC;AAClH,OAAO,EAAE,0BAA0B,EAAE,MAAM,oDAAoD,CAAC;AAChG,OAAO,EAAE,4BAA4B,EAAE,MAAM,0DAA0D,CAAC;AACxG,OAAO,EAAE,yBAAyB,EAAE,MAAM,uDAAuD,CAAC;AAClG,OAAO,EAAE,6BAA6B,EAAE,MAAM,2DAA2D,CAAC;AAC1G,OAAO,EAAE,0BAA0B,EAAE,MAAM,wDAAwD,CAAC;AACpG,OAAO,EAAE,yBAAyB,EAAE,MAAM,uDAAuD,CAAC;AAClG,OAAO,EAAE,2BAA2B,EAAE,MAAM,yDAAyD,CAAC;AACtG,OAAO,EAAE,uBAAuB,EAAE,MAAM,qDAAqD,CAAC;AAC9F,OAAO,EAAE,6BAA6B,EAAE,MAAM,2DAA2D,CAAC;AAE1G,mGAAmG;AACnG,MAAM,UAAU,0BAA0B,CACxC,YAA2C,EAAE;IAE7C,OAAO;QACL,cAAc,EAAE,SAAS,CAAC,cAAc,IAAI,wBAAwB;QACpE,SAAS,EAAE,SAAS,CAAC,SAAS,IAAI,yBAAyB;QAC3D,UAAU,EAAE,SAAS,CAAC,UAAU,IAAI,0BAA0B;QAC9D,WAAW,EAAE,SAAS,CAAC,WAAW,IAAI,2BAA2B;QACjE,iBAAiB,EAAE,SAAS,CAAC,iBAAiB,IAAI,iCAAiC;QACnF,cAAc,EAAE,SAAS,CAAC,cAAc,IAAI,iCAAiC;QAC7E,uBAAuB,EACrB,SAAS,CAAC,uBAAuB,IAAI,mCAAmC;QAC1E,UAAU,EAAE,SAAS,CAAC,UAAU,IAAI;YAClC,QAAQ,EAAE,6BAA6B;YACvC,IAAI,EAAE,yBAAyB;YAC/B,QAAQ,EAAE,6BAA6B;YACvC,EAAE,EAAE,uBAAuB;YAC3B,MAAM,EAAE,2BAA2B;YACnC,OAAO,EAAE,0BAA0B;YACnC,IAAI,EAAE,yBAAyB;YAC/B,OAAO,EAAE,4BAA4B;SACtC;QACD,kBAAkB,EAChB,SAAS,CAAC,kBAAkB;YAC5B,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;gBACpB,eAAe,EAAE,qCAAqC,EAAE;gBACxD,WAAW,EAAE,gCAAgC,CAAC;oBAC5C,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,kBAAkB,EAAE,OAAO,CAAC,GAAG;iBAChC,CAAC;gBACF,OAAO,EAAE,gCAAgC,CAAC,OAAO,CAAC,GAAG,CAAC;aACvD,CAAC,CAAC;KACN,CAAC;AACJ,CAAC","sourcesContent":["import type { InfraCommandServices } from '../../../types/infraCli.js';\nimport { createEnvironmentInfraSecretPort } from '../adapters/outbound/createEnvironmentInfraSecretPort.js';\nimport { createNodeInfraAdapterPackageResolver } from '../adapters/outbound/createNodeInfraAdapterPackageResolver.js';\nimport { createProjectInfraCredentialPort } from '../adapters/outbound/createProjectInfraCredentialPort.js';\nimport { readStoredInfraStateAsync } from '../adapters/outbound/readStoredInfraStateAsync.js';\nimport { removeStoredInfraCredentialsAsync } from '../adapters/outbound/removeStoredInfraCredentialsAsync.js';\nimport { removeStoredInfraStateAsync } from '../adapters/outbound/removeStoredInfraStateAsync.js';\nimport { resolveInfraProjectAsync } from '../adapters/outbound/resolveInfraProjectAsync.js';\nimport { writeInfraGeneratedArtifactsAsync } from '../adapters/outbound/writeInfraGeneratedArtifactsAsync.js';\nimport { writeProjectEnvironmentOutputsAsync } from '../adapters/outbound/writeProjectEnvironmentOutputsAsync.js';\nimport { writeStoredInfraStateAsync } from '../adapters/outbound/writeStoredInfraStateAsync.js';\nimport { destroyInfraEnvironmentAsync } from '../application/use-cases/destroyInfraEnvironmentAsync.js';\nimport { downInfraEnvironmentAsync } from '../application/use-cases/downInfraEnvironmentAsync.js';\nimport { generateInfraEnvironmentAsync } from '../application/use-cases/generateInfraEnvironmentAsync.js';\nimport { getInfraEnvironmentOutputs } from '../application/use-cases/getInfraEnvironmentOutputs.js';\nimport { planInfraEnvironmentAsync } from '../application/use-cases/planInfraEnvironmentAsync.js';\nimport { statusInfraEnvironmentAsync } from '../application/use-cases/statusInfraEnvironmentAsync.js';\nimport { upInfraEnvironmentAsync } from '../application/use-cases/upInfraEnvironmentAsync.js';\nimport { validateInfraEnvironmentAsync } from '../application/use-cases/validateInfraEnvironmentAsync.js';\n\n/*** Compose command use cases with filesystem, environment-value and package-resolver adapters. */\nexport function createInfraCommandServices(\n overrides: Partial<InfraCommandServices> = {},\n): InfraCommandServices {\n return {\n resolveProject: overrides.resolveProject ?? resolveInfraProjectAsync,\n readState: overrides.readState ?? readStoredInfraStateAsync,\n writeState: overrides.writeState ?? writeStoredInfraStateAsync,\n removeState: overrides.removeState ?? removeStoredInfraStateAsync,\n removeCredentials: overrides.removeCredentials ?? removeStoredInfraCredentialsAsync,\n writeArtifacts: overrides.writeArtifacts ?? writeInfraGeneratedArtifactsAsync,\n writeEnvironmentOutputs:\n overrides.writeEnvironmentOutputs ?? writeProjectEnvironmentOutputsAsync,\n operations: overrides.operations ?? {\n validate: validateInfraEnvironmentAsync,\n plan: planInfraEnvironmentAsync,\n generate: generateInfraEnvironmentAsync,\n up: upInfraEnvironmentAsync,\n status: statusInfraEnvironmentAsync,\n outputs: getInfraEnvironmentOutputs,\n down: downInfraEnvironmentAsync,\n destroy: destroyInfraEnvironmentAsync,\n },\n createDependencies:\n overrides.createDependencies ??\n ((context, scope) => ({\n adapterResolver: createNodeInfraAdapterPackageResolver(),\n credentials: createProjectInfraCredentialPort({\n projectPath: scope.projectPath,\n environment: scope.environment,\n processEnvironment: context.env,\n }),\n secrets: createEnvironmentInfraSecretPort(context.env),\n })),\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"createProjectInfraLifecycle.d.ts","sourceRoot":"","sources":["../../../../src/features/environment-lifecycle/composition/createProjectInfraLifecycle.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,kCAAkC,EAElC,qBAAqB,EAEtB,MAAM,gCAAgC,CAAC;AAGxC,0GAA0G;AAC1G,wBAAgB,2BAA2B,CACzC,OAAO,GAAE,kCAAuC,GAC/C,qBAAqB,CA6FvB"}
1
+ {"version":3,"file":"createProjectInfraLifecycle.d.ts","sourceRoot":"","sources":["../../../../src/features/environment-lifecycle/composition/createProjectInfraLifecycle.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,kCAAkC,EAElC,qBAAqB,EAEtB,MAAM,gCAAgC,CAAC;AAGxC,0GAA0G;AAC1G,wBAAgB,2BAA2B,CACzC,OAAO,GAAE,kCAAuC,GAC/C,qBAAqB,CAkGvB"}
@@ -35,6 +35,7 @@ export function createProjectInfraLifecycle(options = {}) {
35
35
  desired: prepared.desired,
36
36
  ledger: result.value.ledger,
37
37
  });
38
+ await services.writeEnvironmentOutputs(request.projectPath, request.environment, result.value.outputs);
38
39
  return result;
39
40
  },
40
41
  async statusAsync(request) {
@@ -1 +1 @@
1
- {"version":3,"file":"createProjectInfraLifecycle.js","sourceRoot":"","sources":["../../../../src/features/environment-lifecycle/composition/createProjectInfraLifecycle.ts"],"names":[],"mappings":"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","sourcesContent":["import type { InfraEnvironmentSpec, InfraManifest, InfraResult } from '@ankhorage/contracts/infra';\n\nimport { INFRA_PACKAGE_VERSION } from '../../../constants.js';\nimport type { InfraOperationRequest, InfraStoredState } from '../../../types/infraOrchestration.js';\nimport type {\n CreateProjectInfraLifecycleOptions,\n ProjectInfraDestroyRequest,\n ProjectInfraLifecycle,\n ProjectInfraOperationRequest,\n} from '../../../types/infraProject.js';\nimport { createInfraCommandServices } from './createInfraCommandServices.js';\n\n/*** Create the typed project-facing Infra lifecycle backed by canonical use cases and ownership state. */\nexport function createProjectInfraLifecycle(\n options: CreateProjectInfraLifecycleOptions = {},\n): ProjectInfraLifecycle {\n const services = createInfraCommandServices(options.services);\n return {\n async validateAsync(request) {\n const prepared = await prepareProjectOperationAsync(request, services);\n return services.operations.validate(prepared.operation, prepared.dependencies);\n },\n async planAsync(request) {\n const prepared = await prepareProjectOperationAsync(request, services);\n return services.operations.plan(prepared.operation, prepared.dependencies);\n },\n async generateAsync(request) {\n const prepared = await prepareProjectOperationAsync(request, services);\n const result = await services.operations.generate(prepared.operation, prepared.dependencies);\n if (!result.ok) return result;\n await services.writeArtifacts(\n request.projectPath,\n result.value.artifacts,\n prepared.state?.ledger,\n );\n await services.writeState(request.projectPath, {\n schemaVersion: 1,\n desired: prepared.desired,\n ledger: result.value.ledger,\n });\n return result;\n },\n async upAsync(request) {\n const prepared = await prepareProjectOperationAsync(request, services);\n const result = await services.operations.up(prepared.operation, prepared.dependencies);\n if (!result.ok) return result;\n await services.writeState(request.projectPath, {\n schemaVersion: 1,\n desired: prepared.desired,\n ledger: result.value.ledger,\n });\n return result;\n },\n async statusAsync(request) {\n const prepared = await prepareProjectOperationAsync(request, services);\n return services.operations.status(prepared.operation, prepared.dependencies);\n },\n async outputsAsync(request) {\n const prepared = await prepareProjectOperationAsync(request, services);\n return services.operations.outputs(prepared.operation);\n },\n async downAsync(request) {\n const prepared = await prepareProjectOperationAsync(request, services);\n const result = await services.operations.down(prepared.operation, prepared.dependencies);\n if (!result.ok) return result;\n await services.writeState(request.projectPath, {\n schemaVersion: 1,\n desired: prepared.desired,\n ledger: result.value.ledger,\n });\n return result;\n },\n async destroyAsync(request) {\n const state = await services.readState(request.projectPath, request.environment);\n if (state === null) {\n const safety = validateCredentialStateDestroy(request);\n if (!safety.ok) return safety;\n await services.removeCredentials(request.projectPath, request.environment);\n return {\n ok: true,\n value: { environment: request.environment, ledger: null },\n diagnostics: [],\n };\n }\n const prepared = await prepareProjectOperationAsync(request, services, true, state);\n const result = await services.operations.destroy(\n {\n ...prepared.operation,\n confirmation: request.confirmation,\n persistence: request.persistence,\n },\n prepared.dependencies,\n );\n if (!result.ok) return result;\n await services.writeArtifacts(request.projectPath, [], prepared.state?.ledger);\n if (result.value.ledger === null) {\n await services.removeState(request.projectPath, request.environment);\n await services.removeCredentials(request.projectPath, request.environment);\n } else {\n await services.writeState(request.projectPath, {\n schemaVersion: 1,\n desired: prepared.desired,\n ledger: result.value.ledger,\n });\n }\n return result;\n },\n };\n}\n\ninterface PreparedProjectOperation {\n readonly operation: InfraOperationRequest;\n readonly desired: InfraEnvironmentSpec;\n readonly state: InfraStoredState | null;\n readonly dependencies: ReturnType<\n ReturnType<typeof createInfraCommandServices>['createDependencies']\n >;\n}\n\n/*** Resolve one explicit project/environment request with its prior ownership state and dependencies. */\nasync function prepareProjectOperationAsync(\n request: ProjectInfraOperationRequest,\n services: ReturnType<typeof createInfraCommandServices>,\n useStoredDesired = false,\n knownState?: InfraStoredState,\n): Promise<PreparedProjectOperation> {\n const state = knownState ?? (await services.readState(request.projectPath, request.environment));\n const currentDesired = readEnvironment(request.manifest, request.environment);\n const desired = useStoredDesired && state !== null ? state.desired : currentDesired;\n if (desired === undefined) {\n throw new Error(`Infra environment \"${request.environment}\" is not configured.`);\n }\n const context = {\n cwd: request.projectPath,\n env: request.executionEnvironment ?? process.env,\n version: INFRA_PACKAGE_VERSION,\n writeStdout: () => undefined,\n writeStderr: () => undefined,\n };\n return {\n state,\n desired,\n operation: {\n projectId: request.projectId,\n manifest: replaceEnvironment(request.manifest, request.environment, desired),\n environment: request.environment,\n ...(state === null ? {} : { previous: state.ledger, previousDesired: state.desired }),\n ...(request.signal === undefined ? {} : { signal: request.signal }),\n },\n dependencies: services.createDependencies(context, {\n projectPath: request.projectPath,\n environment: request.environment,\n }),\n };\n}\n\n/*** Require exact scope confirmation before deleting orphaned project credential state. */\nfunction validateCredentialStateDestroy(request: ProjectInfraDestroyRequest): InfraResult<null> {\n if (\n request.confirmation.projectId !== request.projectId ||\n request.confirmation.environment !== request.environment\n ) {\n return {\n ok: false,\n diagnostics: [\n {\n severity: 'error',\n code: 'infra-destroy-confirmation-mismatch',\n message:\n 'Infra destroy confirmation must exactly match the selected project and environment.',\n },\n ],\n };\n }\n return { ok: true, value: null, diagnostics: [] };\n}\n\n/*** Read one exact environment without inventing a fallback. */\nfunction readEnvironment(\n manifest: InfraManifest,\n environment: ProjectInfraOperationRequest['environment'],\n): InfraEnvironmentSpec | undefined {\n if (environment === 'local') return manifest.environments.local;\n if (environment === 'preview') return manifest.environments.preview;\n return manifest.environments.production;\n}\n\n/*** Replace one selected environment while preserving all other manifest state. */\nfunction replaceEnvironment(\n manifest: InfraManifest,\n environment: ProjectInfraOperationRequest['environment'],\n desired: InfraEnvironmentSpec,\n): InfraManifest {\n return { ...manifest, environments: { ...manifest.environments, [environment]: desired } };\n}\n"]}
1
+ {"version":3,"file":"createProjectInfraLifecycle.js","sourceRoot":"","sources":["../../../../src/features/environment-lifecycle/composition/createProjectInfraLifecycle.ts"],"names":[],"mappings":"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","sourcesContent":["import type { InfraEnvironmentSpec, InfraManifest, InfraResult } from '@ankhorage/contracts/infra';\n\nimport { INFRA_PACKAGE_VERSION } from '../../../constants.js';\nimport type { InfraOperationRequest, InfraStoredState } from '../../../types/infraOrchestration.js';\nimport type {\n CreateProjectInfraLifecycleOptions,\n ProjectInfraDestroyRequest,\n ProjectInfraLifecycle,\n ProjectInfraOperationRequest,\n} from '../../../types/infraProject.js';\nimport { createInfraCommandServices } from './createInfraCommandServices.js';\n\n/*** Create the typed project-facing Infra lifecycle backed by canonical use cases and ownership state. */\nexport function createProjectInfraLifecycle(\n options: CreateProjectInfraLifecycleOptions = {},\n): ProjectInfraLifecycle {\n const services = createInfraCommandServices(options.services);\n return {\n async validateAsync(request) {\n const prepared = await prepareProjectOperationAsync(request, services);\n return services.operations.validate(prepared.operation, prepared.dependencies);\n },\n async planAsync(request) {\n const prepared = await prepareProjectOperationAsync(request, services);\n return services.operations.plan(prepared.operation, prepared.dependencies);\n },\n async generateAsync(request) {\n const prepared = await prepareProjectOperationAsync(request, services);\n const result = await services.operations.generate(prepared.operation, prepared.dependencies);\n if (!result.ok) return result;\n await services.writeArtifacts(\n request.projectPath,\n result.value.artifacts,\n prepared.state?.ledger,\n );\n await services.writeState(request.projectPath, {\n schemaVersion: 1,\n desired: prepared.desired,\n ledger: result.value.ledger,\n });\n return result;\n },\n async upAsync(request) {\n const prepared = await prepareProjectOperationAsync(request, services);\n const result = await services.operations.up(prepared.operation, prepared.dependencies);\n if (!result.ok) return result;\n await services.writeState(request.projectPath, {\n schemaVersion: 1,\n desired: prepared.desired,\n ledger: result.value.ledger,\n });\n await services.writeEnvironmentOutputs(\n request.projectPath,\n request.environment,\n result.value.outputs,\n );\n return result;\n },\n async statusAsync(request) {\n const prepared = await prepareProjectOperationAsync(request, services);\n return services.operations.status(prepared.operation, prepared.dependencies);\n },\n async outputsAsync(request) {\n const prepared = await prepareProjectOperationAsync(request, services);\n return services.operations.outputs(prepared.operation);\n },\n async downAsync(request) {\n const prepared = await prepareProjectOperationAsync(request, services);\n const result = await services.operations.down(prepared.operation, prepared.dependencies);\n if (!result.ok) return result;\n await services.writeState(request.projectPath, {\n schemaVersion: 1,\n desired: prepared.desired,\n ledger: result.value.ledger,\n });\n return result;\n },\n async destroyAsync(request) {\n const state = await services.readState(request.projectPath, request.environment);\n if (state === null) {\n const safety = validateCredentialStateDestroy(request);\n if (!safety.ok) return safety;\n await services.removeCredentials(request.projectPath, request.environment);\n return {\n ok: true,\n value: { environment: request.environment, ledger: null },\n diagnostics: [],\n };\n }\n const prepared = await prepareProjectOperationAsync(request, services, true, state);\n const result = await services.operations.destroy(\n {\n ...prepared.operation,\n confirmation: request.confirmation,\n persistence: request.persistence,\n },\n prepared.dependencies,\n );\n if (!result.ok) return result;\n await services.writeArtifacts(request.projectPath, [], prepared.state?.ledger);\n if (result.value.ledger === null) {\n await services.removeState(request.projectPath, request.environment);\n await services.removeCredentials(request.projectPath, request.environment);\n } else {\n await services.writeState(request.projectPath, {\n schemaVersion: 1,\n desired: prepared.desired,\n ledger: result.value.ledger,\n });\n }\n return result;\n },\n };\n}\n\ninterface PreparedProjectOperation {\n readonly operation: InfraOperationRequest;\n readonly desired: InfraEnvironmentSpec;\n readonly state: InfraStoredState | null;\n readonly dependencies: ReturnType<\n ReturnType<typeof createInfraCommandServices>['createDependencies']\n >;\n}\n\n/*** Resolve one explicit project/environment request with its prior ownership state and dependencies. */\nasync function prepareProjectOperationAsync(\n request: ProjectInfraOperationRequest,\n services: ReturnType<typeof createInfraCommandServices>,\n useStoredDesired = false,\n knownState?: InfraStoredState,\n): Promise<PreparedProjectOperation> {\n const state = knownState ?? (await services.readState(request.projectPath, request.environment));\n const currentDesired = readEnvironment(request.manifest, request.environment);\n const desired = useStoredDesired && state !== null ? state.desired : currentDesired;\n if (desired === undefined) {\n throw new Error(`Infra environment \"${request.environment}\" is not configured.`);\n }\n const context = {\n cwd: request.projectPath,\n env: request.executionEnvironment ?? process.env,\n version: INFRA_PACKAGE_VERSION,\n writeStdout: () => undefined,\n writeStderr: () => undefined,\n };\n return {\n state,\n desired,\n operation: {\n projectId: request.projectId,\n manifest: replaceEnvironment(request.manifest, request.environment, desired),\n environment: request.environment,\n ...(state === null ? {} : { previous: state.ledger, previousDesired: state.desired }),\n ...(request.signal === undefined ? {} : { signal: request.signal }),\n },\n dependencies: services.createDependencies(context, {\n projectPath: request.projectPath,\n environment: request.environment,\n }),\n };\n}\n\n/*** Require exact scope confirmation before deleting orphaned project credential state. */\nfunction validateCredentialStateDestroy(request: ProjectInfraDestroyRequest): InfraResult<null> {\n if (\n request.confirmation.projectId !== request.projectId ||\n request.confirmation.environment !== request.environment\n ) {\n return {\n ok: false,\n diagnostics: [\n {\n severity: 'error',\n code: 'infra-destroy-confirmation-mismatch',\n message:\n 'Infra destroy confirmation must exactly match the selected project and environment.',\n },\n ],\n };\n }\n return { ok: true, value: null, diagnostics: [] };\n}\n\n/*** Read one exact environment without inventing a fallback. */\nfunction readEnvironment(\n manifest: InfraManifest,\n environment: ProjectInfraOperationRequest['environment'],\n): InfraEnvironmentSpec | undefined {\n if (environment === 'local') return manifest.environments.local;\n if (environment === 'preview') return manifest.environments.preview;\n return manifest.environments.production;\n}\n\n/*** Replace one selected environment while preserving all other manifest state. */\nfunction replaceEnvironment(\n manifest: InfraManifest,\n environment: ProjectInfraOperationRequest['environment'],\n desired: InfraEnvironmentSpec,\n): InfraManifest {\n return { ...manifest, environments: { ...manifest.environments, [environment]: desired } };\n}\n"]}
@@ -5,6 +5,7 @@ import type { readStoredInfraStateAsync } from '../features/environment-lifecycl
5
5
  import type { removeStoredInfraCredentialsAsync } from '../features/environment-lifecycle/adapters/outbound/removeStoredInfraCredentialsAsync.js';
6
6
  import type { removeStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/removeStoredInfraStateAsync.js';
7
7
  import type { writeInfraGeneratedArtifactsAsync } from '../features/environment-lifecycle/adapters/outbound/writeInfraGeneratedArtifactsAsync.js';
8
+ import type { writeProjectEnvironmentOutputsAsync } from '../features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.js';
8
9
  import type { writeStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/writeStoredInfraStateAsync.js';
9
10
  import type { destroyInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/destroyInfraEnvironmentAsync.js';
10
11
  import type { downInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/downInfraEnvironmentAsync.js';
@@ -75,6 +76,7 @@ export interface InfraCommandServices {
75
76
  readonly removeState: typeof removeStoredInfraStateAsync;
76
77
  readonly removeCredentials: typeof removeStoredInfraCredentialsAsync;
77
78
  readonly writeArtifacts: typeof writeInfraGeneratedArtifactsAsync;
79
+ readonly writeEnvironmentOutputs: typeof writeProjectEnvironmentOutputsAsync;
78
80
  readonly operations: InfraLifecycleOperations;
79
81
  readonly createDependencies: (context: InfraCommandContext, scope: InfraDependencyScope) => InfraOrchestrationDependencies;
80
82
  }
@@ -1 +1 @@
1
- {"version":3,"file":"infraCli.d.ts","sourceRoot":"","sources":["../../src/types/infraCli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"infraCli.d.ts","sourceRoot":"","sources":["../../src/types/infraCli.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"infraCli.js","sourceRoot":"","sources":["../../src/types/infraCli.ts"],"names":[],"mappings":"","sourcesContent":["import type { AnkhCapabilityId } from '@ankhorage/contracts/cli';\nimport type { AppEnvironmentId } from '@ankhorage/contracts/environments';\nimport type { InfraEnvironmentSpec } from '@ankhorage/contracts/infra';\n\nimport type { readStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/readStoredInfraStateAsync.js';\nimport type { removeStoredInfraCredentialsAsync } from '../features/environment-lifecycle/adapters/outbound/removeStoredInfraCredentialsAsync.js';\nimport type { removeStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/removeStoredInfraStateAsync.js';\nimport type { writeInfraGeneratedArtifactsAsync } from '../features/environment-lifecycle/adapters/outbound/writeInfraGeneratedArtifactsAsync.js';\nimport type { writeStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/writeStoredInfraStateAsync.js';\nimport type { destroyInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/destroyInfraEnvironmentAsync.js';\nimport type { downInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/downInfraEnvironmentAsync.js';\nimport type { generateInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/generateInfraEnvironmentAsync.js';\nimport type { getInfraEnvironmentOutputs } from '../features/environment-lifecycle/application/use-cases/getInfraEnvironmentOutputs.js';\nimport type { planInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/planInfraEnvironmentAsync.js';\nimport type { statusInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/statusInfraEnvironmentAsync.js';\nimport type { upInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/upInfraEnvironmentAsync.js';\nimport type { validateInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/validateInfraEnvironmentAsync.js';\nimport type {\n InfraOperationRequest,\n InfraOrchestrationDependencies,\n InfraStoredState,\n} from './infraOrchestration.js';\nimport type { ResolvedInfraProject } from './infraProject.js';\n\ntype InfraCommandName =\n 'validate' | 'plan' | 'generate' | 'up' | 'status' | 'outputs' | 'down' | 'destroy';\n\nexport interface InfraCommandContext {\n readonly cwd: string;\n readonly env: Readonly<Record<string, string | undefined>>;\n readonly version: string;\n writeStdout(text: string): void;\n writeStderr(text: string): void;\n}\n\nexport interface InfraCommandRunResult {\n readonly exitCode: number;\n}\n\nexport interface ParsedInfraArguments {\n readonly projectId?: string;\n readonly environment?: AppEnvironmentId;\n readonly format: 'human' | 'json' | 'env';\n readonly confirmation?: string;\n readonly deleteResources: readonly string[];\n}\n\nexport interface InfraCommandRunRequest {\n readonly context: InfraCommandContext;\n readonly arguments: ParsedInfraArguments;\n}\n\ntype InfraCommandImplementation = (\n request: InfraCommandRunRequest,\n services: InfraCommandServices,\n) => Promise<InfraCommandRunResult>;\n\nexport interface InfraCommandDefinition {\n readonly capability: AnkhCapabilityId;\n readonly path: readonly [InfraCommandName];\n readonly standaloneName: InfraCommandName;\n readonly summary: string;\n readonly run: InfraCommandImplementation;\n}\n\nexport interface InfraCommandInvocation {\n readonly argv: readonly string[];\n readonly command: InfraCommandDefinition;\n readonly context: InfraCommandContext;\n}\n\nexport interface InfraLifecycleOperations {\n readonly validate: typeof validateInfraEnvironmentAsync;\n readonly plan: typeof planInfraEnvironmentAsync;\n readonly generate: typeof generateInfraEnvironmentAsync;\n readonly up: typeof upInfraEnvironmentAsync;\n readonly status: typeof statusInfraEnvironmentAsync;\n readonly outputs: typeof getInfraEnvironmentOutputs;\n readonly down: typeof downInfraEnvironmentAsync;\n readonly destroy: typeof destroyInfraEnvironmentAsync;\n}\n\ninterface InfraDependencyScope {\n readonly projectPath: string;\n readonly environment: AppEnvironmentId;\n}\n\nexport interface InfraCommandServices {\n readonly resolveProject: (options: {\n readonly cwd: string;\n readonly projectId?: string;\n }) => Promise<ResolvedInfraProject>;\n readonly readState: typeof readStoredInfraStateAsync;\n readonly writeState: typeof writeStoredInfraStateAsync;\n readonly removeState: typeof removeStoredInfraStateAsync;\n readonly removeCredentials: typeof removeStoredInfraCredentialsAsync;\n readonly writeArtifacts: typeof writeInfraGeneratedArtifactsAsync;\n readonly operations: InfraLifecycleOperations;\n readonly createDependencies: (\n context: InfraCommandContext,\n scope: InfraDependencyScope,\n ) => InfraOrchestrationDependencies;\n}\n\nexport interface RunInfraCommandOptions {\n readonly services?: Partial<InfraCommandServices>;\n}\n\nexport interface CreateInfraRuntimeProviderOptions {\n readonly runCommandImpl?: RunInfraCommandImpl;\n readonly services?: Partial<InfraCommandServices>;\n}\n\nexport type RunInfraCommandImpl = (\n request: InfraCommandInvocation,\n options?: RunInfraCommandOptions,\n) => Promise<InfraCommandRunResult>;\n\nexport interface PreparedInfraCommandOperation {\n readonly project: ResolvedInfraProject;\n readonly state: InfraStoredState | null;\n readonly desired: InfraEnvironmentSpec;\n readonly operation: InfraOperationRequest;\n readonly dependencies: InfraOrchestrationDependencies;\n}\n"]}
1
+ {"version":3,"file":"infraCli.js","sourceRoot":"","sources":["../../src/types/infraCli.ts"],"names":[],"mappings":"","sourcesContent":["import type { AnkhCapabilityId } from '@ankhorage/contracts/cli';\nimport type { AppEnvironmentId } from '@ankhorage/contracts/environments';\nimport type { InfraEnvironmentSpec } from '@ankhorage/contracts/infra';\n\nimport type { readStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/readStoredInfraStateAsync.js';\nimport type { removeStoredInfraCredentialsAsync } from '../features/environment-lifecycle/adapters/outbound/removeStoredInfraCredentialsAsync.js';\nimport type { removeStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/removeStoredInfraStateAsync.js';\nimport type { writeInfraGeneratedArtifactsAsync } from '../features/environment-lifecycle/adapters/outbound/writeInfraGeneratedArtifactsAsync.js';\nimport type { writeProjectEnvironmentOutputsAsync } from '../features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.js';\nimport type { writeStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/writeStoredInfraStateAsync.js';\nimport type { destroyInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/destroyInfraEnvironmentAsync.js';\nimport type { downInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/downInfraEnvironmentAsync.js';\nimport type { generateInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/generateInfraEnvironmentAsync.js';\nimport type { getInfraEnvironmentOutputs } from '../features/environment-lifecycle/application/use-cases/getInfraEnvironmentOutputs.js';\nimport type { planInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/planInfraEnvironmentAsync.js';\nimport type { statusInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/statusInfraEnvironmentAsync.js';\nimport type { upInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/upInfraEnvironmentAsync.js';\nimport type { validateInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/validateInfraEnvironmentAsync.js';\nimport type {\n InfraOperationRequest,\n InfraOrchestrationDependencies,\n InfraStoredState,\n} from './infraOrchestration.js';\nimport type { ResolvedInfraProject } from './infraProject.js';\n\ntype InfraCommandName =\n 'validate' | 'plan' | 'generate' | 'up' | 'status' | 'outputs' | 'down' | 'destroy';\n\nexport interface InfraCommandContext {\n readonly cwd: string;\n readonly env: Readonly<Record<string, string | undefined>>;\n readonly version: string;\n writeStdout(text: string): void;\n writeStderr(text: string): void;\n}\n\nexport interface InfraCommandRunResult {\n readonly exitCode: number;\n}\n\nexport interface ParsedInfraArguments {\n readonly projectId?: string;\n readonly environment?: AppEnvironmentId;\n readonly format: 'human' | 'json' | 'env';\n readonly confirmation?: string;\n readonly deleteResources: readonly string[];\n}\n\nexport interface InfraCommandRunRequest {\n readonly context: InfraCommandContext;\n readonly arguments: ParsedInfraArguments;\n}\n\ntype InfraCommandImplementation = (\n request: InfraCommandRunRequest,\n services: InfraCommandServices,\n) => Promise<InfraCommandRunResult>;\n\nexport interface InfraCommandDefinition {\n readonly capability: AnkhCapabilityId;\n readonly path: readonly [InfraCommandName];\n readonly standaloneName: InfraCommandName;\n readonly summary: string;\n readonly run: InfraCommandImplementation;\n}\n\nexport interface InfraCommandInvocation {\n readonly argv: readonly string[];\n readonly command: InfraCommandDefinition;\n readonly context: InfraCommandContext;\n}\n\nexport interface InfraLifecycleOperations {\n readonly validate: typeof validateInfraEnvironmentAsync;\n readonly plan: typeof planInfraEnvironmentAsync;\n readonly generate: typeof generateInfraEnvironmentAsync;\n readonly up: typeof upInfraEnvironmentAsync;\n readonly status: typeof statusInfraEnvironmentAsync;\n readonly outputs: typeof getInfraEnvironmentOutputs;\n readonly down: typeof downInfraEnvironmentAsync;\n readonly destroy: typeof destroyInfraEnvironmentAsync;\n}\n\ninterface InfraDependencyScope {\n readonly projectPath: string;\n readonly environment: AppEnvironmentId;\n}\n\nexport interface InfraCommandServices {\n readonly resolveProject: (options: {\n readonly cwd: string;\n readonly projectId?: string;\n }) => Promise<ResolvedInfraProject>;\n readonly readState: typeof readStoredInfraStateAsync;\n readonly writeState: typeof writeStoredInfraStateAsync;\n readonly removeState: typeof removeStoredInfraStateAsync;\n readonly removeCredentials: typeof removeStoredInfraCredentialsAsync;\n readonly writeArtifacts: typeof writeInfraGeneratedArtifactsAsync;\n readonly writeEnvironmentOutputs: typeof writeProjectEnvironmentOutputsAsync;\n readonly operations: InfraLifecycleOperations;\n readonly createDependencies: (\n context: InfraCommandContext,\n scope: InfraDependencyScope,\n ) => InfraOrchestrationDependencies;\n}\n\nexport interface RunInfraCommandOptions {\n readonly services?: Partial<InfraCommandServices>;\n}\n\nexport interface CreateInfraRuntimeProviderOptions {\n readonly runCommandImpl?: RunInfraCommandImpl;\n readonly services?: Partial<InfraCommandServices>;\n}\n\nexport type RunInfraCommandImpl = (\n request: InfraCommandInvocation,\n options?: RunInfraCommandOptions,\n) => Promise<InfraCommandRunResult>;\n\nexport interface PreparedInfraCommandOperation {\n readonly project: ResolvedInfraProject;\n readonly state: InfraStoredState | null;\n readonly desired: InfraEnvironmentSpec;\n readonly operation: InfraOperationRequest;\n readonly dependencies: InfraOrchestrationDependencies;\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ankhorage/infra",
3
3
  "type": "module",
4
- "version": "7.1.1",
4
+ "version": "7.1.3",
5
5
  "description": "Project-aware infrastructure generation library and executable Ankh provider for Ankhorage.",
6
6
  "homepage": "https://github.com/ankhorage/infra#readme",
7
7
  "bugs": {
@@ -35,6 +35,7 @@
35
35
  "openapi"
36
36
  ],
37
37
  "dependencies": {
38
+ "@ankhorage/ankh": "^0.9.1",
38
39
  "@ankhorage/contracts": "^21.0.0",
39
40
  "@ankhorage/utility": "^1.2.0"
40
41
  },
@@ -111,9 +112,8 @@
111
112
  "knip:test": "bun run knip:check"
112
113
  },
113
114
  "devDependencies": {
114
- "@ankhorage/ankh": "^0.8.11",
115
115
  "@ankhorage/cerbos": "^0.2.0",
116
- "@ankhorage/devtools": "^1.14.0",
116
+ "@ankhorage/devtools": "^1.15.3",
117
117
  "@ankhorage/docker-compose": "^0.5.3",
118
118
  "@ankhorage/hetzner": "^0.3.0",
119
119
  "@ankhorage/k3s": "^0.4.1",
@@ -1,15 +1,31 @@
1
+ import { renderProviderHelp } from '@ankhorage/ankh';
1
2
  import { describe, expect, test } from 'bun:test';
2
3
 
4
+ import { INFRA_PACKAGE_DESCRIPTION } from '../constants.js';
3
5
  import { createCapturedCommandContext } from '../testSupport.js';
6
+ import { createInfraRuntimeProvider } from './createInfraRuntimeProvider.js';
4
7
  import { runInfraCliAsync } from './runInfraCliAsync.js';
5
8
 
6
9
  describe('standalone Infra CLI', () => {
7
- test('prints help/version and dispatches all commands through the shared runner', async () => {
8
- const help = createCapturedCommandContext('/workspace', '9.9.9');
10
+ test('renders every help alias from the canonical provider manifest', async () => {
11
+ const expectedHelp = renderProviderHelp({
12
+ commandPrefix: ['ankhorage-infra'],
13
+ description: INFRA_PACKAGE_DESCRIPTION,
14
+ manifest: createInfraRuntimeProvider(),
15
+ });
16
+
17
+ for (const argv of [[], ['-h'], ['--help'], ['help']] as const) {
18
+ const captured = createCapturedCommandContext('/workspace', '9.9.9');
19
+ const result = await runInfraCliAsync(argv, { context: captured.context });
20
+
21
+ expect(result).toEqual({ exitCode: 0 });
22
+ expect(captured.stdout.value).toBe(expectedHelp);
23
+ expect(captured.stderr.value).toBe('');
24
+ }
25
+ });
26
+
27
+ test('prints version and dispatches all commands through the shared runner', async () => {
9
28
  const version = createCapturedCommandContext('/workspace', '9.9.9');
10
- expect((await runInfraCliAsync([], { context: help.context })).exitCode).toBe(0);
11
- expect(help.stdout.value).toContain('ankhorage-infra <command>');
12
- expect(help.stdout.value).toContain('destroy');
13
29
  expect((await runInfraCliAsync(['--version'], { context: version.context })).exitCode).toBe(0);
14
30
  expect(version.stdout.value).toBe('9.9.9\n');
15
31
 
@@ -19,6 +19,11 @@ export const up = {
19
19
  desired: operation.desired,
20
20
  ledger: result.value.ledger,
21
21
  });
22
+ await services.writeEnvironmentOutputs(
23
+ operation.project.projectPath,
24
+ result.value.environment,
25
+ result.value.outputs,
26
+ );
22
27
  writeInfraStructured(request.context, request.arguments.format, {
23
28
  environment: result.value.environment,
24
29
  resources: result.value.resources.length,
@@ -1,3 +1,6 @@
1
+ import { isHelpToken, renderProviderHelp } from '@ankhorage/ankh';
2
+
3
+ import { INFRA_PACKAGE_DESCRIPTION } from '../constants.js';
1
4
  import type {
2
5
  InfraCommandContext,
3
6
  InfraCommandRunResult,
@@ -5,8 +8,8 @@ import type {
5
8
  RunInfraCommandImpl,
6
9
  } from '../types/infraCli.js';
7
10
  import { createDefaultInfraCommandContext } from './createDefaultInfraCommandContext.js';
11
+ import { createInfraRuntimeProvider } from './createInfraRuntimeProvider.js';
8
12
  import { findInfraCommand } from './findInfraCommand.js';
9
- import { renderInfraRootHelp } from './renderInfraRootHelp.js';
10
13
  import { renderUnknownInfraCommand } from './renderUnknownInfraCommand.js';
11
14
  import { runInfraCommandAsync } from './runInfraCommandAsync.js';
12
15
 
@@ -19,7 +22,13 @@ export async function runInfraCliAsync(
19
22
  const runCommand = options.runCommandImpl ?? runInfraCommandAsync;
20
23
  const [firstToken, ...restTokens] = argv;
21
24
  if (firstToken === undefined || isHelpToken(firstToken)) {
22
- context.writeStdout(renderInfraRootHelp(context.version));
25
+ context.writeStdout(
26
+ renderProviderHelp({
27
+ commandPrefix: ['ankhorage-infra'],
28
+ description: INFRA_PACKAGE_DESCRIPTION,
29
+ manifest: createInfraRuntimeProvider(),
30
+ }),
31
+ );
23
32
  return { exitCode: 0 };
24
33
  }
25
34
  if (isVersionToken(firstToken)) {
@@ -40,11 +49,6 @@ interface InfraCliOptions {
40
49
  readonly services?: Partial<InfraCommandServices>;
41
50
  }
42
51
 
43
- /*** Recognize standalone help tokens. */
44
- function isHelpToken(value: string): boolean {
45
- return value === '--help' || value === '-h' || value === 'help';
46
- }
47
-
48
52
  /*** Recognize standalone version tokens. */
49
53
  function isVersionToken(value: string): boolean {
50
54
  return value === '--version' || value === '-v' || value === 'version';
@@ -1,12 +1,14 @@
1
+ import { renderProviderHelp } from '@ankhorage/ankh';
1
2
  import type { AppManifest } from '@ankhorage/contracts';
2
3
  import type { InfraEnvironmentSpec, InfraLedger, InfraResult } from '@ankhorage/contracts/infra';
3
4
  import { describe, expect, test } from 'bun:test';
4
5
 
5
6
  import { INFRA_COMMANDS } from './cli/constants.js';
7
+ import { createInfraRuntimeProvider } from './cli/createInfraRuntimeProvider.js';
6
8
  import { createProviderCommandDescriptors } from './cli/createProviderCommandDescriptors.js';
7
9
  import { findInfraCommand } from './cli/findInfraCommand.js';
8
- import { renderInfraRootHelp } from './cli/renderInfraRootHelp.js';
9
10
  import { runInfraCommandAsync } from './cli/runInfraCommandAsync.js';
11
+ import { INFRA_PACKAGE_DESCRIPTION } from './constants.js';
10
12
  import { createAppManifest, createCapturedCommandContext } from './testSupport.js';
11
13
  import type { InfraCommandServices, InfraLifecycleOperations } from './types/infraCli.js';
12
14
  import type { InfraDestroyOperationRequest } from './types/infraOrchestration.js';
@@ -16,7 +18,11 @@ describe('canonical Infra commands', () => {
16
18
  const names = ['validate', 'plan', 'generate', 'up', 'status', 'outputs', 'down', 'destroy'];
17
19
  expect(INFRA_COMMANDS.map(({ standaloneName }) => standaloneName)).toEqual(names);
18
20
  expect(createProviderCommandDescriptors().map(({ path }) => path.join(' '))).toEqual(names);
19
- const help = renderInfraRootHelp('9.9.9');
21
+ const help = renderProviderHelp({
22
+ commandPrefix: ['ankhorage-infra'],
23
+ description: INFRA_PACKAGE_DESCRIPTION,
24
+ manifest: createInfraRuntimeProvider(),
25
+ });
20
26
  for (const name of names) expect(help).toContain(name);
21
27
  expect(help).not.toContain('port-forward');
22
28
  expect(help).not.toContain('reset');
package/src/constants.ts CHANGED
@@ -8,6 +8,7 @@ import packageJson from '../package.json';
8
8
 
9
9
  export const INFRA_PACKAGE_NAME = packageJson.name;
10
10
  export const INFRA_PACKAGE_VERSION = packageJson.version;
11
+ export const INFRA_PACKAGE_DESCRIPTION = packageJson.description;
11
12
  export const INFRA_COMMAND_CATEGORY = 'infra' as const satisfies AnkhCommandCategory;
12
13
  export const INFRA_CAPABILITIES = [
13
14
  'infra.validate',
@@ -0,0 +1,84 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ import type { AppEnvironmentId } from '@ankhorage/contracts/environments';
5
+ import type { InfraOutput } from '@ankhorage/contracts/infra';
6
+ import { pathExists } from '@ankhorage/utility/node/fs';
7
+
8
+ const ENVIRONMENT_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/u;
9
+ const ENVIRONMENT_ASSIGNMENT_PATTERN = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/u;
10
+
11
+ /*** Materialize public local Infra outputs into the project app environment while preserving unrelated entries. */
12
+ export async function writeProjectEnvironmentOutputsAsync(
13
+ projectPath: string,
14
+ environment: AppEnvironmentId,
15
+ outputs: readonly InfraOutput[],
16
+ ): Promise<void> {
17
+ if (environment !== 'local') return;
18
+
19
+ const values = collectEnvironmentValues(outputs);
20
+ if (values.size === 0) return;
21
+
22
+ const environmentPath = path.join(projectPath, '.env.local');
23
+ const current = (await pathExists(environmentPath))
24
+ ? await fs.readFile(environmentPath, 'utf8')
25
+ : '';
26
+ const next = mergeEnvironmentFile(current, values);
27
+ if (next === current) return;
28
+
29
+ await fs.mkdir(projectPath, { recursive: true });
30
+ await fs.writeFile(environmentPath, next, 'utf8');
31
+ }
32
+
33
+ /*** Collect only browser-safe public outputs that explicitly declare an environment variable. */
34
+ function collectEnvironmentValues(outputs: readonly InfraOutput[]): ReadonlyMap<string, string> {
35
+ const values = new Map<string, string>();
36
+ for (const output of outputs) {
37
+ if (output.visibility !== 'public' || output.environmentVariable === undefined) continue;
38
+ if (!ENVIRONMENT_NAME_PATTERN.test(output.environmentVariable)) {
39
+ throw new Error(`Invalid Infra environment variable name: ${output.environmentVariable}`);
40
+ }
41
+ values.set(output.environmentVariable, String(output.value));
42
+ }
43
+ return values;
44
+ }
45
+
46
+ /*** Merge managed environment values without changing unrelated lines or retaining duplicate managed keys. */
47
+ function mergeEnvironmentFile(current: string, values: ReadonlyMap<string, string>): string {
48
+ const normalized = current.replaceAll('\r\n', '\n');
49
+ const lines = normalized.length === 0 ? [] : normalized.split('\n');
50
+ if (lines.at(-1) === '') lines.pop();
51
+
52
+ const written = new Set<string>();
53
+ const nextLines: string[] = [];
54
+ for (const line of lines) {
55
+ const name = readEnvironmentAssignmentName(line);
56
+ if (name !== undefined && values.has(name)) {
57
+ if (!written.has(name)) {
58
+ nextLines.push(`${name}=${serializeEnvironmentValue(values.get(name) ?? '')}`);
59
+ written.add(name);
60
+ }
61
+ continue;
62
+ }
63
+ nextLines.push(line);
64
+ }
65
+
66
+ for (const [name, value] of [...values.entries()].sort(([left], [right]) =>
67
+ left.localeCompare(right),
68
+ )) {
69
+ if (written.has(name)) continue;
70
+ nextLines.push(`${name}=${serializeEnvironmentValue(value)}`);
71
+ }
72
+
73
+ return nextLines.length === 0 ? '' : `${nextLines.join('\n')}\n`;
74
+ }
75
+
76
+ /*** Read an environment assignment name without interpreting or mutating its value. */
77
+ function readEnvironmentAssignmentName(line: string): string | undefined {
78
+ return ENVIRONMENT_ASSIGNMENT_PATTERN.exec(line)?.[1];
79
+ }
80
+
81
+ /*** Serialize one primitive Infra output as a quoted dotenv value. */
82
+ function serializeEnvironmentValue(value: string): string {
83
+ return JSON.stringify(value);
84
+ }
@@ -7,6 +7,7 @@ import { removeStoredInfraCredentialsAsync } from '../adapters/outbound/removeSt
7
7
  import { removeStoredInfraStateAsync } from '../adapters/outbound/removeStoredInfraStateAsync.js';
8
8
  import { resolveInfraProjectAsync } from '../adapters/outbound/resolveInfraProjectAsync.js';
9
9
  import { writeInfraGeneratedArtifactsAsync } from '../adapters/outbound/writeInfraGeneratedArtifactsAsync.js';
10
+ import { writeProjectEnvironmentOutputsAsync } from '../adapters/outbound/writeProjectEnvironmentOutputsAsync.js';
10
11
  import { writeStoredInfraStateAsync } from '../adapters/outbound/writeStoredInfraStateAsync.js';
11
12
  import { destroyInfraEnvironmentAsync } from '../application/use-cases/destroyInfraEnvironmentAsync.js';
12
13
  import { downInfraEnvironmentAsync } from '../application/use-cases/downInfraEnvironmentAsync.js';
@@ -28,6 +29,8 @@ export function createInfraCommandServices(
28
29
  removeState: overrides.removeState ?? removeStoredInfraStateAsync,
29
30
  removeCredentials: overrides.removeCredentials ?? removeStoredInfraCredentialsAsync,
30
31
  writeArtifacts: overrides.writeArtifacts ?? writeInfraGeneratedArtifactsAsync,
32
+ writeEnvironmentOutputs:
33
+ overrides.writeEnvironmentOutputs ?? writeProjectEnvironmentOutputsAsync,
31
34
  operations: overrides.operations ?? {
32
35
  validate: validateInfraEnvironmentAsync,
33
36
  plan: planInfraEnvironmentAsync,
@@ -49,6 +49,11 @@ export function createProjectInfraLifecycle(
49
49
  desired: prepared.desired,
50
50
  ledger: result.value.ledger,
51
51
  });
52
+ await services.writeEnvironmentOutputs(
53
+ request.projectPath,
54
+ request.environment,
55
+ result.value.outputs,
56
+ );
52
57
  return result;
53
58
  },
54
59
  async statusAsync(request) {
@@ -0,0 +1,225 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+
5
+ import type {
6
+ InfraEnvironmentSpec,
7
+ InfraLedger,
8
+ InfraOutput,
9
+ InfraResult,
10
+ } from '@ankhorage/contracts/infra';
11
+ import { afterEach, expect, test } from 'bun:test';
12
+
13
+ import { up } from './cli/commands/up.js';
14
+ import { writeProjectEnvironmentOutputsAsync } from './features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.js';
15
+ import { createInfraCommandServices } from './features/environment-lifecycle/composition/createInfraCommandServices.js';
16
+ import { createProjectInfraLifecycle } from './project/index.js';
17
+ import { createAppManifest, createCapturedCommandContext } from './testSupport.js';
18
+ import type { InfraLifecycleOperations } from './types/infraCli.js';
19
+ import type { InfraDestroyOperationRequest } from './types/infraOrchestration.js';
20
+
21
+ const temporaryPaths = new Set<string>();
22
+
23
+ afterEach(async () => {
24
+ await Promise.all(
25
+ [...temporaryPaths].map((entry) => fs.rm(entry, { force: true, recursive: true })),
26
+ );
27
+ temporaryPaths.clear();
28
+ });
29
+
30
+ test('project local up materializes only named public outputs and preserves unrelated env content', async () => {
31
+ const projectPath = await fs.mkdtemp(path.join(os.tmpdir(), 'infra-project-env-'));
32
+ temporaryPaths.add(projectPath);
33
+ await fs.writeFile(
34
+ path.join(projectPath, '.env.local'),
35
+ '# existing\nUNCHANGED=value\nEXPO_PUBLIC_SUPABASE_URL=stale\nEXPO_PUBLIC_SUPABASE_URL=duplicate\n',
36
+ 'utf8',
37
+ );
38
+
39
+ const lifecycle = createProjectInfraLifecycle({
40
+ services: {
41
+ readState: () => Promise.resolve(null),
42
+ writeState: () => Promise.resolve(),
43
+ createDependencies: createDependencies,
44
+ operations: createOperations(),
45
+ },
46
+ });
47
+ const request = {
48
+ projectId: 'sample',
49
+ projectPath,
50
+ manifest: { environments: { local: desired }, modules: [] },
51
+ environment: 'local' as const,
52
+ };
53
+
54
+ expect((await lifecycle.upAsync(request)).ok).toBe(true);
55
+ const first = await fs.readFile(path.join(projectPath, '.env.local'), 'utf8');
56
+ expect(first).toBe(
57
+ '# existing\nUNCHANGED=value\nEXPO_PUBLIC_SUPABASE_URL="https://supabase.example.test"\nEXPO_PUBLIC_SUPABASE_ANON_KEY="public-anon-key"\n',
58
+ );
59
+ expect(first).not.toContain('ignored-public-value');
60
+ expect(first).not.toContain('database-password');
61
+
62
+ expect((await lifecycle.upAsync(request)).ok).toBe(true);
63
+ expect(await fs.readFile(path.join(projectPath, '.env.local'), 'utf8')).toBe(first);
64
+ });
65
+
66
+ test('non-local output materialization leaves the local app environment untouched', async () => {
67
+ const projectPath = await fs.mkdtemp(path.join(os.tmpdir(), 'infra-project-env-'));
68
+ temporaryPaths.add(projectPath);
69
+ const environmentPath = path.join(projectPath, '.env.local');
70
+ await fs.writeFile(environmentPath, 'UNCHANGED=value\n', 'utf8');
71
+
72
+ await writeProjectEnvironmentOutputsAsync(projectPath, 'preview', outputs);
73
+
74
+ expect(await fs.readFile(environmentPath, 'utf8')).toBe('UNCHANGED=value\n');
75
+ });
76
+
77
+ test('standalone up delegates local public output materialization through the shared service', async () => {
78
+ const writes: {
79
+ environment: string;
80
+ outputs: readonly InfraOutput[];
81
+ projectPath: string;
82
+ }[] = [];
83
+ const manifest = createAppManifest('sample', {
84
+ environments: { local: desired },
85
+ modules: [],
86
+ });
87
+ const services = createInfraCommandServices({
88
+ resolveProject: () =>
89
+ Promise.resolve({
90
+ appsRoot: '/workspace/apps',
91
+ workspaceRoot: '/workspace',
92
+ manifestPath: '/workspace/apps/sample/ankh.config.json',
93
+ projectId: 'sample',
94
+ projectPath: '/workspace/apps/sample',
95
+ manifest,
96
+ }),
97
+ readState: () => Promise.resolve(null),
98
+ writeState: () => Promise.resolve(),
99
+ writeEnvironmentOutputs: (projectPath, environment, resultOutputs) => {
100
+ writes.push({ projectPath, environment, outputs: resultOutputs });
101
+ return Promise.resolve();
102
+ },
103
+ createDependencies,
104
+ operations: createOperations(),
105
+ });
106
+ const captured = createCapturedCommandContext('/workspace');
107
+
108
+ const result = await up.run(
109
+ {
110
+ context: captured.context,
111
+ arguments: {
112
+ projectId: 'sample',
113
+ environment: 'local',
114
+ format: 'json',
115
+ deleteResources: [],
116
+ },
117
+ },
118
+ services,
119
+ );
120
+
121
+ expect(result.exitCode).toBe(0);
122
+ expect(writes).toEqual([
123
+ { projectPath: '/workspace/apps/sample', environment: 'local', outputs },
124
+ ]);
125
+ });
126
+
127
+ const desired = {
128
+ deployment: {
129
+ compute: { provider: 'local' },
130
+ runtime: { provider: 'docker-compose' },
131
+ },
132
+ } as const satisfies InfraEnvironmentSpec;
133
+
134
+ const owner = {
135
+ projectId: 'sample',
136
+ environment: 'local',
137
+ adapter: 'supabase',
138
+ resourceId: 'runtime',
139
+ } as const;
140
+
141
+ const outputs = [
142
+ {
143
+ owner,
144
+ name: 'url',
145
+ visibility: 'public',
146
+ value: 'https://supabase.example.test',
147
+ environmentVariable: 'EXPO_PUBLIC_SUPABASE_URL',
148
+ },
149
+ {
150
+ owner,
151
+ name: 'anon-key',
152
+ visibility: 'public',
153
+ value: 'public-anon-key',
154
+ environmentVariable: 'EXPO_PUBLIC_SUPABASE_ANON_KEY',
155
+ },
156
+ {
157
+ owner,
158
+ name: 'ignored',
159
+ visibility: 'public',
160
+ value: 'ignored-public-value',
161
+ },
162
+ {
163
+ owner,
164
+ name: 'password',
165
+ visibility: 'secret',
166
+ reference: {
167
+ source: 'secret-store',
168
+ projectId: 'sample',
169
+ environment: 'local',
170
+ ref: 'database',
171
+ key: 'database-password',
172
+ },
173
+ },
174
+ ] as const satisfies readonly InfraOutput[];
175
+
176
+ const ledger = {
177
+ schemaVersion: 1,
178
+ projectId: 'sample',
179
+ environment: 'local',
180
+ targets: [],
181
+ resources: [],
182
+ outputs,
183
+ artifacts: [],
184
+ } as const satisfies InfraLedger;
185
+
186
+ /*** Create deterministic project and command dependencies for environment-output tests. */
187
+ function createDependencies() {
188
+ return {
189
+ adapterResolver: { loadAsync: () => Promise.resolve({}) },
190
+ credentials: { resolveAsync: () => Promise.resolve(success({})) },
191
+ secrets: { resolveAsync: () => Promise.resolve(success('secret')) },
192
+ };
193
+ }
194
+
195
+ /*** Create deterministic lifecycle operations that expose representative public and secret outputs. */
196
+ function createOperations(): InfraLifecycleOperations {
197
+ return {
198
+ validate: () => Promise.resolve(success({ environment: 'local' })),
199
+ plan: (request) =>
200
+ Promise.resolve(success({ projectId: request.projectId, environment: 'local', actions: [] })),
201
+ generate: () => Promise.resolve(success({ environment: 'local', artifacts: [], ledger })),
202
+ up: () =>
203
+ Promise.resolve(
204
+ success({ environment: 'local', targets: [], resources: [], outputs, ledger }),
205
+ ),
206
+ status: (request) =>
207
+ Promise.resolve(
208
+ success({
209
+ projectId: request.projectId,
210
+ environment: 'local',
211
+ state: 'ready',
212
+ resources: [],
213
+ }),
214
+ ),
215
+ outputs: () => success({ environment: 'local', outputs }),
216
+ down: () => Promise.resolve(success({ environment: 'local', ledger })),
217
+ destroy: (request: InfraDestroyOperationRequest) =>
218
+ Promise.resolve(success({ environment: request.environment ?? 'local', ledger: null })),
219
+ };
220
+ }
221
+
222
+ /*** Create one successful Infra result for deterministic operation fakes. */
223
+ function success<T>(value: T): InfraResult<T> {
224
+ return { ok: true, value, diagnostics: [] };
225
+ }
@@ -6,6 +6,7 @@ import type { readStoredInfraStateAsync } from '../features/environment-lifecycl
6
6
  import type { removeStoredInfraCredentialsAsync } from '../features/environment-lifecycle/adapters/outbound/removeStoredInfraCredentialsAsync.js';
7
7
  import type { removeStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/removeStoredInfraStateAsync.js';
8
8
  import type { writeInfraGeneratedArtifactsAsync } from '../features/environment-lifecycle/adapters/outbound/writeInfraGeneratedArtifactsAsync.js';
9
+ import type { writeProjectEnvironmentOutputsAsync } from '../features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.js';
9
10
  import type { writeStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/writeStoredInfraStateAsync.js';
10
11
  import type { destroyInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/destroyInfraEnvironmentAsync.js';
11
12
  import type { downInfraEnvironmentAsync } from '../features/environment-lifecycle/application/use-cases/downInfraEnvironmentAsync.js';
@@ -95,6 +96,7 @@ export interface InfraCommandServices {
95
96
  readonly removeState: typeof removeStoredInfraStateAsync;
96
97
  readonly removeCredentials: typeof removeStoredInfraCredentialsAsync;
97
98
  readonly writeArtifacts: typeof writeInfraGeneratedArtifactsAsync;
99
+ readonly writeEnvironmentOutputs: typeof writeProjectEnvironmentOutputsAsync;
98
100
  readonly operations: InfraLifecycleOperations;
99
101
  readonly createDependencies: (
100
102
  context: InfraCommandContext,
@@ -1,3 +0,0 @@
1
- /*** Render the standalone Infra command surface and environment safety rules. */
2
- export declare function renderInfraRootHelp(version: string): string;
3
- //# sourceMappingURL=renderInfraRootHelp.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"renderInfraRootHelp.d.ts","sourceRoot":"","sources":["../../src/cli/renderInfraRootHelp.ts"],"names":[],"mappings":"AAGA,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAkB3D"}
@@ -1,21 +0,0 @@
1
- import { INFRA_COMMAND_CATEGORY } from '../constants.js';
2
- import { INFRA_COMMANDS } from './constants.js';
3
- /*** Render the standalone Infra command surface and environment safety rules. */
4
- export function renderInfraRootHelp(version) {
5
- const commands = INFRA_COMMANDS.map(({ standaloneName, summary }) => ` ${standaloneName.padEnd(8, ' ')} ${summary}`).join('\n');
6
- return [
7
- `@ankhorage/infra v${version}`,
8
- '',
9
- 'Usage:',
10
- ' ankhorage-infra <command> [project] [--environment <environment>]',
11
- ` ankh ${INFRA_COMMAND_CATEGORY} <command> [project] [--environment <environment>]`,
12
- '',
13
- 'Commands:',
14
- commands,
15
- '',
16
- 'Safety:',
17
- ' local is the only implicit environment; destroy always requires --environment and --confirm.',
18
- '',
19
- ].join('\n');
20
- }
21
- //# sourceMappingURL=renderInfraRootHelp.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"renderInfraRootHelp.js","sourceRoot":"","sources":["../../src/cli/renderInfraRootHelp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,iFAAiF;AACjF,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CACjC,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,KAAK,cAAc,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,OAAO,EAAE,CACjF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,OAAO;QACL,qBAAqB,OAAO,EAAE;QAC9B,EAAE;QACF,QAAQ;QACR,qEAAqE;QACrE,UAAU,sBAAsB,oDAAoD;QACpF,EAAE;QACF,WAAW;QACX,QAAQ;QACR,EAAE;QACF,SAAS;QACT,gGAAgG;QAChG,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC","sourcesContent":["import { INFRA_COMMAND_CATEGORY } from '../constants.js';\nimport { INFRA_COMMANDS } from './constants.js';\n\n/*** Render the standalone Infra command surface and environment safety rules. */\nexport function renderInfraRootHelp(version: string): string {\n const commands = INFRA_COMMANDS.map(\n ({ standaloneName, summary }) => ` ${standaloneName.padEnd(8, ' ')} ${summary}`,\n ).join('\\n');\n return [\n `@ankhorage/infra v${version}`,\n '',\n 'Usage:',\n ' ankhorage-infra <command> [project] [--environment <environment>]',\n ` ankh ${INFRA_COMMAND_CATEGORY} <command> [project] [--environment <environment>]`,\n '',\n 'Commands:',\n commands,\n '',\n 'Safety:',\n ' local is the only implicit environment; destroy always requires --environment and --confirm.',\n '',\n ].join('\\n');\n}\n"]}
@@ -1,23 +0,0 @@
1
- import { INFRA_COMMAND_CATEGORY } from '../constants.js';
2
- import { INFRA_COMMANDS } from './constants.js';
3
-
4
- /*** Render the standalone Infra command surface and environment safety rules. */
5
- export function renderInfraRootHelp(version: string): string {
6
- const commands = INFRA_COMMANDS.map(
7
- ({ standaloneName, summary }) => ` ${standaloneName.padEnd(8, ' ')} ${summary}`,
8
- ).join('\n');
9
- return [
10
- `@ankhorage/infra v${version}`,
11
- '',
12
- 'Usage:',
13
- ' ankhorage-infra <command> [project] [--environment <environment>]',
14
- ` ankh ${INFRA_COMMAND_CATEGORY} <command> [project] [--environment <environment>]`,
15
- '',
16
- 'Commands:',
17
- commands,
18
- '',
19
- 'Safety:',
20
- ' local is the only implicit environment; destroy always requires --environment and --confirm.',
21
- '',
22
- ].join('\n');
23
- }