@intentius/chant-lexicon-terraform 0.124.57 → 0.124.59
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/action-ops.d.ts +148 -0
- package/dist/action-ops.d.ts.map +1 -0
- package/dist/action-ops.js +270 -0
- package/dist/components/capability-plugin.d.ts +1 -0
- package/dist/components/capability-plugin.d.ts.map +1 -1
- package/dist/components/capability-plugin.js +4 -1
- package/dist/integrity.json +2 -2
- package/dist/manifest.json +1 -1
- package/dist/pin/scan.d.ts +6 -1
- package/dist/pin/scan.d.ts.map +1 -1
- package/dist/pin/scan.js +12 -2
- package/dist/state-ops.d.ts +5 -0
- package/dist/state-ops.d.ts.map +1 -1
- package/dist/state-ops.js +1 -1
- package/dist/template/index.d.ts +8 -0
- package/dist/template/index.d.ts.map +1 -0
- package/dist/template/index.js +6 -0
- package/dist/template/render.d.ts +97 -0
- package/dist/template/render.d.ts.map +1 -0
- package/dist/template/render.js +276 -0
- package/package.json +7 -2
- package/src/action-ops.test.ts +293 -0
- package/src/action-ops.ts +370 -0
- package/src/components/capability-plugin.test.ts +1 -1
- package/src/components/capability-plugin.ts +4 -1
- package/src/pin/scan.ts +13 -2
- package/src/state-ops.ts +6 -1
- package/src/template/__fixtures__/app-root.golden.tf +25 -0
- package/src/template/index.ts +17 -0
- package/src/template/render.test.ts +230 -0
- package/src/template/render.ts +352 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import type { Capability } from "@intentius/chant/components/capability";
|
|
2
|
+
import { type GatedRequestRules } from "@intentius/chant/lifecycle/gated-request";
|
|
3
|
+
import { type BinaryExec } from "./state/exec.js";
|
|
4
|
+
import { type GatedRequestLedger } from "./state-ops.js";
|
|
5
|
+
/** The op an action's request waits at. */
|
|
6
|
+
export declare const ACTION_OP = "tf-action";
|
|
7
|
+
/** The request kind of an action. */
|
|
8
|
+
export declare const ACTION_KIND = "action";
|
|
9
|
+
/** The oldest Terraform that invokes an action on its own. */
|
|
10
|
+
export declare const ACTION_MIN_TERRAFORM = "1.14.0";
|
|
11
|
+
/** Why an action was refused before it asked for anything. */
|
|
12
|
+
export type ActionRefusal = "action-engine" | "action-address" | "unknown-action";
|
|
13
|
+
/** An action address `-invoke` takes: module steps, then `action.<type>.<label>`, instance keys allowed. */
|
|
14
|
+
export declare const ACTION_ADDRESS: RegExp;
|
|
15
|
+
/** The subject an action's request is asked and approved under: `<root>:<address>`. */
|
|
16
|
+
export declare const actionSubject: (root: string, address: string) => string;
|
|
17
|
+
export interface InvokeActionInput {
|
|
18
|
+
/** The root's name, as records and messages name it. */
|
|
19
|
+
root: string;
|
|
20
|
+
/** The root's directory. */
|
|
21
|
+
dir: string;
|
|
22
|
+
/** The binary. Default `terraform`. */
|
|
23
|
+
binary?: string;
|
|
24
|
+
/** Its version, when the caller knows it (an image's pin). Absent: read with `version -json` before the plan. */
|
|
25
|
+
version?: string;
|
|
26
|
+
/** The action's address: `action.<type>.<label>` or `module.<name>.action.<type>.<label>`. */
|
|
27
|
+
address: string;
|
|
28
|
+
/** Who asks. */
|
|
29
|
+
requester: string;
|
|
30
|
+
/** Which approvals count. */
|
|
31
|
+
rules: GatedRequestRules;
|
|
32
|
+
/** The commit the root is at, bound by the request. */
|
|
33
|
+
commit?: string;
|
|
34
|
+
/** The saved plan. Default `<dir>/.chant-action.tfplan`. */
|
|
35
|
+
planFile?: string;
|
|
36
|
+
lockTimeout?: string | false;
|
|
37
|
+
env?: NodeJS.ProcessEnv;
|
|
38
|
+
exec?: BinaryExec;
|
|
39
|
+
ledger?: GatedRequestLedger;
|
|
40
|
+
/** The project's directory, where the ledger is. */
|
|
41
|
+
cwd?: string;
|
|
42
|
+
now?: string;
|
|
43
|
+
runId?: string;
|
|
44
|
+
expiry?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Ask anew even when the same request (same subject, requester and
|
|
47
|
+
* fields) applied already. Absent, a call that matches an applied request
|
|
48
|
+
* answers `spent`, so a retried job never runs the action twice.
|
|
49
|
+
*/
|
|
50
|
+
anew?: boolean;
|
|
51
|
+
}
|
|
52
|
+
/** How an action call ended. `exit` is the code a command that ran it exits with. */
|
|
53
|
+
export type InvokeActionResult = {
|
|
54
|
+
outcome: "refused";
|
|
55
|
+
code: ActionRefusal;
|
|
56
|
+
reason: string;
|
|
57
|
+
exit: number;
|
|
58
|
+
}
|
|
59
|
+
/** No approval counts yet; nothing ran past the plan. `reason` names an approval that stands and does not count. */
|
|
60
|
+
| {
|
|
61
|
+
outcome: "gated";
|
|
62
|
+
digest: string;
|
|
63
|
+
subject: string;
|
|
64
|
+
command: string;
|
|
65
|
+
reason?: string;
|
|
66
|
+
exit: number;
|
|
67
|
+
}
|
|
68
|
+
/** The request applied already, and a request applies once; nothing ran past the plan. */
|
|
69
|
+
| {
|
|
70
|
+
outcome: "spent";
|
|
71
|
+
digest: string;
|
|
72
|
+
subject: string;
|
|
73
|
+
exit: number;
|
|
74
|
+
} | {
|
|
75
|
+
outcome: "ok";
|
|
76
|
+
digest: string;
|
|
77
|
+
subject: string;
|
|
78
|
+
approvedBy: string;
|
|
79
|
+
tail: string;
|
|
80
|
+
recorded: boolean;
|
|
81
|
+
exit: number;
|
|
82
|
+
} | {
|
|
83
|
+
outcome: "failed";
|
|
84
|
+
digest: string;
|
|
85
|
+
subject: string;
|
|
86
|
+
approvedBy: string;
|
|
87
|
+
error: string;
|
|
88
|
+
tail: string;
|
|
89
|
+
recorded: boolean;
|
|
90
|
+
exit: number;
|
|
91
|
+
};
|
|
92
|
+
/** Whether `version` is at least {@link ACTION_MIN_TERRAFORM}. */
|
|
93
|
+
export declare function invokesActions(version: string): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Refuse a binary that cannot invoke an action, before any exec call when
|
|
96
|
+
* its name or the given version settles it. Undefined: it may run.
|
|
97
|
+
*/
|
|
98
|
+
export declare function actionEngineRefusal(root: string, binary: string, version: string | undefined): string | undefined;
|
|
99
|
+
/** The plan's `action_invocations`, as a request binds them: each entry in canonical form, sorted, hashed. */
|
|
100
|
+
export declare function actionInvocationsDigest(plan: unknown): string;
|
|
101
|
+
/** The addresses the plan's `action_invocations` name. */
|
|
102
|
+
export declare function invokedAddresses(plan: unknown): string[];
|
|
103
|
+
/** An action's plan read back: the saved plan, its JSON, and the request fields it binds. */
|
|
104
|
+
export interface ActionPlanRead {
|
|
105
|
+
planFile: string;
|
|
106
|
+
json: unknown;
|
|
107
|
+
fields: Record<string, string>;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Check the binary and the address, plan the invocation and read it back.
|
|
111
|
+
* A refusal comes back as a result; a binary run that fails throws
|
|
112
|
+
* {@link StateOpError}.
|
|
113
|
+
*/
|
|
114
|
+
export declare function planAction(input: InvokeActionInput): Promise<ActionPlanRead | Extract<InvokeActionResult, {
|
|
115
|
+
outcome: "refused";
|
|
116
|
+
}>>;
|
|
117
|
+
/**
|
|
118
|
+
* Invoke one action under a gated request: plan it, ask, and once an
|
|
119
|
+
* approval by someone other than the requester counts, spend it, apply the
|
|
120
|
+
* saved plan and record how it ended.
|
|
121
|
+
*/
|
|
122
|
+
export declare function invokeAction(input: InvokeActionInput): Promise<InvokeActionResult>;
|
|
123
|
+
/** `terraform-action`: invoke one action of a root under a gated request. */
|
|
124
|
+
export interface ActionStepInput {
|
|
125
|
+
root: string;
|
|
126
|
+
/** The action's address. */
|
|
127
|
+
address: string;
|
|
128
|
+
/** The project's directory, where the ledger is and roots are found. Default the process's. */
|
|
129
|
+
cwd?: string;
|
|
130
|
+
/** The root's directory. Default `root` under the project. */
|
|
131
|
+
dir?: string;
|
|
132
|
+
binary?: string;
|
|
133
|
+
/** The binary's version, when the step knows it. */
|
|
134
|
+
version?: string;
|
|
135
|
+
/** Who asks. Default the CI actor, else the user. */
|
|
136
|
+
by?: string;
|
|
137
|
+
/** Which approvals count. Default the ledger's. */
|
|
138
|
+
approval?: GatedRequestRules["mode"];
|
|
139
|
+
/** The commit the request binds. Default the CI's commit variable, when set. */
|
|
140
|
+
commit?: string;
|
|
141
|
+
lockTimeout?: string | false;
|
|
142
|
+
}
|
|
143
|
+
export declare const terraformActionCapability: Capability<ActionStepInput, {
|
|
144
|
+
root: string;
|
|
145
|
+
address: string;
|
|
146
|
+
digest: string;
|
|
147
|
+
}>;
|
|
148
|
+
//# sourceMappingURL=action-ops.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-ops.d.ts","sourceRoot":"","sources":["../src/action-ops.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A day-2 action (#4653): one Terraform `action` block invoked on its own,
|
|
3
|
+
* under a gated request on the ledger, the way a state-lock release runs
|
|
4
|
+
* (./state-ops.ts).
|
|
5
|
+
*
|
|
6
|
+
* `invokeAction` runs fixed argument lists only. The caller names the root,
|
|
7
|
+
* the binary and the action's address, never extra arguments:
|
|
8
|
+
*
|
|
9
|
+
* 1. `plan -input=false -no-color -invoke=<address> -out=<file>`, then
|
|
10
|
+
* `show -json <file>`. The address must be one of the plan's
|
|
11
|
+
* `action_invocations`.
|
|
12
|
+
* 2. `requestGate` under op `tf-action`, subject `<root>:<address>`. The
|
|
13
|
+
* request's fields bind the address, the commit when given, and a digest
|
|
14
|
+
* of the plan's `action_invocations`, so a plan whose action input moved
|
|
15
|
+
* after the approval asks anew. Without an approval that counts (the
|
|
16
|
+
* requester's own never does) it answers `gated`, exit 3, and runs nothing.
|
|
17
|
+
* 3. With one, `spendGatedRequest`, then `apply <file>`, then
|
|
18
|
+
* `finishGatedRequest`. The finished line's `result` stays chant's
|
|
19
|
+
* `applied | failed`; `detail.result` carries `ok` or `failed`, with the
|
|
20
|
+
* exit code and the last lines of the binary's output.
|
|
21
|
+
*
|
|
22
|
+
* The address is checked before anything runs: `action.<type>.<label>`,
|
|
23
|
+
* after any number of `module.<name>.` steps, each with an optional instance
|
|
24
|
+
* key (`[0]`, `["a"]`). Terraform 1.14.9 parses a module address for
|
|
25
|
+
* `-invoke` (`addrs.ParseTargetAction` reads the module prefix first, and its
|
|
26
|
+
* tests "action invoke in module" and "action invoke in expanded module"
|
|
27
|
+
* expect success), so a templated app's root, which holds only `module
|
|
28
|
+
* "app"`, invokes `module.app.action.<type>.<label>` and needs no root-level
|
|
29
|
+
* action blocks.
|
|
30
|
+
*
|
|
31
|
+
* Only Terraform 1.14 or newer invokes an action. An OpenTofu or choudoufu
|
|
32
|
+
* binary is refused by its engine's name before any exec call (`action-engine`).
|
|
33
|
+
* A `terraform` binary is refused when its version, passed in or read with
|
|
34
|
+
* `version -json`, is older than 1.14.
|
|
35
|
+
*
|
|
36
|
+
* `-invoke` plans in refresh-only mode and refuses `-target`, so the plan
|
|
37
|
+
* changes no resource: the apply runs the action and nothing else.
|
|
38
|
+
*
|
|
39
|
+
* The exec and the ledger are injectable, so a test runs no binary and
|
|
40
|
+
* writes no ledger.
|
|
41
|
+
*/
|
|
42
|
+
import { createHash } from "node:crypto";
|
|
43
|
+
import { basename, join } from "node:path";
|
|
44
|
+
import { CHANT_EXIT } from "@intentius/chant/exit-codes";
|
|
45
|
+
import { readGatedRequests } from "@intentius/chant/lifecycle/gated-request";
|
|
46
|
+
import { terraformChangeSetPart } from "./change-set.js";
|
|
47
|
+
import { DEFAULT_LOCK_TIMEOUT, lockTimeoutArgs } from "./lock-timeout.js";
|
|
48
|
+
import { lastLines, runBinary } from "./state/exec.js";
|
|
49
|
+
import { gatedStateOp, StateOpError, StateOpWaitingError } from "./state-ops.js";
|
|
50
|
+
/** The op an action's request waits at. */
|
|
51
|
+
export const ACTION_OP = "tf-action";
|
|
52
|
+
/** The request kind of an action. */
|
|
53
|
+
export const ACTION_KIND = "action";
|
|
54
|
+
/** The oldest Terraform that invokes an action on its own. */
|
|
55
|
+
export const ACTION_MIN_TERRAFORM = "1.14.0";
|
|
56
|
+
const KEY = String.raw `\[(?:[0-9]+|"[A-Za-z0-9_-]+")\]`;
|
|
57
|
+
/** An action address `-invoke` takes: module steps, then `action.<type>.<label>`, instance keys allowed. */
|
|
58
|
+
export const ACTION_ADDRESS = new RegExp(String.raw `^(?:module\.[A-Za-z_][A-Za-z0-9_-]*(?:${KEY})?\.)*action\.[a-z0-9_]+\.[A-Za-z_][A-Za-z0-9_-]*(?:${KEY})?$`);
|
|
59
|
+
/** The subject an action's request is asked and approved under: `<root>:<address>`. */
|
|
60
|
+
export const actionSubject = (root, address) => `${root}:${address}`;
|
|
61
|
+
const refused = (code, reason) => ({ outcome: "refused", code, reason, exit: CHANT_EXIT.failed });
|
|
62
|
+
/** The engine a binary name runs, when it is one that has no `-invoke`. */
|
|
63
|
+
function otherEngine(binary) {
|
|
64
|
+
const name = basename(binary).toLowerCase().replace(/\.exe$/, "");
|
|
65
|
+
if (name === "tofu" || name === "opentofu" || name.startsWith("tofu-") || name.startsWith("opentofu"))
|
|
66
|
+
return "OpenTofu";
|
|
67
|
+
if (name.startsWith("choudoufu"))
|
|
68
|
+
return "choudoufu";
|
|
69
|
+
if (!/^terraform([-_.]?[0-9][0-9.]*)?$/.test(name))
|
|
70
|
+
return name;
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
/** Whether `version` is at least {@link ACTION_MIN_TERRAFORM}. */
|
|
74
|
+
export function invokesActions(version) {
|
|
75
|
+
const m = /^v?(\d+)\.(\d+)/.exec(version.trim());
|
|
76
|
+
if (!m)
|
|
77
|
+
return false;
|
|
78
|
+
const major = Number(m[1]);
|
|
79
|
+
const minor = Number(m[2]);
|
|
80
|
+
return major > 1 || (major === 1 && minor >= 14);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Refuse a binary that cannot invoke an action, before any exec call when
|
|
84
|
+
* its name or the given version settles it. Undefined: it may run.
|
|
85
|
+
*/
|
|
86
|
+
export function actionEngineRefusal(root, binary, version) {
|
|
87
|
+
const engine = otherEngine(binary);
|
|
88
|
+
const named = `${binary}${version ? ` ${version}` : ""}`;
|
|
89
|
+
if (engine)
|
|
90
|
+
return `${root}: an action runs on Terraform ${ACTION_MIN_TERRAFORM.replace(/\.0$/, "")} or newer, and this root runs ${engine} (${named}), which has no action invocation`;
|
|
91
|
+
if (version !== undefined && !invokesActions(version))
|
|
92
|
+
return `${root}: an action runs on Terraform ${ACTION_MIN_TERRAFORM.replace(/\.0$/, "")} or newer, and this root runs Terraform ${version} (${binary})`;
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
const isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
96
|
+
/** JSON with every object's keys sorted, so a digest does not follow the emitter's key order. */
|
|
97
|
+
const canonical = (v) => Array.isArray(v) ? `[${v.map(canonical).join(",")}]` : isObject(v) ? `{${Object.keys(v).sort().map((k) => `${JSON.stringify(k)}:${canonical(v[k])}`).join(",")}}` : JSON.stringify(v ?? null);
|
|
98
|
+
/** The plan's `action_invocations`, as a request binds them: each entry in canonical form, sorted, hashed. */
|
|
99
|
+
export function actionInvocationsDigest(plan) {
|
|
100
|
+
const list = isObject(plan) && Array.isArray(plan.action_invocations) ? plan.action_invocations.map(canonical).sort() : [];
|
|
101
|
+
return `sha256:${createHash("sha256").update(`[${list.join(",")}]`).digest("hex")}`;
|
|
102
|
+
}
|
|
103
|
+
/** The addresses the plan's `action_invocations` name. */
|
|
104
|
+
export function invokedAddresses(plan) {
|
|
105
|
+
const list = isObject(plan) && Array.isArray(plan.action_invocations) ? plan.action_invocations : [];
|
|
106
|
+
return list.flatMap((inv) => (isObject(inv) && typeof inv.address === "string" ? [inv.address] : []));
|
|
107
|
+
}
|
|
108
|
+
async function run(input, binary, args, label) {
|
|
109
|
+
const exec = input.exec ?? runBinary;
|
|
110
|
+
const done = await exec(binary, args, input.dir, input.env ?? process.env);
|
|
111
|
+
if (done.code !== 0)
|
|
112
|
+
throw new StateOpError(input.root, `${binary} ${label}`, done.code, lastLines(done.out, 10));
|
|
113
|
+
return done;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Check the binary and the address, plan the invocation and read it back.
|
|
117
|
+
* A refusal comes back as a result; a binary run that fails throws
|
|
118
|
+
* {@link StateOpError}.
|
|
119
|
+
*/
|
|
120
|
+
export async function planAction(input) {
|
|
121
|
+
const binary = input.binary ?? "terraform";
|
|
122
|
+
const early = actionEngineRefusal(input.root, binary, input.version);
|
|
123
|
+
if (early)
|
|
124
|
+
return refused("action-engine", early);
|
|
125
|
+
if (!ACTION_ADDRESS.test(input.address)) {
|
|
126
|
+
return refused("action-address", `${input.root}: "${input.address}" is not an action address; give action.<type>.<label>, after module.<name>. for an action in a module`);
|
|
127
|
+
}
|
|
128
|
+
if (input.version === undefined) {
|
|
129
|
+
const shown = await run(input, binary, ["version", "-json"], "version -json");
|
|
130
|
+
let version = "";
|
|
131
|
+
try {
|
|
132
|
+
const v = JSON.parse(shown.stdout);
|
|
133
|
+
version = typeof v.terraform_version === "string" ? v.terraform_version : "";
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
version = "";
|
|
137
|
+
}
|
|
138
|
+
const late = actionEngineRefusal(input.root, binary, version || "of no known version");
|
|
139
|
+
if (late)
|
|
140
|
+
return refused("action-engine", late);
|
|
141
|
+
}
|
|
142
|
+
const planFile = input.planFile ?? join(input.dir, ".chant-action.tfplan");
|
|
143
|
+
await run(input, binary, ["plan", "-input=false", "-no-color", `-invoke=${input.address}`, `-out=${planFile}`], `plan -invoke=${input.address}`);
|
|
144
|
+
const show = await run(input, binary, ["show", "-json", planFile], "show -json");
|
|
145
|
+
let json;
|
|
146
|
+
try {
|
|
147
|
+
json = JSON.parse(show.stdout);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
throw new StateOpError(input.root, `${binary} show -json`, 0, `printed no plan: ${lastLines(show.out, 10)}`);
|
|
151
|
+
}
|
|
152
|
+
const invoked = invokedAddresses(json);
|
|
153
|
+
if (!invoked.includes(input.address)) {
|
|
154
|
+
return refused("unknown-action", `${input.root}: the plan invokes ${invoked.length > 0 ? invoked.join(", ") : "no action"}, and not ${input.address}; nothing applied`);
|
|
155
|
+
}
|
|
156
|
+
const fields = { address: input.address, invocations: actionInvocationsDigest(json), ...(input.commit ? { commit: input.commit } : {}) };
|
|
157
|
+
return { planFile, json, fields };
|
|
158
|
+
}
|
|
159
|
+
/** The time of the newest request with these fields that applied already, so asking again answers `spent`. */
|
|
160
|
+
async function appliedAt(input, subject, fields) {
|
|
161
|
+
const read = input.ledger?.readGatedRequests ?? readGatedRequests;
|
|
162
|
+
const all = await read(ACTION_OP, input.cwd ? { cwd: input.cwd } : undefined).catch(() => []);
|
|
163
|
+
const same = JSON.stringify(Object.entries(fields).sort());
|
|
164
|
+
const last = all
|
|
165
|
+
.filter((g) => g.request.kind === ACTION_KIND && g.request.subject === subject && g.request.by === input.requester)
|
|
166
|
+
.filter((g) => JSON.stringify(Object.entries(g.request.fields).sort()) === same)
|
|
167
|
+
.at(-1);
|
|
168
|
+
return last?.applied ? last.request.at : undefined;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Invoke one action under a gated request: plan it, ask, and once an
|
|
172
|
+
* approval by someone other than the requester counts, spend it, apply the
|
|
173
|
+
* saved plan and record how it ended.
|
|
174
|
+
*/
|
|
175
|
+
export async function invokeAction(input) {
|
|
176
|
+
const binary = input.binary ?? "terraform";
|
|
177
|
+
const planned = await planAction(input);
|
|
178
|
+
if ("outcome" in planned)
|
|
179
|
+
return planned;
|
|
180
|
+
const subject = actionSubject(input.root, input.address);
|
|
181
|
+
const at = input.anew ? undefined : await appliedAt(input, subject, planned.fields);
|
|
182
|
+
let tail = "";
|
|
183
|
+
const result = await gatedStateOp({
|
|
184
|
+
op: ACTION_OP,
|
|
185
|
+
request: { kind: ACTION_KIND, subject, by: input.requester, fields: planned.fields, ...(at ? { at } : {}) },
|
|
186
|
+
rules: input.rules,
|
|
187
|
+
description: `action ${input.address} on ${input.root}, requested by ${input.requester}`,
|
|
188
|
+
...(input.expiry ? { expiry: input.expiry } : {}),
|
|
189
|
+
...(input.cwd ? { cwd: input.cwd } : {}),
|
|
190
|
+
...(input.now ? { now: input.now } : {}),
|
|
191
|
+
...(input.runId ? { runId: input.runId } : {}),
|
|
192
|
+
...(input.commit ? { commit: input.commit } : {}),
|
|
193
|
+
...(input.ledger ? { ledger: input.ledger } : {}),
|
|
194
|
+
failedDetail: (error) => error instanceof StateOpError ? { result: "failed", exit: error.code, tail: error.tail.slice(-400), address: input.address } : { result: "failed", address: input.address },
|
|
195
|
+
}, async () => {
|
|
196
|
+
const done = await run(input, binary, ["apply", "-input=false", "-no-color", ...lockTimeoutArgs("apply", input.lockTimeout ?? DEFAULT_LOCK_TIMEOUT, input.env ?? process.env), planned.planFile], "apply");
|
|
197
|
+
tail = lastLines(done.out, 10);
|
|
198
|
+
return { output: tail, detail: { result: "ok", exit: 0, tail: tail.slice(-400), address: input.address } };
|
|
199
|
+
});
|
|
200
|
+
switch (result.status) {
|
|
201
|
+
case "waiting":
|
|
202
|
+
return { outcome: "gated", digest: result.digest, subject, command: result.command, exit: CHANT_EXIT.waiting };
|
|
203
|
+
case "refused":
|
|
204
|
+
return { outcome: "gated", digest: result.digest, subject, command: result.command, reason: result.reason, exit: CHANT_EXIT.waiting };
|
|
205
|
+
case "spent":
|
|
206
|
+
return { outcome: "spent", digest: result.digest, subject, exit: CHANT_EXIT.failed };
|
|
207
|
+
case "held":
|
|
208
|
+
// No last check is passed, so nothing holds; kept for the union.
|
|
209
|
+
return { outcome: "gated", digest: result.digest, subject, command: "", reason: result.reason, exit: CHANT_EXIT.waiting };
|
|
210
|
+
case "done":
|
|
211
|
+
return { outcome: "ok", digest: result.digest, subject, approvedBy: result.approvedBy, tail: result.output, recorded: result.recorded, exit: CHANT_EXIT.done };
|
|
212
|
+
case "failed": {
|
|
213
|
+
const e = result.error;
|
|
214
|
+
return {
|
|
215
|
+
outcome: "failed",
|
|
216
|
+
digest: result.digest,
|
|
217
|
+
subject,
|
|
218
|
+
approvedBy: result.approvedBy,
|
|
219
|
+
error: e.message,
|
|
220
|
+
tail: e instanceof StateOpError ? e.tail : tail,
|
|
221
|
+
recorded: result.recorded,
|
|
222
|
+
exit: CHANT_EXIT.failed,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
const actorOf = (env) => env.GITHUB_ACTOR || env.GITLAB_USER_LOGIN || env.USER || env.USERNAME || "unknown";
|
|
228
|
+
function stepInvoke(input) {
|
|
229
|
+
const cwd = input.cwd ?? process.cwd();
|
|
230
|
+
const commit = input.commit ?? (process.env.GITHUB_SHA || process.env.CI_COMMIT_SHA || undefined);
|
|
231
|
+
return {
|
|
232
|
+
root: input.root,
|
|
233
|
+
dir: input.dir ?? join(cwd, input.root),
|
|
234
|
+
address: input.address,
|
|
235
|
+
requester: input.by ?? actorOf(process.env),
|
|
236
|
+
rules: { mode: input.approval ?? "ledger" },
|
|
237
|
+
cwd,
|
|
238
|
+
...(input.binary ? { binary: input.binary } : {}),
|
|
239
|
+
...(input.version ? { version: input.version } : {}),
|
|
240
|
+
...(commit ? { commit } : {}),
|
|
241
|
+
...(input.lockTimeout !== undefined ? { lockTimeout: input.lockTimeout } : {}),
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
export const terraformActionCapability = {
|
|
245
|
+
kind: "terraform-action",
|
|
246
|
+
rollbackPolicy: "none-by-design",
|
|
247
|
+
targets: { refuse: "an action is invoked by its own address" },
|
|
248
|
+
async plan(_ctx, input) {
|
|
249
|
+
const planned = await planAction(stepInvoke(input));
|
|
250
|
+
if ("outcome" in planned)
|
|
251
|
+
throw new Error(planned.reason);
|
|
252
|
+
const part = terraformChangeSetPart({ member: input.root, plan: planned.json });
|
|
253
|
+
return { member: input.root, planDigest: part.member.planDigest ?? "", changeSet: part };
|
|
254
|
+
},
|
|
255
|
+
async run(_ctx, input) {
|
|
256
|
+
const result = await invokeAction(stepInvoke(input));
|
|
257
|
+
switch (result.outcome) {
|
|
258
|
+
case "ok":
|
|
259
|
+
return { root: input.root, address: input.address, digest: result.digest };
|
|
260
|
+
case "gated":
|
|
261
|
+
throw new StateOpWaitingError(ACTION_OP, result.subject, result.digest, result.command);
|
|
262
|
+
case "spent":
|
|
263
|
+
throw new Error(`${ACTION_OP} ${result.subject}: the request ${result.digest} applied already, and a request applies once`);
|
|
264
|
+
case "refused":
|
|
265
|
+
throw new Error(result.reason);
|
|
266
|
+
case "failed":
|
|
267
|
+
throw new Error(result.error);
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
};
|
|
@@ -203,6 +203,7 @@ export declare const TERRAFORM_VERB_FAMILIES: {
|
|
|
203
203
|
readonly apply: readonly ["terraform-apply"];
|
|
204
204
|
readonly state: readonly ["terraform-state-unlock", "terraform-state-push"];
|
|
205
205
|
readonly copy: readonly ["terraform-copy"];
|
|
206
|
+
readonly action: readonly ["terraform-action"];
|
|
206
207
|
};
|
|
207
208
|
export declare const terraformCapabilityPlugin: CapabilityPlugin;
|
|
208
209
|
//# sourceMappingURL=capability-plugin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability-plugin.d.ts","sourceRoot":"","sources":["../../src/components/capability-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4HG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAiC,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAExH,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,2CAA2C,CAAC;AAGnD,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,+CAA+C,CAAC;AACzG,OAAO,KAAK,EAAmB,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,kDAAkD,CAAC;AA0BlI,OAAO,EAA0D,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"capability-plugin.d.ts","sourceRoot":"","sources":["../../src/components/capability-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4HG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAiC,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAExH,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,2CAA2C,CAAC;AAGnD,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,+CAA+C,CAAC;AACzG,OAAO,KAAK,EAAmB,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,kDAAkD,CAAC;AA0BlI,OAAO,EAA0D,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAIjH,0CAA0C;AAC1C,MAAM,WAAW,uBAAuB;IACtC,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+HAA+H;IAC/H,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yGAAyG;IACzG,WAAW,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC7B,qFAAqF;IACrF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gHAAgH;IAChH,KAAK,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAC9B;AAED,6FAA6F;AAC7F,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,YAAY,EAAE,OAAO,CAAC;IACtB,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAyGD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CAerE;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,GAAG,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG,oBAAoB,CAEhI;AAID;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,kBAInC,CAAC;AA4BF,4GAA4G;AAC5G,eAAO,MAAM,iBAAiB,0BAA0B,CAAC;AAEzD,iHAAiH;AACjH,MAAM,WAAW,sBAAuB,SAAQ,iBAAiB;IAC/D,IAAI,EAAE,uBAAuB,CAAC;CAC/B;AAsFD;;;;;;;GAOG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;aAEpB,IAAI,EAAE,MAAM;IADxC,QAAQ,CAAC,SAAS,QAAQ;IAC1B,YAA4B,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAGxD;CACF;AA6DD,eAAO,MAAM,wBAAwB,EAAE,UAAU,CAAC,uBAAuB,EAAE,wBAAwB,CAwHlG,CAAC;AAEF,eAAO,MAAM,uBAAuB;aAClC,KAAK,YAAG,iBAAiB;aAEzB,KAAK,YAAG,wBAAwB,EAAE,sBAAsB;aACxD,IAAI,YAAG,gBAAgB;aAEvB,MAAM,YAAG,kBAAkB;CACnB,CAAC;AAEX,eAAO,MAAM,yBAAyB,EAAE,gBAcvC,CAAC"}
|
|
@@ -145,6 +145,7 @@ import { DEFAULT_LOCK_TIMEOUT, isLockTimeout } from "../lock-timeout.js";
|
|
|
145
145
|
import { conePlanDigest } from "../cone.js";
|
|
146
146
|
import { fillStateReads, stateReadsProblems, waitingReadsReason } from "../state-reads.js";
|
|
147
147
|
import { terraformStateOpCapabilities } from "../state-ops.js";
|
|
148
|
+
import { terraformActionCapability } from "../action-ops.js";
|
|
148
149
|
/** The lock timeout a step's plan and apply pass (#4545). */
|
|
149
150
|
function lockTimeoutOf(input) {
|
|
150
151
|
if (input.lockTimeout === false)
|
|
@@ -587,6 +588,8 @@ export const TERRAFORM_VERB_FAMILIES = {
|
|
|
587
588
|
// #4618: the binary runs outside waves, each a fixed operation; the two that change state on their own run under a gated request.
|
|
588
589
|
state: ["terraform-state-unlock", "terraform-state-push"],
|
|
589
590
|
copy: ["terraform-copy"],
|
|
591
|
+
// #4653: one action block invoked on its own, under a gated request.
|
|
592
|
+
action: ["terraform-action"],
|
|
590
593
|
};
|
|
591
594
|
export const terraformCapabilityPlugin = {
|
|
592
595
|
name: "terraform",
|
|
@@ -594,7 +597,7 @@ export const terraformCapabilityPlugin = {
|
|
|
594
597
|
return ownPackageVersion(import.meta.url);
|
|
595
598
|
},
|
|
596
599
|
capabilities() {
|
|
597
|
-
return [terraformApplyCapability, ...terraformStateOpCapabilities.map((c) => c)];
|
|
600
|
+
return [terraformApplyCapability, ...terraformStateOpCapabilities.map((c) => c), terraformActionCapability];
|
|
598
601
|
},
|
|
599
602
|
families() {
|
|
600
603
|
return TERRAFORM_VERB_FAMILIES;
|
package/dist/integrity.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
4
|
+
"manifest.json": "9d0b2a34e8ab7ef946ff820f524b61023dcbfde27bb6c087f18536fab7356b53",
|
|
5
5
|
"meta.json": "ca3d163bab055381827226140568f3bef7eaac187cebd76878e0b63e9e442356",
|
|
6
6
|
"types/index.d.ts": "022927e6a7b351cc4cf52d5f973f60ccd140e5810e17b32fb8868965aa1db161",
|
|
7
7
|
"rules/plan-before-apply.ts": "7c10245b2c3335253b48ee7d8b075d89f43116bde20313a5d1031b343fef1282",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"rules/tf047.ts": "bfa86f85c4c5efff297280fc2f15104d6319fa96dfc444a31829fb7353224092",
|
|
60
60
|
"skills/chant-terraform.md": "53dd11c7b289652f92fdaf2c03766abda46d8964e31fe709e8b142ced4f19c50"
|
|
61
61
|
},
|
|
62
|
-
"composite": "
|
|
62
|
+
"composite": "2c430036fefe238c43a24320fc630c35a3430dd1cdaf4e6a54c9fac464699b0a"
|
|
63
63
|
}
|
package/dist/manifest.json
CHANGED
package/dist/pin/scan.d.ts
CHANGED
|
@@ -49,6 +49,11 @@ export declare class HclScanError extends Error {
|
|
|
49
49
|
export declare function scanBlocks(text: string, file: string): ScannedBlock[];
|
|
50
50
|
/** Undo HCL's string escapes, so a literal's raw text compares to the value the reader returned. */
|
|
51
51
|
export declare function unescapeHcl(raw: string): string;
|
|
52
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* Write a value as the content of an HCL string literal: `\` and `"`
|
|
54
|
+
* escaped, a control character as `\n`, `\r`, `\t` or `\uNNNN`, and `${`
|
|
55
|
+
* and `%{` doubled so nothing in it is a template. The replacements are
|
|
56
|
+
* functions because a replacement string reads `$$` as one `$`.
|
|
57
|
+
*/
|
|
53
58
|
export declare function escapeHcl(value: string): string;
|
|
54
59
|
//# sourceMappingURL=scan.d.ts.map
|
package/dist/pin/scan.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/pin/scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,gDAAgD;IAChD,GAAG,EAAE,MAAM,CAAC;CACb;AAED,+GAA+G;AAC/G,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,kGAAkG;IAClG,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAYD,0EAA0E;AAC1E,qBAAa,YAAa,SAAQ,KAAK;IACrC,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAGxC;CACF;AAmID,0EAA0E;AAC1E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,EAAE,CAgCrE;AAkDD,oGAAoG;AACpG,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAyB/C;
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/pin/scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,gDAAgD;IAChD,GAAG,EAAE,MAAM,CAAC;CACb;AAED,+GAA+G;AAC/G,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,kGAAkG;IAClG,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAYD,0EAA0E;AAC1E,qBAAa,YAAa,SAAQ,KAAK;IACrC,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAGxC;CACF;AAmID,0EAA0E;AAC1E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,EAAE,CAgCrE;AAkDD,oGAAoG;AACpG,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAyB/C;AAID;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM/C"}
|
package/dist/pin/scan.js
CHANGED
|
@@ -281,7 +281,17 @@ export function unescapeHcl(raw) {
|
|
|
281
281
|
}
|
|
282
282
|
return out;
|
|
283
283
|
}
|
|
284
|
-
|
|
284
|
+
const CONTROL_ESCAPES = { "\n": "\\n", "\r": "\\r", "\t": "\\t" };
|
|
285
|
+
/**
|
|
286
|
+
* Write a value as the content of an HCL string literal: `\` and `"`
|
|
287
|
+
* escaped, a control character as `\n`, `\r`, `\t` or `\uNNNN`, and `${`
|
|
288
|
+
* and `%{` doubled so nothing in it is a template. The replacements are
|
|
289
|
+
* functions because a replacement string reads `$$` as one `$`.
|
|
290
|
+
*/
|
|
285
291
|
export function escapeHcl(value) {
|
|
286
|
-
return value
|
|
292
|
+
return value
|
|
293
|
+
.replace(/[\\"]/g, (c) => `\\${c}`)
|
|
294
|
+
.replace(/[\u0000-\u001f\u007f]/g, (c) => CONTROL_ESCAPES[c] ?? `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`)
|
|
295
|
+
.replace(/\$\{/g, () => "$${")
|
|
296
|
+
.replace(/%\{/g, () => "%%{");
|
|
287
297
|
}
|
package/dist/state-ops.d.ts
CHANGED
|
@@ -148,6 +148,11 @@ export interface GatedStateOpInput {
|
|
|
148
148
|
* the operation with that reason, and the approval is not spent.
|
|
149
149
|
*/
|
|
150
150
|
beforeSpend?: () => Promise<string | undefined>;
|
|
151
|
+
/**
|
|
152
|
+
* The flat facts of a failed act's finished line, beside its `error`, such
|
|
153
|
+
* as the binary's exit code and last lines (#4653). Default none.
|
|
154
|
+
*/
|
|
155
|
+
failedDetail?: (error: Error) => Record<string, string | number | boolean>;
|
|
151
156
|
}
|
|
152
157
|
/** How a gated operation ended. */
|
|
153
158
|
export type GatedStateOpResult<T> = Exclude<RequestGateResult, {
|
package/dist/state-ops.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-ops.d.ts","sourceRoot":"","sources":["../src/state-ops.ts"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,wCAAwC,CAAC;AACzF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,EACL,kBAAkB,EAElB,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACvB,MAAM,0CAA0C,CAAC;AAGlD,OAAO,EAAwB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAErE,iGAAiG;AACjG,eAAO,MAAM,SAAS;aACpB,MAAM,EAAE,WAAW;aACnB,OAAO,EAAE,YAAY;aACrB,MAAM,EAAE,iBAAiB;CACjB,CAAC;AAEX,2CAA2C;AAC3C,eAAO,MAAM,cAAc;aACzB,MAAM,EAAE,QAAQ;aAChB,OAAO,EAAE,SAAS;aAClB,MAAM,EAAE,cAAc;CACd,CAAC;AAEX,sEAAsE;AACtE,qBAAa,YAAa,SAAQ,KAAK;IAEnC,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM;IAJvB,YACW,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAItB;CACF;AAED,kHAAkH;AAClH,qBAAa,mBAAoB,SAAQ,KAAK;IAG1C,QAAQ,CAAC,EAAE,EAAE,MAAM;IACnB,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM;IAL1B,QAAQ,CAAC,QAAQ,IAAsB;IACvC,YACW,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EAIzB;CACF;AAED,kDAAkD;AAClD,MAAM,WAAW,OAAO;IACtB,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAWD,iGAAiG;AACjG,wBAAsB,QAAQ,CAAC,CAAC,EAAE,OAAO,GAAG;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5H;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EAAE,OAAO,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjF;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjH;AAED,iEAAiE;AACjE,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAcD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAEnG;AAED,gGAAgG;AAChG,MAAM,WAAW,YAAa,SAAQ,QAAQ;IAC5C,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAC5B,CAAC,EAAE,OAAO,GAAG;IAAE,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GACxI,OAAO,CAAC,YAAY,CAAC,CAQvB;AAED,mFAAmF;AACnF,wBAAsB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAElH;AAID,4FAA4F;AAC5F,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,OAAO,WAAW,CAAC;IAChC,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;CAC7C;AAID;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,EACjC,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,mBAAmB,CAAC,CAAA;CAAO,GACnG,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED,yEAAyE;AACzE,eAAO,MAAM,gBAAgB,eAAgB,MAAM,KAAG,MAA2E,CAAC;AAElI,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,+DAA+D;IAC/D,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,KAAK,EAAE,iBAAiB,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iGAAiG;IACjG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,KAAK,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAClC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"state-ops.d.ts","sourceRoot":"","sources":["../src/state-ops.ts"],"names":[],"mappings":"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"}
|
package/dist/state-ops.js
CHANGED
|
@@ -228,7 +228,7 @@ export async function gatedStateOp(input, act) {
|
|
|
228
228
|
}
|
|
229
229
|
catch (e) {
|
|
230
230
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
231
|
-
return { status: "failed", digest, request: asked.request, approvedBy, error, recorded: await finish("failed", { error: error.message.slice(0, 400) }) };
|
|
231
|
+
return { status: "failed", digest, request: asked.request, approvedBy, error, recorded: await finish("failed", { ...(input.failedDetail?.(error) ?? {}), error: error.message.slice(0, 400) }) };
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
234
|
/** The digest a request binds, for a caller that prints it before it asks. */
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@intentius/chant-lexicon-terraform/template` (#4652): a template request
|
|
3
|
+
* (`@intentius/chant/template-request`) as Terraform files, an app's new
|
|
4
|
+
* root or an add-on's module call in it. Nothing here reads the disk.
|
|
5
|
+
*/
|
|
6
|
+
export { renderAppRoot, renderAddonCall, terraformInputType, addonFile, TemplateRenderError, APP_MODULE_NAME, APP_OUTPUT_PREFIX, APP_ROOT_FILE, } from "./render.js";
|
|
7
|
+
export type { RenderAppRootOptions, RenderAddonCallOptions, RenderedFile, TemplateOutput, TemplateRenderErrorCode } from "./render.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/template/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,SAAS,EACT,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,aAAa,GACd,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,YAAY,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@intentius/chant-lexicon-terraform/template` (#4652): a template request
|
|
3
|
+
* (`@intentius/chant/template-request`) as Terraform files, an app's new
|
|
4
|
+
* root or an add-on's module call in it. Nothing here reads the disk.
|
|
5
|
+
*/
|
|
6
|
+
export { renderAppRoot, renderAddonCall, terraformInputType, addonFile, TemplateRenderError, APP_MODULE_NAME, APP_OUTPUT_PREFIX, APP_ROOT_FILE, } from "./render.js";
|