@clef-sh/core 0.1.14-beta.95 → 0.1.15-beta.97
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/dist/__mocks__/write-file-atomic.d.ts +5 -0
- package/dist/__mocks__/write-file-atomic.d.ts.map +1 -0
- package/dist/bulk/ops.d.ts +13 -4
- package/dist/bulk/ops.d.ts.map +1 -1
- package/dist/git/integration.d.ts +73 -2
- package/dist/git/integration.d.ts.map +1 -1
- package/dist/import/index.d.ts +12 -3
- package/dist/import/index.d.ts.map +1 -1
- package/dist/index.d.mts +8 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4695 -1433
- package/dist/index.js.map +4 -4
- package/dist/index.mjs +3971 -692
- package/dist/index.mjs.map +4 -4
- package/dist/lint/runner.d.ts.map +1 -1
- package/dist/manifest/io.d.ts +16 -0
- package/dist/manifest/io.d.ts.map +1 -1
- package/dist/manifest/parser.d.ts.map +1 -1
- package/dist/migration/backend.d.ts +20 -3
- package/dist/migration/backend.d.ts.map +1 -1
- package/dist/recipients/index.d.ts +9 -4
- package/dist/recipients/index.d.ts.map +1 -1
- package/dist/reset/manager.d.ts +118 -0
- package/dist/reset/manager.d.ts.map +1 -0
- package/dist/service-identity/manager.d.ts +67 -10
- package/dist/service-identity/manager.d.ts.map +1 -1
- package/dist/sops/client.d.ts.map +1 -1
- package/dist/structure/manager.d.ts +155 -0
- package/dist/structure/manager.d.ts.map +1 -0
- package/dist/tx/errors.d.ts +32 -0
- package/dist/tx/errors.d.ts.map +1 -0
- package/dist/tx/index.d.ts +4 -0
- package/dist/tx/index.d.ts.map +1 -0
- package/dist/tx/transaction-manager.d.ts +66 -0
- package/dist/tx/transaction-manager.d.ts.map +1 -0
- package/package.json +5 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/lint/runner.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EAEZ,UAAU,EAGX,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAG7C;;;;;;;;GAQG;AACH,qBAAa,UAAU;IAEnB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAFV,aAAa,EAAE,aAAa,EAC5B,eAAe,EAAE,eAAe,EAChC,UAAU,EAAE,iBAAiB;IAGhD;;;;;;OAMG;IACG,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IA6NxE;;OAEG;YACW,qBAAqB;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/lint/runner.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EAEZ,UAAU,EAGX,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAG7C;;;;;;;;GAQG;AACH,qBAAa,UAAU;IAEnB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAFV,aAAa,EAAE,aAAa,EAC5B,eAAe,EAAE,eAAe,EAChC,UAAU,EAAE,iBAAiB;IAGhD;;;;;;OAMG;IACG,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IA6NxE;;OAEG;YACW,qBAAqB;IAiFnC;;;;;OAKG;IACG,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CAWzE"}
|
package/dist/manifest/io.d.ts
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
1
|
export declare function readManifestYaml(repoRoot: string): Record<string, unknown>;
|
|
2
|
+
/**
|
|
3
|
+
* Write the manifest atomically via write-file-atomic.
|
|
4
|
+
*
|
|
5
|
+
* Uses temp-file-then-rename in the same directory as the manifest, so the
|
|
6
|
+
* rename is atomic on POSIX (cross-filesystem renames degrade to copy+delete
|
|
7
|
+
* and are not atomic). Another reader sees either the old contents or the new
|
|
8
|
+
* contents — never a half-written file. If the process dies mid-write, the
|
|
9
|
+
* temp file is cleaned up by write-file-atomic's signal-exit handler. Handles
|
|
10
|
+
* Windows EPERM retries internally.
|
|
11
|
+
*/
|
|
2
12
|
export declare function writeManifestYaml(repoRoot: string, doc: Record<string, unknown>): void;
|
|
13
|
+
/**
|
|
14
|
+
* Write a raw manifest string atomically. Used for rollback paths that need
|
|
15
|
+
* to restore an exact byte-for-byte snapshot of the original file (avoiding
|
|
16
|
+
* any YAML parse → stringify round-trip that could change formatting).
|
|
17
|
+
*/
|
|
18
|
+
export declare function writeManifestYamlRaw(repoRoot: string, contents: string): void;
|
|
3
19
|
//# sourceMappingURL=io.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/manifest/io.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/manifest/io.ts"],"names":[],"mappings":"AAMA,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAG1E;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAGtF;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAG7E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/manifest/parser.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,YAAY,EAMb,MAAM,UAAU,CAAC;AAGlB;;;GAGG;AACH,eAAO,MAAM,sBAAsB,cAAc,CAAC;AAgBlD;;;;;;;;GAQG;AACH,qBAAa,cAAc;IACzB;;;;;;;OAOG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY;IAsBrC;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY;
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/manifest/parser.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,YAAY,EAMb,MAAM,UAAU,CAAC;AAGlB;;;GAGG;AACH,eAAO,MAAM,sBAAsB,cAAc,CAAC;AAgBlD;;;;;;;;GAQG;AACH,qBAAa,cAAc;IACzB;;;;;;;OAOG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY;IAsBrC;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY;IAylBtC;;;;;;OAMG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,GAAG,MAAM,IAAI;CAchF"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { BackendType, ClefManifest, EncryptionBackend } from "../types";
|
|
1
|
+
import { BackendType, ClefManifest, EncryptionBackend, EnvironmentSopsOverride } from "../types";
|
|
2
2
|
import { MatrixManager } from "../matrix/manager";
|
|
3
|
+
import { TransactionManager } from "../tx";
|
|
3
4
|
export interface MigrationTarget {
|
|
4
5
|
backend: BackendType;
|
|
5
6
|
/** Key identifier: ARN, resource ID, URL, or fingerprint. Undefined for age. */
|
|
@@ -27,20 +28,36 @@ export interface MigrationProgressEvent {
|
|
|
27
28
|
file?: string;
|
|
28
29
|
message: string;
|
|
29
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Maps a SOPS backend to the manifest field that holds its key identifier.
|
|
33
|
+
* `undefined` for backends that don't take a key (age, cloud).
|
|
34
|
+
*
|
|
35
|
+
* Exported so other backend-aware commands (clef reset, etc.) can
|
|
36
|
+
* honour the same field layout without duplicating the mapping.
|
|
37
|
+
*/
|
|
38
|
+
export declare const BACKEND_KEY_FIELDS: Record<BackendType, keyof EnvironmentSopsOverride | undefined>;
|
|
39
|
+
/**
|
|
40
|
+
* Build a per-environment SOPS override block.
|
|
41
|
+
* Shared by BackendMigrator and ResetManager so the key-field mapping
|
|
42
|
+
* lives in one place.
|
|
43
|
+
*/
|
|
44
|
+
export declare function buildSopsOverride(backend: BackendType, key: string | undefined): EnvironmentSopsOverride;
|
|
30
45
|
export declare class BackendMigrator {
|
|
31
46
|
private readonly matrixManager;
|
|
47
|
+
private readonly tx;
|
|
32
48
|
private readonly decryptBackend;
|
|
33
49
|
private readonly encryptBackend;
|
|
34
50
|
/**
|
|
35
51
|
* @param encryption - Backend used for both decrypt and encrypt (standard case).
|
|
36
52
|
* @param matrixManager - Matrix resolver.
|
|
53
|
+
* @param tx - Transaction manager that wraps the migration in a single git commit
|
|
54
|
+
* so a partial failure rolls back ALL files + the manifest via `git reset --hard`.
|
|
37
55
|
* @param targetEncryption - Optional separate backend for encrypt. Use when migrating
|
|
38
56
|
* from cloud (decrypt via keyservice) to another backend (encrypt via local credentials).
|
|
39
57
|
*/
|
|
40
|
-
constructor(encryption: EncryptionBackend, matrixManager: MatrixManager, targetEncryption?: EncryptionBackend);
|
|
58
|
+
constructor(encryption: EncryptionBackend, matrixManager: MatrixManager, tx: TransactionManager, targetEncryption?: EncryptionBackend);
|
|
41
59
|
migrate(manifest: ClefManifest, repoRoot: string, options: MigrationOptions, onProgress?: (event: MigrationProgressEvent) => void): Promise<MigrationResult>;
|
|
42
60
|
private updateManifestDoc;
|
|
43
|
-
private rollback;
|
|
44
61
|
private checkAgeRecipientsWarning;
|
|
45
62
|
}
|
|
46
63
|
//# sourceMappingURL=backend.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/migration/backend.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/migration/backend.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,uBAAuB,EAGxB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,OAAO,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAE3C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,WAAW,CAAC;IACrB,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAID;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,uBAAuB,GAAG,SAAS,CAO7F,CAAC;AAMF;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,WAAW,EACpB,GAAG,EAAE,MAAM,GAAG,SAAS,GACtB,uBAAuB,CAOzB;AAUD,qBAAa,eAAe;IAcxB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,EAAE;IAdrB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAoB;IACnD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAoB;IAEnD;;;;;;;OAOG;gBAED,UAAU,EAAE,iBAAiB,EACZ,aAAa,EAAE,aAAa,EAC5B,EAAE,EAAE,kBAAkB,EACvC,gBAAgB,CAAC,EAAE,iBAAiB;IAMhC,OAAO,CACX,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,gBAAgB,EACzB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,GACnD,OAAO,CAAC,eAAe,CAAC;IAoL3B,OAAO,CAAC,iBAAiB;IA6CzB,OAAO,CAAC,yBAAyB;CAmBlC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ClefManifest, EncryptionBackend } from "../types";
|
|
2
2
|
import { MatrixManager } from "../matrix/manager";
|
|
3
|
+
import { TransactionManager } from "../tx";
|
|
3
4
|
export interface Recipient {
|
|
4
5
|
key: string;
|
|
5
6
|
preview: string;
|
|
@@ -14,19 +15,23 @@ export interface RecipientsResult {
|
|
|
14
15
|
warnings: string[];
|
|
15
16
|
}
|
|
16
17
|
/**
|
|
17
|
-
* Manages age recipient keys in the manifest and re-encrypts matrix files on
|
|
18
|
-
*
|
|
18
|
+
* Manages age recipient keys in the manifest and re-encrypts matrix files on
|
|
19
|
+
* add/remove. Both `add` and `remove` run inside a single TransactionManager
|
|
20
|
+
* commit — any failure rolls back ALL re-encrypted files plus the manifest
|
|
21
|
+
* via `git reset --hard` rather than the previous in-method rollback dance.
|
|
19
22
|
*
|
|
20
23
|
* @example
|
|
21
24
|
* ```ts
|
|
22
|
-
* const
|
|
25
|
+
* const tx = new TransactionManager(new GitIntegration(runner));
|
|
26
|
+
* const manager = new RecipientManager(sopsClient, matrixManager, tx);
|
|
23
27
|
* const result = await manager.add("age1...", "Alice", manifest, repoRoot);
|
|
24
28
|
* ```
|
|
25
29
|
*/
|
|
26
30
|
export declare class RecipientManager {
|
|
27
31
|
private readonly encryption;
|
|
28
32
|
private readonly matrixManager;
|
|
29
|
-
|
|
33
|
+
private readonly tx;
|
|
34
|
+
constructor(encryption: EncryptionBackend, matrixManager: MatrixManager, tx: TransactionManager);
|
|
30
35
|
/**
|
|
31
36
|
* List all age recipients declared in the manifest.
|
|
32
37
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recipients/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recipients/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAIlD,OAAO,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAE3C,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAsFD;;;;;;;;;;;;GAYG;AACH,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAFF,UAAU,EAAE,iBAAiB,EAC7B,aAAa,EAAE,aAAa,EAC5B,EAAE,EAAE,kBAAkB;IAGzC;;;;;;OAMG;IACG,IAAI,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAchG;;;;;;;;;;OAUG;IACG,GAAG,CACP,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,gBAAgB,CAAC;IA0E5B;;;;;;;;;;OAUG;IACG,MAAM,CACV,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,gBAAgB,CAAC;CAiE7B"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { BackendType, ClefManifest, EncryptionBackend } from "../types";
|
|
2
|
+
import { MatrixManager } from "../matrix/manager";
|
|
3
|
+
import { SchemaValidator } from "../schema/validator";
|
|
4
|
+
import { TransactionManager } from "../tx";
|
|
5
|
+
/**
|
|
6
|
+
* Target scope for a reset operation. The CLI command refuses a naked
|
|
7
|
+
* `clef reset` with no scope — the user must name what they're destroying.
|
|
8
|
+
*/
|
|
9
|
+
export type ResetScope = {
|
|
10
|
+
kind: "env";
|
|
11
|
+
name: string;
|
|
12
|
+
} | {
|
|
13
|
+
kind: "namespace";
|
|
14
|
+
name: string;
|
|
15
|
+
} | {
|
|
16
|
+
kind: "cell";
|
|
17
|
+
namespace: string;
|
|
18
|
+
environment: string;
|
|
19
|
+
};
|
|
20
|
+
export interface ResetOptions {
|
|
21
|
+
scope: ResetScope;
|
|
22
|
+
/**
|
|
23
|
+
* If provided, switch the affected environments to this backend as part
|
|
24
|
+
* of the reset. Written as a per-env SOPS override so other environments
|
|
25
|
+
* are unaffected. When omitted, reset uses whatever backend the manifest
|
|
26
|
+
* currently specifies.
|
|
27
|
+
*/
|
|
28
|
+
backend?: BackendType;
|
|
29
|
+
/**
|
|
30
|
+
* Key identifier for KMS backends (ARN, resource ID, URL, fingerprint).
|
|
31
|
+
* Required when `backend` is `awskms`, `gcpkms`, `azurekv`, or `pgp`.
|
|
32
|
+
*/
|
|
33
|
+
key?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Explicit key names to scaffold as pending random placeholders. Used
|
|
36
|
+
* when the affected namespace has no schema. Ignored when a schema is
|
|
37
|
+
* present — the schema's keys are authoritative.
|
|
38
|
+
*/
|
|
39
|
+
keys?: string[];
|
|
40
|
+
}
|
|
41
|
+
export interface ResetResult {
|
|
42
|
+
scaffoldedCells: string[];
|
|
43
|
+
pendingKeysByCell: Record<string, string[]>;
|
|
44
|
+
backendChanged: boolean;
|
|
45
|
+
affectedEnvironments: string[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Destructive recovery command. Abandons the current encrypted contents of
|
|
49
|
+
* matrix cells in a target scope and scaffolds fresh empty/placeholder cells
|
|
50
|
+
* using the current manifest backend (or a new one supplied via options).
|
|
51
|
+
*
|
|
52
|
+
* Critical property: this command does NOT attempt to decrypt anything. It
|
|
53
|
+
* exists precisely for the case where decryption is impossible (lost age
|
|
54
|
+
* key, nuked KMS key, deleted cloud env). The scaffold path only needs
|
|
55
|
+
* encrypt access to whatever backend the manifest resolves for each env —
|
|
56
|
+
* which can be freshly provided via `options.backend` + `options.key` as
|
|
57
|
+
* part of the same transaction.
|
|
58
|
+
*
|
|
59
|
+
* Placeholder strategy:
|
|
60
|
+
* - If the affected namespace has a schema, every schema key is scaffolded
|
|
61
|
+
* with a random value and marked pending. User runs `clef set` to refill.
|
|
62
|
+
* - If no schema and `options.keys` is provided, that key list is used.
|
|
63
|
+
* - Otherwise an empty cell (`{}`) is scaffolded.
|
|
64
|
+
*
|
|
65
|
+
* Transaction: the manifest update (when switching backends) and every
|
|
66
|
+
* cell re-scaffold run inside one TransactionManager commit. Any failure
|
|
67
|
+
* rolls back the manifest AND the cell writes via `git reset --hard`.
|
|
68
|
+
*/
|
|
69
|
+
export declare class ResetManager {
|
|
70
|
+
private readonly matrixManager;
|
|
71
|
+
private readonly encryption;
|
|
72
|
+
private readonly schemaValidator;
|
|
73
|
+
private readonly tx;
|
|
74
|
+
constructor(matrixManager: MatrixManager, encryption: EncryptionBackend, schemaValidator: SchemaValidator, tx: TransactionManager);
|
|
75
|
+
reset(opts: ResetOptions, manifest: ClefManifest, repoRoot: string): Promise<ResetResult>;
|
|
76
|
+
/**
|
|
77
|
+
* Resolve the scope into an explicit list of cells. Assumes the scope has
|
|
78
|
+
* already been validated by `validateResetScope`. Unlike most other
|
|
79
|
+
* commands, reset includes cells whether or not the file currently exists
|
|
80
|
+
* on disk — "reset a namespace" also re-scaffolds any missing cells under
|
|
81
|
+
* it, which is the natural interpretation of "reset everything in this
|
|
82
|
+
* scope."
|
|
83
|
+
*/
|
|
84
|
+
private resolveCells;
|
|
85
|
+
/**
|
|
86
|
+
* Build the placeholder values for a new cell from a pre-resolved key list.
|
|
87
|
+
* The list is computed once per namespace by `resolveKeyPlan` so schema
|
|
88
|
+
* files aren't re-read for every cell in a namespace-spanning reset.
|
|
89
|
+
*/
|
|
90
|
+
private buildPlaceholders;
|
|
91
|
+
/**
|
|
92
|
+
* Decide the scaffold key list for each affected namespace exactly once.
|
|
93
|
+
*
|
|
94
|
+
* - Namespace has a schema → every schema key (schema errors propagate;
|
|
95
|
+
* a corrupt schema is a configuration problem, not a silent fallback).
|
|
96
|
+
* - No schema and `--keys` provided → that list.
|
|
97
|
+
* - Otherwise → empty, user fills via `clef set`.
|
|
98
|
+
*/
|
|
99
|
+
private resolveKeyPlan;
|
|
100
|
+
}
|
|
101
|
+
/** Human-readable description of a reset scope for commit messages and errors. */
|
|
102
|
+
export declare function describeScope(scope: ResetScope): string;
|
|
103
|
+
/**
|
|
104
|
+
* Validate a reset scope against the manifest. Exported so the CLI can
|
|
105
|
+
* reject a bad scope *before* prompting for destructive confirmation —
|
|
106
|
+
* otherwise the user is asked to confirm destroying something, types "y",
|
|
107
|
+
* and only then finds out the name was wrong. The ResetManager re-uses
|
|
108
|
+
* this as the authoritative check at the top of `reset()`.
|
|
109
|
+
*/
|
|
110
|
+
export declare function validateResetScope(scope: ResetScope, manifest: {
|
|
111
|
+
environments: {
|
|
112
|
+
name: string;
|
|
113
|
+
}[];
|
|
114
|
+
namespaces: {
|
|
115
|
+
name: string;
|
|
116
|
+
}[];
|
|
117
|
+
}): void;
|
|
118
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/reset/manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,iBAAiB,EAAc,MAAM,UAAU,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAItD,OAAO,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAG3C;;;GAGG;AACH,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,UAAU,CAAC;IAClB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC5C,cAAc,EAAE,OAAO,CAAC;IACxB,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,YAAY;IAErB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAHF,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,iBAAiB,EAC7B,eAAe,EAAE,eAAe,EAChC,EAAE,EAAE,kBAAkB;IAGnC,KAAK,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAwF/F;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY;IAcpB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAQzB;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;CAkBvB;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CASvD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE;IAAE,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAAC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,GAC7E,IAAI,CA2BN"}
|
|
@@ -1,26 +1,31 @@
|
|
|
1
1
|
import { ClefManifest, EncryptionBackend, KmsConfig, ServiceIdentityDefinition, ServiceIdentityDriftIssue } from "../types";
|
|
2
2
|
import { MatrixManager } from "../matrix/manager";
|
|
3
|
-
|
|
4
|
-
* Thrown when key rotation partially completes before a failure.
|
|
5
|
-
* Contains the private keys for environments that were successfully rotated.
|
|
6
|
-
*/
|
|
7
|
-
export declare class PartialRotationError extends Error {
|
|
8
|
-
readonly rotatedKeys: Record<string, string>;
|
|
9
|
-
constructor(message: string, rotatedKeys: Record<string, string>);
|
|
10
|
-
}
|
|
3
|
+
import { TransactionManager } from "../tx";
|
|
11
4
|
/**
|
|
12
5
|
* Manages service identities: creation, listing, key rotation, and drift validation.
|
|
13
6
|
*
|
|
7
|
+
* Mutating methods (create, delete, addNamespacesToScope, etc.) wrap their
|
|
8
|
+
* work in a TransactionManager so a failure rolls back ALL of the cell-file
|
|
9
|
+
* + manifest writes via `git reset --hard` rather than leaving the matrix in
|
|
10
|
+
* a partial state.
|
|
11
|
+
*
|
|
14
12
|
* @example
|
|
15
13
|
* ```ts
|
|
16
|
-
* const
|
|
14
|
+
* const tx = new TransactionManager(new GitIntegration(runner));
|
|
15
|
+
* const manager = new ServiceIdentityManager(sopsClient, matrixManager, tx);
|
|
17
16
|
* const result = await manager.create("api-gw", ["api"], "API gateway", manifest, repoRoot);
|
|
18
17
|
* ```
|
|
19
18
|
*/
|
|
20
19
|
export declare class ServiceIdentityManager {
|
|
21
20
|
private readonly encryption;
|
|
22
21
|
private readonly matrixManager;
|
|
23
|
-
|
|
22
|
+
private readonly tx;
|
|
23
|
+
constructor(encryption: EncryptionBackend, matrixManager: MatrixManager, tx: TransactionManager);
|
|
24
|
+
/**
|
|
25
|
+
* Compute repo-relative paths for a set of cells plus the manifest. Used
|
|
26
|
+
* to seed TransactionManager.run's `paths` argument.
|
|
27
|
+
*/
|
|
28
|
+
private txPaths;
|
|
24
29
|
/**
|
|
25
30
|
* Create a new service identity with per-environment age key pairs or KMS envelope config.
|
|
26
31
|
* For age-only: generates keys, updates the manifest, and registers public keys as SOPS recipients.
|
|
@@ -59,9 +64,61 @@ export declare class ServiceIdentityManager {
|
|
|
59
64
|
* Register a service identity's public keys as SOPS recipients on scoped matrix files.
|
|
60
65
|
*/
|
|
61
66
|
registerRecipients(identity: ServiceIdentityDefinition, manifest: ClefManifest, repoRoot: string): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Expand a service identity's namespace scope. Registers the SI's existing
|
|
69
|
+
* per-env recipient on every matrix cell in the new namespace × env
|
|
70
|
+
* combinations. KMS-backed environments are skipped (no recipient to
|
|
71
|
+
* register).
|
|
72
|
+
*
|
|
73
|
+
* Idempotent: namespaces already in scope are silently skipped. Refuses if
|
|
74
|
+
* any requested namespace does not exist in the manifest.
|
|
75
|
+
*/
|
|
76
|
+
addNamespacesToScope(name: string, namespacesToAdd: string[], manifest: ClefManifest, repoRoot: string): Promise<{
|
|
77
|
+
added: string[];
|
|
78
|
+
affectedFiles: string[];
|
|
79
|
+
}>;
|
|
80
|
+
/**
|
|
81
|
+
* Shrink a service identity's namespace scope. De-registers the SI's
|
|
82
|
+
* per-env recipient from every matrix cell in the removed namespace × env
|
|
83
|
+
* combinations. KMS-backed environments are skipped (no recipient to remove).
|
|
84
|
+
*
|
|
85
|
+
* Refuses if removing would leave the SI with zero namespaces — point the
|
|
86
|
+
* caller at `clef service delete` for that case. Refuses if any requested
|
|
87
|
+
* namespace is not currently in the SI's scope.
|
|
88
|
+
*/
|
|
89
|
+
removeNamespacesFromScope(name: string, namespacesToRemove: string[], manifest: ClefManifest, repoRoot: string): Promise<{
|
|
90
|
+
removed: string[];
|
|
91
|
+
affectedFiles: string[];
|
|
92
|
+
}>;
|
|
93
|
+
/**
|
|
94
|
+
* Extend a service identity to cover an additional environment. Generates a
|
|
95
|
+
* fresh age key for the new env (or uses the supplied KMS config), registers
|
|
96
|
+
* the new recipient on every cell in the SI's scoped namespaces × this env,
|
|
97
|
+
* and adds the env entry to the SI's `environments{}` map in the manifest.
|
|
98
|
+
*
|
|
99
|
+
* Used as the explicit follow-up to `clef env add`. The env-add command
|
|
100
|
+
* deliberately doesn't cascade to existing SIs — `clef lint` reports the
|
|
101
|
+
* gap as a `missing_environment` issue and the user runs this method (via
|
|
102
|
+
* `clef service add-env <si> <env>`) once per SI to fill it in,
|
|
103
|
+
* choosing the backend deliberately at that moment.
|
|
104
|
+
*
|
|
105
|
+
* Refuses if the SI doesn't exist, the env doesn't exist in the manifest,
|
|
106
|
+
* or the env is already configured on the SI.
|
|
107
|
+
*
|
|
108
|
+
* @returns The new private key (for age) or `undefined` (for KMS), keyed
|
|
109
|
+
* by env name. The caller is responsible for storing it securely.
|
|
110
|
+
*/
|
|
111
|
+
addEnvironmentToScope(name: string, envName: string, manifest: ClefManifest, repoRoot: string, kmsConfig?: KmsConfig): Promise<{
|
|
112
|
+
privateKey: string | undefined;
|
|
113
|
+
}>;
|
|
62
114
|
/**
|
|
63
115
|
* Rotate the age key for a service identity (all envs or a specific env).
|
|
64
116
|
* Returns the new private keys.
|
|
117
|
+
*
|
|
118
|
+
* The whole rotation runs inside a single transaction: any cell-write
|
|
119
|
+
* failure rolls back ALL recipient swaps and the manifest update via
|
|
120
|
+
* `git reset --hard` to the pre-rotation state. The previous in-method
|
|
121
|
+
* `PartialRotationError` rollback dance is no longer needed.
|
|
65
122
|
*/
|
|
66
123
|
rotateKey(name: string, manifest: ClefManifest, repoRoot: string, environment?: string): Promise<Record<string, string>>;
|
|
67
124
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/service-identity/manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/service-identity/manager.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,SAAS,EAET,yBAAyB,EACzB,yBAAyB,EAG1B,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,OAAO,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAE3C;;;;;;;;;;;;;;GAcG;AACH,qBAAa,sBAAsB;IAE/B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAFF,UAAU,EAAE,iBAAiB,EAC7B,aAAa,EAAE,aAAa,EAC5B,EAAE,EAAE,kBAAkB;IAGzC;;;OAGG;IACH,OAAO,CAAC,OAAO;IAIf;;;;;;;;OAQG;IACG,MAAM,CACV,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAAE,EACpB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,MAAM,EAChB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GACxC,OAAO,CAAC;QACT,QAAQ,EAAE,yBAAyB,CAAC;QACpC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACrC,CAAC;IAwEF;;OAEG;IACH,IAAI,CAAC,QAAQ,EAAE,YAAY,GAAG,yBAAyB,EAAE;IAIzD;;OAEG;IACH,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,yBAAyB,GAAG,SAAS;IAIhF;;;OAGG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCnF;;;;OAIG;IACG,kBAAkB,CACtB,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACxC,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;IA2DnD;;OAEG;IACG,kBAAkB,CACtB,QAAQ,EAAE,yBAAyB,EACnC,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IA0BhB;;;;;;;;OAQG;IACG,oBAAoB,CACxB,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,MAAM,EAAE,EACzB,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAgExD;;;;;;;;OAQG;IACG,yBAAyB,CAC7B,IAAI,EAAE,MAAM,EACZ,kBAAkB,EAAE,MAAM,EAAE,EAC5B,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IA8D1D;;;;;;;;;;;;;;;;;OAiBG;IACG,qBAAqB,CACzB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,SAAS,GACpB,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IAwE9C;;;;;;;;OAQG;IACG,SAAS,CACb,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAmFlC;;OAEG;IACG,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,EAAE,CAAC;CAoF/F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/sops/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/sops/client.ts"],"names":[],"mappings":"AAiBA,OAAO,EAEL,YAAY,EACZ,aAAa,EACb,iBAAiB,EAIjB,YAAY,EACZ,gBAAgB,EAGjB,MAAM,UAAU,CAAC;AAyClB;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMnD;AAED;;;;;;;;;GASG;AACH,qBAAa,UAAW,YAAW,iBAAiB;IAgBhD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAjB1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAW;IAE1C;;;;;;;;;;OAUG;gBAEgB,MAAM,EAAE,gBAAgB,EACxB,UAAU,CAAC,EAAE,MAAM,YAAA,EACnB,MAAM,CAAC,EAAE,MAAM,YAAA,EAChC,QAAQ,CAAC,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,MAAM;IAQzB,OAAO,CAAC,YAAY;IAWpB;;;;;;;OAOG;IACG,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA6CvD;;;;;;;;;OASG;IACG,OAAO,CACX,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,QAAQ,EAAE,YAAY,EACtB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC;IAuEhB;;;;;;OAMG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhE;;;;;;OAMG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBhE;;;;;;OAMG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBnE;;;;;OAKG;IACG,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAU5D;;;;;;;OAOG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAgB1D;;;;;;;OAOG;YACW,oBAAoB;IAsClC,OAAO,CAAC,qBAAqB;IAoC7B,OAAO,CAAC,aAAa;IAoBrB,OAAO,CAAC,iBAAiB;IAiCzB,OAAO,CAAC,gBAAgB;CA4DzB"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { ClefManifest, EncryptionBackend } from "../types";
|
|
2
|
+
import { MatrixManager } from "../matrix/manager";
|
|
3
|
+
import { TransactionManager } from "../tx";
|
|
4
|
+
export interface NamespaceEditOptions {
|
|
5
|
+
/** New name for the namespace. Renames cell files on disk and SI references. */
|
|
6
|
+
rename?: string;
|
|
7
|
+
/** Replace the namespace's description. Manifest-only update. */
|
|
8
|
+
description?: string;
|
|
9
|
+
/** Replace the namespace's schema path. Manifest-only update. */
|
|
10
|
+
schema?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface EnvironmentEditOptions {
|
|
13
|
+
/** New name for the environment. Renames cell files on disk and SI references. */
|
|
14
|
+
rename?: string;
|
|
15
|
+
/** Replace the environment's description. Manifest-only update. */
|
|
16
|
+
description?: string;
|
|
17
|
+
/** Mark the environment as protected. Manifest-only update. */
|
|
18
|
+
protected?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface AddNamespaceOptions {
|
|
21
|
+
/** Human-readable description for the new namespace. */
|
|
22
|
+
description?: string;
|
|
23
|
+
/** Optional schema file path for the new namespace. */
|
|
24
|
+
schema?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface AddEnvironmentOptions {
|
|
27
|
+
/** Human-readable description for the new environment. */
|
|
28
|
+
description?: string;
|
|
29
|
+
/** Mark the new environment as protected from the start. */
|
|
30
|
+
protected?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Manages namespace and environment CRUD on the manifest. Covers add, remove,
|
|
34
|
+
* and edit operations. Renames cascade through service identity references;
|
|
35
|
+
* removes refuse if they would orphan an SI (force the user to clean up SIs
|
|
36
|
+
* first) or break the manifest (last namespace, last environment, protected
|
|
37
|
+
* environment).
|
|
38
|
+
*
|
|
39
|
+
* Every mutation runs inside TransactionManager so cell-file ops + the
|
|
40
|
+
* manifest update + SI cascade updates land as one git commit, or roll back
|
|
41
|
+
* via `git reset --hard` on failure.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* const tx = new TransactionManager(new GitIntegration(runner));
|
|
46
|
+
* const structure = new StructureManager(matrixManager, sopsClient, tx);
|
|
47
|
+
* await structure.addNamespace("billing", {}, manifest, repoRoot);
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare class StructureManager {
|
|
51
|
+
private readonly matrixManager;
|
|
52
|
+
private readonly encryption;
|
|
53
|
+
private readonly tx;
|
|
54
|
+
constructor(matrixManager: MatrixManager, encryption: EncryptionBackend, tx: TransactionManager);
|
|
55
|
+
/**
|
|
56
|
+
* Add a new namespace to the manifest and scaffold an empty encrypted cell
|
|
57
|
+
* for every existing environment. Refuses if the name already exists, the
|
|
58
|
+
* identifier is invalid, or any of the target cell files are already on
|
|
59
|
+
* disk.
|
|
60
|
+
*/
|
|
61
|
+
addNamespace(name: string, opts: AddNamespaceOptions, manifest: ClefManifest, repoRoot: string): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Add a new environment to the manifest and scaffold an empty encrypted
|
|
64
|
+
* cell for every existing namespace. Refuses if the name already exists,
|
|
65
|
+
* the identifier is invalid, or any of the target cell files are already
|
|
66
|
+
* on disk.
|
|
67
|
+
*
|
|
68
|
+
* Does NOT cascade to service identities — existing SIs will not have a
|
|
69
|
+
* config for the new env. Lint will surface that gap; users explicitly
|
|
70
|
+
* close it via `clef service update --add-env` (Phase 1c).
|
|
71
|
+
*/
|
|
72
|
+
addEnvironment(name: string, opts: AddEnvironmentOptions, manifest: ClefManifest, repoRoot: string): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Remove a namespace from the manifest and delete every cell file under
|
|
75
|
+
* it. Cascades through service identities by removing the namespace from
|
|
76
|
+
* each SI's `namespaces[]` array. Refuses if removing it would leave any
|
|
77
|
+
* SI with zero scope (the user must delete those SIs first or add other
|
|
78
|
+
* namespaces to them) or if it would leave the manifest with zero
|
|
79
|
+
* namespaces.
|
|
80
|
+
*/
|
|
81
|
+
removeNamespace(name: string, manifest: ClefManifest, repoRoot: string): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Remove an environment from the manifest and delete every cell file for
|
|
84
|
+
* it across all namespaces. Cascades through service identities by
|
|
85
|
+
* removing the env entry from each SI's `environments{}` map. Refuses on
|
|
86
|
+
* protected environments (force the user to `clef env edit --unprotect`
|
|
87
|
+
* first), if it would leave the manifest with zero environments, or if
|
|
88
|
+
* the env doesn't exist.
|
|
89
|
+
*/
|
|
90
|
+
removeEnvironment(name: string, manifest: ClefManifest, repoRoot: string): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Edit a namespace's manifest entry, optionally renaming the namespace
|
|
93
|
+
* (which also renames cell files on disk and updates every service
|
|
94
|
+
* identity that references it).
|
|
95
|
+
*/
|
|
96
|
+
editNamespace(name: string, opts: NamespaceEditOptions, manifest: ClefManifest, repoRoot: string): Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* Edit an environment's manifest entry, optionally renaming the env
|
|
99
|
+
* (which also renames cell files across every namespace and updates
|
|
100
|
+
* every service identity's environments map key).
|
|
101
|
+
*/
|
|
102
|
+
editEnvironment(name: string, opts: EnvironmentEditOptions, manifest: ClefManifest, repoRoot: string): Promise<void>;
|
|
103
|
+
/**
|
|
104
|
+
* For a rename, return every (oldPath, newPath) pair that needs to move on
|
|
105
|
+
* disk. Includes the encrypted cell files AND their sibling .clef-meta.yaml
|
|
106
|
+
* pending-metadata files. Filters to existing cells only — empty cells
|
|
107
|
+
* (no file on disk) need no rename.
|
|
108
|
+
*/
|
|
109
|
+
private collectRenamePairs;
|
|
110
|
+
/**
|
|
111
|
+
* Build the new file path by substituting the renamed axis (namespace or
|
|
112
|
+
* environment) into the manifest's file_pattern. Reuses MatrixManager's
|
|
113
|
+
* resolution logic instead of doing string surgery on the existing path.
|
|
114
|
+
*/
|
|
115
|
+
private swapAxisInCellPath;
|
|
116
|
+
/**
|
|
117
|
+
* Compute the repo-relative paths a transaction needs to know about.
|
|
118
|
+
* Includes both ends of every rename plus the manifest itself.
|
|
119
|
+
*/
|
|
120
|
+
private txPaths;
|
|
121
|
+
/**
|
|
122
|
+
* Apply each rename in order. Creates parent directories as needed (a
|
|
123
|
+
* namespace rename moves files into a brand-new directory).
|
|
124
|
+
*/
|
|
125
|
+
private applyRenames;
|
|
126
|
+
/**
|
|
127
|
+
* Compute the repo-relative paths for a remove op. Includes every cell
|
|
128
|
+
* file being deleted, every existing .clef-meta.yaml sibling, and the
|
|
129
|
+
* manifest itself.
|
|
130
|
+
*/
|
|
131
|
+
private deletePaths;
|
|
132
|
+
/**
|
|
133
|
+
* Delete the .clef-meta.yaml sibling of a cell file if it exists. No-op
|
|
134
|
+
* otherwise. Used by remove ops to keep pending-state files in sync with
|
|
135
|
+
* the cells they describe.
|
|
136
|
+
*/
|
|
137
|
+
private unlinkMetaSibling;
|
|
138
|
+
/**
|
|
139
|
+
* Mutate the manifest doc in place to apply a namespace edit. Handles
|
|
140
|
+
* description/schema replacement and the rename cascade through every
|
|
141
|
+
* service identity that references the namespace.
|
|
142
|
+
*/
|
|
143
|
+
private applyNamespaceManifestEdit;
|
|
144
|
+
/**
|
|
145
|
+
* Mutate the manifest doc in place to apply an environment edit. Handles
|
|
146
|
+
* description/protected updates and the rename cascade through every
|
|
147
|
+
* service identity's environments map.
|
|
148
|
+
*/
|
|
149
|
+
private applyEnvironmentManifestEdit;
|
|
150
|
+
/** Reject rename targets that aren't safe path segments. */
|
|
151
|
+
private assertValidIdentifier;
|
|
152
|
+
/** Build the human-readable commit message for an edit. */
|
|
153
|
+
private describeEdit;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/structure/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thrown when the transaction lock is held by another process and could not
|
|
3
|
+
* be acquired within the configured retry budget.
|
|
4
|
+
*/
|
|
5
|
+
export declare class TransactionLockError extends Error {
|
|
6
|
+
readonly holderPid: number | null;
|
|
7
|
+
constructor(holderPid: number | null, message: string);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Thrown when the preflight checks fail before any mutation is attempted.
|
|
11
|
+
* No side effects have occurred at this point — the working tree is untouched.
|
|
12
|
+
*/
|
|
13
|
+
export declare class TransactionPreflightError extends Error {
|
|
14
|
+
readonly reason: "not-a-repo" | "dirty-tree" | "mid-operation" | "no-author-identity" | "no-commits";
|
|
15
|
+
readonly hint?: string | undefined;
|
|
16
|
+
constructor(reason: "not-a-repo" | "dirty-tree" | "mid-operation" | "no-author-identity" | "no-commits", message: string, hint?: string | undefined);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Thrown when a mutation failed AND the rollback either succeeded or failed.
|
|
20
|
+
*
|
|
21
|
+
* If `rollbackOk` is true, the working tree was restored to its pre-mutation
|
|
22
|
+
* state and the user only needs to address the original error.
|
|
23
|
+
*
|
|
24
|
+
* If `rollbackOk` is false, the working tree is in an unknown state and the
|
|
25
|
+
* user must inspect manually with `git status`.
|
|
26
|
+
*/
|
|
27
|
+
export declare class TransactionRollbackError extends Error {
|
|
28
|
+
readonly originalError: Error;
|
|
29
|
+
readonly rollbackOk: boolean;
|
|
30
|
+
constructor(originalError: Error, rollbackOk: boolean, message: string);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/tx/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;aAE3B,SAAS,EAAE,MAAM,GAAG,IAAI;gBAAxB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxC,OAAO,EAAE,MAAM;CAKlB;AAED;;;GAGG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;aAEhC,MAAM,EAClB,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,oBAAoB,GACpB,YAAY;aAEA,IAAI,CAAC,EAAE,MAAM;gBAPb,MAAM,EAClB,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,oBAAoB,GACpB,YAAY,EAChB,OAAO,EAAE,MAAM,EACC,IAAI,CAAC,EAAE,MAAM,YAAA;CAKhC;AAED;;;;;;;;GAQG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;aAE/B,aAAa,EAAE,KAAK;aACpB,UAAU,EAAE,OAAO;gBADnB,aAAa,EAAE,KAAK,EACpB,UAAU,EAAE,OAAO,EACnC,OAAO,EAAE,MAAM;CAKlB"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { TransactionManager } from "./transaction-manager";
|
|
2
|
+
export type { TransactionOptions, TransactionResult } from "./transaction-manager";
|
|
3
|
+
export { TransactionLockError, TransactionPreflightError, TransactionRollbackError, } from "./errors";
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tx/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,UAAU,CAAC"}
|