@kici-dev/shared 0.1.0 → 0.1.2
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/idempotency.d.ts +33 -11
- package/dist/idempotency.js +9 -5
- package/package.json +7 -8
- package/sbom.spdx.json +5 -5
package/dist/idempotency.d.ts
CHANGED
|
@@ -6,15 +6,17 @@
|
|
|
6
6
|
* npm, git remotes, DNS, TF state, workflow step side effects) is wrapped
|
|
7
7
|
* as an IdempotentStep whose check() returns a typed drift value or null.
|
|
8
8
|
* Null means the system is already in the desired state — the runner
|
|
9
|
-
* silently skips
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* silently skips, optionally invoking whenInSync() to surface the
|
|
10
|
+
* already-satisfied resource (e.g. an existing resource id). A non-null
|
|
11
|
+
* drift means apply() would change state — the runner asks the caller's
|
|
12
|
+
* confirm() before invoking apply(), unless yes or dryRun overrides are
|
|
13
|
+
* set. apply() returns the typed result of the change for the caller.
|
|
12
14
|
*
|
|
13
15
|
* The runner has no UI dependency. CLI consumers pass an inquirer-backed
|
|
14
16
|
* confirm; future SDK / agent consumers pass their own policy function.
|
|
15
17
|
* See `.claude/rules/idempotency.md` for the full rule and adopters.
|
|
16
18
|
*/
|
|
17
|
-
export interface IdempotentStep<TDrift> {
|
|
19
|
+
export interface IdempotentStep<TDrift, TInSync = void, TApplied = void> {
|
|
18
20
|
/** Human-readable name; appears in logs and the confirm prompt. */
|
|
19
21
|
name: string;
|
|
20
22
|
/** Read-only inspection. Returns drift value if apply() would change
|
|
@@ -22,8 +24,15 @@ export interface IdempotentStep<TDrift> {
|
|
|
22
24
|
check: () => Promise<TDrift | null>;
|
|
23
25
|
/** Multi-line description of what apply() would do, given drift. */
|
|
24
26
|
summarize: (drift: TDrift) => string;
|
|
25
|
-
/** Destructive action that brings the system into the desired state.
|
|
26
|
-
|
|
27
|
+
/** Destructive action that brings the system into the desired state.
|
|
28
|
+
* Its return value is surfaced in StepResult.result on the 'applied'
|
|
29
|
+
* outcome. */
|
|
30
|
+
apply: (drift: TDrift) => Promise<TApplied>;
|
|
31
|
+
/** Optional: runs when check() returns null. Use this to fetch the
|
|
32
|
+
* already-satisfied resource (e.g. read the existing id when a
|
|
33
|
+
* create-if-missing was already done). Return value is surfaced in
|
|
34
|
+
* StepResult.result on the 'skipped' outcome. */
|
|
35
|
+
whenInSync?: () => Promise<TInSync>;
|
|
27
36
|
}
|
|
28
37
|
export type ConfirmFn = (message: string) => Promise<boolean>;
|
|
29
38
|
export interface RunOptions {
|
|
@@ -38,9 +47,22 @@ export interface RunOptions {
|
|
|
38
47
|
log?: (line: string) => void;
|
|
39
48
|
}
|
|
40
49
|
export type StepOutcome = 'skipped' | 'applied' | 'declined' | 'dry-run';
|
|
41
|
-
export
|
|
42
|
-
outcome:
|
|
43
|
-
drift:
|
|
44
|
-
|
|
45
|
-
|
|
50
|
+
export type StepResult<TDrift, TInSync = void, TApplied = void> = {
|
|
51
|
+
outcome: 'skipped';
|
|
52
|
+
drift: null;
|
|
53
|
+
result: TInSync;
|
|
54
|
+
} | {
|
|
55
|
+
outcome: 'applied';
|
|
56
|
+
drift: TDrift;
|
|
57
|
+
result: TApplied;
|
|
58
|
+
} | {
|
|
59
|
+
outcome: 'declined';
|
|
60
|
+
drift: TDrift;
|
|
61
|
+
result: undefined;
|
|
62
|
+
} | {
|
|
63
|
+
outcome: 'dry-run';
|
|
64
|
+
drift: TDrift;
|
|
65
|
+
result: undefined;
|
|
66
|
+
};
|
|
67
|
+
export declare function runIdempotentStep<TDrift, TInSync = void, TApplied = void>(step: IdempotentStep<TDrift, TInSync, TApplied>, opts?: RunOptions): Promise<StepResult<TDrift, TInSync, TApplied>>;
|
|
46
68
|
//# sourceMappingURL=idempotency.d.ts.map
|
package/dist/idempotency.js
CHANGED
|
@@ -7,7 +7,8 @@ async function runIdempotentStep(step, opts = {}) {
|
|
|
7
7
|
log(`✓ ${step.name} — in sync, skipping`);
|
|
8
8
|
return {
|
|
9
9
|
outcome: "skipped",
|
|
10
|
-
drift: null
|
|
10
|
+
drift: null,
|
|
11
|
+
result: step.whenInSync ? await step.whenInSync() : void 0
|
|
11
12
|
};
|
|
12
13
|
}
|
|
13
14
|
log(`! ${step.name} — drift detected:`);
|
|
@@ -16,7 +17,8 @@ async function runIdempotentStep(step, opts = {}) {
|
|
|
16
17
|
log(` (dry-run; would apply)`);
|
|
17
18
|
return {
|
|
18
19
|
outcome: "dry-run",
|
|
19
|
-
drift
|
|
20
|
+
drift,
|
|
21
|
+
result: void 0
|
|
20
22
|
};
|
|
21
23
|
}
|
|
22
24
|
let approved;
|
|
@@ -29,14 +31,16 @@ async function runIdempotentStep(step, opts = {}) {
|
|
|
29
31
|
log(` declined; skipping`);
|
|
30
32
|
return {
|
|
31
33
|
outcome: "declined",
|
|
32
|
-
drift
|
|
34
|
+
drift,
|
|
35
|
+
result: void 0
|
|
33
36
|
};
|
|
34
37
|
}
|
|
35
|
-
await step.apply(drift);
|
|
38
|
+
const appliedResult = await step.apply(drift);
|
|
36
39
|
log(`✓ ${step.name} — applied`);
|
|
37
40
|
return {
|
|
38
41
|
outcome: "applied",
|
|
39
|
-
drift
|
|
42
|
+
drift,
|
|
43
|
+
result: appliedResult
|
|
40
44
|
};
|
|
41
45
|
}
|
|
42
46
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kici-dev/shared",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Shared utilities for the KiCI CI/CD stack — logging, zx setup, crypto, telemetry, health and metrics routes. No business logic.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"kici",
|
|
@@ -55,12 +55,6 @@
|
|
|
55
55
|
"types": "./dist/idempotency-files.d.ts"
|
|
56
56
|
}
|
|
57
57
|
},
|
|
58
|
-
"scripts": {
|
|
59
|
-
"build": "node ../../scripts/build-ts.mjs && tsc --emitDeclarationOnly",
|
|
60
|
-
"test": "vitest run",
|
|
61
|
-
"typecheck": "tsc --noEmit",
|
|
62
|
-
"prepublishOnly": "npx tsx ../../hack/generate-sbom.ts --package packages/shared --name @kici-dev/shared"
|
|
63
|
-
},
|
|
64
58
|
"dependencies": {
|
|
65
59
|
"@aws-sdk/client-s3": "^3.1038.0",
|
|
66
60
|
"@opentelemetry/api": "^1.9.1",
|
|
@@ -85,5 +79,10 @@
|
|
|
85
79
|
"devDependencies": {
|
|
86
80
|
"@opentelemetry/sdk-trace-base": "^2.7.0",
|
|
87
81
|
"@types/diff": "^7.0.0"
|
|
82
|
+
},
|
|
83
|
+
"scripts": {
|
|
84
|
+
"build": "node ../../scripts/build-ts.mjs && tsc --emitDeclarationOnly",
|
|
85
|
+
"test": "vitest run",
|
|
86
|
+
"typecheck": "tsc --noEmit"
|
|
88
87
|
}
|
|
89
|
-
}
|
|
88
|
+
}
|
package/sbom.spdx.json
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"spdxVersion": "SPDX-2.3",
|
|
3
3
|
"dataLicense": "CC0-1.0",
|
|
4
4
|
"SPDXID": "SPDXRef-DOCUMENT",
|
|
5
|
-
"name": "@kici-dev/shared@0.1.
|
|
6
|
-
"documentNamespace": "https://kici.dev/sbom/%40kici-dev%2Fshared/0.1.
|
|
5
|
+
"name": "@kici-dev/shared@0.1.2",
|
|
6
|
+
"documentNamespace": "https://kici.dev/sbom/%40kici-dev%2Fshared/0.1.2/c6592910-3b7c-45da-bf64-9a87e8a37548",
|
|
7
7
|
"creationInfo": {
|
|
8
|
-
"created": "2026-05-
|
|
8
|
+
"created": "2026-05-15T11:43:36Z",
|
|
9
9
|
"creators": [
|
|
10
10
|
"Tool: kici-sbom-generator"
|
|
11
11
|
]
|
|
@@ -947,7 +947,7 @@
|
|
|
947
947
|
{
|
|
948
948
|
"SPDXID": "SPDXRef-RootPackage",
|
|
949
949
|
"name": "@kici-dev/shared",
|
|
950
|
-
"versionInfo": "0.1.
|
|
950
|
+
"versionInfo": "0.1.2",
|
|
951
951
|
"downloadLocation": "NOASSERTION",
|
|
952
952
|
"filesAnalyzed": false,
|
|
953
953
|
"licenseConcluded": "NOASSERTION",
|
|
@@ -958,7 +958,7 @@
|
|
|
958
958
|
{
|
|
959
959
|
"referenceCategory": "PACKAGE-MANAGER",
|
|
960
960
|
"referenceType": "purl",
|
|
961
|
-
"referenceLocator": "pkg:npm/%40kici-dev/shared@0.1.
|
|
961
|
+
"referenceLocator": "pkg:npm/%40kici-dev/shared@0.1.2"
|
|
962
962
|
}
|
|
963
963
|
],
|
|
964
964
|
"description": "Shared utilities for the KiCI CI/CD stack — logging, zx setup, crypto, telemetry, health and metrics routes. No business logic.",
|