aws-cdk 2.1128.0 → 2.1129.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +1 -0
  2. package/THIRD_PARTY_LICENSES +2822 -2593
  3. package/build-info.json +2 -2
  4. package/docs/confirmation-prompts.md +79 -0
  5. package/lib/api-private.d.ts +2 -0
  6. package/lib/api-private.js +29 -3
  7. package/lib/cli/cdk-toolkit.d.ts +8 -1
  8. package/lib/cli/cdk-toolkit.js +164 -125
  9. package/lib/cli/cli-config.js +40 -4
  10. package/lib/cli/cli-type-registry.json +16 -1
  11. package/lib/cli/cli.js +49 -10
  12. package/lib/cli/convert-to-user-input.js +7 -1
  13. package/lib/cli/display-version.js +46 -7
  14. package/lib/cli/io-host/cli-io-host.d.ts +211 -23
  15. package/lib/cli/io-host/cli-io-host.js +321 -95
  16. package/lib/cli/parse-command-line-arguments.js +51 -3
  17. package/lib/cli/platform-warnings.js +36 -3
  18. package/lib/cli/pretty-print-error.d.ts +4 -1
  19. package/lib/cli/pretty-print-error.js +15 -7
  20. package/lib/cli/proxy-agent.js +36 -2
  21. package/lib/cli/root-dir.js +36 -3
  22. package/lib/cli/tables.js +35 -2
  23. package/lib/cli/telemetry/installation-id.js +36 -3
  24. package/lib/cli/telemetry/library-version.js +36 -3
  25. package/lib/cli/telemetry/messages.js +35 -2
  26. package/lib/cli/telemetry/session.js +9 -2
  27. package/lib/cli/telemetry/sink/endpoint-sink.js +5 -2
  28. package/lib/cli/telemetry/sink/file-sink.js +37 -2
  29. package/lib/cli/telemetry/sink/funnel.js +2 -1
  30. package/lib/cli/telemetry/sink/io-host-sink.js +2 -1
  31. package/lib/cli/telemetry/telemetry-state.js +36 -3
  32. package/lib/cli/user-configuration.js +51 -13
  33. package/lib/cli/user-input.d.ts +19 -1
  34. package/lib/cli/user-input.js +1 -1
  35. package/lib/cli/util/fs-util.js +35 -2
  36. package/lib/cli/version.js +35 -2
  37. package/lib/commands/context.js +11 -8
  38. package/lib/commands/docs.js +41 -5
  39. package/lib/commands/doctor.js +45 -9
  40. package/lib/commands/flags/flags.js +5 -1
  41. package/lib/commands/flags/interactive-handler.js +3 -1
  42. package/lib/commands/flags/operations.js +58 -14
  43. package/lib/commands/flags/router.js +4 -1
  44. package/lib/commands/flags/validator.js +2 -1
  45. package/lib/commands/init/init-hooks.js +35 -2
  46. package/lib/commands/init/init.js +63 -22
  47. package/lib/commands/init/os.js +40 -4
  48. package/lib/commands/migrate.js +44 -6
  49. package/lib/cxapp/cloud-assembly.js +35 -2
  50. package/lib/cxapp/cloud-executable.d.ts +7 -0
  51. package/lib/cxapp/cloud-executable.js +48 -2
  52. package/lib/cxapp/exec.js +38 -5
  53. package/lib/index.js +284512 -245081
  54. package/package.json +9 -9
@@ -1,7 +1,7 @@
1
1
  import type { Agent } from 'node:https';
2
2
  import { RequireApproval } from '@aws-cdk/cloud-assembly-schema';
3
3
  import type { IIoHost, IoMessage, IoMessageCode, IoMessageLevel, IoRequest, ToolkitAction } from '@aws-cdk/toolkit-lib';
4
- import type { IoHelper, IoMessageMaker, IoDefaultMessages } from '../../../lib/api-private';
4
+ import type { IoHelper, IoMessageMaker, IoRequestMaker, IoDefaultMessages } from '../../../lib/api-private';
5
5
  import type { Context } from '../../api/context';
6
6
  import { StackActivityProgress } from '../../commands/deploy';
7
7
  import { TelemetrySession } from '../telemetry/session';
@@ -72,9 +72,9 @@ export type TargetStream = 'stdout' | 'stderr' | 'drop';
72
72
  /**
73
73
  * The result a message listener may return to influence how a message is handled.
74
74
  *
75
- * A listener can only update the message _text_; it cannot change any other
76
- * field of the message (such as its `code`), which keeps the code-keyed
77
- * listener registry valid.
75
+ * A listener may update the message _text_ and/or its _level_; it cannot change
76
+ * any other field of the message (such as its `code`), which keeps the
77
+ * code-keyed listener registry valid.
78
78
  */
79
79
  export interface MessageListenerResult {
80
80
  /**
@@ -84,16 +84,113 @@ export interface MessageListenerResult {
84
84
  */
85
85
  readonly message?: string;
86
86
  /**
87
- * Skip the default processing of the message, i.e. do not write it to a stream.
87
+ * Override the level of this message.
88
+ *
89
+ * The new level is used for both verbosity filtering and stream selection, so
90
+ * this can move a message between stdout/stderr (e.g. downgrade a `result` to
91
+ * `info`). The `code` is intentionally left unchanged.
92
+ *
93
+ * @default - the message level is left unchanged
94
+ */
95
+ readonly level?: IoMessageLevel;
96
+ /**
97
+ * Skip the default handling of the message.
98
+ *
99
+ * For a notification this means it is not written to a stream. For a request
100
+ * it stops processing entirely: the user is not prompted, nothing is written,
101
+ * and the request resolves with its (possibly `respond`-overridden) default
102
+ * response.
88
103
  *
89
104
  * @default false
90
105
  */
91
106
  readonly preventDefault?: boolean;
107
+ /**
108
+ * For requests only: the value to resolve the request with. It is folded into
109
+ * the request's default response and skips the prompt (the request is treated
110
+ * as not promptable). The question is still written unless `preventDefault` is
111
+ * also set. Ignored for plain notifications.
112
+ *
113
+ * The presence of the key is what matters, so `false`/`0`/`''` are valid
114
+ * answers. Use the `respond`/`respondOnce` helpers for the common case.
115
+ *
116
+ * @default - this listener does not supply a response
117
+ */
118
+ readonly respond?: unknown;
119
+ }
120
+ /**
121
+ * What a message listener may return: nothing, a `MessageListenerResult`, or a
122
+ * `Promise` of either.
123
+ *
124
+ * Listeners may be async. The host awaits each listener before running the
125
+ * next, so registration order — and the cumulative effect on the message — is
126
+ * preserved regardless of whether listeners are sync or async.
127
+ */
128
+ export type MessageListenerResultOrPromise = void | MessageListenerResult | Promise<void | MessageListenerResult>;
129
+ /**
130
+ * Selects which messages a listener applies to.
131
+ *
132
+ * Either a message/request *maker* — the listener fires for messages with that
133
+ * maker's `code` (the original behavior) — or a custom *predicate* over the
134
+ * message. A maker's `.is` type guard (e.g. `IO.CDK_TOOLKIT_I7010.is`) is a
135
+ * convenient predicate, but any `(msg) => boolean` works (e.g. to match a family
136
+ * of codes, or on the message level).
137
+ */
138
+ export type MessageSelector<T> = IoMessageMaker<T> | IoRequestMaker<T, any> | ((msg: IoMessage<any>) => boolean);
139
+ /**
140
+ * How an IoHost processed a single message or request.
141
+ *
142
+ * This describes the message *as the host handled it*, which can differ from
143
+ * what was emitted: listeners may rewrite the text or level, prevent it from
144
+ * being written at all, or (for requests) answer it on the user's behalf.
145
+ *
146
+ * Both notifications (`notify`) and requests (`requestResponse`) are reported,
147
+ * so an observer sees the complete, ordered stream the host handled. Use
148
+ * `type` to tell them apart.
149
+ */
150
+ export interface IoMessageObservation {
151
+ /**
152
+ * Whether this observation describes a plain notification (`notify`) or a
153
+ * request that asked for a response (`requestResponse`).
154
+ */
155
+ readonly type: 'notify' | 'request';
156
+ /**
157
+ * The message exactly as it was emitted to the host (before any listeners).
158
+ */
159
+ readonly emitted: IoMessage<unknown>;
160
+ /**
161
+ * The message after the host's listeners ran (text and/or level may differ).
162
+ */
163
+ readonly effective: IoMessage<unknown>;
164
+ /**
165
+ * Whether a listener prevented this message from being written, i.e. the user
166
+ * would not see it. Always `false` for requests (a request is reported once
167
+ * it has been resolved, regardless of how it was answered).
168
+ */
169
+ readonly dropped: boolean;
170
+ }
171
+ /**
172
+ * An IoHost whose message handling can be observed.
173
+ *
174
+ * This is a CLI-internal contract used by tests to record the *effective*,
175
+ * user-facing message stream (after listeners) without reaching into host
176
+ * internals. It is intentionally separate from `IIoHost` so that the recorder
177
+ * can work with any `IIoHost` and only enrich its output when the host also
178
+ * implements this interface.
179
+ */
180
+ export interface ObservableIoHost {
181
+ /**
182
+ * Register an observer that is invoked for every message the host handles —
183
+ * both notifications and requests — with the disposition the host computed
184
+ * for it (its effective form after listeners and whether it was dropped). For
185
+ * a request, the resolved answer is the effective message's `defaultResponse`.
186
+ * Returns a function that removes the observer again.
187
+ */
188
+ observeMessages(observer: (observation: IoMessageObservation) => void): () => void;
92
189
  }
93
190
  /**
94
191
  * A simple IO host for the CLI that writes messages to the console.
95
192
  */
96
- export declare class CliIoHost implements IIoHost {
193
+ export declare class CliIoHost implements IIoHost, ObservableIoHost {
97
194
  /**
98
195
  * Returns the singleton instance
99
196
  */
@@ -142,6 +239,8 @@ export declare class CliIoHost implements IIoHost {
142
239
  private corkedCounter;
143
240
  private readonly corkedLoggingBuffer;
144
241
  private readonly messageListeners;
242
+ private readonly messageObservers;
243
+ private corkReplaying;
145
244
  private readonly autoRespond;
146
245
  /**
147
246
  * The telemetry session object
@@ -178,51 +277,108 @@ export declare class CliIoHost implements IIoHost {
178
277
  *
179
278
  * The listener may return a `MessageListenerResult` to update the message
180
279
  * text and/or prevent the default processing (writing it to a stream);
181
- * returning nothing leaves the message untouched. Returns a function that
182
- * removes the listener again.
280
+ * returning nothing leaves the message untouched. The listener may be async
281
+ * (return a `Promise`); the host awaits it before processing the message
282
+ * further. Returns a function that removes the listener again.
183
283
  *
184
284
  * @example
185
- * const dispose = ioHost.on(IO.CDK_TOOLKIT_I2901, (msg) => {
285
+ * const dispose = ioHost.on(IO.CDK_TOOLKIT_I2901, async (msg) => {
186
286
  * myCount += msg.data.stacks.length;
287
+ * await persist(myCount);
187
288
  * });
289
+ *
290
+ * @example
291
+ * // Match with a custom predicate instead of a code, e.g. a maker's `.is`:
292
+ * const dispose = ioHost.on(IO.CDK_TOOLKIT_I7010.is, (msg) => ({ respond: true }));
293
+ */
294
+ on<T>(selector: IoMessageMaker<T> | IoRequestMaker<T, any> | ((msg: IoMessage<any>) => msg is IoMessage<T>), listener: (msg: IoMessage<T>) => MessageListenerResultOrPromise): () => void;
295
+ on(predicate: (msg: IoMessage<any>) => boolean, listener: (msg: IoMessage<unknown>) => MessageListenerResultOrPromise): () => void;
296
+ /**
297
+ * Register an observer that is invoked for every message the host handles —
298
+ * both notifications and requests — with the disposition the host computed
299
+ * for it (its effective form after listeners and whether it was dropped). For
300
+ * a request, the resolved answer is the effective message's `defaultResponse`.
301
+ * Returns a function that removes the observer.
302
+ *
303
+ * @see ObservableIoHost
188
304
  */
189
- on<T>(code: IoMessageMaker<T>, listener: (msg: IoMessage<T>) => void | MessageListenerResult): () => void;
305
+ observeMessages(observer: (observation: IoMessageObservation) => void): () => void;
190
306
  /**
191
307
  * Like `on`, but the listener is automatically removed after it has been
192
308
  * invoked once.
193
309
  */
194
- once<T>(code: IoMessageMaker<T>, listener: (msg: IoMessage<T>) => void | MessageListenerResult): () => void;
310
+ once<T>(selector: IoMessageMaker<T> | IoRequestMaker<T, any> | ((msg: IoMessage<any>) => msg is IoMessage<T>), listener: (msg: IoMessage<T>) => MessageListenerResultOrPromise): () => void;
311
+ once(predicate: (msg: IoMessage<any>) => boolean, listener: (msg: IoMessage<unknown>) => MessageListenerResultOrPromise): () => void;
312
+ /**
313
+ * Remove every message listener registered via `on`/`once`/`rewrite`/`respond`.
314
+ *
315
+ * The host's own internal listeners (such as stack-activity routing) are kept,
316
+ * so the host keeps working afterwards. Message observers registered via
317
+ * `observeMessages` are a separate mechanism and are not affected.
318
+ *
319
+ * This is mainly useful for tests that share the singleton host and need to
320
+ * reset listener state between cases (a leftover listener would otherwise
321
+ * leak into the next test).
322
+ */
323
+ removeAllListeners(): void;
324
+ /**
325
+ * Answer a request (by its code) on the user's behalf with a fixed value, so
326
+ * the host does not prompt. Syntactic sugar for an `on` listener returning
327
+ * `{ respond: value, preventDefault: suppressQuestion }`; for conditional
328
+ * answers or to also reword the question, use `on`/`once` directly. Returns a
329
+ * function that removes the responder again.
330
+ *
331
+ * @param suppressQuestion - whether to also suppress writing the question text.
332
+ * Defaults to `true` (answer silently). Pass `false` to still surface the
333
+ * question while answering it.
334
+ *
335
+ * @example
336
+ * // Under --force, auto-confirm the destroy prompt without prompting.
337
+ * const dispose = ioHost.respond(IO.CDK_TOOLKIT_I7010, true);
338
+ */
339
+ respond<T, U>(code: IoRequestMaker<T, U>, value: U, suppressQuestion?: boolean): () => void;
340
+ /**
341
+ * Like `respond`, but the answer is given only once and then removed.
342
+ */
343
+ respondOnce<T, U>(code: IoRequestMaker<T, U>, value: U, suppressQuestion?: boolean): () => void;
195
344
  /**
196
345
  * Register a formatter that replaces the printed text of messages with the
197
346
  * given code. This lets a caller define _how_ a toolkit message is presented
198
347
  * without the IoHost needing to know about it.
199
348
  *
200
- * Syntactic sugar for an `on` listener that returns `{ message }`. Returns a
201
- * function that removes the formatter again.
349
+ * Optionally pass a `level` to also override the message's level (which moves
350
+ * it between stdout/stderr and changes verbosity filtering). For the rarer
351
+ * case of overriding only the level, use `on`/`once` returning `{ level }`.
352
+ *
353
+ * Syntactic sugar for an `on` listener that returns `{ message, level? }`.
354
+ * Returns a function that removes the formatter again.
202
355
  *
203
356
  * @example
204
357
  * const dispose = ioHost.rewrite(IO.CDK_TOOLKIT_I2901, (msg) =>
205
358
  * serializeStructure(msg.data.stacks, true));
206
359
  */
207
- rewrite<T>(code: IoMessageMaker<T>, formatter: (msg: IoMessage<T>) => string): () => void;
360
+ rewrite<T>(code: IoMessageMaker<T> | IoRequestMaker<T, any>, formatter: (msg: IoMessage<T>) => string, level?: IoMessageLevel): () => void;
208
361
  /**
209
362
  * Like `rewrite`, but the formatter is automatically removed after it has
210
363
  * been applied once.
211
364
  */
212
- rewriteOnce<T>(code: IoMessageMaker<T>, formatter: (msg: IoMessage<T>) => string): () => void;
365
+ rewriteOnce<T>(code: IoMessageMaker<T> | IoRequestMaker<T, any>, formatter: (msg: IoMessage<T>) => string, level?: IoMessageLevel): () => void;
213
366
  /**
214
367
  * Add a listener to the registry and return a function that removes it.
215
368
  */
216
369
  private addMessageListener;
217
370
  /**
218
- * Run all registered listeners for a message's code, in registration order.
371
+ * Run every registered listener that matches the message, in registration
372
+ * order. A listener matches by its code (maker) or its custom predicate.
219
373
  *
220
- * A listener may update the message text (which is passed on to subsequent
221
- * listeners and the rest of the pipeline) and/or request that the default
222
- * processing be skipped. `once` listeners are removed after they have run.
374
+ * A listener may update the message text/level (passed on to subsequent
375
+ * listeners and the rest of the pipeline), prevent the default processing, or
376
+ * (for requests) answer it. `once` listeners are removed after they have run.
377
+ * Matching is decided against the message as emitted, so a rewrite by an
378
+ * earlier listener does not change which later listeners apply.
223
379
  *
224
- * Returns the (possibly text-updated) message and whether any listener
225
- * prevented the default processing.
380
+ * Returns the (possibly updated) message, whether the default processing was
381
+ * prevented, and whether a listener answered the request (and with what).
226
382
  */
227
383
  private applyMessageListeners;
228
384
  /**
@@ -230,6 +386,18 @@ export declare class CliIoHost implements IIoHost {
230
386
  * The caller waits until the notification completes.
231
387
  */
232
388
  notify(msg: IoMessage<unknown>): Promise<void>;
389
+ /**
390
+ * Notify every registered message observer of how a message or request was
391
+ * handled. A no-op when nothing is observing (i.e. outside of tests), so the
392
+ * surrounding hot paths pay nothing in production.
393
+ */
394
+ private notifyObservers;
395
+ /**
396
+ * Write a (already listener-processed) message to its target stream, honoring
397
+ * the log level and corked-logging buffer. Shared by `notify` and the
398
+ * non-prompting `requestResponse` path.
399
+ */
400
+ private writeMessage;
233
401
  private maybeEmitTelemetry;
234
402
  /**
235
403
  * Route stack-activity messages to the activity printer (progress bar or
@@ -256,10 +424,21 @@ export declare class CliIoHost implements IIoHost {
256
424
  /**
257
425
  * Notifies the host of a message that requires a response.
258
426
  *
259
- * If the host does not return a response the suggested
260
- * default response from the input message will be used.
427
+ * Registered listeners run first: a listener may reword the question (its text
428
+ * or level) or answer it outright via `respond` (e.g. `--force` auto-confirms
429
+ * a destroy). If no listener answers and the host cannot prompt, the suggested
430
+ * default response is used.
261
431
  */
262
432
  requestResponse<DataType, ResponseType>(msg: IoRequest<DataType, ResponseType>): Promise<ResponseType>;
433
+ /**
434
+ * Resolve a request to its response: a listener's answer if one was given,
435
+ * otherwise the answer prompted from the user, otherwise the suggested
436
+ * default when the host cannot prompt.
437
+ *
438
+ * Kept separate from `requestResponse` so the response can be observed in a
439
+ * single place regardless of which of these paths produced it.
440
+ */
441
+ private resolveRequest;
263
442
  /**
264
443
  * Formats a message for console output with optional color support
265
444
  */
@@ -273,3 +452,12 @@ export declare class CliIoHost implements IIoHost {
273
452
  */
274
453
  private makeActivityPrinter;
275
454
  }
455
+ /**
456
+ * Combine several selectors into a single predicate that matches a message when
457
+ * *any* of them matches. Each selector may be a maker (matched by its `code`)
458
+ * or a predicate.
459
+ *
460
+ * Useful for one listener that spans multiple codes, e.g.
461
+ * `ioHost.on(matchAny(IO.CDK_TOOLKIT_I5501, IO.CDK_TOOLKIT_I5502), listener)`.
462
+ */
463
+ export declare function matchAny(...selectors: MessageSelector<any>[]): (msg: IoMessage<unknown>) => boolean;