@ankhorage/infra 7.0.0 → 7.1.1
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/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/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/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/project/index.d.ts +1 -0
- package/dist/project/index.d.ts.map +1 -1
- package/dist/project/index.js +1 -0
- package/dist/project/index.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 +4 -3
- package/src/cli/commands/destroy.ts +1 -0
- package/src/cli/utils/prepareInfraCommandOperationAsync.ts +4 -1
- 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/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/hetznerK3sProduction.test.ts +29 -3
- package/src/hetznerK3sSupabaseR2.test.ts +33 -4
- package/src/localDockerComposeProviders.integration.test.ts +90 -51
- package/src/localK3sSupabase.test.ts +85 -27
- package/src/localMinikubeSupabase.integration.test.ts +175 -122
- package/src/localMinikubeSupabaseRecovery.integration.test.ts +37 -10
- package/src/project/index.test.ts +3 -1
- package/src/project/index.ts +1 -0
- package/src/projectCredentialLifecycle.test.ts +161 -0
- package/src/projectCredentialStore.test.ts +151 -0
- package/src/types/infraCli.ts +11 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @ankhorage/infra
|
|
2
2
|
|
|
3
|
+
## 7.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 7440682: Expose the project-scoped credential port constructor from `@ankhorage/infra/project` for downstream host composition without exposing credential storage details.
|
|
8
|
+
|
|
9
|
+
## 7.1.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- afc7347: Persist provider-generated control-plane credential bundles inside Infra-owned project/environment state, reuse them across fresh processes, and remove them only with complete environment destruction.
|
|
14
|
+
|
|
3
15
|
## 7.0.0
|
|
4
16
|
|
|
5
17
|
### Major Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"destroy.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/destroy.ts"],"names":[],"mappings":"AAUA,+FAA+F;AAC/F,eAAO,MAAM,OAAO;;;;;;;;
|
|
1
|
+
{"version":3,"file":"destroy.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/destroy.ts"],"names":[],"mappings":"AAUA,+FAA+F;AAC/F,eAAO,MAAM,OAAO;;;;;;;;CAwCuB,CAAC"}
|
|
@@ -27,6 +27,7 @@ export const destroy = {
|
|
|
27
27
|
await services.writeArtifacts(operation.project.projectPath, [], operation.state?.ledger);
|
|
28
28
|
if (result.value.ledger === null) {
|
|
29
29
|
await services.removeState(operation.project.projectPath, environment);
|
|
30
|
+
await services.removeCredentials(operation.project.projectPath, environment);
|
|
30
31
|
}
|
|
31
32
|
else {
|
|
32
33
|
await services.writeState(operation.project.projectPath, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"destroy.js","sourceRoot":"","sources":["../../../src/cli/commands/destroy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,EAAE,iCAAiC,EAAE,MAAM,+CAA+C,CAAC;AAClG,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAExE,+FAA+F;AAC/F,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,cAAc,EAAE,SAAS;IACzB,IAAI,EAAE,CAAC,SAAS,CAAC;IACjB,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,EAAE,IAAI,CAAC,CAAC;QACnF,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACtE,MAAM,YAAY,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,SAAS,IAAI,WAAW,EAAE,CAAC;QACrE,IAAI,OAAO,CAAC,SAAS,CAAC,YAAY,KAAK,YAAY,EAAE,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,oCAAoC,YAAY,GAAG,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,cAAc,GAAiC;YACnD,GAAG,SAAS,CAAC,SAAS;YACtB,WAAW;YACX,YAAY,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE;YACrE,WAAW,EAAE,uBAAuB,CAClC,SAAS,CAAC,KAAK,EAAE,MAAM,EACvB,OAAO,CAAC,SAAS,CAAC,eAAe,CAClC;SACF,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,cAAc,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;QACzF,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7C,MAAM,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC1F,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACjC,MAAM,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"destroy.js","sourceRoot":"","sources":["../../../src/cli/commands/destroy.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AppEnvironmentId } from '@ankhorage/contracts/environments';\n\nimport { INFRA_CAPABILITIES } from '../../constants.js';\nimport type { InfraCommandDefinition } from '../../types/infraCli.js';\nimport type { InfraDestroyOperationRequest } from '../../types/infraOrchestration.js';\nimport { prepareInfraCommandOperationAsync } from '../utils/prepareInfraCommandOperationAsync.js';\nimport { requireInfraSuccess } from '../utils/requireInfraSuccess.js';\nimport { resolveInfraPersistence } from '../utils/resolveInfraPersistence.js';\nimport { writeInfraStructured } from '../utils/writeInfraStructured.js';\n\n/*** Define exact-scope destruction behind environment and persistent-resource confirmation. */\nexport const destroy = {\n standaloneName: 'destroy',\n path: ['destroy'],\n capability: INFRA_CAPABILITIES[7],\n summary: 'Destroy exact owned resources behind explicit confirmation.',\n async run(request, services) {\n const operation = await prepareInfraCommandOperationAsync(request, services, true);\n const environment = requireEnvironment(request.arguments.environment);\n const confirmation = `${operation.project.projectId}:${environment}`;\n if (request.arguments.confirmation !== confirmation) {\n throw new Error(`Infra destroy requires --confirm ${confirmation}.`);\n }\n const destroyRequest: InfraDestroyOperationRequest = {\n ...operation.operation,\n environment,\n confirmation: { projectId: operation.project.projectId, environment },\n persistence: resolveInfraPersistence(\n operation.state?.ledger,\n request.arguments.deleteResources,\n ),\n };\n const result = await services.operations.destroy(destroyRequest, operation.dependencies);\n requireInfraSuccess(result, request.context);\n await services.writeArtifacts(operation.project.projectPath, [], operation.state?.ledger);\n if (result.value.ledger === null) {\n await services.removeState(operation.project.projectPath, environment);\n await services.removeCredentials(operation.project.projectPath, environment);\n } else {\n await services.writeState(operation.project.projectPath, {\n schemaVersion: 1,\n desired: operation.desired,\n ledger: result.value.ledger,\n });\n }\n writeInfraStructured(request.context, request.arguments.format, {\n environment: result.value.environment,\n retainedResources: result.value.ledger?.resources.length ?? 0,\n });\n return { exitCode: 0 };\n },\n} as const satisfies InfraCommandDefinition;\n\n/*** Require the explicit destroy environment after CLI parsing. */\nfunction requireEnvironment(value: AppEnvironmentId | undefined): AppEnvironmentId {\n if (value === undefined) throw new Error('Infra destroy requires an explicit environment.');\n return value;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prepareInfraCommandOperationAsync.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/prepareInfraCommandOperationAsync.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,sBAAsB,EACtB,oBAAoB,EACpB,6BAA6B,EAC9B,MAAM,yBAAyB,CAAC;AAEjC,sGAAsG;AACtG,wBAAsB,iCAAiC,CACrD,OAAO,EAAE,sBAAsB,EAC/B,QAAQ,EAAE,oBAAoB,EAC9B,gBAAgB,UAAQ,GACvB,OAAO,CAAC,6BAA6B,CAAC,
|
|
1
|
+
{"version":3,"file":"prepareInfraCommandOperationAsync.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/prepareInfraCommandOperationAsync.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,sBAAsB,EACtB,oBAAoB,EACpB,6BAA6B,EAC9B,MAAM,yBAAyB,CAAC;AAEjC,sGAAsG;AACtG,wBAAsB,iCAAiC,CACrD,OAAO,EAAE,sBAAsB,EAC/B,QAAQ,EAAE,oBAAoB,EAC9B,gBAAgB,UAAQ,GACvB,OAAO,CAAC,6BAA6B,CAAC,CA8BxC"}
|
|
@@ -24,7 +24,10 @@ export async function prepareInfraCommandOperationAsync(request, services, useSt
|
|
|
24
24
|
...(request.arguments.environment === undefined ? {} : { environment }),
|
|
25
25
|
...(state === null ? {} : { previous: state.ledger, previousDesired: state.desired }),
|
|
26
26
|
},
|
|
27
|
-
dependencies: services.createDependencies(request.context
|
|
27
|
+
dependencies: services.createDependencies(request.context, {
|
|
28
|
+
projectPath: project.projectPath,
|
|
29
|
+
environment,
|
|
30
|
+
}),
|
|
28
31
|
};
|
|
29
32
|
}
|
|
30
33
|
/*** Select one exact environment specification from the canonical manifest. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prepareInfraCommandOperationAsync.js","sourceRoot":"","sources":["../../../src/cli/utils/prepareInfraCommandOperationAsync.ts"],"names":[],"mappings":"AASA,sGAAsG;AACtG,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,OAA+B,EAC/B,QAA8B,EAC9B,gBAAgB,GAAG,KAAK;IAExB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,cAAc,CAAC;QAC5C,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG;QACxB,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,KAAK,SAAS;YAC3C,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;KAChD,CAAC,CAAC;IACH,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,WAAW,IAAI,OAAO,CAAC;IAC7D,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACzE,MAAM,cAAc,GAAG,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAC/E,MAAM,OAAO,GAAG,gBAAgB,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC;IACpF,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,sBAAsB,WAAW,sBAAsB,CAAC,CAAC;IAC3E,CAAC;IACD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAClF,OAAO;QACL,OAAO;QACP,KAAK;QACL,OAAO;QACP,SAAS,EAAE;YACT,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,QAAQ;YACR,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;YACvE,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;SACtF;QACD,YAAY,EAAE,QAAQ,CAAC,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"prepareInfraCommandOperationAsync.js","sourceRoot":"","sources":["../../../src/cli/utils/prepareInfraCommandOperationAsync.ts"],"names":[],"mappings":"AASA,sGAAsG;AACtG,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,OAA+B,EAC/B,QAA8B,EAC9B,gBAAgB,GAAG,KAAK;IAExB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,cAAc,CAAC;QAC5C,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG;QACxB,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,KAAK,SAAS;YAC3C,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;KAChD,CAAC,CAAC;IACH,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,WAAW,IAAI,OAAO,CAAC;IAC7D,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACzE,MAAM,cAAc,GAAG,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAC/E,MAAM,OAAO,GAAG,gBAAgB,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC;IACpF,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,sBAAsB,WAAW,sBAAsB,CAAC,CAAC;IAC3E,CAAC;IACD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAClF,OAAO;QACL,OAAO;QACP,KAAK;QACL,OAAO;QACP,SAAS,EAAE;YACT,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,QAAQ;YACR,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;YACvE,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;SACtF;QACD,YAAY,EAAE,QAAQ,CAAC,kBAAkB,CAAC,OAAO,CAAC,OAAO,EAAE;YACzD,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,WAAW;SACZ,CAAC;KACH,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,SAAS,kBAAkB,CACzB,QAAuB,EACvB,WAA6B;IAE7B,IAAI,WAAW,KAAK,OAAO;QAAE,OAAO,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC;IAChE,IAAI,WAAW,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC;IACpE,OAAO,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC;AAC1C,CAAC;AAED,oFAAoF;AACpF,SAAS,kBAAkB,CACzB,QAAuB,EACvB,WAA6B,EAC7B,OAA6B;IAE7B,OAAO;QACL,GAAG,QAAQ;QACX,YAAY,EAAE,EAAE,GAAG,QAAQ,CAAC,YAAY,EAAE,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE;KACnE,CAAC;AACJ,CAAC","sourcesContent":["import type { AppEnvironmentId } from '@ankhorage/contracts/environments';\nimport type { InfraEnvironmentSpec, InfraManifest } from '@ankhorage/contracts/infra';\n\nimport type {\n InfraCommandRunRequest,\n InfraCommandServices,\n PreparedInfraCommandOperation,\n} from '../../types/infraCli.js';\n\n/*** Resolve one command's project, desired environment, stored ownership and adapter dependencies. */\nexport async function prepareInfraCommandOperationAsync(\n request: InfraCommandRunRequest,\n services: InfraCommandServices,\n useStoredDesired = false,\n): Promise<PreparedInfraCommandOperation> {\n const project = await services.resolveProject({\n cwd: request.context.cwd,\n ...(request.arguments.projectId === undefined\n ? {}\n : { projectId: request.arguments.projectId }),\n });\n const environment = request.arguments.environment ?? 'local';\n const state = await services.readState(project.projectPath, environment);\n const currentDesired = environmentDesired(project.manifest.infra, environment);\n const desired = useStoredDesired && state !== null ? state.desired : currentDesired;\n if (desired === undefined) {\n throw new Error(`Infra environment \"${environment}\" is not configured.`);\n }\n const manifest = replaceEnvironment(project.manifest.infra, environment, desired);\n return {\n project,\n state,\n desired,\n operation: {\n projectId: project.projectId,\n manifest,\n ...(request.arguments.environment === undefined ? {} : { environment }),\n ...(state === null ? {} : { previous: state.ledger, previousDesired: state.desired }),\n },\n dependencies: services.createDependencies(request.context, {\n projectPath: project.projectPath,\n environment,\n }),\n };\n}\n\n/*** Select one exact environment specification from the canonical manifest. */\nfunction environmentDesired(\n manifest: InfraManifest,\n environment: AppEnvironmentId,\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 environment while preserving the rest of the canonical manifest. */\nfunction replaceEnvironment(\n manifest: InfraManifest,\n environment: AppEnvironmentId,\n desired: InfraEnvironmentSpec,\n): InfraManifest {\n return {\n ...manifest,\n environments: { ...manifest.environments, [environment]: desired },\n };\n}\n"]}
|
package/dist/features/environment-lifecycle/adapters/outbound/createProjectInfraCredentialPort.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AppEnvironmentId } from '@ankhorage/contracts/environments';
|
|
2
|
+
import type { InfraCredentialPort } from '@ankhorage/contracts/infra';
|
|
3
|
+
/*** Resolve explicit environment overrides before durable project-local bootstrap credentials. */
|
|
4
|
+
export declare function createProjectInfraCredentialPort(options: ProjectInfraCredentialPortOptions): InfraCredentialPort;
|
|
5
|
+
interface ProjectInfraCredentialPortOptions {
|
|
6
|
+
readonly projectPath: string;
|
|
7
|
+
readonly environment: AppEnvironmentId;
|
|
8
|
+
readonly processEnvironment: Readonly<Record<string, string | undefined>>;
|
|
9
|
+
}
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=createProjectInfraCredentialPort.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createProjectInfraCredentialPort.d.ts","sourceRoot":"","sources":["../../../../../src/features/environment-lifecycle/adapters/outbound/createProjectInfraCredentialPort.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAEV,mBAAmB,EAEpB,MAAM,4BAA4B,CAAC;AAQpC,kGAAkG;AAClG,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,iCAAiC,GACzC,mBAAmB,CAsBrB;AAED,UAAU,iCAAiC;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IACvC,QAAQ,CAAC,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;CAC3E"}
|
package/dist/features/environment-lifecycle/adapters/outbound/createProjectInfraCredentialPort.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { promises as fs } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { isRecord, isRecordOf } from '@ankhorage/utility/object';
|
|
5
|
+
import { createInfraFailure } from '../../utils/createInfraFailure.js';
|
|
6
|
+
import { normalizeInfraEnvironmentKey } from '../../utils/normalizeInfraEnvironmentKey.js';
|
|
7
|
+
import { resolveInfraEnvironmentStateDirectory } from '../../utils/resolveInfraEnvironmentStateDirectory.js';
|
|
8
|
+
import { createEnvironmentInfraCredentialPort } from './createEnvironmentInfraCredentialPort.js';
|
|
9
|
+
/*** Resolve explicit environment overrides before durable project-local bootstrap credentials. */
|
|
10
|
+
export function createProjectInfraCredentialPort(options) {
|
|
11
|
+
const environmentPort = createEnvironmentInfraCredentialPort(options.processEnvironment);
|
|
12
|
+
return {
|
|
13
|
+
findAsync: (reference) => findProjectCredentialAsync(options, environmentPort, reference),
|
|
14
|
+
async resolveAsync(reference) {
|
|
15
|
+
const found = await findProjectCredentialAsync(options, environmentPort, reference);
|
|
16
|
+
if (!found.ok)
|
|
17
|
+
return found;
|
|
18
|
+
if (found.value !== null) {
|
|
19
|
+
return { ok: true, value: found.value, diagnostics: found.diagnostics };
|
|
20
|
+
}
|
|
21
|
+
return missingCredential(reference.name);
|
|
22
|
+
},
|
|
23
|
+
async persistAsync(reference, values) {
|
|
24
|
+
if (!isStringRecord(values)) {
|
|
25
|
+
return createInfraFailure('infra-control-plane-credential-invalid', `Control-plane credential ${reference.name} must contain only string fields.`);
|
|
26
|
+
}
|
|
27
|
+
return writeStoredCredentialAsync(options, reference, values);
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/*** Resolve environment precedence before falling through to project-local state. */
|
|
32
|
+
async function findProjectCredentialAsync(options, environmentPort, reference) {
|
|
33
|
+
const overridden = await environmentPort.findAsync(reference);
|
|
34
|
+
if (!overridden.ok || overridden.value !== null)
|
|
35
|
+
return overridden;
|
|
36
|
+
return readStoredCredentialAsync(options, reference);
|
|
37
|
+
}
|
|
38
|
+
/*** Read one exact credential bundle without enumerating or exposing sibling credentials. */
|
|
39
|
+
async function readStoredCredentialAsync(options, reference) {
|
|
40
|
+
const credentialPath = resolveCredentialPath(options, reference.name);
|
|
41
|
+
try {
|
|
42
|
+
const parsed = JSON.parse(await fs.readFile(credentialPath, 'utf8'));
|
|
43
|
+
if (!isStoredCredentialBundle(parsed) || parsed.name !== reference.name) {
|
|
44
|
+
return invalidCredentialStore(reference.name);
|
|
45
|
+
}
|
|
46
|
+
return { ok: true, value: parsed.values, diagnostics: [] };
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
if (isMissingFile(error))
|
|
50
|
+
return { ok: true, value: null, diagnostics: [] };
|
|
51
|
+
if (error instanceof SyntaxError)
|
|
52
|
+
return invalidCredentialStore(reference.name);
|
|
53
|
+
return createInfraFailure('infra-control-plane-credential-store-read-failed', `Control-plane credential ${reference.name} could not be read from project state.`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/*** Persist one opaque bundle atomically with restrictive local-host permissions. */
|
|
57
|
+
async function writeStoredCredentialAsync(options, reference, values) {
|
|
58
|
+
const credentialPath = resolveCredentialPath(options, reference.name);
|
|
59
|
+
const directory = path.dirname(credentialPath);
|
|
60
|
+
const temporaryPath = `${credentialPath}.${process.pid}.${randomUUID()}.tmp`;
|
|
61
|
+
const stored = { schemaVersion: 1, name: reference.name, values };
|
|
62
|
+
try {
|
|
63
|
+
await fs.mkdir(directory, { recursive: true, mode: 0o700 });
|
|
64
|
+
await restrictPermissionsAsync(directory, 0o700);
|
|
65
|
+
await fs.writeFile(temporaryPath, `${JSON.stringify(stored, null, 2)}\n`, {
|
|
66
|
+
encoding: 'utf8',
|
|
67
|
+
mode: 0o600,
|
|
68
|
+
flag: 'wx',
|
|
69
|
+
});
|
|
70
|
+
await fs.rename(temporaryPath, credentialPath);
|
|
71
|
+
await restrictPermissionsAsync(credentialPath, 0o600);
|
|
72
|
+
return { ok: true, value: null, diagnostics: [] };
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
await removeTemporaryCredentialAsync(temporaryPath);
|
|
76
|
+
return createInfraFailure('infra-control-plane-credential-store-write-failed', `Control-plane credential ${reference.name} could not be persisted to project state.`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/*** Remove an abandoned unique temporary credential file without masking the original write failure. */
|
|
80
|
+
async function removeTemporaryCredentialAsync(temporaryPath) {
|
|
81
|
+
try {
|
|
82
|
+
await fs.rm(temporaryPath, { force: true });
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/*** Resolve one credential to an opaque hash-named file inside its project/environment scope. */
|
|
89
|
+
function resolveCredentialPath(options, name) {
|
|
90
|
+
const digest = createHash('sha256').update(name).digest('hex');
|
|
91
|
+
return path.join(resolveInfraEnvironmentStateDirectory(options.projectPath, options.environment), 'credentials', `${digest}.json`);
|
|
92
|
+
}
|
|
93
|
+
/*** Apply owner-only permissions where the host platform supports POSIX file modes. */
|
|
94
|
+
async function restrictPermissionsAsync(targetPath, mode) {
|
|
95
|
+
if (process.platform !== 'win32')
|
|
96
|
+
await fs.chmod(targetPath, mode);
|
|
97
|
+
}
|
|
98
|
+
/*** Create the canonical missing-credential diagnostic after every trusted source was checked. */
|
|
99
|
+
function missingCredential(name) {
|
|
100
|
+
const prefixedName = `ANKH_INFRA_CREDENTIAL_${normalizeInfraEnvironmentKey(name)}`;
|
|
101
|
+
return createInfraFailure('infra-control-plane-credential-missing', `Control-plane credential ${name} is unavailable. Set ${name} or ${prefixedName}.`);
|
|
102
|
+
}
|
|
103
|
+
/*** Reject malformed persisted state without exposing or replacing any stored value. */
|
|
104
|
+
function invalidCredentialStore(name) {
|
|
105
|
+
return createInfraFailure('infra-control-plane-credential-store-invalid', `Stored control-plane credential ${name} has an invalid project-state shape.`);
|
|
106
|
+
}
|
|
107
|
+
/*** Recognize the private stored credential record. */
|
|
108
|
+
function isStoredCredentialBundle(value) {
|
|
109
|
+
if (!isRecord(value))
|
|
110
|
+
return false;
|
|
111
|
+
return (value.schemaVersion === 1 && typeof value.name === 'string' && isStringRecord(value.values));
|
|
112
|
+
}
|
|
113
|
+
/*** Recognize string-only opaque provider credential bundles. */
|
|
114
|
+
function isStringRecord(value) {
|
|
115
|
+
return isRecordOf(value, isString);
|
|
116
|
+
}
|
|
117
|
+
/*** Narrow one unknown value to a string. */
|
|
118
|
+
function isString(value) {
|
|
119
|
+
return typeof value === 'string';
|
|
120
|
+
}
|
|
121
|
+
/*** Recognize only the filesystem's absent-file failure. */
|
|
122
|
+
function isMissingFile(error) {
|
|
123
|
+
return isRecord(error) && error.code === 'ENOENT';
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=createProjectInfraCredentialPort.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createProjectInfraCredentialPort.js","sourceRoot":"","sources":["../../../../../src/features/environment-lifecycle/adapters/outbound/createProjectInfraCredentialPort.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomUUID } from 'node:crypto';\nimport { promises as fs } from 'node:fs';\nimport path from 'node:path';\n\nimport type { AppEnvironmentId } from '@ankhorage/contracts/environments';\nimport type {\n InfraControlPlaneCredentialRef,\n InfraCredentialPort,\n InfraResult,\n} from '@ankhorage/contracts/infra';\nimport { isRecord, isRecordOf } from '@ankhorage/utility/object';\n\nimport { createInfraFailure } from '../../utils/createInfraFailure.js';\nimport { normalizeInfraEnvironmentKey } from '../../utils/normalizeInfraEnvironmentKey.js';\nimport { resolveInfraEnvironmentStateDirectory } from '../../utils/resolveInfraEnvironmentStateDirectory.js';\nimport { createEnvironmentInfraCredentialPort } from './createEnvironmentInfraCredentialPort.js';\n\n/*** Resolve explicit environment overrides before durable project-local bootstrap credentials. */\nexport function createProjectInfraCredentialPort(\n options: ProjectInfraCredentialPortOptions,\n): InfraCredentialPort {\n const environmentPort = createEnvironmentInfraCredentialPort(options.processEnvironment);\n return {\n findAsync: (reference) => findProjectCredentialAsync(options, environmentPort, reference),\n async resolveAsync(reference) {\n const found = await findProjectCredentialAsync(options, environmentPort, reference);\n if (!found.ok) return found;\n if (found.value !== null) {\n return { ok: true, value: found.value, diagnostics: found.diagnostics };\n }\n return missingCredential(reference.name);\n },\n async persistAsync(reference, values) {\n if (!isStringRecord(values)) {\n return createInfraFailure(\n 'infra-control-plane-credential-invalid',\n `Control-plane credential ${reference.name} must contain only string fields.`,\n );\n }\n return writeStoredCredentialAsync(options, reference, values);\n },\n };\n}\n\ninterface ProjectInfraCredentialPortOptions {\n readonly projectPath: string;\n readonly environment: AppEnvironmentId;\n readonly processEnvironment: Readonly<Record<string, string | undefined>>;\n}\n\ninterface StoredCredentialBundle {\n readonly schemaVersion: 1;\n readonly name: string;\n readonly values: Readonly<Record<string, string>>;\n}\n\n/*** Resolve environment precedence before falling through to project-local state. */\nasync function findProjectCredentialAsync(\n options: ProjectInfraCredentialPortOptions,\n environmentPort: InfraCredentialPort,\n reference: InfraControlPlaneCredentialRef,\n): Promise<InfraResult<Readonly<Record<string, string>> | null>> {\n const overridden = await environmentPort.findAsync(reference);\n if (!overridden.ok || overridden.value !== null) return overridden;\n return readStoredCredentialAsync(options, reference);\n}\n\n/*** Read one exact credential bundle without enumerating or exposing sibling credentials. */\nasync function readStoredCredentialAsync(\n options: ProjectInfraCredentialPortOptions,\n reference: InfraControlPlaneCredentialRef,\n): Promise<InfraResult<Readonly<Record<string, string>> | null>> {\n const credentialPath = resolveCredentialPath(options, reference.name);\n try {\n const parsed: unknown = JSON.parse(await fs.readFile(credentialPath, 'utf8'));\n if (!isStoredCredentialBundle(parsed) || parsed.name !== reference.name) {\n return invalidCredentialStore(reference.name);\n }\n return { ok: true, value: parsed.values, diagnostics: [] };\n } catch (error) {\n if (isMissingFile(error)) return { ok: true, value: null, diagnostics: [] };\n if (error instanceof SyntaxError) return invalidCredentialStore(reference.name);\n return createInfraFailure(\n 'infra-control-plane-credential-store-read-failed',\n `Control-plane credential ${reference.name} could not be read from project state.`,\n );\n }\n}\n\n/*** Persist one opaque bundle atomically with restrictive local-host permissions. */\nasync function writeStoredCredentialAsync(\n options: ProjectInfraCredentialPortOptions,\n reference: InfraControlPlaneCredentialRef,\n values: Readonly<Record<string, string>>,\n): Promise<InfraResult<null>> {\n const credentialPath = resolveCredentialPath(options, reference.name);\n const directory = path.dirname(credentialPath);\n const temporaryPath = `${credentialPath}.${process.pid}.${randomUUID()}.tmp`;\n const stored: StoredCredentialBundle = { schemaVersion: 1, name: reference.name, values };\n try {\n await fs.mkdir(directory, { recursive: true, mode: 0o700 });\n await restrictPermissionsAsync(directory, 0o700);\n await fs.writeFile(temporaryPath, `${JSON.stringify(stored, null, 2)}\\n`, {\n encoding: 'utf8',\n mode: 0o600,\n flag: 'wx',\n });\n await fs.rename(temporaryPath, credentialPath);\n await restrictPermissionsAsync(credentialPath, 0o600);\n return { ok: true, value: null, diagnostics: [] };\n } catch {\n await removeTemporaryCredentialAsync(temporaryPath);\n return createInfraFailure(\n 'infra-control-plane-credential-store-write-failed',\n `Control-plane credential ${reference.name} could not be persisted to project state.`,\n );\n }\n}\n\n/*** Remove an abandoned unique temporary credential file without masking the original write failure. */\nasync function removeTemporaryCredentialAsync(temporaryPath: string): Promise<void> {\n try {\n await fs.rm(temporaryPath, { force: true });\n } catch {\n return;\n }\n}\n\n/*** Resolve one credential to an opaque hash-named file inside its project/environment scope. */\nfunction resolveCredentialPath(options: ProjectInfraCredentialPortOptions, name: string): string {\n const digest = createHash('sha256').update(name).digest('hex');\n return path.join(\n resolveInfraEnvironmentStateDirectory(options.projectPath, options.environment),\n 'credentials',\n `${digest}.json`,\n );\n}\n\n/*** Apply owner-only permissions where the host platform supports POSIX file modes. */\nasync function restrictPermissionsAsync(targetPath: string, mode: number): Promise<void> {\n if (process.platform !== 'win32') await fs.chmod(targetPath, mode);\n}\n\n/*** Create the canonical missing-credential diagnostic after every trusted source was checked. */\nfunction missingCredential(name: string): InfraResult<never> {\n const prefixedName = `ANKH_INFRA_CREDENTIAL_${normalizeInfraEnvironmentKey(name)}`;\n return createInfraFailure(\n 'infra-control-plane-credential-missing',\n `Control-plane credential ${name} is unavailable. Set ${name} or ${prefixedName}.`,\n );\n}\n\n/*** Reject malformed persisted state without exposing or replacing any stored value. */\nfunction invalidCredentialStore(name: string): InfraResult<never> {\n return createInfraFailure(\n 'infra-control-plane-credential-store-invalid',\n `Stored control-plane credential ${name} has an invalid project-state shape.`,\n );\n}\n\n/*** Recognize the private stored credential record. */\nfunction isStoredCredentialBundle(value: unknown): value is StoredCredentialBundle {\n if (!isRecord(value)) return false;\n return (\n value.schemaVersion === 1 && typeof value.name === 'string' && isStringRecord(value.values)\n );\n}\n\n/*** Recognize string-only opaque provider credential bundles. */\nfunction isStringRecord(value: unknown): value is Readonly<Record<string, string>> {\n return isRecordOf(value, isString);\n}\n\n/*** Narrow one unknown value to a string. */\nfunction isString(value: unknown): value is string {\n return typeof value === 'string';\n}\n\n/*** Recognize only the filesystem's absent-file failure. */\nfunction isMissingFile(error: unknown): boolean {\n return isRecord(error) && error.code === 'ENOENT';\n}\n"]}
|
package/dist/features/environment-lifecycle/adapters/outbound/removeStoredInfraCredentialsAsync.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AppEnvironmentId } from '@ankhorage/contracts/environments';
|
|
2
|
+
/*** Remove only persisted generated credential state for one explicit project environment. */
|
|
3
|
+
export declare function removeStoredInfraCredentialsAsync(projectPath: string, environment: AppEnvironmentId): Promise<void>;
|
|
4
|
+
//# sourceMappingURL=removeStoredInfraCredentialsAsync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"removeStoredInfraCredentialsAsync.d.ts","sourceRoot":"","sources":["../../../../../src/features/environment-lifecycle/adapters/outbound/removeStoredInfraCredentialsAsync.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAI1E,8FAA8F;AAC9F,wBAAsB,iCAAiC,CACrD,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,gBAAgB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
package/dist/features/environment-lifecycle/adapters/outbound/removeStoredInfraCredentialsAsync.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { resolveInfraEnvironmentStateDirectory } from '../../utils/resolveInfraEnvironmentStateDirectory.js';
|
|
4
|
+
/*** Remove only persisted generated credential state for one explicit project environment. */
|
|
5
|
+
export async function removeStoredInfraCredentialsAsync(projectPath, environment) {
|
|
6
|
+
const credentialDirectory = path.join(resolveInfraEnvironmentStateDirectory(projectPath, environment), 'credentials');
|
|
7
|
+
await fs.rm(credentialDirectory, { recursive: true, force: true });
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=removeStoredInfraCredentialsAsync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"removeStoredInfraCredentialsAsync.js","sourceRoot":"","sources":["../../../../../src/features/environment-lifecycle/adapters/outbound/removeStoredInfraCredentialsAsync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,OAAO,EAAE,qCAAqC,EAAE,MAAM,sDAAsD,CAAC;AAE7G,8FAA8F;AAC9F,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,WAAmB,EACnB,WAA6B;IAE7B,MAAM,mBAAmB,GAAG,IAAI,CAAC,IAAI,CACnC,qCAAqC,CAAC,WAAW,EAAE,WAAW,CAAC,EAC/D,aAAa,CACd,CAAC;IACF,MAAM,EAAE,CAAC,EAAE,CAAC,mBAAmB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACrE,CAAC","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\n\nimport type { AppEnvironmentId } from '@ankhorage/contracts/environments';\n\nimport { resolveInfraEnvironmentStateDirectory } from '../../utils/resolveInfraEnvironmentStateDirectory.js';\n\n/*** Remove only persisted generated credential state for one explicit project environment. */\nexport async function removeStoredInfraCredentialsAsync(\n projectPath: string,\n environment: AppEnvironmentId,\n): Promise<void> {\n const credentialDirectory = path.join(\n resolveInfraEnvironmentStateDirectory(projectPath, environment),\n 'credentials',\n );\n await fs.rm(credentialDirectory, { recursive: true, force: true });\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;AAmBvE,mGAAmG;AACnG,wBAAgB,0BAA0B,CACxC,SAAS,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAC5C,oBAAoB,CA8BtB"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { createEnvironmentInfraCredentialPort } from '../adapters/outbound/createEnvironmentInfraCredentialPort.js';
|
|
2
1
|
import { createEnvironmentInfraSecretPort } from '../adapters/outbound/createEnvironmentInfraSecretPort.js';
|
|
3
2
|
import { createNodeInfraAdapterPackageResolver } from '../adapters/outbound/createNodeInfraAdapterPackageResolver.js';
|
|
3
|
+
import { createProjectInfraCredentialPort } from '../adapters/outbound/createProjectInfraCredentialPort.js';
|
|
4
4
|
import { readStoredInfraStateAsync } from '../adapters/outbound/readStoredInfraStateAsync.js';
|
|
5
|
+
import { removeStoredInfraCredentialsAsync } from '../adapters/outbound/removeStoredInfraCredentialsAsync.js';
|
|
5
6
|
import { removeStoredInfraStateAsync } from '../adapters/outbound/removeStoredInfraStateAsync.js';
|
|
6
7
|
import { resolveInfraProjectAsync } from '../adapters/outbound/resolveInfraProjectAsync.js';
|
|
7
8
|
import { writeInfraGeneratedArtifactsAsync } from '../adapters/outbound/writeInfraGeneratedArtifactsAsync.js';
|
|
@@ -21,6 +22,7 @@ export function createInfraCommandServices(overrides = {}) {
|
|
|
21
22
|
readState: overrides.readState ?? readStoredInfraStateAsync,
|
|
22
23
|
writeState: overrides.writeState ?? writeStoredInfraStateAsync,
|
|
23
24
|
removeState: overrides.removeState ?? removeStoredInfraStateAsync,
|
|
25
|
+
removeCredentials: overrides.removeCredentials ?? removeStoredInfraCredentialsAsync,
|
|
24
26
|
writeArtifacts: overrides.writeArtifacts ?? writeInfraGeneratedArtifactsAsync,
|
|
25
27
|
operations: overrides.operations ?? {
|
|
26
28
|
validate: validateInfraEnvironmentAsync,
|
|
@@ -33,9 +35,13 @@ export function createInfraCommandServices(overrides = {}) {
|
|
|
33
35
|
destroy: destroyInfraEnvironmentAsync,
|
|
34
36
|
},
|
|
35
37
|
createDependencies: overrides.createDependencies ??
|
|
36
|
-
((context) => ({
|
|
38
|
+
((context, scope) => ({
|
|
37
39
|
adapterResolver: createNodeInfraAdapterPackageResolver(),
|
|
38
|
-
credentials:
|
|
40
|
+
credentials: createProjectInfraCredentialPort({
|
|
41
|
+
projectPath: scope.projectPath,
|
|
42
|
+
environment: scope.environment,
|
|
43
|
+
processEnvironment: context.env,
|
|
44
|
+
}),
|
|
39
45
|
secrets: createEnvironmentInfraSecretPort(context.env),
|
|
40
46
|
})),
|
|
41
47
|
};
|
|
@@ -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":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAO9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAE7E,0GAA0G;AAC1G,MAAM,UAAU,2BAA2B,CACzC,UAA8C,EAAE;IAEhD,MAAM,QAAQ,GAAG,0BAA0B,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9D,OAAO;QACL,KAAK,CAAC,aAAa,CAAC,OAAO;YACzB,MAAM,QAAQ,GAAG,MAAM,4BAA4B,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACvE,OAAO,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;QACjF,CAAC;QACD,KAAK,CAAC,SAAS,CAAC,OAAO;YACrB,MAAM,QAAQ,GAAG,MAAM,4BAA4B,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACvE,OAAO,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;QAC7E,CAAC;QACD,KAAK,CAAC,aAAa,CAAC,OAAO;YACzB,MAAM,QAAQ,GAAG,MAAM,4BAA4B,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACvE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;YAC7F,IAAI,CAAC,MAAM,CAAC,EAAE;gBAAE,OAAO,MAAM,CAAC;YAC9B,MAAM,QAAQ,CAAC,cAAc,CAC3B,OAAO,CAAC,WAAW,EACnB,MAAM,CAAC,KAAK,CAAC,SAAS,EACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CACvB,CAAC;YACF,MAAM,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE;gBAC7C,aAAa,EAAE,CAAC;gBAChB,OAAO,EAAE,QAAQ,CAAC,OAAO;gBACzB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;aAC5B,CAAC,CAAC;YACH,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,OAAO;YACnB,MAAM,QAAQ,GAAG,MAAM,4BAA4B,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACvE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;YACvF,IAAI,CAAC,MAAM,CAAC,EAAE;gBAAE,OAAO,MAAM,CAAC;YAC9B,MAAM,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE;gBAC7C,aAAa,EAAE,CAAC;gBAChB,OAAO,EAAE,QAAQ,CAAC,OAAO;gBACzB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;aAC5B,CAAC,CAAC;YACH,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,KAAK,CAAC,WAAW,CAAC,OAAO;YACvB,MAAM,QAAQ,GAAG,MAAM,4BAA4B,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACvE,OAAO,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;QAC/E,CAAC;QACD,KAAK,CAAC,YAAY,CAAC,OAAO;YACxB,MAAM,QAAQ,GAAG,MAAM,4BAA4B,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACvE,OAAO,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACzD,CAAC;QACD,KAAK,CAAC,SAAS,CAAC,OAAO;YACrB,MAAM,QAAQ,GAAG,MAAM,4BAA4B,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACvE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;YACzF,IAAI,CAAC,MAAM,CAAC,EAAE;gBAAE,OAAO,MAAM,CAAC;YAC9B,MAAM,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE;gBAC7C,aAAa,EAAE,CAAC;gBAChB,OAAO,EAAE,QAAQ,CAAC,OAAO;gBACzB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;aAC5B,CAAC,CAAC;YACH,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,KAAK,CAAC,YAAY,CAAC,OAAO;YACxB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;YACjF,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACnB,OAAO;oBACL,EAAE,EAAE,IAAI;oBACR,KAAK,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE;oBACzD,WAAW,EAAE,EAAE;iBAChB,CAAC;YACJ,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,4BAA4B,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YACpF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,OAAO,CAC9C;gBACE,GAAG,QAAQ,CAAC,SAAS;gBACrB,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,WAAW,EAAE,OAAO,CAAC,WAAW;aACjC,EACD,QAAQ,CAAC,YAAY,CACtB,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,EAAE;gBAAE,OAAO,MAAM,CAAC;YAC9B,MAAM,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,EAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC/E,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,IAAI;gBAC9B,MAAM,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;iBAClE,CAAC;gBACJ,MAAM,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE;oBAC7C,aAAa,EAAE,CAAC;oBAChB,OAAO,EAAE,QAAQ,CAAC,OAAO;oBACzB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;iBAC5B,CAAC,CAAC;YACL,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC;AAWD,yGAAyG;AACzG,KAAK,UAAU,4BAA4B,CACzC,OAAqC,EACrC,QAAuD,EACvD,gBAAgB,GAAG,KAAK,EACxB,UAA6B;IAE7B,MAAM,KAAK,GAAG,UAAU,IAAI,CAAC,MAAM,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;IACjG,MAAM,cAAc,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9E,MAAM,OAAO,GAAG,gBAAgB,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC;IACpF,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,sBAAsB,OAAO,CAAC,WAAW,sBAAsB,CAAC,CAAC;IACnF,CAAC;IACD,MAAM,OAAO,GAAG;QACd,GAAG,EAAE,OAAO,CAAC,WAAW;QACxB,GAAG,EAAE,OAAO,CAAC,oBAAoB,IAAI,OAAO,CAAC,GAAG;QAChD,OAAO,EAAE,qBAAqB;QAC9B,WAAW,EAAE,GAAG,EAAE,CAAC,SAAS;QAC5B,WAAW,EAAE,GAAG,EAAE,CAAC,SAAS;KAC7B,CAAC;IACF,OAAO;QACL,KAAK;QACL,OAAO;QACP,SAAS,EAAE;YACT,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,QAAQ,EAAE,kBAAkB,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC;YAC5E,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;YACrF,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;SACpE;QACD,YAAY,EAAE,QAAQ,CAAC,kBAAkB,CAAC,OAAO,CAAC;KACnD,CAAC;AACJ,CAAC;AAED,gEAAgE;AAChE,SAAS,eAAe,CACtB,QAAuB,EACvB,WAAwD;IAExD,IAAI,WAAW,KAAK,OAAO;QAAE,OAAO,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC;IAChE,IAAI,WAAW,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC;IACpE,OAAO,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC;AAC1C,CAAC;AAED,mFAAmF;AACnF,SAAS,kBAAkB,CACzB,QAAuB,EACvB,WAAwD,EACxD,OAA6B;IAE7B,OAAO,EAAE,GAAG,QAAQ,EAAE,YAAY,EAAE,EAAE,GAAG,QAAQ,CAAC,YAAY,EAAE,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;AAC7F,CAAC","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/project/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { createProjectInfraCredentialPort } from '../features/environment-lifecycle/adapters/outbound/createProjectInfraCredentialPort.js';
|
|
1
2
|
export { readStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/readStoredInfraStateAsync.js';
|
|
2
3
|
export { removeStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/removeStoredInfraStateAsync.js';
|
|
3
4
|
export { resolveInfraProjectAsync } from '../features/environment-lifecycle/adapters/outbound/resolveInfraProjectAsync.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/project/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,kFAAkF,CAAC;AAC7H,OAAO,EAAE,2BAA2B,EAAE,MAAM,oFAAoF,CAAC;AACjI,OAAO,EAAE,wBAAwB,EAAE,MAAM,iFAAiF,CAAC;AAC3H,OAAO,EAAE,iCAAiC,EAAE,MAAM,0FAA0F,CAAC;AAC7I,OAAO,EAAE,0BAA0B,EAAE,MAAM,mFAAmF,CAAC;AAC/H,OAAO,EAAE,2BAA2B,EAAE,MAAM,8EAA8E,CAAC;AAC3H,OAAO,EAAE,kBAAkB,EAAE,MAAM,+DAA+D,CAAC;AACnG,YAAY,EACV,kCAAkC,EAClC,wBAAwB,EACxB,0BAA0B,EAC1B,qBAAqB,EACrB,4BAA4B,EAC5B,oBAAoB,GACrB,MAAM,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/project/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gCAAgC,EAAE,MAAM,yFAAyF,CAAC;AAC3I,OAAO,EAAE,yBAAyB,EAAE,MAAM,kFAAkF,CAAC;AAC7H,OAAO,EAAE,2BAA2B,EAAE,MAAM,oFAAoF,CAAC;AACjI,OAAO,EAAE,wBAAwB,EAAE,MAAM,iFAAiF,CAAC;AAC3H,OAAO,EAAE,iCAAiC,EAAE,MAAM,0FAA0F,CAAC;AAC7I,OAAO,EAAE,0BAA0B,EAAE,MAAM,mFAAmF,CAAC;AAC/H,OAAO,EAAE,2BAA2B,EAAE,MAAM,8EAA8E,CAAC;AAC3H,OAAO,EAAE,kBAAkB,EAAE,MAAM,+DAA+D,CAAC;AACnG,YAAY,EACV,kCAAkC,EAClC,wBAAwB,EACxB,0BAA0B,EAC1B,qBAAqB,EACrB,4BAA4B,EAC5B,oBAAoB,GACrB,MAAM,0BAA0B,CAAC"}
|
package/dist/project/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { createProjectInfraCredentialPort } from '../features/environment-lifecycle/adapters/outbound/createProjectInfraCredentialPort.js';
|
|
1
2
|
export { readStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/readStoredInfraStateAsync.js';
|
|
2
3
|
export { removeStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/removeStoredInfraStateAsync.js';
|
|
3
4
|
export { resolveInfraProjectAsync } from '../features/environment-lifecycle/adapters/outbound/resolveInfraProjectAsync.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/project/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,kFAAkF,CAAC;AAC7H,OAAO,EAAE,2BAA2B,EAAE,MAAM,oFAAoF,CAAC;AACjI,OAAO,EAAE,wBAAwB,EAAE,MAAM,iFAAiF,CAAC;AAC3H,OAAO,EAAE,iCAAiC,EAAE,MAAM,0FAA0F,CAAC;AAC7I,OAAO,EAAE,0BAA0B,EAAE,MAAM,mFAAmF,CAAC;AAC/H,OAAO,EAAE,2BAA2B,EAAE,MAAM,8EAA8E,CAAC;AAC3H,OAAO,EAAE,kBAAkB,EAAE,MAAM,+DAA+D,CAAC","sourcesContent":["export { readStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/readStoredInfraStateAsync.js';\nexport { removeStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/removeStoredInfraStateAsync.js';\nexport { resolveInfraProjectAsync } from '../features/environment-lifecycle/adapters/outbound/resolveInfraProjectAsync.js';\nexport { writeInfraGeneratedArtifactsAsync } from '../features/environment-lifecycle/adapters/outbound/writeInfraGeneratedArtifactsAsync.js';\nexport { writeStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/writeStoredInfraStateAsync.js';\nexport { createProjectInfraLifecycle } from '../features/environment-lifecycle/composition/createProjectInfraLifecycle.js';\nexport { resolveProjectFile } from '../features/environment-lifecycle/utils/resolveProjectFile.js';\nexport type {\n CreateProjectInfraLifecycleOptions,\n InfraArtifactWriteResult,\n ProjectInfraDestroyRequest,\n ProjectInfraLifecycle,\n ProjectInfraOperationRequest,\n ResolvedInfraProject,\n} from '../types/infraProject.js';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/project/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gCAAgC,EAAE,MAAM,yFAAyF,CAAC;AAC3I,OAAO,EAAE,yBAAyB,EAAE,MAAM,kFAAkF,CAAC;AAC7H,OAAO,EAAE,2BAA2B,EAAE,MAAM,oFAAoF,CAAC;AACjI,OAAO,EAAE,wBAAwB,EAAE,MAAM,iFAAiF,CAAC;AAC3H,OAAO,EAAE,iCAAiC,EAAE,MAAM,0FAA0F,CAAC;AAC7I,OAAO,EAAE,0BAA0B,EAAE,MAAM,mFAAmF,CAAC;AAC/H,OAAO,EAAE,2BAA2B,EAAE,MAAM,8EAA8E,CAAC;AAC3H,OAAO,EAAE,kBAAkB,EAAE,MAAM,+DAA+D,CAAC","sourcesContent":["export { createProjectInfraCredentialPort } from '../features/environment-lifecycle/adapters/outbound/createProjectInfraCredentialPort.js';\nexport { readStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/readStoredInfraStateAsync.js';\nexport { removeStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/removeStoredInfraStateAsync.js';\nexport { resolveInfraProjectAsync } from '../features/environment-lifecycle/adapters/outbound/resolveInfraProjectAsync.js';\nexport { writeInfraGeneratedArtifactsAsync } from '../features/environment-lifecycle/adapters/outbound/writeInfraGeneratedArtifactsAsync.js';\nexport { writeStoredInfraStateAsync } from '../features/environment-lifecycle/adapters/outbound/writeStoredInfraStateAsync.js';\nexport { createProjectInfraLifecycle } from '../features/environment-lifecycle/composition/createProjectInfraLifecycle.js';\nexport { resolveProjectFile } from '../features/environment-lifecycle/utils/resolveProjectFile.js';\nexport type {\n CreateProjectInfraLifecycleOptions,\n InfraArtifactWriteResult,\n ProjectInfraDestroyRequest,\n ProjectInfraLifecycle,\n ProjectInfraOperationRequest,\n ResolvedInfraProject,\n} from '../types/infraProject.js';\n"]}
|