@ankhorage/infra 7.1.2 → 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.
- package/CHANGELOG.md +6 -0
- package/dist/cli/commands/up.d.ts.map +1 -1
- package/dist/cli/commands/up.js +1 -0
- package/dist/cli/commands/up.js.map +1 -1
- package/dist/features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.d.ts +5 -0
- package/dist/features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.d.ts.map +1 -0
- package/dist/features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.js +70 -0
- package/dist/features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.js.map +1 -0
- package/dist/features/environment-lifecycle/composition/createInfraCommandServices.d.ts.map +1 -1
- package/dist/features/environment-lifecycle/composition/createInfraCommandServices.js +2 -0
- package/dist/features/environment-lifecycle/composition/createInfraCommandServices.js.map +1 -1
- package/dist/features/environment-lifecycle/composition/createProjectInfraLifecycle.d.ts.map +1 -1
- package/dist/features/environment-lifecycle/composition/createProjectInfraLifecycle.js +1 -0
- package/dist/features/environment-lifecycle/composition/createProjectInfraLifecycle.js.map +1 -1
- package/dist/types/infraCli.d.ts +2 -0
- package/dist/types/infraCli.d.ts.map +1 -1
- package/dist/types/infraCli.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/commands/up.ts +5 -0
- package/src/features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.ts +84 -0
- package/src/features/environment-lifecycle/composition/createInfraCommandServices.ts +3 -0
- package/src/features/environment-lifecycle/composition/createProjectInfraLifecycle.ts +5 -0
- package/src/projectEnvironmentOutputs.test.ts +225 -0
- package/src/types/infraCli.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
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
|
+
|
|
3
9
|
## 7.1.2
|
|
4
10
|
|
|
5
11
|
### 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;;;;;;;;
|
|
1
|
+
{"version":3,"file":"up.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/up.ts"],"names":[],"mappings":"AAMA,kEAAkE;AAClE,eAAO,MAAM,EAAE;;;;;;;;CA0B4B,CAAC"}
|
package/dist/cli/commands/up.js
CHANGED
|
@@ -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"]}
|
|
@@ -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"}
|
package/dist/features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.js
ADDED
|
@@ -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;
|
|
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"]}
|
package/dist/features/environment-lifecycle/composition/createProjectInfraLifecycle.d.ts.map
CHANGED
|
@@ -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,
|
|
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"]}
|
package/dist/types/infraCli.d.ts
CHANGED
|
@@ -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.
|
|
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": {
|
package/src/cli/commands/up.ts
CHANGED
|
@@ -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,
|
package/src/features/environment-lifecycle/adapters/outbound/writeProjectEnvironmentOutputsAsync.ts
ADDED
|
@@ -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
|
+
}
|
package/src/types/infraCli.ts
CHANGED
|
@@ -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,
|