cdktn 0.25.0-pre.9 → 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 (79) hide show
  1. package/.jsii +2191 -422
  2. package/README.md +12 -0
  3. package/lib/annotations.js +1 -1
  4. package/lib/app.js +1 -1
  5. package/lib/aspect.js +1 -1
  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 +2 -2
  13. package/lib/backends/cloud-backend.js +10 -7
  14. package/lib/backends/consul-backend.js +2 -2
  15. package/lib/backends/cos-backend.js +2 -2
  16. package/lib/backends/gcs-backend.js +2 -2
  17. package/lib/backends/http-backend.js +2 -2
  18. package/lib/backends/local-backend.js +2 -2
  19. package/lib/backends/oss-backend.js +2 -2
  20. package/lib/backends/pg-backend.js +2 -2
  21. package/lib/backends/remote-backend.js +4 -4
  22. package/lib/backends/s3-backend.js +2 -2
  23. package/lib/backends/swift-backend.js +2 -2
  24. package/lib/complex-computed-list.js +26 -26
  25. package/lib/errors.d.ts +16 -0
  26. package/lib/errors.js +51 -3
  27. package/lib/functions/provider-function.js +1 -1
  28. package/lib/functions/terraform-functions.generated.js +1 -1
  29. package/lib/ignore-strategy.d.ts +82 -0
  30. package/lib/ignore-strategy.js +29 -0
  31. package/lib/importable-resource.js +7 -4
  32. package/lib/index.d.ts +4 -0
  33. package/lib/index.js +5 -1
  34. package/lib/manifest.js +1 -1
  35. package/lib/private/fs.d.ts +74 -2
  36. package/lib/private/fs.js +93 -14
  37. package/lib/resource.js +1 -1
  38. package/lib/synthesize/synthesizer.js +9 -22
  39. package/lib/terraform-asset.d.ts +68 -5
  40. package/lib/terraform-asset.js +86 -36
  41. package/lib/terraform-backend.js +1 -1
  42. package/lib/terraform-count.js +1 -1
  43. package/lib/terraform-data-resource.d.ts +1 -1
  44. package/lib/terraform-data-resource.js +8 -5
  45. package/lib/terraform-data-source.js +1 -1
  46. package/lib/terraform-element.js +1 -1
  47. package/lib/terraform-ephemeral-resource.js +1 -1
  48. package/lib/terraform-functions.js +1 -1
  49. package/lib/terraform-hcl-module.js +1 -1
  50. package/lib/terraform-iterator.js +6 -6
  51. package/lib/terraform-local.js +1 -1
  52. package/lib/terraform-module.js +1 -1
  53. package/lib/terraform-operators.js +1 -1
  54. package/lib/terraform-output.js +1 -1
  55. package/lib/terraform-provider.js +1 -1
  56. package/lib/terraform-provisioner.js +1 -1
  57. package/lib/terraform-remote-state.js +1 -1
  58. package/lib/terraform-resource-targets.js +1 -1
  59. package/lib/terraform-resource.js +9 -4
  60. package/lib/terraform-stack.js +1 -1
  61. package/lib/terraform-variable.js +2 -2
  62. package/lib/testing/adapters/jest.d.ts +2 -1
  63. package/lib/testing/adapters/jest.js +3 -3
  64. package/lib/testing/index.js +1 -1
  65. package/lib/testing/matchers.d.ts +34 -30
  66. package/lib/testing/matchers.js +292 -89
  67. package/lib/tokens/lazy.js +2 -2
  68. package/lib/tokens/resolvable.js +2 -2
  69. package/lib/tokens/string-fragments.js +2 -2
  70. package/lib/tokens/token.js +2 -2
  71. package/lib/upgrade-id-aspect.js +1 -1
  72. package/lib/validations/index.d.ts +0 -1
  73. package/lib/validations/index.js +1 -2
  74. package/package.json +17 -3
  75. package/scripts/pack.mjs +27 -12
  76. package/lib/validations/validate-binary-version.d.ts +0 -23
  77. package/lib/validations/validate-binary-version.js +0 -91
  78. package/lib/validations/validate-terraform-version.d.ts +0 -13
  79. package/lib/validations/validate-terraform-version.js +0 -23
package/README.md CHANGED
@@ -3,6 +3,18 @@
3
3
  cdktn is a framework for defining cloud infrastructure using Terraform providers and modules. It allows for
4
4
  users to define infrastructure resources using higher-level programming languages.
5
5
 
6
+ CDK Terrain (CDKTN) is the community-maintained successor to CDK for Terraform (CDKTF). Migrating from CDKTF? Follow the [migration guide](https://cdktn.io/docs/release/upgrade-guide-v0-22).
7
+
8
+ ## Use with AI agents
9
+
10
+ The CDKTN docs are served to AI coding agents by a hosted [MCP server](https://cdktn.io/docs/ai-agents) at `https://cdktn.io/docs/mcp` (streamable HTTP, no auth). Point your agent at it rather than relying on prior CDKTF knowledge:
11
+
12
+ ```bash
13
+ claude mcp add --transport http cdktn https://cdktn.io/docs/mcp
14
+ ```
15
+
16
+ An [agent skill](https://cdktn.io/docs/skill.md) and an [llms.txt index](https://cdktn.io/llms.txt) are also available.
17
+
6
18
  ## Build
7
19
 
8
20
  Install dependencies
@@ -14,7 +14,7 @@ exports.DISABLE_STACK_TRACE_IN_METADATA = "@cdktf/disable_stack_trace_in_metadat
14
14
  */
15
15
  class Annotations {
16
16
  scope;
17
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdktn.Annotations", version: "0.25.0-pre.9" };
17
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdktn.Annotations", version: "0.25.0" };
18
18
  /**
19
19
  * Returns the annotations API for a construct scope.
20
20
  * @param scope The scope
package/lib/app.js CHANGED
@@ -51,7 +51,7 @@ exports.CONTEXT_ENV = "CDKTF_CONTEXT_JSON";
51
51
  * Represents a cdktn application.
52
52
  */
53
53
  class App extends constructs_1.Construct {
54
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdktn.App", version: "0.25.0-pre.9" };
54
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdktn.App", version: "0.25.0" };
55
55
  /**
56
56
  * The output directory into which resources will be synthesized.
57
57
  */
package/lib/aspect.js CHANGED
@@ -8,7 +8,7 @@ const ASPECTS_SYMBOL = Symbol("cdktf-aspects");
8
8
  * synthesis.
9
9
  */
10
10
  class Aspects {
11
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdktn.Aspects", version: "0.25.0-pre.9" };
11
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdktn.Aspects", version: "0.25.0" };
12
12
  /**
13
13
  * Returns the `Aspects` object associated with a construct scope.
14
14
  * @param scope The scope for which these aspects will apply.
@@ -0,0 +1,75 @@
1
+ import { IIgnoreStrategy } from "./ignore-strategy";
2
+ /**
3
+ * Options for {@link AssetHash.of}.
4
+ */
5
+ export interface AssetHashOptions {
6
+ /**
7
+ * Paths to exclude, relative to the hashed path. Cannot be combined with
8
+ * `ignoreStrategy`, which replaces this matcher rather than layering on
9
+ * top of it.
10
+ *
11
+ * @default - nothing is excluded
12
+ */
13
+ readonly exclude?: string[];
14
+ /**
15
+ * Extra information to fold into the hash.
16
+ *
17
+ * @default - no extra data
18
+ */
19
+ readonly extraHash?: string;
20
+ /**
21
+ * Exclusion matching, for callers that need `.gitignore` / `.dockerignore`
22
+ * parity rather than the built-in exact-path / suffix / directory matcher.
23
+ *
24
+ * @default - `exclude` is used with the built-in matcher
25
+ */
26
+ readonly ignoreStrategy?: IIgnoreStrategy;
27
+ }
28
+ /**
29
+ * Computes a content hash of a file or directory without staging it.
30
+ *
31
+ * Providers that read a local path directly — a Docker build `context`, for
32
+ * example — need a content hash to drive `triggers`, but have no use for a
33
+ * staged copy of the source. `Asset` and `TerraformAsset` always produce a
34
+ * staged copy; this is the identity half without the staging half.
35
+ */
36
+ export declare class AssetHash {
37
+ /**
38
+ * Content hash of a file or directory, without staging it.
39
+ *
40
+ * This is a hash of the source tree, and it does not depend on how the
41
+ * source is later packaged. `hashPath` is always called with `archive`
42
+ * unset, so directory records are part of the digest; the hash of a given
43
+ * tree is therefore the same whether it is later copied, zipped, or packed
44
+ * by a custom `IAssetPackaging` such as `tar.bz2`.
45
+ *
46
+ * A consequence worth stating: this does not equal
47
+ * `TerraformAsset(dir, { type: ARCHIVE }).assetHash` for a directory with
48
+ * subdirectories. That asset frames its hash to the emitted ZIP, which has
49
+ * no directory entries (see #323), so directory-only changes move it and
50
+ * not this. It equals a `FILE` / `DIRECTORY` `TerraformAsset` hash only
51
+ * when the `canonicalAssetHashes` flag is enabled, since that flag is what
52
+ * puts the asset on this same canonical scheme.
53
+ *
54
+ * A relative `filePath` is resolved against the directory containing
55
+ * `cdktf.json`, the same base `TerraformAsset` uses, so both hash the same
56
+ * source regardless of the process working directory. Absolute paths are
57
+ * used as-is. Throws if `filePath` is relative and no `cdktf.json` is found
58
+ * above the working directory.
59
+ * @param filePath - path to a file or directory to hash
60
+ * @param options - see {@link AssetHashOptions}
61
+ */
62
+ static of(filePath: string, options?: AssetHashOptions): string;
63
+ /**
64
+ * Resolve `filePath` to an absolute path using the same base as
65
+ * `TerraformAsset`: relative paths are anchored to the directory holding
66
+ * `cdktf.json`, not `process.cwd()`, so a hash taken here matches the one
67
+ * `TerraformAsset` computes for the same source even when the app is run
68
+ * from a subdirectory or a test runner. Unlike `TerraformAsset`, there is
69
+ * no construct scope to read the `cdktfJsonPath` context from, so this uses
70
+ * the `findFileAboveCwd` fallback directly.
71
+ * @param filePath - path passed to {@link AssetHash.of}
72
+ */
73
+ private static resolvePath;
74
+ private constructor();
75
+ }
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.AssetHash = void 0;
37
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
38
+ // Copyright (c) HashiCorp, Inc
39
+ // SPDX-License-Identifier: MPL-2.0
40
+ const crypto = __importStar(require("crypto"));
41
+ const path = __importStar(require("path"));
42
+ const fs_1 = require("./private/fs");
43
+ const ignore_strategy_1 = require("./ignore-strategy");
44
+ const errors_1 = require("./errors");
45
+ /**
46
+ * Computes a content hash of a file or directory without staging it.
47
+ *
48
+ * Providers that read a local path directly — a Docker build `context`, for
49
+ * example — need a content hash to drive `triggers`, but have no use for a
50
+ * staged copy of the source. `Asset` and `TerraformAsset` always produce a
51
+ * staged copy; this is the identity half without the staging half.
52
+ */
53
+ class AssetHash {
54
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdktn.AssetHash", version: "0.25.0" };
55
+ /**
56
+ * Content hash of a file or directory, without staging it.
57
+ *
58
+ * This is a hash of the source tree, and it does not depend on how the
59
+ * source is later packaged. `hashPath` is always called with `archive`
60
+ * unset, so directory records are part of the digest; the hash of a given
61
+ * tree is therefore the same whether it is later copied, zipped, or packed
62
+ * by a custom `IAssetPackaging` such as `tar.bz2`.
63
+ *
64
+ * A consequence worth stating: this does not equal
65
+ * `TerraformAsset(dir, { type: ARCHIVE }).assetHash` for a directory with
66
+ * subdirectories. That asset frames its hash to the emitted ZIP, which has
67
+ * no directory entries (see #323), so directory-only changes move it and
68
+ * not this. It equals a `FILE` / `DIRECTORY` `TerraformAsset` hash only
69
+ * when the `canonicalAssetHashes` flag is enabled, since that flag is what
70
+ * puts the asset on this same canonical scheme.
71
+ *
72
+ * A relative `filePath` is resolved against the directory containing
73
+ * `cdktf.json`, the same base `TerraformAsset` uses, so both hash the same
74
+ * source regardless of the process working directory. Absolute paths are
75
+ * used as-is. Throws if `filePath` is relative and no `cdktf.json` is found
76
+ * above the working directory.
77
+ * @param filePath - path to a file or directory to hash
78
+ * @param options - see {@link AssetHashOptions}
79
+ */
80
+ static of(filePath, options = {}) {
81
+ if (options.exclude?.length && options.ignoreStrategy) {
82
+ throw (0, errors_1.assetHashConflictingExcludeOptions)();
83
+ }
84
+ const resolved = AssetHash.resolvePath(filePath);
85
+ const strategy = options.ignoreStrategy ??
86
+ new ignore_strategy_1.ExcludeIgnoreStrategy(options.exclude ?? []);
87
+ // Pinned to the canonical scheme: this is a brand-new API with no
88
+ // existing hashes to preserve, so it has no reason to start on the
89
+ // legacy scheme that `canonicalAssetHashes` exists to move away from.
90
+ const baseHash = (0, fs_1.hashPath)(resolved, {
91
+ canonical: true,
92
+ shouldExclude: (relativePath, isDirectory) => strategy.ignores({ relativePath, isDirectory }),
93
+ descendIntoExcludedDirectories: strategy.pruneExcludedDirectories === false,
94
+ });
95
+ if (!options.extraHash) {
96
+ return baseHash;
97
+ }
98
+ return crypto
99
+ .createHash("md5")
100
+ .update(baseHash)
101
+ .update(options.extraHash)
102
+ .digest("hex")
103
+ .slice(0, 32)
104
+ .toUpperCase();
105
+ }
106
+ /**
107
+ * Resolve `filePath` to an absolute path using the same base as
108
+ * `TerraformAsset`: relative paths are anchored to the directory holding
109
+ * `cdktf.json`, not `process.cwd()`, so a hash taken here matches the one
110
+ * `TerraformAsset` computes for the same source even when the app is run
111
+ * from a subdirectory or a test runner. Unlike `TerraformAsset`, there is
112
+ * no construct scope to read the `cdktfJsonPath` context from, so this uses
113
+ * the `findFileAboveCwd` fallback directly.
114
+ * @param filePath - path passed to {@link AssetHash.of}
115
+ */
116
+ static resolvePath(filePath) {
117
+ if (path.isAbsolute(filePath)) {
118
+ return filePath;
119
+ }
120
+ const cdktfJsonPath = (0, fs_1.findFileAboveCwd)("cdktf.json");
121
+ if (!cdktfJsonPath) {
122
+ throw (0, errors_1.assetHashOutOfScopeCdktnJson)(filePath);
123
+ }
124
+ return path.resolve(path.dirname(cdktfJsonPath), filePath);
125
+ }
126
+ constructor() { }
127
+ }
128
+ exports.AssetHash = AssetHash;
129
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXQtaGFzaC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9hc3NldC1oYXNoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQkFBK0I7QUFDL0IsbUNBQW1DO0FBQ25DLCtDQUFpQztBQUNqQywyQ0FBNkI7QUFDN0IscUNBQTBEO0FBQzFELHVEQUEyRTtBQUMzRSxxQ0FHa0I7QUErQmxCOzs7Ozs7O0dBT0c7QUFDSCxNQUFhLFNBQVM7O0lBQ3BCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0F3Qkc7SUFDSSxNQUFNLENBQUMsRUFBRSxDQUFDLFFBQWdCLEVBQUUsVUFBNEIsRUFBRTtRQUMvRCxJQUFJLE9BQU8sQ0FBQyxPQUFPLEVBQUUsTUFBTSxJQUFJLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN0RCxNQUFNLElBQUEsMkNBQWtDLEdBQUUsQ0FBQztRQUM3QyxDQUFDO1FBRUQsTUFBTSxRQUFRLEdBQUcsU0FBUyxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNqRCxNQUFNLFFBQVEsR0FDWixPQUFPLENBQUMsY0FBYztZQUN0QixJQUFJLHVDQUFxQixDQUFDLE9BQU8sQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUM7UUFFbkQsa0VBQWtFO1FBQ2xFLG1FQUFtRTtRQUNuRSxzRUFBc0U7UUFDdEUsTUFBTSxRQUFRLEdBQUcsSUFBQSxhQUFRLEVBQUMsUUFBUSxFQUFFO1lBQ2xDLFNBQVMsRUFBRSxJQUFJO1lBQ2YsYUFBYSxFQUFFLENBQUMsWUFBWSxFQUFFLFdBQVcsRUFBRSxFQUFFLENBQzNDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLENBQUM7WUFDakQsOEJBQThCLEVBQzVCLFFBQVEsQ0FBQyx3QkFBd0IsS0FBSyxLQUFLO1NBQzlDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDdkIsT0FBTyxRQUFRLENBQUM7UUFDbEIsQ0FBQztRQUVELE9BQU8sTUFBTTthQUNWLFVBQVUsQ0FBQyxLQUFLLENBQUM7YUFDakIsTUFBTSxDQUFDLFFBQVEsQ0FBQzthQUNoQixNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQzthQUN6QixNQUFNLENBQUMsS0FBSyxDQUFDO2FBQ2IsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7YUFDWixXQUFXLEVBQUUsQ0FBQztJQUNuQixDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ssTUFBTSxDQUFDLFdBQVcsQ0FBQyxRQUFnQjtRQUN6QyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUM5QixPQUFPLFFBQVEsQ0FBQztRQUNsQixDQUFDO1FBQ0QsTUFBTSxhQUFhLEdBQUcsSUFBQSxxQkFBZ0IsRUFBQyxZQUFZLENBQUMsQ0FBQztRQUNyRCxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDbkIsTUFBTSxJQUFBLHFDQUE0QixFQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQy9DLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBRUQsZ0JBQXVCLENBQUM7O0FBakYxQiw4QkFrRkMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIEhhc2hpQ29ycCwgSW5jXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTVBMLTIuMFxuaW1wb3J0ICogYXMgY3J5cHRvIGZyb20gXCJjcnlwdG9cIjtcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IGhhc2hQYXRoLCBmaW5kRmlsZUFib3ZlQ3dkIH0gZnJvbSBcIi4vcHJpdmF0ZS9mc1wiO1xuaW1wb3J0IHsgRXhjbHVkZUlnbm9yZVN0cmF0ZWd5LCBJSWdub3JlU3RyYXRlZ3kgfSBmcm9tIFwiLi9pZ25vcmUtc3RyYXRlZ3lcIjtcbmltcG9ydCB7XG4gIGFzc2V0SGFzaENvbmZsaWN0aW5nRXhjbHVkZU9wdGlvbnMsXG4gIGFzc2V0SGFzaE91dE9mU2NvcGVDZGt0bkpzb24sXG59IGZyb20gXCIuL2Vycm9yc1wiO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBBc3NldEhhc2gub2Z9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFzc2V0SGFzaE9wdGlvbnMge1xuICAvKipcbiAgICogUGF0aHMgdG8gZXhjbHVkZSwgcmVsYXRpdmUgdG8gdGhlIGhhc2hlZCBwYXRoLiBDYW5ub3QgYmUgY29tYmluZWQgd2l0aFxuICAgKiBgaWdub3JlU3RyYXRlZ3lgLCB3aGljaCByZXBsYWNlcyB0aGlzIG1hdGNoZXIgcmF0aGVyIHRoYW4gbGF5ZXJpbmcgb25cbiAgICogdG9wIG9mIGl0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vdGhpbmcgaXMgZXhjbHVkZWRcbiAgICovXG4gIHJlYWRvbmx5IGV4Y2x1ZGU/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogRXh0cmEgaW5mb3JtYXRpb24gdG8gZm9sZCBpbnRvIHRoZSBoYXNoLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGV4dHJhIGRhdGFcbiAgICovXG4gIHJlYWRvbmx5IGV4dHJhSGFzaD86IHN0cmluZztcblxuICAvKipcbiAgICogRXhjbHVzaW9uIG1hdGNoaW5nLCBmb3IgY2FsbGVycyB0aGF0IG5lZWQgYC5naXRpZ25vcmVgIC8gYC5kb2NrZXJpZ25vcmVgXG4gICAqIHBhcml0eSByYXRoZXIgdGhhbiB0aGUgYnVpbHQtaW4gZXhhY3QtcGF0aCAvIHN1ZmZpeCAvIGRpcmVjdG9yeSBtYXRjaGVyLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGBleGNsdWRlYCBpcyB1c2VkIHdpdGggdGhlIGJ1aWx0LWluIG1hdGNoZXJcbiAgICovXG4gIHJlYWRvbmx5IGlnbm9yZVN0cmF0ZWd5PzogSUlnbm9yZVN0cmF0ZWd5O1xufVxuXG4vKipcbiAqIENvbXB1dGVzIGEgY29udGVudCBoYXNoIG9mIGEgZmlsZSBvciBkaXJlY3Rvcnkgd2l0aG91dCBzdGFnaW5nIGl0LlxuICpcbiAqIFByb3ZpZGVycyB0aGF0IHJlYWQgYSBsb2NhbCBwYXRoIGRpcmVjdGx5IOKAlCBhIERvY2tlciBidWlsZCBgY29udGV4dGAsIGZvclxuICogZXhhbXBsZSDigJQgbmVlZCBhIGNvbnRlbnQgaGFzaCB0byBkcml2ZSBgdHJpZ2dlcnNgLCBidXQgaGF2ZSBubyB1c2UgZm9yIGFcbiAqIHN0YWdlZCBjb3B5IG9mIHRoZSBzb3VyY2UuIGBBc3NldGAgYW5kIGBUZXJyYWZvcm1Bc3NldGAgYWx3YXlzIHByb2R1Y2UgYVxuICogc3RhZ2VkIGNvcHk7IHRoaXMgaXMgdGhlIGlkZW50aXR5IGhhbGYgd2l0aG91dCB0aGUgc3RhZ2luZyBoYWxmLlxuICovXG5leHBvcnQgY2xhc3MgQXNzZXRIYXNoIHtcbiAgLyoqXG4gICAqIENvbnRlbnQgaGFzaCBvZiBhIGZpbGUgb3IgZGlyZWN0b3J5LCB3aXRob3V0IHN0YWdpbmcgaXQuXG4gICAqXG4gICAqIFRoaXMgaXMgYSBoYXNoIG9mIHRoZSBzb3VyY2UgdHJlZSwgYW5kIGl0IGRvZXMgbm90IGRlcGVuZCBvbiBob3cgdGhlXG4gICAqIHNvdXJjZSBpcyBsYXRlciBwYWNrYWdlZC4gYGhhc2hQYXRoYCBpcyBhbHdheXMgY2FsbGVkIHdpdGggYGFyY2hpdmVgXG4gICAqIHVuc2V0LCBzbyBkaXJlY3RvcnkgcmVjb3JkcyBhcmUgcGFydCBvZiB0aGUgZGlnZXN0OyB0aGUgaGFzaCBvZiBhIGdpdmVuXG4gICAqIHRyZWUgaXMgdGhlcmVmb3JlIHRoZSBzYW1lIHdoZXRoZXIgaXQgaXMgbGF0ZXIgY29waWVkLCB6aXBwZWQsIG9yIHBhY2tlZFxuICAgKiBieSBhIGN1c3RvbSBgSUFzc2V0UGFja2FnaW5nYCBzdWNoIGFzIGB0YXIuYnoyYC5cbiAgICpcbiAgICogQSBjb25zZXF1ZW5jZSB3b3J0aCBzdGF0aW5nOiB0aGlzIGRvZXMgbm90IGVxdWFsXG4gICAqIGBUZXJyYWZvcm1Bc3NldChkaXIsIHsgdHlwZTogQVJDSElWRSB9KS5hc3NldEhhc2hgIGZvciBhIGRpcmVjdG9yeSB3aXRoXG4gICAqIHN1YmRpcmVjdG9yaWVzLiBUaGF0IGFzc2V0IGZyYW1lcyBpdHMgaGFzaCB0byB0aGUgZW1pdHRlZCBaSVAsIHdoaWNoIGhhc1xuICAgKiBubyBkaXJlY3RvcnkgZW50cmllcyAoc2VlICMzMjMpLCBzbyBkaXJlY3Rvcnktb25seSBjaGFuZ2VzIG1vdmUgaXQgYW5kXG4gICAqIG5vdCB0aGlzLiBJdCBlcXVhbHMgYSBgRklMRWAgLyBgRElSRUNUT1JZYCBgVGVycmFmb3JtQXNzZXRgIGhhc2ggb25seVxuICAgKiB3aGVuIHRoZSBgY2Fub25pY2FsQXNzZXRIYXNoZXNgIGZsYWcgaXMgZW5hYmxlZCwgc2luY2UgdGhhdCBmbGFnIGlzIHdoYXRcbiAgICogcHV0cyB0aGUgYXNzZXQgb24gdGhpcyBzYW1lIGNhbm9uaWNhbCBzY2hlbWUuXG4gICAqXG4gICAqIEEgcmVsYXRpdmUgYGZpbGVQYXRoYCBpcyByZXNvbHZlZCBhZ2FpbnN0IHRoZSBkaXJlY3RvcnkgY29udGFpbmluZ1xuICAgKiBgY2RrdGYuanNvbmAsIHRoZSBzYW1lIGJhc2UgYFRlcnJhZm9ybUFzc2V0YCB1c2VzLCBzbyBib3RoIGhhc2ggdGhlIHNhbWVcbiAgICogc291cmNlIHJlZ2FyZGxlc3Mgb2YgdGhlIHByb2Nlc3Mgd29ya2luZyBkaXJlY3RvcnkuIEFic29sdXRlIHBhdGhzIGFyZVxuICAgKiB1c2VkIGFzLWlzLiBUaHJvd3MgaWYgYGZpbGVQYXRoYCBpcyByZWxhdGl2ZSBhbmQgbm8gYGNka3RmLmpzb25gIGlzIGZvdW5kXG4gICAqIGFib3ZlIHRoZSB3b3JraW5nIGRpcmVjdG9yeS5cbiAgICogQHBhcmFtIGZpbGVQYXRoIC0gcGF0aCB0byBhIGZpbGUgb3IgZGlyZWN0b3J5IHRvIGhhc2hcbiAgICogQHBhcmFtIG9wdGlvbnMgLSBzZWUge0BsaW5rIEFzc2V0SGFzaE9wdGlvbnN9XG4gICAqL1xuICBwdWJsaWMgc3RhdGljIG9mKGZpbGVQYXRoOiBzdHJpbmcsIG9wdGlvbnM6IEFzc2V0SGFzaE9wdGlvbnMgPSB7fSk6IHN0cmluZyB7XG4gICAgaWYgKG9wdGlvbnMuZXhjbHVkZT8ubGVuZ3RoICYmIG9wdGlvbnMuaWdub3JlU3RyYXRlZ3kpIHtcbiAgICAgIHRocm93IGFzc2V0SGFzaENvbmZsaWN0aW5nRXhjbHVkZU9wdGlvbnMoKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXNvbHZlZCA9IEFzc2V0SGFzaC5yZXNvbHZlUGF0aChmaWxlUGF0aCk7XG4gICAgY29uc3Qgc3RyYXRlZ3kgPVxuICAgICAgb3B0aW9ucy5pZ25vcmVTdHJhdGVneSA/P1xuICAgICAgbmV3IEV4Y2x1ZGVJZ25vcmVTdHJhdGVneShvcHRpb25zLmV4Y2x1ZGUgPz8gW10pO1xuXG4gICAgLy8gUGlubmVkIHRvIHRoZSBjYW5vbmljYWwgc2NoZW1lOiB0aGlzIGlzIGEgYnJhbmQtbmV3IEFQSSB3aXRoIG5vXG4gICAgLy8gZXhpc3RpbmcgaGFzaGVzIHRvIHByZXNlcnZlLCBzbyBpdCBoYXMgbm8gcmVhc29uIHRvIHN0YXJ0IG9uIHRoZVxuICAgIC8vIGxlZ2FjeSBzY2hlbWUgdGhhdCBgY2Fub25pY2FsQXNzZXRIYXNoZXNgIGV4aXN0cyB0byBtb3ZlIGF3YXkgZnJvbS5cbiAgICBjb25zdCBiYXNlSGFzaCA9IGhhc2hQYXRoKHJlc29sdmVkLCB7XG4gICAgICBjYW5vbmljYWw6IHRydWUsXG4gICAgICBzaG91bGRFeGNsdWRlOiAocmVsYXRpdmVQYXRoLCBpc0RpcmVjdG9yeSkgPT5cbiAgICAgICAgc3RyYXRlZ3kuaWdub3Jlcyh7IHJlbGF0aXZlUGF0aCwgaXNEaXJlY3RvcnkgfSksXG4gICAgICBkZXNjZW5kSW50b0V4Y2x1ZGVkRGlyZWN0b3JpZXM6XG4gICAgICAgIHN0cmF0ZWd5LnBydW5lRXhjbHVkZWREaXJlY3RvcmllcyA9PT0gZmFsc2UsXG4gICAgfSk7XG5cbiAgICBpZiAoIW9wdGlvbnMuZXh0cmFIYXNoKSB7XG4gICAgICByZXR1cm4gYmFzZUhhc2g7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNyeXB0b1xuICAgICAgLmNyZWF0ZUhhc2goXCJtZDVcIilcbiAgICAgIC51cGRhdGUoYmFzZUhhc2gpXG4gICAgICAudXBkYXRlKG9wdGlvbnMuZXh0cmFIYXNoKVxuICAgICAgLmRpZ2VzdChcImhleFwiKVxuICAgICAgLnNsaWNlKDAsIDMyKVxuICAgICAgLnRvVXBwZXJDYXNlKCk7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSBgZmlsZVBhdGhgIHRvIGFuIGFic29sdXRlIHBhdGggdXNpbmcgdGhlIHNhbWUgYmFzZSBhc1xuICAgKiBgVGVycmFmb3JtQXNzZXRgOiByZWxhdGl2ZSBwYXRocyBhcmUgYW5jaG9yZWQgdG8gdGhlIGRpcmVjdG9yeSBob2xkaW5nXG4gICAqIGBjZGt0Zi5qc29uYCwgbm90IGBwcm9jZXNzLmN3ZCgpYCwgc28gYSBoYXNoIHRha2VuIGhlcmUgbWF0Y2hlcyB0aGUgb25lXG4gICAqIGBUZXJyYWZvcm1Bc3NldGAgY29tcHV0ZXMgZm9yIHRoZSBzYW1lIHNvdXJjZSBldmVuIHdoZW4gdGhlIGFwcCBpcyBydW5cbiAgICogZnJvbSBhIHN1YmRpcmVjdG9yeSBvciBhIHRlc3QgcnVubmVyLiBVbmxpa2UgYFRlcnJhZm9ybUFzc2V0YCwgdGhlcmUgaXNcbiAgICogbm8gY29uc3RydWN0IHNjb3BlIHRvIHJlYWQgdGhlIGBjZGt0Zkpzb25QYXRoYCBjb250ZXh0IGZyb20sIHNvIHRoaXMgdXNlc1xuICAgKiB0aGUgYGZpbmRGaWxlQWJvdmVDd2RgIGZhbGxiYWNrIGRpcmVjdGx5LlxuICAgKiBAcGFyYW0gZmlsZVBhdGggLSBwYXRoIHBhc3NlZCB0byB7QGxpbmsgQXNzZXRIYXNoLm9mfVxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgcmVzb2x2ZVBhdGgoZmlsZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKHBhdGguaXNBYnNvbHV0ZShmaWxlUGF0aCkpIHtcbiAgICAgIHJldHVybiBmaWxlUGF0aDtcbiAgICB9XG4gICAgY29uc3QgY2RrdGZKc29uUGF0aCA9IGZpbmRGaWxlQWJvdmVDd2QoXCJjZGt0Zi5qc29uXCIpO1xuICAgIGlmICghY2RrdGZKc29uUGF0aCkge1xuICAgICAgdGhyb3cgYXNzZXRIYXNoT3V0T2ZTY29wZUNka3RuSnNvbihmaWxlUGF0aCk7XG4gICAgfVxuICAgIHJldHVybiBwYXRoLnJlc29sdmUocGF0aC5kaXJuYW1lKGNka3RmSnNvblBhdGgpLCBmaWxlUGF0aCk7XG4gIH1cblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cbn1cbiJdfQ==
@@ -0,0 +1,180 @@
1
+ import { Construct } from "constructs";
2
+ import { AssetOptions, IAsset, IAssetBundler, IAssetPackaging } from "./assets";
3
+ import { IIgnoreStrategy } from "./ignore-strategy";
4
+ /**
5
+ * Context key for a value folded into every computed asset hash in the
6
+ * construct tree, alongside `extraHash`. A bulk cache-busting escape hatch —
7
+ * `extraHash` is scoped to one asset, this is scoped to the whole app.
8
+ */
9
+ export declare const ASSET_HASH_SALT_CONTEXT_KEY = "cdktn:assetHashSalt";
10
+ /**
11
+ * Options for {@link AssetStaging}.
12
+ */
13
+ export interface AssetStagingOptions extends AssetOptions {
14
+ /**
15
+ * Absolute path to the source file or directory. Resolving a relative path
16
+ * against `cdktf.json` is the caller's responsibility.
17
+ */
18
+ readonly sourcePath: string;
19
+ /**
20
+ * How the staged result is produced and shaped. The caller decides this
21
+ * (e.g. from its own `AssetType`) — `AssetStaging` never infers or changes
22
+ * it based on `exclude`/`extraHash`.
23
+ */
24
+ readonly packaging: IAssetPackaging;
25
+ /**
26
+ * Paths to exclude, relative to `sourcePath`. Cannot be combined with
27
+ * `ignoreStrategy`, which replaces this matcher rather than layering on
28
+ * top of it.
29
+ *
30
+ * @default - nothing is excluded
31
+ */
32
+ readonly exclude?: string[];
33
+ /**
34
+ * Exclusion matching, for callers that need `.gitignore` / `.dockerignore`
35
+ * parity rather than the built-in exact-path / suffix / directory matcher.
36
+ *
37
+ * @default - `exclude` is used with the built-in matcher
38
+ */
39
+ readonly ignoreStrategy?: IIgnoreStrategy;
40
+ /**
41
+ * Extra information to fold into the hash (e.g. build instructions and
42
+ * other inputs).
43
+ *
44
+ * @default - no extra hash
45
+ */
46
+ readonly extraHash?: string;
47
+ /**
48
+ * A bundler that builds the source into an artifact before staging.
49
+ *
50
+ * Under the default `SOURCE` hashing the build is deferred to `stage()` and
51
+ * stays skippable; `OUTPUT` hashing builds eagerly at construction time to
52
+ * hash the artifact, forgoing skippability. The bundler's declared output
53
+ * shape must match the packaging: a `BundleResult.directory` needs a
54
+ * directory-accepting packaging, a `BundleResult.file` a single-file one
55
+ * (`AssetType.FILE`). The mismatch is caught once the build runs.
56
+ *
57
+ * @default - the source is staged verbatim, with no build step
58
+ */
59
+ readonly bundler?: IAssetBundler;
60
+ /**
61
+ * Identifier used in error messages, so they name the user-facing construct
62
+ * (e.g. the `TerraformAsset`) rather than this internal staging child.
63
+ *
64
+ * @default - the staging construct's own id
65
+ */
66
+ readonly displayName?: string;
67
+ }
68
+ /**
69
+ * Resolves an asset's identity and stages its content to disk.
70
+ *
71
+ * The hash is available immediately after construction; the filesystem write
72
+ * is deferred to `stage()`, the one window where it is safe. Hashing is
73
+ * cached per synth (see {@link hashCachesByRoot}) so an asset referenced from
74
+ * several places is walked once. Without a bundler, `SOURCE` and `OUTPUT` both
75
+ * hash the source; with one they diverge, as `AssetStagingOptions.bundler`
76
+ * describes.
77
+ */
78
+ export declare class AssetStaging extends Construct implements IAsset {
79
+ private readonly sourcePath;
80
+ private readonly displayName;
81
+ private readonly ignoreStrategy;
82
+ private readonly hasExclusions;
83
+ private readonly hashCache;
84
+ private readonly bundler?;
85
+ /**
86
+ * Output of an eager `OUTPUT`-hash build, carried to `stage()` for reuse.
87
+ *
88
+ * Undefined on every other path, where the build is deferred or absent.
89
+ */
90
+ private eagerBuild?;
91
+ /**
92
+ * Set once `stage()` has run, so a second call cannot rebuild. An eager
93
+ * `OUTPUT` build is captured at construction and consumed by the first
94
+ * `stage()`; without this guard a second call would fall through to the
95
+ * deferred build path and stage bytes that no longer match the hash.
96
+ */
97
+ private staged;
98
+ readonly packaging: IAssetPackaging;
99
+ readonly isDirectory: boolean;
100
+ readonly assetHash: string;
101
+ constructor(scope: Construct, id: string, props: AssetStagingOptions);
102
+ private resolveAssetHash;
103
+ /**
104
+ * Hash the source tree, honoring the ignore strategy.
105
+ *
106
+ * Cached per synth so an asset referenced more than once is walked once.
107
+ */
108
+ private hashSource;
109
+ /**
110
+ * Build the bundler's output eagerly and hash the built artifact.
111
+ *
112
+ * The output is stashed for `stage()` to reuse, so the build is not
113
+ * repeated. It is hashed verbatim: `exclude` filters the source a bundler
114
+ * reads, not the artifact it produces.
115
+ */
116
+ private hashOutput;
117
+ /**
118
+ * Run the bundler against the filtered source and return its output.
119
+ *
120
+ * The bundler is handed an absolute `source` (its cwd is its own, so a
121
+ * relative path would resolve elsewhere) that has already had `exclude`
122
+ * applied. Materialising the filtered input here is what makes the bundler
123
+ * read exactly the tree the hash was taken over, which a raw source
124
+ * hand-off would not, since `hashSource` honours `exclude`.
125
+ */
126
+ private runBundle;
127
+ /**
128
+ * Reject a bundler result whose declared shape does not match what is on
129
+ * disk, or does not match the packaging.
130
+ *
131
+ * Catching the mismatch here turns an opaque EISDIR/EPERM at pack time into
132
+ * a clear error naming the packaging the bundler's output shape needs.
133
+ */
134
+ private validateOutputShape;
135
+ /**
136
+ * Whether the packaging stages a single file verbatim (AssetType.FILE).
137
+ *
138
+ * A verbatim-file packaging neither produces a directory nor reads one as
139
+ * its source. Derived from existing `IAssetPackaging` flags so out-of-tree
140
+ * packagings need no new interface member.
141
+ */
142
+ private get stagesSingleFile();
143
+ /**
144
+ * Absolute path to the source the bundler should read.
145
+ *
146
+ * With no exclusions, or with a file source, the resolved source is handed
147
+ * over directly — a file has no children to filter, matching `hashSource`,
148
+ * which only ever applies the ignore strategy to a directory's entries and
149
+ * never to the root itself. Otherwise the excluded source tree is
150
+ * materialised into the scratch directory, so the bundler sees the same
151
+ * file set the hash was taken over.
152
+ */
153
+ private filteredSource;
154
+ /**
155
+ * Stage the asset's content to `targetPath`.
156
+ *
157
+ * Called from the owning construct's `onSynthesize` hook. Without a bundler
158
+ * the source is packaged verbatim; with one, the bundler's output is, built
159
+ * eagerly for `OUTPUT` hashing or deferred to here for `SOURCE`.
160
+ */
161
+ stage(targetPath: string): void;
162
+ /**
163
+ * Remove a bundler scratch directory and drop it from the exit-sweep set.
164
+ */
165
+ private cleanupScratch;
166
+ /**
167
+ * Package a bundler's output into `targetPath`, verbatim.
168
+ *
169
+ * The output's shape was already validated against the packaging in
170
+ * {@link runBundle}, so the packaging handles the source directly — a file
171
+ * source for AssetType.FILE, a directory source otherwise.
172
+ *
173
+ * The ignore strategy is deliberately not applied. `exclude` filters the
174
+ * source a bundler reads, not its product: an install-style bundler
175
+ * (`npm install --production`, `pip install -t`) writes exactly the
176
+ * dependency directory a user excludes from source, and re-applying the
177
+ * exclusion would ship an artifact missing those dependencies.
178
+ */
179
+ private packBundlerOutput;
180
+ }