cdktn 0.25.0-pre.8 → 0.25.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 (94) hide show
  1. package/.jsii +2194 -424
  2. package/README.md +12 -0
  3. package/lib/annotations.js +4 -4
  4. package/lib/app.js +54 -5
  5. package/lib/aspect.js +3 -4
  6. package/lib/asset-hash.d.ts +75 -0
  7. package/lib/asset-hash.js +129 -0
  8. package/lib/asset-staging.d.ts +180 -0
  9. package/lib/asset-staging.js +464 -0
  10. package/lib/assets.d.ts +401 -0
  11. package/lib/assets.js +333 -0
  12. package/lib/backends/azurerm-backend.js +4 -6
  13. package/lib/backends/cloud-backend.js +15 -12
  14. package/lib/backends/consul-backend.js +4 -6
  15. package/lib/backends/cos-backend.js +4 -6
  16. package/lib/backends/gcs-backend.js +4 -6
  17. package/lib/backends/http-backend.js +4 -6
  18. package/lib/backends/local-backend.js +38 -7
  19. package/lib/backends/oss-backend.js +4 -6
  20. package/lib/backends/pg-backend.js +4 -6
  21. package/lib/backends/remote-backend.js +8 -10
  22. package/lib/backends/s3-backend.js +4 -6
  23. package/lib/backends/swift-backend.js +4 -6
  24. package/lib/complex-computed-list.js +114 -65
  25. package/lib/errors.d.ts +16 -0
  26. package/lib/errors.js +51 -3
  27. package/lib/functions/provider-function.js +2 -4
  28. package/lib/functions/terraform-functions.generated.js +2 -4
  29. package/lib/ignore-strategy.d.ts +82 -0
  30. package/lib/ignore-strategy.js +29 -0
  31. package/lib/importable-resource.js +8 -6
  32. package/lib/index.d.ts +4 -0
  33. package/lib/index.js +28 -2
  34. package/lib/manifest.js +49 -11
  35. package/lib/private/fs.d.ts +74 -2
  36. package/lib/private/fs.js +129 -17
  37. package/lib/private/unique.js +35 -2
  38. package/lib/resource.js +3 -4
  39. package/lib/synthesize/synthesizer.js +51 -25
  40. package/lib/terraform-asset.d.ts +68 -5
  41. package/lib/terraform-asset.js +127 -40
  42. package/lib/terraform-backend.js +3 -4
  43. package/lib/terraform-count.js +3 -4
  44. package/lib/terraform-data-resource.d.ts +1 -1
  45. package/lib/terraform-data-resource.js +18 -13
  46. package/lib/terraform-data-source.js +10 -4
  47. package/lib/terraform-dynamic-block.js +5 -2
  48. package/lib/terraform-dynamic-expression.js +4 -1
  49. package/lib/terraform-element.js +34 -6
  50. package/lib/terraform-ephemeral-resource.js +10 -4
  51. package/lib/terraform-functions.js +2 -4
  52. package/lib/terraform-hcl-module.js +3 -4
  53. package/lib/terraform-iterator.js +11 -12
  54. package/lib/terraform-local.js +3 -4
  55. package/lib/terraform-module-asset.js +39 -4
  56. package/lib/terraform-module.js +8 -4
  57. package/lib/terraform-operators.js +2 -4
  58. package/lib/terraform-output.js +7 -4
  59. package/lib/terraform-provider.js +5 -4
  60. package/lib/terraform-provisioner.js +2 -4
  61. package/lib/terraform-remote-state.js +5 -5
  62. package/lib/terraform-resource-targets.js +3 -7
  63. package/lib/terraform-resource.js +23 -7
  64. package/lib/terraform-stack.js +38 -38
  65. package/lib/terraform-variable.js +25 -22
  66. package/lib/testing/adapters/jest.d.ts +2 -1
  67. package/lib/testing/adapters/jest.js +3 -3
  68. package/lib/testing/index.js +42 -8
  69. package/lib/testing/matchers.d.ts +34 -30
  70. package/lib/testing/matchers.js +329 -93
  71. package/lib/tfExpression.js +25 -8
  72. package/lib/tokens/lazy.js +11 -7
  73. package/lib/tokens/private/dependency.js +2 -2
  74. package/lib/tokens/private/encoding.js +6 -1
  75. package/lib/tokens/private/intrinsic.js +6 -1
  76. package/lib/tokens/private/resolve.js +2 -5
  77. package/lib/tokens/private/token-map.js +4 -6
  78. package/lib/tokens/private/uniqueid.js +35 -2
  79. package/lib/tokens/resolvable.js +4 -6
  80. package/lib/tokens/string-fragments.js +6 -10
  81. package/lib/tokens/token.js +15 -18
  82. package/lib/upgrade-id-aspect.js +37 -6
  83. package/lib/validations/index.d.ts +0 -1
  84. package/lib/validations/index.js +1 -2
  85. package/lib/validations/target-versions.js +39 -2
  86. package/lib/validations/validate-function-version-support.js +2 -1
  87. package/lib/validations/validate-provider-function-target-support.js +2 -1
  88. package/lib/validations/validate-provider-presence.js +10 -9
  89. package/package.json +21 -7
  90. package/scripts/pack.mjs +27 -12
  91. package/lib/validations/validate-binary-version.d.ts +0 -23
  92. package/lib/validations/validate-binary-version.js +0 -54
  93. package/lib/validations/validate-terraform-version.d.ts +0 -13
  94. package/lib/validations/validate-terraform-version.js +0 -21
@@ -0,0 +1,401 @@
1
+ import { IIgnoreStrategy } from "./ignore-strategy";
2
+ /**
3
+ * Common interface for all assets.
4
+ */
5
+ export interface IAsset {
6
+ /**
7
+ * A hash of this asset, available at construction time.
8
+ *
9
+ * Being a plain string, it can be used in construct IDs to force a new
10
+ * resource when the content hash changes.
11
+ */
12
+ readonly assetHash: string;
13
+ }
14
+ /**
15
+ * Options controlling how an asset's hash is derived.
16
+ */
17
+ export interface AssetOptions {
18
+ /**
19
+ * Specify a custom hash for this asset. If `assetHashType` is set it must
20
+ * be set to `AssetHashType.CUSTOM`. The value is used verbatim as the asset
21
+ * hash, and because it names the staged asset file it may only contain
22
+ * letters, digits, `_`, `.` and `-`.
23
+ *
24
+ * The hash identifies a specific revision of the asset and caches deployment
25
+ * work (packaging, uploading). A custom hash must be updated whenever the
26
+ * asset changes, or some deployments will not be invalidated.
27
+ *
28
+ * @default - based on `assetHashType`
29
+ */
30
+ readonly assetHash?: string;
31
+ /**
32
+ * Specifies the type of hash to calculate for this asset.
33
+ *
34
+ * If `assetHash` is configured, this option must be `undefined` or
35
+ * `AssetHashType.CUSTOM`.
36
+ *
37
+ * @default - the default is `AssetHashType.SOURCE`, but if `assetHash` is
38
+ * explicitly specified this value defaults to `AssetHashType.CUSTOM`.
39
+ */
40
+ readonly assetHashType?: AssetHashType;
41
+ }
42
+ /**
43
+ * The type of asset hash.
44
+ *
45
+ * The hash identifies a specific revision of the asset and caches deployment
46
+ * work such as packaging and uploading.
47
+ */
48
+ export declare enum AssetHashType {
49
+ /**
50
+ * Based on the content of the source path.
51
+ *
52
+ * Use `SOURCE` to track changes to the source files directly.
53
+ */
54
+ SOURCE = "source",
55
+ /**
56
+ * Based on the content of the bundling output.
57
+ *
58
+ * Use `OUTPUT` when the source is a top-level folder holding code and/or
59
+ * dependencies not directly linked to the asset.
60
+ */
61
+ OUTPUT = "output",
62
+ /**
63
+ * Use a custom hash.
64
+ */
65
+ CUSTOM = "custom"
66
+ }
67
+ /**
68
+ * How a staged asset is produced and what shape it takes on disk.
69
+ *
70
+ * Packaging answers two independent questions: how the artifact is produced
71
+ * (copy, zip, tar.gz, ...) and whether the result is a directory or a single
72
+ * file. A closed enum can only ever answer the second one, so it is an
73
+ * interface rather than an enum — custom formats (e.g. `tar.bz2`) need no
74
+ * core change.
75
+ */
76
+ export interface IAssetPackaging {
77
+ /**
78
+ * Appended to the staged artifact name, e.g. ".zip", "", ".tar.bz2".
79
+ */
80
+ readonly extension: string;
81
+ /**
82
+ * Whether the staged result is a directory rather than a single file.
83
+ *
84
+ * Publishers branch on this to decide whether they upload one object or
85
+ * sync a tree.
86
+ */
87
+ readonly producesDirectory: boolean;
88
+ /**
89
+ * Whether `pack` accepts a directory as its `source`.
90
+ *
91
+ * Independent of `producesDirectory` and `omitsDirectoryEntries`, both of
92
+ * which describe the output: a `tar.gz` packaging takes a directory source
93
+ * yet emits a single file. Bundler output is always a directory, so a
94
+ * packaging that is `false` here cannot stage it.
95
+ */
96
+ readonly acceptsDirectorySource: boolean;
97
+ /**
98
+ * Whether `pack` emits an artifact with no directory entries of its own —
99
+ * only the ignore-strategy-aware source walk. `hashPath`'s `archive` frame
100
+ * must agree with this or the hash and the artifact describe different
101
+ * file sets.
102
+ *
103
+ * `ZipPackaging` sets this because `archiveSync` never emits ZIP directory
104
+ * entries. A directory-producing packaging that mirrors the source tree
105
+ * (e.g. `DirectoryPackaging`) leaves this false, since its directories are
106
+ * real entries on disk.
107
+ */
108
+ readonly omitsDirectoryEntries: boolean;
109
+ /**
110
+ * Write the packaged result to `options.target`.
111
+ */
112
+ pack(options: PackOptions): void;
113
+ }
114
+ /**
115
+ * Options for {@link IAssetPackaging.pack}.
116
+ *
117
+ * A struct rather than positional parameters: adding a struct field is
118
+ * additive, adding a method parameter is not, and `pack` is called through
119
+ * JSII where that distinction is a breaking-change boundary.
120
+ */
121
+ export interface PackOptions {
122
+ /**
123
+ * Path to the resolved (already bundled, if applicable) source.
124
+ */
125
+ readonly source: string;
126
+ /**
127
+ * Path the packaged result should be written to.
128
+ */
129
+ readonly target: string;
130
+ /**
131
+ * Entries to omit from the packaged result. Must match the strategy used
132
+ * to hash the same source, or the hash and the artifact describe
133
+ * different sets of files.
134
+ *
135
+ * @default - nothing is excluded
136
+ */
137
+ readonly ignoreStrategy?: IIgnoreStrategy;
138
+ }
139
+ /**
140
+ * Built-in packaging strategies. Custom formats implement `IAssetPackaging`
141
+ * directly rather than extending this class.
142
+ */
143
+ export declare class AssetPackaging {
144
+ /**
145
+ * Copy a single file as-is.
146
+ */
147
+ static readonly FILE: IAssetPackaging;
148
+ /**
149
+ * Copy a directory tree as-is, without archiving.
150
+ */
151
+ static readonly DIRECTORY: IAssetPackaging;
152
+ /**
153
+ * Archive a directory tree into a single zip file.
154
+ */
155
+ static readonly ZIP: IAssetPackaging;
156
+ private constructor();
157
+ }
158
+ /**
159
+ * Options handed to an {@link IAssetBundler} when it runs.
160
+ *
161
+ * A struct rather than positional parameters: adding a field is additive,
162
+ * adding a method parameter is not, and `bundle` is called through JSII where
163
+ * that distinction is a breaking-change boundary.
164
+ */
165
+ export interface BundleOptions {
166
+ /**
167
+ * Absolute path to the asset's source file or directory. The bundler reads
168
+ * from here and must not modify it.
169
+ *
170
+ * Exclusions (`exclude` / `ignoreStrategy`) are already applied: when any
171
+ * are configured this points at a filtered copy, not the original tree, so
172
+ * the bundler reads exactly the file set the asset hash was taken over.
173
+ */
174
+ readonly source: string;
175
+ /**
176
+ * A scratch directory the bundler may write into, owned and created by the
177
+ * caller. The bundler produces its output here (or in a subdirectory) and
178
+ * returns a {@link BundleResult} pointing at the finished artifact — see
179
+ * {@link IAssetBundler.bundle}.
180
+ */
181
+ readonly outputDir: string;
182
+ }
183
+ /**
184
+ * The shape of a bundler's output, so staging and packaging can treat a
185
+ * single-file artifact (a tarball, a `.zip`) differently from a directory
186
+ * tree without inferring it from the path.
187
+ */
188
+ export declare enum BundleOutputType {
189
+ /**
190
+ * The output is a directory tree.
191
+ *
192
+ * Packaged like an unbundled source directory. The default, and the only
193
+ * shape that predates archive support.
194
+ */
195
+ DIRECTORY = "directory",
196
+ /**
197
+ * The output is a single file the bundler already produced in its final
198
+ * form.
199
+ *
200
+ * A tarball or a deterministic `.zip`. Staged verbatim rather than
201
+ * re-archived, so `AssetType.FILE` no longer has to reject a bundler.
202
+ */
203
+ FILE = "file"
204
+ }
205
+ /**
206
+ * What a bundler produced, returned from {@link IAssetBundler.bundle}.
207
+ *
208
+ * Carries the artifact path and its shape, or a declined state signalling the
209
+ * caller should fall back. See {@link declined} for the decline protocol.
210
+ */
211
+ export declare class BundleResult {
212
+ /**
213
+ * A directory-tree artifact at `path`.
214
+ */
215
+ static directory(path: string): BundleResult;
216
+ /**
217
+ * A single-file artifact at `path` (a tarball, a `.zip`), staged verbatim.
218
+ */
219
+ static file(path: string): BundleResult;
220
+ /**
221
+ * The bundler declined to run here; the caller should fall back.
222
+ *
223
+ * Distinct from a thrown error, which is a hard failure.
224
+ */
225
+ static declined(): BundleResult;
226
+ /**
227
+ * The artifact's shape, or undefined when {@link isDeclined}.
228
+ */
229
+ readonly outputType?: BundleOutputType;
230
+ /**
231
+ * The artifact path, or undefined when {@link isDeclined}.
232
+ */
233
+ readonly path?: string;
234
+ /**
235
+ * Whether the bundler declined to run, signalling the caller to fall back.
236
+ */
237
+ readonly isDeclined: boolean;
238
+ private constructor();
239
+ }
240
+ /**
241
+ * Transforms a source tree into a built artifact. Runs at synth, before the
242
+ * output is packaged and staged.
243
+ *
244
+ * This is the extension point for asset bundling: core ships no bundler.
245
+ * Docker, esbuild, pip, `go build`, and similar are an open-ended, non
246
+ * cloud-specific set, so each lives in its own package and implements this
247
+ * one interface — the same way {@link IIgnoreStrategy} lets richer exclusion
248
+ * live outside core. Users pass an instance via the consuming construct's
249
+ * `bundler` option.
250
+ *
251
+ * `bundle` runs during the owning construct's `onSynthesize` hook and may
252
+ * touch the filesystem. Deferring it there keeps it skippable when the asset's
253
+ * stack is not being synthesized, which holds as long as the hash is taken
254
+ * over the source rather than the built output.
255
+ *
256
+ * Bundlers compose through {@link ChainBundler} rather than a hierarchy: a
257
+ * bundler declines (see {@link BundleResult.declined}) instead of failing when
258
+ * it cannot run, and the chain falls through to the next.
259
+ */
260
+ export interface IAssetBundler {
261
+ /**
262
+ * A value identifying the build, folded into the asset hash.
263
+ *
264
+ * The source tree alone cannot see the build, so swapping a `node:18` base
265
+ * image for `node:20` would otherwise leave identity unchanged. Under
266
+ * `SOURCE` hashing this is the only channel by which the build reaches
267
+ * identity, so it must serialize every input that can move the output, or a
268
+ * changed build silently reuses a stale artifact. {@link BundlerKey} builds
269
+ * one from an ordered set of parts.
270
+ *
271
+ * Mirrors {@link IIgnoreStrategy.cacheKey}: omit it when the build cannot be
272
+ * summarized as a string, and fall back to `extraHash`.
273
+ *
274
+ * @default - the build does not contribute to the hash
275
+ */
276
+ readonly bundlerKey?: string;
277
+ /**
278
+ * The name a single-file artifact is staged under (e.g. `archive.zip`).
279
+ *
280
+ * A file-producing bundler (`BundleResult.file`) staged with
281
+ * `AssetType.FILE` would otherwise take the source path's basename, which is
282
+ * a directory name when the source is a directory. Declaring the name here
283
+ * lets the artifact reflect what the bundler produces. It is static
284
+ * configuration, needed at construction before a deferred `SOURCE` build
285
+ * runs, not the file's runtime name.
286
+ *
287
+ * Valid only for a file-producing bundler: setting it with a directory
288
+ * packaging (anything but `AssetType.FILE`) is rejected at construction.
289
+ *
290
+ * @default - the source path's basename
291
+ */
292
+ readonly outputFileName?: string;
293
+ /**
294
+ * Produce the artifact and return a {@link BundleResult} describing it.
295
+ *
296
+ * Implementations write into `options.outputDir` and never write back to
297
+ * `options.source`. The returned path must exist and match its declared
298
+ * shape, or staging rejects it.
299
+ *
300
+ * A bundler that cannot run in this environment returns
301
+ * `BundleResult.declined()` so a {@link ChainBundler} can fall through to
302
+ * the next; a thrown error is a hard failure, not a decline.
303
+ */
304
+ bundle(options: BundleOptions): BundleResult;
305
+ }
306
+ /**
307
+ * Builds an {@link IAssetBundler.bundlerKey} from an ordered set of parts.
308
+ *
309
+ * A `bundlerKey` has to serialize everything that can move a build's output;
310
+ * done ad hoc, every bundler invents its own delimiter and forgets an input
311
+ * differently. This gives the convention one implementation: parts are joined
312
+ * with a separator that is escaped inside values, so distinct inputs cannot
313
+ * collide into the same key.
314
+ *
315
+ * @example
316
+ * const key = BundlerKey.of("docker", image, command)
317
+ * .withEnv({ NODE_ENV: nodeEnv })
318
+ * .toString();
319
+ */
320
+ export declare class BundlerKey {
321
+ private readonly parts;
322
+ /**
323
+ * Start a key from an ordered list of parts.
324
+ *
325
+ * Order is significant: it is part of what the key identifies.
326
+ */
327
+ static of(...parts: string[]): BundlerKey;
328
+ private static escape;
329
+ private constructor();
330
+ /**
331
+ * Append parts, returning a new key.
332
+ */
333
+ add(...parts: string[]): BundlerKey;
334
+ /**
335
+ * Append `key=value` parts for a record, sorted by key so the result does
336
+ * not depend on property order.
337
+ */
338
+ withEnv(entries: Record<string, string>): BundlerKey;
339
+ /**
340
+ * Render the collected parts to the string passed as `bundlerKey`.
341
+ */
342
+ toString(): string;
343
+ }
344
+ /**
345
+ * Composes bundlers into a "try each in order until one runs" chain.
346
+ *
347
+ * This is how a local bundler and a Docker bundler compose without being
348
+ * rewritten as one: each leg declines (`BundleResult.declined()`) when it
349
+ * cannot run here, and the chain moves to the next. The first non-declining
350
+ * result wins; if all decline, `bundle` throws, since staging has nothing to
351
+ * fall back to. Each leg builds into its own output directory, so a leg that
352
+ * writes before declining cannot leak partial files into the leg that wins.
353
+ *
354
+ * The chain's `bundlerKey` folds in *every* leg's key, so identity is the same
355
+ * regardless of which leg ends up running — a build that could have gone local
356
+ * or Docker is one asset, not two.
357
+ *
358
+ * This makes the legs interchangeable only if they produce equivalent output.
359
+ * Under `SOURCE` hashing they must: a machine with a host tool and one without
360
+ * run different legs, and non-equivalent legs would stage different bytes under
361
+ * the same hash. Use `OUTPUT` hashing when legs may diverge, so identity tracks
362
+ * the artifact each leg actually produced.
363
+ */
364
+ export declare class ChainBundler implements IAssetBundler {
365
+ private readonly bundlers;
366
+ /**
367
+ * Chain bundlers in the order given; earlier bundlers are preferred.
368
+ */
369
+ static of(...bundlers: IAssetBundler[]): ChainBundler;
370
+ readonly bundlerKey?: string;
371
+ readonly outputFileName?: string;
372
+ private constructor();
373
+ bundle(options: BundleOptions): BundleResult;
374
+ }
375
+ /**
376
+ * A staged artifact, ready to hand to an `IAssetPublisher`.
377
+ *
378
+ * Deliberately narrower than a location: `path` and `isDirectory` are known
379
+ * once staging runs, at synth time, before anything is published. Where an
380
+ * asset ends up — a bucket name, an object key, a URL — is resolved at
381
+ * apply time and belongs on the publisher's own reference type instead.
382
+ */
383
+ export interface StagedAsset {
384
+ /**
385
+ * A hash on the content source, uniquely identifying this asset.
386
+ *
387
+ * The asset is not rebuilt or republished while this value is unchanged.
388
+ */
389
+ readonly assetHash: string;
390
+ /**
391
+ * The path to the staged artifact, relative to the stack directory.
392
+ */
393
+ readonly path: string;
394
+ /**
395
+ * Whether the staged artifact is a directory rather than a single file.
396
+ *
397
+ * Publishers branch on this to decide whether they upload one object or
398
+ * sync a tree; see `IAssetPackaging.producesDirectory`.
399
+ */
400
+ readonly isDirectory: boolean;
401
+ }