@ankhorage/infra 6.0.0 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/dist/cli/commands/destroy.d.ts.map +1 -1
- package/dist/cli/commands/destroy.js +1 -0
- package/dist/cli/commands/destroy.js.map +1 -1
- package/dist/cli/utils/prepareInfraCommandOperationAsync.d.ts.map +1 -1
- package/dist/cli/utils/prepareInfraCommandOperationAsync.js +4 -1
- package/dist/cli/utils/prepareInfraCommandOperationAsync.js.map +1 -1
- package/dist/features/environment-lifecycle/adapters/outbound/createEnvironmentInfraCredentialPort.d.ts.map +1 -1
- package/dist/features/environment-lifecycle/adapters/outbound/createEnvironmentInfraCredentialPort.js +33 -10
- package/dist/features/environment-lifecycle/adapters/outbound/createEnvironmentInfraCredentialPort.js.map +1 -1
- package/dist/features/environment-lifecycle/adapters/outbound/createProjectInfraCredentialPort.d.ts +11 -0
- package/dist/features/environment-lifecycle/adapters/outbound/createProjectInfraCredentialPort.d.ts.map +1 -0
- package/dist/features/environment-lifecycle/adapters/outbound/createProjectInfraCredentialPort.js +125 -0
- package/dist/features/environment-lifecycle/adapters/outbound/createProjectInfraCredentialPort.js.map +1 -0
- package/dist/features/environment-lifecycle/adapters/outbound/removeStoredInfraCredentialsAsync.d.ts +4 -0
- package/dist/features/environment-lifecycle/adapters/outbound/removeStoredInfraCredentialsAsync.d.ts.map +1 -0
- package/dist/features/environment-lifecycle/adapters/outbound/removeStoredInfraCredentialsAsync.js +9 -0
- package/dist/features/environment-lifecycle/adapters/outbound/removeStoredInfraCredentialsAsync.js.map +1 -0
- package/dist/features/environment-lifecycle/application/use-cases/prepareInfraServicesAsync.d.ts +4 -0
- package/dist/features/environment-lifecycle/application/use-cases/prepareInfraServicesAsync.d.ts.map +1 -0
- package/dist/features/environment-lifecycle/application/use-cases/prepareInfraServicesAsync.js +15 -0
- package/dist/features/environment-lifecycle/application/use-cases/prepareInfraServicesAsync.js.map +1 -0
- package/dist/features/environment-lifecycle/application/use-cases/upInfraEnvironmentAsync.d.ts +1 -1
- package/dist/features/environment-lifecycle/application/use-cases/upInfraEnvironmentAsync.d.ts.map +1 -1
- package/dist/features/environment-lifecycle/application/use-cases/upInfraEnvironmentAsync.js +10 -5
- package/dist/features/environment-lifecycle/application/use-cases/upInfraEnvironmentAsync.js.map +1 -1
- package/dist/features/environment-lifecycle/composition/createInfraCommandServices.d.ts.map +1 -1
- package/dist/features/environment-lifecycle/composition/createInfraCommandServices.js +9 -3
- 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 +28 -2
- package/dist/features/environment-lifecycle/composition/createProjectInfraLifecycle.js.map +1 -1
- package/dist/features/environment-lifecycle/utils/resolveInfraEnvironmentStateDirectory.d.ts +4 -0
- package/dist/features/environment-lifecycle/utils/resolveInfraEnvironmentStateDirectory.d.ts.map +1 -0
- package/dist/features/environment-lifecycle/utils/resolveInfraEnvironmentStateDirectory.js +11 -0
- package/dist/features/environment-lifecycle/utils/resolveInfraEnvironmentStateDirectory.js.map +1 -0
- package/dist/features/environment-lifecycle/utils/resolveInfraStatePath.d.ts +1 -1
- package/dist/features/environment-lifecycle/utils/resolveInfraStatePath.d.ts.map +1 -1
- package/dist/features/environment-lifecycle/utils/resolveInfraStatePath.js +2 -6
- package/dist/features/environment-lifecycle/utils/resolveInfraStatePath.js.map +1 -1
- package/dist/types/infraCli.d.ts +7 -1
- package/dist/types/infraCli.d.ts.map +1 -1
- package/dist/types/infraCli.js.map +1 -1
- package/package.json +3 -2
- package/src/cli/commands/destroy.ts +1 -0
- package/src/cli/utils/prepareInfraCommandOperationAsync.ts +4 -1
- package/src/environmentCredentialPort.test.ts +62 -0
- package/src/features/environment-lifecycle/adapters/outbound/createEnvironmentInfraCredentialPort.ts +55 -18
- package/src/features/environment-lifecycle/adapters/outbound/createProjectInfraCredentialPort.ts +182 -0
- package/src/features/environment-lifecycle/adapters/outbound/removeStoredInfraCredentialsAsync.ts +18 -0
- package/src/features/environment-lifecycle/application/use-cases/prepareInfraServicesAsync.ts +23 -0
- package/src/features/environment-lifecycle/application/use-cases/upInfraEnvironmentAsync.ts +8 -4
- package/src/features/environment-lifecycle/composition/createInfraCommandServices.ts +9 -3
- package/src/features/environment-lifecycle/composition/createProjectInfraLifecycle.ts +33 -4
- package/src/features/environment-lifecycle/utils/resolveInfraEnvironmentStateDirectory.ts +16 -0
- package/src/features/environment-lifecycle/utils/resolveInfraStatePath.ts +3 -6
- package/src/infraUp.test.ts +31 -3
- package/src/prepareInfraServices.test.ts +50 -0
- package/src/projectCredentialLifecycle.test.ts +161 -0
- package/src/projectCredentialStore.test.ts +151 -0
- package/src/types/infraCli.ts +11 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createInfraCommandServices.js","sourceRoot":"","sources":["../../../../src/features/environment-lifecycle/composition/createInfraCommandServices.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
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"]}
|
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,
|
|
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"}
|
|
@@ -60,6 +60,10 @@ export function createProjectInfraLifecycle(options = {}) {
|
|
|
60
60
|
async destroyAsync(request) {
|
|
61
61
|
const state = await services.readState(request.projectPath, request.environment);
|
|
62
62
|
if (state === null) {
|
|
63
|
+
const safety = validateCredentialStateDestroy(request);
|
|
64
|
+
if (!safety.ok)
|
|
65
|
+
return safety;
|
|
66
|
+
await services.removeCredentials(request.projectPath, request.environment);
|
|
63
67
|
return {
|
|
64
68
|
ok: true,
|
|
65
69
|
value: { environment: request.environment, ledger: null },
|
|
@@ -75,8 +79,10 @@ export function createProjectInfraLifecycle(options = {}) {
|
|
|
75
79
|
if (!result.ok)
|
|
76
80
|
return result;
|
|
77
81
|
await services.writeArtifacts(request.projectPath, [], prepared.state?.ledger);
|
|
78
|
-
if (result.value.ledger === null)
|
|
82
|
+
if (result.value.ledger === null) {
|
|
79
83
|
await services.removeState(request.projectPath, request.environment);
|
|
84
|
+
await services.removeCredentials(request.projectPath, request.environment);
|
|
85
|
+
}
|
|
80
86
|
else {
|
|
81
87
|
await services.writeState(request.projectPath, {
|
|
82
88
|
schemaVersion: 1,
|
|
@@ -113,9 +119,29 @@ async function prepareProjectOperationAsync(request, services, useStoredDesired
|
|
|
113
119
|
...(state === null ? {} : { previous: state.ledger, previousDesired: state.desired }),
|
|
114
120
|
...(request.signal === undefined ? {} : { signal: request.signal }),
|
|
115
121
|
},
|
|
116
|
-
dependencies: services.createDependencies(context
|
|
122
|
+
dependencies: services.createDependencies(context, {
|
|
123
|
+
projectPath: request.projectPath,
|
|
124
|
+
environment: request.environment,
|
|
125
|
+
}),
|
|
117
126
|
};
|
|
118
127
|
}
|
|
128
|
+
/*** Require exact scope confirmation before deleting orphaned project credential state. */
|
|
129
|
+
function validateCredentialStateDestroy(request) {
|
|
130
|
+
if (request.confirmation.projectId !== request.projectId ||
|
|
131
|
+
request.confirmation.environment !== request.environment) {
|
|
132
|
+
return {
|
|
133
|
+
ok: false,
|
|
134
|
+
diagnostics: [
|
|
135
|
+
{
|
|
136
|
+
severity: 'error',
|
|
137
|
+
code: 'infra-destroy-confirmation-mismatch',
|
|
138
|
+
message: 'Infra destroy confirmation must exactly match the selected project and environment.',
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
return { ok: true, value: null, diagnostics: [] };
|
|
144
|
+
}
|
|
119
145
|
/*** Read one exact environment without inventing a fallback. */
|
|
120
146
|
function readEnvironment(manifest, environment) {
|
|
121
147
|
if (environment === 'local')
|
|
@@ -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 } 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 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 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 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 };\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 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"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AppEnvironmentId } from '@ankhorage/contracts/environments';
|
|
2
|
+
/*** Build the canonical project-local state directory for one closed Infra environment. */
|
|
3
|
+
export declare function resolveInfraEnvironmentStateDirectory(projectPath: string, environment: AppEnvironmentId): string;
|
|
4
|
+
//# sourceMappingURL=resolveInfraEnvironmentStateDirectory.d.ts.map
|
package/dist/features/environment-lifecycle/utils/resolveInfraEnvironmentStateDirectory.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveInfraEnvironmentStateDirectory.d.ts","sourceRoot":"","sources":["../../../../src/features/environment-lifecycle/utils/resolveInfraEnvironmentStateDirectory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAI1E,2FAA2F;AAC3F,wBAAgB,qCAAqC,CACnD,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,gBAAgB,GAC5B,MAAM,CAKR"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { APP_ENVIRONMENT_IDS } from '@ankhorage/contracts/environments';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/*** Build the canonical project-local state directory for one closed Infra environment. */
|
|
4
|
+
export function resolveInfraEnvironmentStateDirectory(projectPath, environment) {
|
|
5
|
+
if (!APP_ENVIRONMENT_IDS.includes(environment)) {
|
|
6
|
+
throw new Error(`Invalid Infra state environment: ${environment}`);
|
|
7
|
+
}
|
|
8
|
+
return path.join(projectPath, INFRA_STATE_ROOT, environment);
|
|
9
|
+
}
|
|
10
|
+
const INFRA_STATE_ROOT = '.ankh/infra';
|
|
11
|
+
//# sourceMappingURL=resolveInfraEnvironmentStateDirectory.js.map
|
package/dist/features/environment-lifecycle/utils/resolveInfraEnvironmentStateDirectory.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveInfraEnvironmentStateDirectory.js","sourceRoot":"","sources":["../../../../src/features/environment-lifecycle/utils/resolveInfraEnvironmentStateDirectory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,2FAA2F;AAC3F,MAAM,UAAU,qCAAqC,CACnD,WAAmB,EACnB,WAA6B;IAE7B,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,oCAAoC,WAAW,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,gBAAgB,EAAE,WAAW,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,gBAAgB,GAAG,aAAa,CAAC","sourcesContent":["import type { AppEnvironmentId } from '@ankhorage/contracts/environments';\nimport { APP_ENVIRONMENT_IDS } from '@ankhorage/contracts/environments';\nimport path from 'path';\n\n/*** Build the canonical project-local state directory for one closed Infra environment. */\nexport function resolveInfraEnvironmentStateDirectory(\n projectPath: string,\n environment: AppEnvironmentId,\n): string {\n if (!APP_ENVIRONMENT_IDS.includes(environment)) {\n throw new Error(`Invalid Infra state environment: ${environment}`);\n }\n return path.join(projectPath, INFRA_STATE_ROOT, environment);\n}\n\nconst INFRA_STATE_ROOT = '.ankh/infra';\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { AppEnvironmentId } from '@ankhorage/contracts/environments';
|
|
2
2
|
/*** Build an exact state-file path from a closed canonical environment identifier. */
|
|
3
3
|
export declare function resolveInfraStatePath(projectPath: string, environment: AppEnvironmentId): string;
|
|
4
4
|
//# sourceMappingURL=resolveInfraStatePath.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveInfraStatePath.d.ts","sourceRoot":"","sources":["../../../../src/features/environment-lifecycle/utils/resolveInfraStatePath.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"resolveInfraStatePath.d.ts","sourceRoot":"","sources":["../../../../src/features/environment-lifecycle/utils/resolveInfraStatePath.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAK1E,sFAAsF;AACtF,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,GAAG,MAAM,CAEhG"}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import { APP_ENVIRONMENT_IDS } from '@ankhorage/contracts/environments';
|
|
2
1
|
import path from 'path';
|
|
3
|
-
|
|
2
|
+
import { resolveInfraEnvironmentStateDirectory } from './resolveInfraEnvironmentStateDirectory.js';
|
|
4
3
|
/*** Build an exact state-file path from a closed canonical environment identifier. */
|
|
5
4
|
export function resolveInfraStatePath(projectPath, environment) {
|
|
6
|
-
|
|
7
|
-
throw new Error(`Invalid Infra state environment: ${environment}`);
|
|
8
|
-
}
|
|
9
|
-
return path.join(projectPath, INFRA_STATE_ROOT, environment, 'state.json');
|
|
5
|
+
return path.join(resolveInfraEnvironmentStateDirectory(projectPath, environment), 'state.json');
|
|
10
6
|
}
|
|
11
7
|
//# sourceMappingURL=resolveInfraStatePath.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveInfraStatePath.js","sourceRoot":"","sources":["../../../../src/features/environment-lifecycle/utils/resolveInfraStatePath.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolveInfraStatePath.js","sourceRoot":"","sources":["../../../../src/features/environment-lifecycle/utils/resolveInfraStatePath.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,qCAAqC,EAAE,MAAM,4CAA4C,CAAC;AAEnG,sFAAsF;AACtF,MAAM,UAAU,qBAAqB,CAAC,WAAmB,EAAE,WAA6B;IACtF,OAAO,IAAI,CAAC,IAAI,CAAC,qCAAqC,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,YAAY,CAAC,CAAC;AAClG,CAAC","sourcesContent":["import type { AppEnvironmentId } from '@ankhorage/contracts/environments';\nimport path from 'path';\n\nimport { resolveInfraEnvironmentStateDirectory } from './resolveInfraEnvironmentStateDirectory.js';\n\n/*** Build an exact state-file path from a closed canonical environment identifier. */\nexport function resolveInfraStatePath(projectPath: string, environment: AppEnvironmentId): string {\n return path.join(resolveInfraEnvironmentStateDirectory(projectPath, environment), 'state.json');\n}\n"]}
|
package/dist/types/infraCli.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { AnkhCapabilityId } from '@ankhorage/contracts/cli';
|
|
|
2
2
|
import type { AppEnvironmentId } from '@ankhorage/contracts/environments';
|
|
3
3
|
import type { InfraEnvironmentSpec } from '@ankhorage/contracts/infra';
|
|
4
4
|
import type { readStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/readStoredInfraStateAsync.js';
|
|
5
|
+
import type { removeStoredInfraCredentialsAsync } from '../features/environment-lifecycle/adapters/outbound/removeStoredInfraCredentialsAsync.js';
|
|
5
6
|
import type { removeStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/removeStoredInfraStateAsync.js';
|
|
6
7
|
import type { writeInfraGeneratedArtifactsAsync } from '../features/environment-lifecycle/adapters/outbound/writeInfraGeneratedArtifactsAsync.js';
|
|
7
8
|
import type { writeStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/writeStoredInfraStateAsync.js';
|
|
@@ -60,6 +61,10 @@ export interface InfraLifecycleOperations {
|
|
|
60
61
|
readonly down: typeof downInfraEnvironmentAsync;
|
|
61
62
|
readonly destroy: typeof destroyInfraEnvironmentAsync;
|
|
62
63
|
}
|
|
64
|
+
interface InfraDependencyScope {
|
|
65
|
+
readonly projectPath: string;
|
|
66
|
+
readonly environment: AppEnvironmentId;
|
|
67
|
+
}
|
|
63
68
|
export interface InfraCommandServices {
|
|
64
69
|
readonly resolveProject: (options: {
|
|
65
70
|
readonly cwd: string;
|
|
@@ -68,9 +73,10 @@ export interface InfraCommandServices {
|
|
|
68
73
|
readonly readState: typeof readStoredInfraStateAsync;
|
|
69
74
|
readonly writeState: typeof writeStoredInfraStateAsync;
|
|
70
75
|
readonly removeState: typeof removeStoredInfraStateAsync;
|
|
76
|
+
readonly removeCredentials: typeof removeStoredInfraCredentialsAsync;
|
|
71
77
|
readonly writeArtifacts: typeof writeInfraGeneratedArtifactsAsync;
|
|
72
78
|
readonly operations: InfraLifecycleOperations;
|
|
73
|
-
readonly createDependencies: (context: InfraCommandContext) => InfraOrchestrationDependencies;
|
|
79
|
+
readonly createDependencies: (context: InfraCommandContext, scope: InfraDependencyScope) => InfraOrchestrationDependencies;
|
|
74
80
|
}
|
|
75
81
|
export interface RunInfraCommandOptions {
|
|
76
82
|
readonly services?: Partial<InfraCommandServices>;
|
|
@@ -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 { 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\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 writeArtifacts: typeof writeInfraGeneratedArtifactsAsync;\n readonly operations: InfraLifecycleOperations;\n readonly createDependencies: (context: InfraCommandContext) => 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 { 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"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/infra",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "7.1.0",
|
|
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,7 +35,8 @@
|
|
|
35
35
|
"openapi"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@ankhorage/contracts": "^
|
|
38
|
+
"@ankhorage/contracts": "^21.0.0",
|
|
39
|
+
"@ankhorage/utility": "^1.2.0"
|
|
39
40
|
},
|
|
40
41
|
"files": [
|
|
41
42
|
"dist",
|
|
@@ -35,6 +35,7 @@ export const destroy = {
|
|
|
35
35
|
await services.writeArtifacts(operation.project.projectPath, [], operation.state?.ledger);
|
|
36
36
|
if (result.value.ledger === null) {
|
|
37
37
|
await services.removeState(operation.project.projectPath, environment);
|
|
38
|
+
await services.removeCredentials(operation.project.projectPath, environment);
|
|
38
39
|
} else {
|
|
39
40
|
await services.writeState(operation.project.projectPath, {
|
|
40
41
|
schemaVersion: 1,
|
|
@@ -37,7 +37,10 @@ export async function prepareInfraCommandOperationAsync(
|
|
|
37
37
|
...(request.arguments.environment === undefined ? {} : { environment }),
|
|
38
38
|
...(state === null ? {} : { previous: state.ledger, previousDesired: state.desired }),
|
|
39
39
|
},
|
|
40
|
-
dependencies: services.createDependencies(request.context
|
|
40
|
+
dependencies: services.createDependencies(request.context, {
|
|
41
|
+
projectPath: project.projectPath,
|
|
42
|
+
environment,
|
|
43
|
+
}),
|
|
41
44
|
};
|
|
42
45
|
}
|
|
43
46
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { InfraControlPlaneCredentialRef } from '@ankhorage/contracts/infra';
|
|
2
|
+
import { expect, it } from 'bun:test';
|
|
3
|
+
|
|
4
|
+
import { createEnvironmentInfraCredentialPort } from './features/environment-lifecycle/adapters/outbound/createEnvironmentInfraCredentialPort';
|
|
5
|
+
|
|
6
|
+
const bundleReference = {
|
|
7
|
+
source: 'control-plane',
|
|
8
|
+
name: 'FIXTURE_BOOTSTRAP',
|
|
9
|
+
} as const satisfies InfraControlPlaneCredentialRef;
|
|
10
|
+
const tokenReference = {
|
|
11
|
+
source: 'control-plane',
|
|
12
|
+
name: 'FIXTURE_TOKEN',
|
|
13
|
+
} as const satisfies InfraControlPlaneCredentialRef;
|
|
14
|
+
|
|
15
|
+
it('finds exact and prefixed environment credentials without mutating state', async () => {
|
|
16
|
+
const port = createEnvironmentInfraCredentialPort({
|
|
17
|
+
FIXTURE_BOOTSTRAP: JSON.stringify({ username: 'fixture', password: 'secret' }),
|
|
18
|
+
ANKH_INFRA_CREDENTIAL_FIXTURE_TOKEN: 'token-value',
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
expect(await port.findAsync(bundleReference)).toEqual({
|
|
22
|
+
ok: true,
|
|
23
|
+
value: { username: 'fixture', password: 'secret' },
|
|
24
|
+
diagnostics: [],
|
|
25
|
+
});
|
|
26
|
+
expect(await port.findAsync(tokenReference)).toEqual({
|
|
27
|
+
ok: true,
|
|
28
|
+
value: { token: 'token-value', apiToken: 'token-value' },
|
|
29
|
+
diagnostics: [],
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('distinguishes optional lookup from strict resolution', async () => {
|
|
34
|
+
const port = createEnvironmentInfraCredentialPort({});
|
|
35
|
+
|
|
36
|
+
expect(await port.findAsync(bundleReference)).toEqual({ ok: true, value: null, diagnostics: [] });
|
|
37
|
+
const resolved = await port.resolveAsync(bundleReference);
|
|
38
|
+
expect(resolved.ok).toBe(false);
|
|
39
|
+
expect(resolved.diagnostics).toEqual([
|
|
40
|
+
{
|
|
41
|
+
severity: 'error',
|
|
42
|
+
code: 'infra-control-plane-credential-missing',
|
|
43
|
+
message:
|
|
44
|
+
'Control-plane credential FIXTURE_BOOTSTRAP is unavailable. Set FIXTURE_BOOTSTRAP or ANKH_INFRA_CREDENTIAL_FIXTURE_BOOTSTRAP.',
|
|
45
|
+
},
|
|
46
|
+
]);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('fails closed when an environment-only source is asked to persist credentials', async () => {
|
|
50
|
+
const port = createEnvironmentInfraCredentialPort({});
|
|
51
|
+
const persisted = await port.persistAsync(bundleReference, { value: 'secret' });
|
|
52
|
+
|
|
53
|
+
expect(persisted.ok).toBe(false);
|
|
54
|
+
expect(persisted.diagnostics).toEqual([
|
|
55
|
+
{
|
|
56
|
+
severity: 'error',
|
|
57
|
+
code: 'infra-control-plane-credential-persistence-unavailable',
|
|
58
|
+
message:
|
|
59
|
+
'Control-plane credential FIXTURE_BOOTSTRAP cannot be persisted by the environment-only credential source.',
|
|
60
|
+
},
|
|
61
|
+
]);
|
|
62
|
+
});
|
package/src/features/environment-lifecycle/adapters/outbound/createEnvironmentInfraCredentialPort.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
InfraControlPlaneCredentialRef,
|
|
3
|
+
InfraExecutionContext,
|
|
4
|
+
InfraResult,
|
|
5
|
+
} from '@ankhorage/contracts/infra';
|
|
2
6
|
|
|
3
7
|
import { createInfraFailure } from '../../utils/createInfraFailure.js';
|
|
4
8
|
import { normalizeInfraEnvironmentKey } from '../../utils/normalizeInfraEnvironmentKey.js';
|
|
@@ -8,23 +12,53 @@ export function createEnvironmentInfraCredentialPort(
|
|
|
8
12
|
environment: Readonly<Record<string, string | undefined>>,
|
|
9
13
|
): InfraExecutionContext['credentials'] {
|
|
10
14
|
return {
|
|
15
|
+
findAsync(reference) {
|
|
16
|
+
return Promise.resolve(findCredential(environment, reference));
|
|
17
|
+
},
|
|
11
18
|
resolveAsync(reference) {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return Promise.resolve(
|
|
17
|
-
createInfraFailure(
|
|
18
|
-
'infra-control-plane-credential-missing',
|
|
19
|
-
`Control-plane credential ${reference.name} is unavailable. Set ${reference.name} or ${prefixedName}.`,
|
|
20
|
-
),
|
|
21
|
-
);
|
|
19
|
+
const found = findCredential(environment, reference);
|
|
20
|
+
if (!found.ok) return Promise.resolve(found);
|
|
21
|
+
if (found.value !== null) {
|
|
22
|
+
return Promise.resolve({ ok: true, value: found.value, diagnostics: found.diagnostics });
|
|
22
23
|
}
|
|
23
|
-
|
|
24
|
+
const prefixedName = prefixedCredentialName(reference.name);
|
|
25
|
+
return Promise.resolve(
|
|
26
|
+
createInfraFailure(
|
|
27
|
+
'infra-control-plane-credential-missing',
|
|
28
|
+
`Control-plane credential ${reference.name} is unavailable. Set ${reference.name} or ${prefixedName}.`,
|
|
29
|
+
),
|
|
30
|
+
);
|
|
31
|
+
},
|
|
32
|
+
persistAsync(reference) {
|
|
33
|
+
return Promise.resolve(
|
|
34
|
+
createInfraFailure(
|
|
35
|
+
'infra-control-plane-credential-persistence-unavailable',
|
|
36
|
+
`Control-plane credential ${reference.name} cannot be persisted by the environment-only credential source.`,
|
|
37
|
+
),
|
|
38
|
+
);
|
|
24
39
|
},
|
|
25
40
|
};
|
|
26
41
|
}
|
|
27
42
|
|
|
43
|
+
/*** Find and parse an optional credential bundle from the environment without treating absence as failure. */
|
|
44
|
+
function findCredential(
|
|
45
|
+
environment: Readonly<Record<string, string | undefined>>,
|
|
46
|
+
reference: InfraControlPlaneCredentialRef,
|
|
47
|
+
): InfraResult<Readonly<Record<string, string>> | null> {
|
|
48
|
+
const prefixedName = prefixedCredentialName(reference.name);
|
|
49
|
+
const rawValue =
|
|
50
|
+
Reflect.get(environment, reference.name) ?? Reflect.get(environment, prefixedName);
|
|
51
|
+
if (rawValue === undefined || rawValue.length === 0) {
|
|
52
|
+
return { ok: true, value: null, diagnostics: [] };
|
|
53
|
+
}
|
|
54
|
+
return parseCredentialBundle(reference.name, rawValue);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/*** Build the canonical prefixed environment variable name for one credential reference. */
|
|
58
|
+
function prefixedCredentialName(name: string): string {
|
|
59
|
+
return `ANKH_INFRA_CREDENTIAL_${normalizeInfraEnvironmentKey(name)}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
28
62
|
/*** Parse JSON credential bundles; token variables also support their conventional scalar form. */
|
|
29
63
|
function parseCredentialBundle(
|
|
30
64
|
name: string,
|
|
@@ -32,9 +66,7 @@ function parseCredentialBundle(
|
|
|
32
66
|
): InfraResult<Readonly<Record<string, string>>> {
|
|
33
67
|
try {
|
|
34
68
|
const parsed: unknown = JSON.parse(rawValue);
|
|
35
|
-
if (
|
|
36
|
-
return { ok: true, value: parsed as Readonly<Record<string, string>>, diagnostics: [] };
|
|
37
|
-
}
|
|
69
|
+
if (isStringRecord(parsed)) return { ok: true, value: parsed, diagnostics: [] };
|
|
38
70
|
} catch {
|
|
39
71
|
if (name.endsWith('_TOKEN')) {
|
|
40
72
|
return { ok: true, value: { token: rawValue, apiToken: rawValue }, diagnostics: [] };
|
|
@@ -46,7 +78,12 @@ function parseCredentialBundle(
|
|
|
46
78
|
);
|
|
47
79
|
}
|
|
48
80
|
|
|
49
|
-
/*** Narrow
|
|
50
|
-
function
|
|
51
|
-
return
|
|
81
|
+
/*** Narrow credential bundle values to a string-only record. */
|
|
82
|
+
function isStringRecord(value: unknown): value is Readonly<Record<string, string>> {
|
|
83
|
+
return (
|
|
84
|
+
typeof value === 'object' &&
|
|
85
|
+
value !== null &&
|
|
86
|
+
!Array.isArray(value) &&
|
|
87
|
+
Object.values(value).every((entry) => typeof entry === 'string')
|
|
88
|
+
);
|
|
52
89
|
}
|