cdktn-cli 0.0.1 → 0.21.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 (82) hide show
  1. package/README.md +1 -0
  2. package/ambient.d.ts +13 -0
  3. package/build.js +139 -0
  4. package/bundle/bin/cdktn +2 -0
  5. package/bundle/bin/cdktn.js +89 -0
  6. package/bundle/bin/cdktn.js.map +7 -0
  7. package/bundle/bin/cmds/handlers.js +740 -0
  8. package/bundle/bin/cmds/handlers.js.map +7 -0
  9. package/bundle/templates/csharp/.hooks.sscaff.js +63 -0
  10. package/bundle/templates/csharp/MainStack.cs +15 -0
  11. package/bundle/templates/csharp/MyTerraformStack.csproj +13 -0
  12. package/bundle/templates/csharp/Program.cs +17 -0
  13. package/bundle/templates/csharp/TestProgram.cs +42 -0
  14. package/bundle/templates/csharp/cdktf.json +11 -0
  15. package/bundle/templates/csharp/help +42 -0
  16. package/bundle/templates/csharp/{{}}.gitignore +345 -0
  17. package/bundle/templates/go/.hooks.sscaff.js +70 -0
  18. package/bundle/templates/go/cdktf.json +12 -0
  19. package/bundle/templates/go/go.mod +8 -0
  20. package/bundle/templates/go/help +32 -0
  21. package/bundle/templates/go/main.go +22 -0
  22. package/bundle/templates/go/main_test.go +42 -0
  23. package/bundle/templates/go/{{}}.gitignore +21 -0
  24. package/bundle/templates/java/.hooks.sscaff.js +64 -0
  25. package/bundle/templates/java/build.gradle +55 -0
  26. package/bundle/templates/java/cdktf.json +12 -0
  27. package/bundle/templates/java/gradle.properties +1 -0
  28. package/bundle/templates/java/gradlew +248 -0
  29. package/bundle/templates/java/gradlew.bat +92 -0
  30. package/bundle/templates/java/help +35 -0
  31. package/bundle/templates/java/settings.gradle +5 -0
  32. package/bundle/templates/java/src/main/java/com/mycompany/app/Main.java +16 -0
  33. package/bundle/templates/java/src/main/java/com/mycompany/app/MainStack.java +14 -0
  34. package/bundle/templates/java/src/test/java/com/company/app/MainTest.java +38 -0
  35. package/bundle/templates/java/{{}}.gitignore +14 -0
  36. package/bundle/templates/python/.hooks.sscaff.js +59 -0
  37. package/bundle/templates/python/Pipfile +7 -0
  38. package/bundle/templates/python/cdktf.json +12 -0
  39. package/bundle/templates/python/help +42 -0
  40. package/bundle/templates/python/main-test.py +26 -0
  41. package/bundle/templates/python/main.py +16 -0
  42. package/bundle/templates/python/{{}}.gitignore +7 -0
  43. package/bundle/templates/python-pip/.hooks.sscaff.js +63 -0
  44. package/bundle/templates/python-pip/cdktf.json +12 -0
  45. package/bundle/templates/python-pip/help +35 -0
  46. package/bundle/templates/python-pip/main-test.py +23 -0
  47. package/bundle/templates/python-pip/main.py +16 -0
  48. package/bundle/templates/python-pip/{{}}.gitignore +7 -0
  49. package/bundle/templates/typescript/.hooks.sscaff.js +78 -0
  50. package/bundle/templates/typescript/__tests__/main-test.ts +89 -0
  51. package/bundle/templates/typescript/cdktf.json +11 -0
  52. package/bundle/templates/typescript/help +51 -0
  53. package/bundle/templates/typescript/jest.config.js +187 -0
  54. package/bundle/templates/typescript/main.ts +14 -0
  55. package/bundle/templates/typescript/package.json +22 -0
  56. package/bundle/templates/typescript/setup.js +2 -0
  57. package/bundle/templates/typescript/tsconfig.json +35 -0
  58. package/bundle/templates/typescript/{{}}.gitignore +11 -0
  59. package/eslint.config.mjs +80 -0
  60. package/jest.config.js +19 -0
  61. package/package.json +133 -7
  62. package/src/bin/cdktn +2 -0
  63. package/src/bin/cmds/helper/__tests__/fixtures/foo.tfvars +4 -0
  64. package/src/bin/cmds/helper/__tests__/fixtures/hey-there.auto.tfvars +5 -0
  65. package/src/bin/cmds/helper/__tests__/fixtures/terraform.tfvars +4 -0
  66. package/src/bin/cmds/helper/render-ink.tsx +24 -0
  67. package/src/bin/cmds/ui/components/bottom-bars/approve.tsx +81 -0
  68. package/src/bin/cmds/ui/components/bottom-bars/outputs.tsx +30 -0
  69. package/src/bin/cmds/ui/components/bottom-bars/override.tsx +68 -0
  70. package/src/bin/cmds/ui/components/bottom-bars/status.tsx +183 -0
  71. package/src/bin/cmds/ui/components/outputs.tsx +103 -0
  72. package/src/bin/cmds/ui/components/stream-view.tsx +72 -0
  73. package/src/bin/cmds/ui/deploy.tsx +139 -0
  74. package/src/bin/cmds/ui/destroy.tsx +86 -0
  75. package/src/bin/cmds/ui/diff.tsx +59 -0
  76. package/src/bin/cmds/ui/get.tsx +134 -0
  77. package/src/bin/cmds/ui/list.tsx +59 -0
  78. package/src/bin/cmds/ui/output.tsx +52 -0
  79. package/src/bin/cmds/ui/provider-list.tsx +17 -0
  80. package/src/bin/cmds/ui/synth.tsx +51 -0
  81. package/src/bin/cmds/ui/watch.tsx +80 -0
  82. package/index.js +0 -2
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ import React from "react";
7
+ import SelectInput from "ink-select-input";
8
+ import { Box, Text } from "ink";
9
+
10
+ type Props = {
11
+ stackName: string;
12
+ onOverride: () => void;
13
+ onReject: () => void;
14
+ };
15
+
16
+ type Option = { label: string; description: string };
17
+ type TransformedOption = Option & { value: string };
18
+ const options: Record<string, Option> = {
19
+ override: {
20
+ label: "Override",
21
+ description: `Overrides the soft failed policy check`,
22
+ },
23
+ reject: {
24
+ label: "Reject",
25
+ description: `Does not override the failed policy check, and stops the operation`,
26
+ },
27
+ };
28
+ export function OverrideBottomBar({ stackName, onOverride, onReject }: Props) {
29
+ const selectOptions: TransformedOption[] = Object.keys(options).map(
30
+ (key) => ({
31
+ ...options[key],
32
+ value: key,
33
+ }),
34
+ );
35
+ const [highlighted, setHighlighted] = React.useState(selectOptions[0].value);
36
+ const handleHighlight = (item: { value: string }) => {
37
+ setHighlighted(item.value);
38
+ };
39
+ const handleSelect = (item: { value: string }) => {
40
+ switch (item.value) {
41
+ case "override":
42
+ onOverride();
43
+ break;
44
+ case "reject":
45
+ onReject();
46
+ break;
47
+ }
48
+ };
49
+
50
+ return (
51
+ <Box flexDirection="column">
52
+ <Box>
53
+ <Text>Please review the above failures for </Text>
54
+ <Text bold>{stackName}</Text>
55
+ </Box>
56
+ <Box>
57
+ <SelectInput
58
+ items={selectOptions}
59
+ onSelect={handleSelect}
60
+ onHighlight={handleHighlight}
61
+ />
62
+ <Box paddingLeft={2}>
63
+ <Text>{options[highlighted].description}</Text>
64
+ </Box>
65
+ </Box>
66
+ </Box>
67
+ );
68
+ }
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ import React from "react";
7
+ import { Text, Box } from "ink";
8
+ import Spinner from "ink-spinner";
9
+ import { Status } from "../../hooks/cdktf-project";
10
+ import { WatchState, CdktfStack } from "@cdktn/cli-core";
11
+
12
+ type Props = {
13
+ status: Status;
14
+ errorMessage?: string;
15
+ children?: any;
16
+ actionName: "deploying" | "destroying";
17
+ };
18
+
19
+ export function StatusBottomBar({
20
+ status,
21
+ children,
22
+ }: Omit<Props, "actionName">) {
23
+ switch (status.type) {
24
+ case "done": {
25
+ if (children) {
26
+ return children;
27
+ }
28
+ return <></>;
29
+ }
30
+
31
+ // This is handled on the outside of this component
32
+ case "waiting for approval of stack":
33
+ return <></>;
34
+
35
+ case "starting":
36
+ return (
37
+ <Box>
38
+ <Box marginRight={2}>
39
+ <Text>
40
+ <Spinner type="dots" />
41
+ </Text>
42
+ </Box>
43
+ <Box>
44
+ <Text bold>Starting</Text>
45
+ </Box>
46
+ </Box>
47
+ );
48
+
49
+ case "synthesizing":
50
+ return (
51
+ <Box>
52
+ <Box marginRight={2}>
53
+ <Text>
54
+ <Spinner type="dots" />
55
+ </Text>
56
+ </Box>
57
+ <Box>
58
+ <Text bold>Synthesizing</Text>
59
+ </Box>
60
+ </Box>
61
+ );
62
+
63
+ case "running":
64
+ return (
65
+ <Box>
66
+ <Box marginRight={2}>
67
+ <Text>
68
+ <Spinner type="dots" />
69
+ </Text>
70
+ </Box>
71
+ <Box>
72
+ <Text bold>Processing</Text>
73
+ </Box>
74
+ </Box>
75
+ );
76
+ }
77
+ }
78
+
79
+ export function localizeStacks(num: number) {
80
+ if (num === 1) {
81
+ return "1 Stack";
82
+ }
83
+ return `${num} Stacks`;
84
+ }
85
+
86
+ function Execution({
87
+ inProgress,
88
+ finished,
89
+ pending,
90
+ actionName,
91
+ }: Pick<Props, "actionName"> & {
92
+ inProgress: CdktfStack[];
93
+ finished: CdktfStack[];
94
+ pending: CdktfStack[];
95
+ }) {
96
+ return (
97
+ <Box marginTop={1}>
98
+ <Box marginRight={5}>
99
+ <Text>
100
+ {localizeStacks(inProgress.length)} {actionName}
101
+ </Text>
102
+ </Box>
103
+ <Box marginRight={5}>
104
+ <Text>{localizeStacks(finished.length)} done</Text>
105
+ </Box>
106
+ <Box>
107
+ <Text>{localizeStacks(pending.length)} waiting</Text>
108
+ </Box>
109
+ </Box>
110
+ );
111
+ }
112
+
113
+ export function ExecutionStatusBottomBar({
114
+ status,
115
+ children,
116
+ actionName,
117
+ }: Props) {
118
+ if (status?.type !== "running") {
119
+ return <StatusBottomBar status={status}>{children}</StatusBottomBar>;
120
+ }
121
+
122
+ return (
123
+ <Execution
124
+ inProgress={status.inProgress}
125
+ finished={status.finished}
126
+ pending={status.pending}
127
+ actionName={actionName}
128
+ />
129
+ );
130
+ }
131
+
132
+ export function WatchStatusBottomBar({
133
+ currentState,
134
+ }: {
135
+ currentState: WatchState;
136
+ }): React.ReactElement {
137
+ switch (currentState.type) {
138
+ case "waiting": {
139
+ return (
140
+ <Box marginTop={1}>
141
+ <Spinner />
142
+ <Box marginLeft={1}>
143
+ <Text>Waiting for changes...</Text>
144
+ </Box>
145
+ </Box>
146
+ );
147
+ }
148
+ case "stopped": {
149
+ return (
150
+ <Box marginTop={1}>
151
+ <Text>Watch was stopped</Text>
152
+ </Box>
153
+ );
154
+ }
155
+
156
+ case "running": {
157
+ if (
158
+ currentState.inProgress.length +
159
+ currentState.finished.length +
160
+ currentState.pending.length ===
161
+ 0
162
+ ) {
163
+ return (
164
+ <Box marginTop={1}>
165
+ <Spinner />
166
+ <Box marginLeft={1}>
167
+ <Text>Synthesizing...</Text>
168
+ </Box>
169
+ </Box>
170
+ );
171
+ }
172
+
173
+ return (
174
+ <Execution
175
+ inProgress={currentState.inProgress}
176
+ finished={currentState.finished}
177
+ pending={currentState.pending}
178
+ actionName="deploying"
179
+ />
180
+ );
181
+ }
182
+ }
183
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ import React from "react";
7
+ import { Text, Box } from "ink";
8
+ import {
9
+ NestedTerraformOutputs,
10
+ TerraformOutput,
11
+ isTerraformOutput,
12
+ } from "@cdktn/cli-core";
13
+
14
+ export interface OutputsConfig {
15
+ outputs: NestedTerraformOutputs;
16
+ }
17
+ function sanitize(value: any) {
18
+ if (typeof value === "object") {
19
+ return JSON.stringify(value, null, 2);
20
+ }
21
+
22
+ return value;
23
+ }
24
+
25
+ function Output({ name, value }: { name: string; value: TerraformOutput }) {
26
+ return (
27
+ <Box key={name}>
28
+ <Text>
29
+ {name} = {value.sensitive ? "<sensitive>" : sanitize(value.value)}
30
+ </Text>
31
+ </Box>
32
+ );
33
+ }
34
+
35
+ // Puts the top-level outputs before the nested outputs
36
+ const compareOutputs =
37
+ (value: NestedTerraformOutputs) =>
38
+ ([k1]: [string, any], [k2]: [string, any]): number => {
39
+ if (isTerraformOutput(value[k1]) && isTerraformOutput(value[k2])) {
40
+ return k1.localeCompare(k2);
41
+ }
42
+
43
+ if (isTerraformOutput(value[k1])) {
44
+ return -1;
45
+ }
46
+
47
+ if (isTerraformOutput(value[k2])) {
48
+ return 1;
49
+ }
50
+ return k1.localeCompare(k2);
51
+ };
52
+
53
+ function NestedOutput({
54
+ name,
55
+ value,
56
+ indentationLevel = 0,
57
+ }: {
58
+ name: string;
59
+ value: NestedTerraformOutputs;
60
+ indentationLevel?: number;
61
+ }) {
62
+ // This is a safe-guard against infinite recursion
63
+ if (indentationLevel > 500) {
64
+ return <></>;
65
+ }
66
+ if (isTerraformOutput(value)) {
67
+ return (
68
+ <Box key={name}>
69
+ <Output name={name} value={value} />
70
+ </Box>
71
+ );
72
+ }
73
+
74
+ return (
75
+ <Box flexDirection="column" key={name} marginLeft={2} marginBottom={1}>
76
+ <Text bold>{name}</Text>
77
+ <Box marginLeft={indentationLevel * 2} flexDirection="column">
78
+ {Object.entries(value)
79
+ .sort(compareOutputs(value))
80
+ .map(([k, v]) => (
81
+ <NestedOutput
82
+ indentationLevel={indentationLevel + 1}
83
+ key={k}
84
+ name={k}
85
+ value={v}
86
+ />
87
+ ))}
88
+ </Box>
89
+ </Box>
90
+ );
91
+ }
92
+
93
+ export const Outputs = ({ outputs }: OutputsConfig): React.ReactElement => {
94
+ return (
95
+ <Box flexDirection="column">
96
+ {Object.entries(outputs).map(([key, value]) => (
97
+ <Box key={key}>
98
+ <NestedOutput name={key} value={value} />
99
+ </Box>
100
+ ))}
101
+ </Box>
102
+ );
103
+ };
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ import React from "react";
7
+ import { Box, Static, Text } from "ink";
8
+ import { LogEntry } from "../hooks/cdktf-project";
9
+
10
+ const possibleColors = [
11
+ "yellow",
12
+ "blue",
13
+ "cyan",
14
+ "green",
15
+ "white",
16
+ "yellowBright",
17
+ "blueBright",
18
+ "cyanBright",
19
+ "greenBright",
20
+ "whiteBright",
21
+ ];
22
+
23
+ let colorPointer = 0;
24
+
25
+ const colorAssignments: Record<string, string> = {};
26
+
27
+ function getColor(stackName: string): string {
28
+ if (colorAssignments[stackName]) {
29
+ return colorAssignments[stackName];
30
+ }
31
+
32
+ const color = possibleColors[colorPointer];
33
+ colorPointer = (colorPointer + 1) % possibleColors.length;
34
+ colorAssignments[stackName] = color;
35
+ return color;
36
+ }
37
+
38
+ export function StreamPrefix({ stackName }: { stackName: string }) {
39
+ return (
40
+ <Text bold color={getColor(stackName)}>
41
+ {stackName}
42
+ </Text>
43
+ );
44
+ }
45
+
46
+ export function StreamView({
47
+ logs,
48
+ children,
49
+ }: {
50
+ logs: LogEntry[];
51
+ children: any;
52
+ }) {
53
+ return (
54
+ <Box>
55
+ <Box>
56
+ <Static items={logs}>
57
+ {({ content, id, stackName }) => (
58
+ <Box key={id}>
59
+ <Box marginRight={2}>
60
+ <StreamPrefix stackName={stackName} />
61
+ </Box>
62
+ <Box>
63
+ <Text>{content.trim()}</Text>
64
+ </Box>
65
+ </Box>
66
+ )}
67
+ </Static>
68
+ </Box>
69
+ <Box marginTop={1}>{children}</Box>
70
+ </Box>
71
+ );
72
+ }
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ /* eslint-disable no-control-regex */
7
+ import React, { useState } from "react";
8
+ import { Text, Box } from "ink";
9
+ import { DeployingResource, NestedTerraformOutputs } from "@cdktn/cli-core";
10
+ import { useCdktfProject } from "./hooks/cdktf-project";
11
+ import {
12
+ StreamView,
13
+ OutputsBottomBar,
14
+ ApproveBottomBar,
15
+ OverrideBottomBar,
16
+ ExecutionStatusBottomBar,
17
+ } from "./components";
18
+ interface DeploySummaryConfig {
19
+ resources: DeployingResource[];
20
+ }
21
+
22
+ export const DeploySummary = ({
23
+ resources,
24
+ }: DeploySummaryConfig): React.ReactElement => {
25
+ const summary = resources.reduce(
26
+ (accumulator, resource) => {
27
+ if (accumulator[resource.applyState] !== undefined) {
28
+ accumulator[resource.applyState] += 1;
29
+ }
30
+
31
+ return accumulator;
32
+ },
33
+ {
34
+ created: 0,
35
+ updated: 0,
36
+ destroyed: 0,
37
+ } as any,
38
+ );
39
+
40
+ return (
41
+ <>
42
+ {Object.keys(summary).map((key, i) => (
43
+ <Box key={key}>
44
+ {i > 0 && <Text>, </Text>}
45
+ <Text>
46
+ {summary[key]} {key}
47
+ </Text>
48
+ </Box>
49
+ ))}
50
+ </>
51
+ );
52
+ };
53
+
54
+ interface DeployConfig {
55
+ outDir: string;
56
+ targetStacks?: string[];
57
+ synthCommand: string;
58
+ autoApprove: boolean;
59
+ onOutputsRetrieved: (outputs: NestedTerraformOutputs) => void;
60
+ outputsPath?: string;
61
+ ignoreMissingStackDependencies?: boolean;
62
+ parallelism?: number;
63
+ refreshOnly?: boolean;
64
+ terraformParallelism?: number;
65
+ vars?: string[];
66
+ varFiles?: string[];
67
+ noColor?: boolean;
68
+ migrateState?: boolean;
69
+ skipSynth?: boolean;
70
+ skipProviderLock?: boolean;
71
+ }
72
+
73
+ export const Deploy = ({
74
+ outDir,
75
+ targetStacks,
76
+ synthCommand,
77
+ autoApprove,
78
+ onOutputsRetrieved,
79
+ outputsPath,
80
+ ignoreMissingStackDependencies,
81
+ parallelism,
82
+ refreshOnly,
83
+ terraformParallelism,
84
+ vars,
85
+ varFiles,
86
+ noColor,
87
+ migrateState,
88
+ skipSynth,
89
+ skipProviderLock,
90
+ }: DeployConfig): React.ReactElement => {
91
+ const [outputs, setOutputs] = useState<NestedTerraformOutputs>();
92
+ const { status, logEntries } = useCdktfProject(
93
+ { outDir, synthCommand },
94
+ async (project) => {
95
+ await project.deploy({
96
+ stackNames: targetStacks,
97
+ autoApprove,
98
+ ignoreMissingStackDependencies,
99
+ parallelism,
100
+ refreshOnly,
101
+ terraformParallelism,
102
+ vars,
103
+ varFiles,
104
+ noColor,
105
+ migrateState,
106
+ skipSynth,
107
+ skipProviderLock,
108
+ });
109
+
110
+ if (onOutputsRetrieved) {
111
+ onOutputsRetrieved(project.outputsByConstructId);
112
+ }
113
+ setOutputs(project.outputsByConstructId);
114
+ },
115
+ );
116
+
117
+ const bottomBar =
118
+ status.type === "done" ? (
119
+ <OutputsBottomBar outputs={outputs} outputsFile={outputsPath} />
120
+ ) : status?.type === "waiting for approval of stack" ? (
121
+ <ApproveBottomBar
122
+ stackName={status.stackName}
123
+ onApprove={status.approve}
124
+ onDismiss={status.dismiss}
125
+ onStop={status.stop}
126
+ />
127
+ ) : status?.type ===
128
+ "waiting for override of sentinel policy check failure" ? (
129
+ <OverrideBottomBar
130
+ stackName={status.stackName}
131
+ onOverride={status.override}
132
+ onReject={status.reject}
133
+ />
134
+ ) : (
135
+ <ExecutionStatusBottomBar status={status} actionName="deploying" />
136
+ );
137
+
138
+ return <StreamView logs={logEntries}>{bottomBar}</StreamView>;
139
+ };
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ /* eslint-disable no-control-regex */
7
+ import React from "react";
8
+
9
+ import { useCdktfProject } from "./hooks/cdktf-project";
10
+ import {
11
+ StreamView,
12
+ ExecutionStatusBottomBar,
13
+ ApproveBottomBar,
14
+ OverrideBottomBar,
15
+ } from "./components";
16
+
17
+ interface DestroyConfig {
18
+ outDir: string;
19
+ targetStacks?: string[];
20
+ synthCommand: string;
21
+ autoApprove: boolean;
22
+ ignoreMissingStackDependencies?: boolean;
23
+ parallelism?: number;
24
+ terraformParallelism?: number;
25
+ noColor?: boolean;
26
+ migrateState?: boolean;
27
+ vars?: string[];
28
+ varFiles?: string[];
29
+ skipSynth?: boolean;
30
+ skipProviderLock?: boolean;
31
+ }
32
+
33
+ export const Destroy = ({
34
+ outDir,
35
+ targetStacks,
36
+ synthCommand,
37
+ autoApprove,
38
+ ignoreMissingStackDependencies,
39
+ parallelism,
40
+ terraformParallelism,
41
+ noColor,
42
+ migrateState,
43
+ vars,
44
+ varFiles,
45
+ skipSynth,
46
+ skipProviderLock,
47
+ }: DestroyConfig): React.ReactElement => {
48
+ const { status, logEntries } = useCdktfProject(
49
+ { outDir, synthCommand },
50
+ (project) =>
51
+ project.destroy({
52
+ stackNames: targetStacks,
53
+ autoApprove,
54
+ ignoreMissingStackDependencies,
55
+ parallelism,
56
+ terraformParallelism,
57
+ noColor,
58
+ migrateState,
59
+ vars,
60
+ varFiles,
61
+ skipSynth,
62
+ skipProviderLock,
63
+ }),
64
+ );
65
+
66
+ const bottomBar =
67
+ status?.type === "waiting for approval of stack" ? (
68
+ <ApproveBottomBar
69
+ stackName={status.stackName}
70
+ onApprove={status.approve}
71
+ onDismiss={status.dismiss}
72
+ onStop={status.stop}
73
+ />
74
+ ) : status?.type ===
75
+ "waiting for override of sentinel policy check failure" ? (
76
+ <OverrideBottomBar
77
+ stackName={status.stackName}
78
+ onOverride={status.override}
79
+ onReject={status.reject}
80
+ />
81
+ ) : (
82
+ <ExecutionStatusBottomBar status={status} actionName="destroying" />
83
+ );
84
+
85
+ return <StreamView logs={logEntries}>{bottomBar}</StreamView>;
86
+ };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ import React from "react";
7
+
8
+ import { useCdktfProject } from "./hooks/cdktf-project";
9
+ import { StreamView, StatusBottomBar } from "./components";
10
+
11
+ interface DiffConfig {
12
+ outDir: string;
13
+ targetStack?: string;
14
+ synthCommand: string;
15
+ refreshOnly?: boolean;
16
+ terraformParallelism?: number;
17
+ vars?: string[];
18
+ varFiles?: string[];
19
+ noColor?: boolean;
20
+ migrateState?: boolean;
21
+ skipSynth?: boolean;
22
+ skipProviderLock?: boolean;
23
+ }
24
+
25
+ export const Diff = ({
26
+ outDir,
27
+ targetStack,
28
+ synthCommand,
29
+ refreshOnly,
30
+ terraformParallelism,
31
+ vars,
32
+ varFiles,
33
+ noColor,
34
+ migrateState,
35
+ skipSynth,
36
+ skipProviderLock,
37
+ }: DiffConfig): React.ReactElement => {
38
+ const { status, logEntries } = useCdktfProject(
39
+ { outDir, synthCommand },
40
+ (project) =>
41
+ project.diff({
42
+ stackName: targetStack,
43
+ refreshOnly,
44
+ terraformParallelism,
45
+ vars,
46
+ varFiles,
47
+ noColor,
48
+ migrateState,
49
+ skipSynth,
50
+ skipProviderLock,
51
+ }),
52
+ );
53
+
54
+ return (
55
+ <StreamView logs={logEntries}>
56
+ <StatusBottomBar status={status} />
57
+ </StreamView>
58
+ );
59
+ };