awscfn 1.4.0 → 1.6.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.
- package/README.md +23 -1
- package/bin/awscfn +269 -11
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/inspectStack.d.ts +6 -0
- package/dist/inspectStack.d.ts.map +1 -0
- package/dist/inspectStack.js +211 -0
- package/dist/inspectStack.js.map +1 -0
- package/dist/lib/cfn/getStackTemplate.d.ts +2 -0
- package/dist/lib/cfn/getStackTemplate.d.ts.map +1 -0
- package/dist/lib/cfn/getStackTemplate.js +30 -0
- package/dist/lib/cfn/getStackTemplate.js.map +1 -0
- package/dist/lib/cfn/index.d.ts +2 -0
- package/dist/lib/cfn/index.d.ts.map +1 -1
- package/dist/lib/cfn/index.js +2 -0
- package/dist/lib/cfn/index.js.map +1 -1
- package/dist/lib/cfn/listStackEvents.d.ts +3 -0
- package/dist/lib/cfn/listStackEvents.d.ts.map +1 -0
- package/dist/lib/cfn/listStackEvents.js +26 -0
- package/dist/lib/cfn/listStackEvents.js.map +1 -0
- package/dist/lib/viewInspectTui.d.ts +10 -0
- package/dist/lib/viewInspectTui.d.ts.map +1 -0
- package/dist/lib/viewInspectTui.js +343 -0
- package/dist/lib/viewInspectTui.js.map +1 -0
- package/dist/lib/viewText.d.ts +5 -0
- package/dist/lib/viewText.d.ts.map +1 -0
- package/dist/lib/viewText.js +57 -0
- package/dist/lib/viewText.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
[](https://conventionalcommits.org)
|
|
10
10
|
[](https://github.com/mhweiner/autorel)
|
|
11
11
|
|
|
12
|
-
Deploy CloudFormation stacks
|
|
12
|
+
Deploy CloudFormation stacks with confidence.
|
|
13
13
|
|
|
14
14
|
## Why awscfn?
|
|
15
15
|
|
|
@@ -104,6 +104,28 @@ List all CloudFormation stacks in the current region (name, status, creation dat
|
|
|
104
104
|
awscfn list-stacks
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
+
### 🔎 inspect-stack
|
|
108
|
+
|
|
109
|
+
Inspect a **deployed** stack in an **interactive multi-pane TUI** (with pager/text fallback), including:
|
|
110
|
+
|
|
111
|
+
- full deployed template body
|
|
112
|
+
- current parameters and outputs
|
|
113
|
+
- stack metadata (raw JSON details)
|
|
114
|
+
- event timeline (chronological)
|
|
115
|
+
- failure events and likely root-cause errors
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
awscfn inspect-stack -n <STACK_NAME>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
| Flag | Description |
|
|
122
|
+
|------|-------------|
|
|
123
|
+
| `--name`, `-n` | Stack name |
|
|
124
|
+
| `--events`, `-e` | Max stack events to fetch (`0` = all available events). Default `500` |
|
|
125
|
+
| `--pager` / `--no-pager` | Use interactive TUI/pager output (default true). Disable to print directly |
|
|
126
|
+
|
|
127
|
+
This command performs read-only CloudFormation API calls (`DescribeStacks`, `GetTemplate`, `DescribeStackEvents`) and makes no stack changes.
|
|
128
|
+
|
|
107
129
|
### 🚀 create-stack
|
|
108
130
|
|
|
109
131
|
```bash
|
package/bin/awscfn
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
|
+
const os = require('os');
|
|
4
5
|
const path = require('path');
|
|
6
|
+
const { spawnSync } = require('node:child_process');
|
|
5
7
|
const yargs = require('yargs');
|
|
6
8
|
|
|
7
9
|
const { createStack } = require('../dist/createStack');
|
|
8
10
|
const { deleteStack } = require('../dist/deleteStack');
|
|
9
11
|
const { listStacks } = require('../dist/listStacks');
|
|
12
|
+
const { inspectStack } = require('../dist/inspectStack');
|
|
10
13
|
const { previewStack } = require('../dist/previewStack');
|
|
11
14
|
const { redeployStack } = require('../dist/redeployStack');
|
|
12
15
|
const { updateStack } = require('../dist/updateStack');
|
|
@@ -16,6 +19,9 @@ const pkg = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../package.json'
|
|
|
16
19
|
const isCI = process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true';
|
|
17
20
|
|
|
18
21
|
const FILE_FLAGS = ['--template', '--params', '-t', '-p'];
|
|
22
|
+
const ASCII_LOGO = [
|
|
23
|
+
'awscfn',
|
|
24
|
+
];
|
|
19
25
|
|
|
20
26
|
function completeFile(current) {
|
|
21
27
|
const dir = path.dirname(current) || '.';
|
|
@@ -49,6 +55,65 @@ function logError(msg) {
|
|
|
49
55
|
console.log(`\x1b[31mError: ${msg}\x1b[0m`);
|
|
50
56
|
}
|
|
51
57
|
|
|
58
|
+
function maybeColorize(text, colorCode) {
|
|
59
|
+
if (!process.stdout.isTTY || process.env.NO_COLOR) {
|
|
60
|
+
return text;
|
|
61
|
+
}
|
|
62
|
+
return `${colorCode}${text}\x1b[0m`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function runImageCommand(command, args) {
|
|
66
|
+
const result = spawnSync(command, args, { stdio: 'inherit' });
|
|
67
|
+
return !result.error && result.status === 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function tryPrintTerminalLogo() {
|
|
71
|
+
if (!process.stdout.isTTY || process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true') {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (process.env.TERM_PROGRAM === 'vscode') {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const logoPath = path.resolve(__dirname, '../docs/awscfn-logo-light.svg');
|
|
80
|
+
if (!fs.existsSync(logoPath)) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Try native terminal image commands (best effort).
|
|
85
|
+
if (process.env.WEZTERM_PANE && runImageCommand('wezterm', ['imgcat', '--width', '40%', logoPath])) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (process.env.KITTY_WINDOW_ID && runImageCommand('kitty', ['+kitten', 'icat', '--align', 'left', logoPath])) {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (process.env.ITERM_SESSION_ID && runImageCommand('imgcat', [logoPath])) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function printLandingHeader() {
|
|
101
|
+
const boldWhite = '\x1b[1;37m';
|
|
102
|
+
const gray = '\x1b[90m';
|
|
103
|
+
const tagline = 'Deploy CloudFormation stacks with confidence.';
|
|
104
|
+
const hr = maybeColorize('─'.repeat(tagline.length), gray);
|
|
105
|
+
|
|
106
|
+
if (!tryPrintTerminalLogo()) {
|
|
107
|
+
console.log(maybeColorize(ASCII_LOGO.join('\n'), boldWhite));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
console.log(hr);
|
|
111
|
+
console.log(tagline);
|
|
112
|
+
console.log(hr);
|
|
113
|
+
console.log(maybeColorize('Quick start: awscfn list-stacks | awscfn inspect-stack -n <stack-name>', gray));
|
|
114
|
+
console.log('');
|
|
115
|
+
}
|
|
116
|
+
|
|
52
117
|
function logErrorDetails(data) {
|
|
53
118
|
if (data) {
|
|
54
119
|
console.log('\nError details:');
|
|
@@ -56,13 +121,162 @@ function logErrorDetails(data) {
|
|
|
56
121
|
}
|
|
57
122
|
}
|
|
58
123
|
|
|
124
|
+
function getProfileAwareCommand(baseCommand) {
|
|
125
|
+
const profile = process.env.AWS_PROFILE;
|
|
126
|
+
if (!profile) return baseCommand;
|
|
127
|
+
|
|
128
|
+
return `${baseCommand} --profile ${profile}`;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function getAwsConfigPath() {
|
|
132
|
+
if (process.env.AWS_CONFIG_FILE) return process.env.AWS_CONFIG_FILE;
|
|
133
|
+
|
|
134
|
+
return path.join(os.homedir(), '.aws', 'config');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function getAwsCredentialsPath() {
|
|
138
|
+
if (process.env.AWS_SHARED_CREDENTIALS_FILE) return process.env.AWS_SHARED_CREDENTIALS_FILE;
|
|
139
|
+
|
|
140
|
+
return path.join(os.homedir(), '.aws', 'credentials');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function readIniSections(filePath) {
|
|
144
|
+
try {
|
|
145
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
146
|
+
|
|
147
|
+
return content
|
|
148
|
+
.split('\n')
|
|
149
|
+
.map((line) => line.trim())
|
|
150
|
+
.filter((line) => line.startsWith('[') && line.endsWith(']'))
|
|
151
|
+
.map((line) => line.slice(1, -1).trim());
|
|
152
|
+
} catch {
|
|
153
|
+
return [];
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function getConfiguredProfiles() {
|
|
158
|
+
const configSections = readIniSections(getAwsConfigPath())
|
|
159
|
+
.map((section) => section.startsWith('profile ') ? section.slice('profile '.length) : section);
|
|
160
|
+
const credentialSections = readIniSections(getAwsCredentialsPath());
|
|
161
|
+
|
|
162
|
+
return new Set([...configSections, ...credentialSections]);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function hasCredentialHints() {
|
|
166
|
+
if (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) {
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const configuredProfiles = getConfiguredProfiles();
|
|
171
|
+
const requestedProfile = process.env.AWS_PROFILE;
|
|
172
|
+
|
|
173
|
+
if (requestedProfile) return configuredProfiles.has(requestedProfile);
|
|
174
|
+
|
|
175
|
+
return configuredProfiles.has('default');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function formatRegionOnlyHelp() {
|
|
179
|
+
const configureCmd = getProfileAwareCommand('aws configure');
|
|
180
|
+
const showRegionCmd = getProfileAwareCommand('aws configure get region');
|
|
181
|
+
|
|
182
|
+
return [
|
|
183
|
+
'AWS region is not configured.',
|
|
184
|
+
[
|
|
185
|
+
'Set a region:',
|
|
186
|
+
' • export AWS_REGION=us-east-1',
|
|
187
|
+
` • ${configureCmd}`,
|
|
188
|
+
].join('\n'),
|
|
189
|
+
[
|
|
190
|
+
'Check current region:',
|
|
191
|
+
` • ${showRegionCmd}`,
|
|
192
|
+
].join('\n'),
|
|
193
|
+
'Tip: if you use named profiles, set AWS_PROFILE first.',
|
|
194
|
+
].join('\n\n');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function formatAuthSetupHelp(profileMissing) {
|
|
198
|
+
const profile = process.env.AWS_PROFILE;
|
|
199
|
+
const showRegionCmd = getProfileAwareCommand('aws configure get region');
|
|
200
|
+
const configureSsoCmd = getProfileAwareCommand('aws configure sso');
|
|
201
|
+
const ssoLoginCmd = getProfileAwareCommand('aws sso login');
|
|
202
|
+
const stsCheckCmd = getProfileAwareCommand('aws sts get-caller-identity');
|
|
203
|
+
const configureCmd = getProfileAwareCommand('aws configure');
|
|
204
|
+
const profileHint = profile ? `Using AWS profile '${profile}'.` : 'Using default AWS profile.';
|
|
205
|
+
|
|
206
|
+
const profileSection = profileMissing && profile
|
|
207
|
+
? [
|
|
208
|
+
`Profile '${profile}' was not found.`,
|
|
209
|
+
`Create it first: ${configureSsoCmd}`,
|
|
210
|
+
].join('\n')
|
|
211
|
+
: profileHint;
|
|
212
|
+
|
|
213
|
+
return [
|
|
214
|
+
'AWS authentication is not configured for this command yet.',
|
|
215
|
+
profileSection,
|
|
216
|
+
'Choose one authentication method:',
|
|
217
|
+
[
|
|
218
|
+
'AWS SSO:',
|
|
219
|
+
` • ${configureSsoCmd}`,
|
|
220
|
+
` • ${ssoLoginCmd}`,
|
|
221
|
+
].join('\n'),
|
|
222
|
+
[
|
|
223
|
+
'Access keys:',
|
|
224
|
+
` • ${configureCmd} # adds keys + default region`,
|
|
225
|
+
].join('\n'),
|
|
226
|
+
[
|
|
227
|
+
'Then verify identity:',
|
|
228
|
+
` • ${stsCheckCmd}`,
|
|
229
|
+
].join('\n'),
|
|
230
|
+
[
|
|
231
|
+
'If region is still missing:',
|
|
232
|
+
' • export AWS_REGION=us-east-1',
|
|
233
|
+
` • ${showRegionCmd}`,
|
|
234
|
+
].join('\n'),
|
|
235
|
+
].filter(Boolean).join('\n\n');
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function formatAuthorizationHelp() {
|
|
239
|
+
const stsCheckCmd = getProfileAwareCommand('aws sts get-caller-identity');
|
|
240
|
+
|
|
241
|
+
return [
|
|
242
|
+
'AWS authentication succeeded, but this identity does not have enough permissions.',
|
|
243
|
+
[
|
|
244
|
+
'Confirm which identity is active:',
|
|
245
|
+
` • ${stsCheckCmd}`,
|
|
246
|
+
].join('\n'),
|
|
247
|
+
'Then ask for the required CloudFormation permissions for this account/role.',
|
|
248
|
+
].join('\n\n');
|
|
249
|
+
}
|
|
250
|
+
|
|
59
251
|
function clarifyAwsError(msg) {
|
|
60
|
-
|
|
61
|
-
|
|
252
|
+
const isRegionMissing = /region\s+is\s+missing|configuration.*region|Missing required key 'region'/i.test(msg);
|
|
253
|
+
const isCredentialsMissing = /Unable to locate credentials|Could not load credentials|NoCredentialProviders/i.test(msg)
|
|
254
|
+
|| /Token is expired|ExpiredToken|security token included in the request is expired/i.test(msg)
|
|
255
|
+
|| /sso.*expired|refresh failed|SSO session.*invalid|aws sso login/i.test(msg)
|
|
256
|
+
|| /resolved credential object is not valid|credential.*could not be loaded/i.test(msg);
|
|
257
|
+
const requestedProfile = process.env.AWS_PROFILE;
|
|
258
|
+
const requestedProfileMissing = Boolean(
|
|
259
|
+
requestedProfile && !getConfiguredProfiles().has(requestedProfile),
|
|
260
|
+
);
|
|
261
|
+
const isProfileMissing = /config profile .* could not be found|profile.*not found/i.test(msg)
|
|
262
|
+
|| requestedProfileMissing;
|
|
263
|
+
|
|
264
|
+
if (isRegionMissing && hasCredentialHints() && !isProfileMissing) {
|
|
265
|
+
return formatRegionOnlyHelp();
|
|
62
266
|
}
|
|
63
|
-
|
|
64
|
-
|
|
267
|
+
|
|
268
|
+
if (
|
|
269
|
+
isRegionMissing
|
|
270
|
+
|| isCredentialsMissing
|
|
271
|
+
|| isProfileMissing
|
|
272
|
+
) {
|
|
273
|
+
return formatAuthSetupHelp(isProfileMissing);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (/AccessDenied|UnauthorizedOperation|is not authorized to perform|AccessDeniedException/i.test(msg)) {
|
|
277
|
+
return formatAuthorizationHelp();
|
|
65
278
|
}
|
|
279
|
+
|
|
66
280
|
return msg;
|
|
67
281
|
}
|
|
68
282
|
|
|
@@ -70,11 +284,17 @@ async function runCommand(fn) {
|
|
|
70
284
|
try {
|
|
71
285
|
await fn();
|
|
72
286
|
} catch (err) {
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
287
|
+
const originalError = err?.message || String(err);
|
|
288
|
+
const message = clarifyAwsError(originalError);
|
|
289
|
+
|
|
290
|
+
logError(originalError);
|
|
291
|
+
|
|
292
|
+
if (message !== originalError) {
|
|
293
|
+
console.log('');
|
|
294
|
+
console.log(maybeColorize('Suggested next steps:', '\x1b[36m'));
|
|
295
|
+
console.log(message);
|
|
77
296
|
}
|
|
297
|
+
|
|
78
298
|
if (getOutputConfig().verbose) {
|
|
79
299
|
logErrorDetails(err.data);
|
|
80
300
|
}
|
|
@@ -113,8 +333,31 @@ const createIfMissingOpt = {
|
|
|
113
333
|
const confirmOpt = {
|
|
114
334
|
confirm: { type: 'string', alias: 'c', describe: 'Repeat stack name to confirm deletion', demandOption: true },
|
|
115
335
|
};
|
|
336
|
+
const eventsLimitOpt = {
|
|
337
|
+
events: {
|
|
338
|
+
type: 'number',
|
|
339
|
+
alias: 'e',
|
|
340
|
+
describe: 'Max stack events to fetch (0 means all available events)',
|
|
341
|
+
demandOption: false,
|
|
342
|
+
default: 500,
|
|
343
|
+
},
|
|
344
|
+
};
|
|
345
|
+
const pagerOpt = {
|
|
346
|
+
pager: {
|
|
347
|
+
type: 'boolean',
|
|
348
|
+
describe: 'Use interactive TUI/pager output (use --no-pager to print directly)',
|
|
349
|
+
demandOption: false,
|
|
350
|
+
default: true,
|
|
351
|
+
},
|
|
352
|
+
};
|
|
116
353
|
|
|
117
|
-
yargs
|
|
354
|
+
const cli = yargs
|
|
355
|
+
.scriptName('awscfn')
|
|
356
|
+
.usage('Usage:\n $0 <command> [options]')
|
|
357
|
+
.example('$0 list-stacks', 'List active stacks in the current AWS region')
|
|
358
|
+
.example('$0 inspect-stack -n my-stack', 'Open interactive stack inspection panes')
|
|
359
|
+
.example('$0 update-stack -n my-stack -t ./template.yaml -p ./params.yaml', 'Update an existing stack')
|
|
360
|
+
.epilog('Tip: run `awscfn <command> --help` for command-specific help.')
|
|
118
361
|
.option('ci', {
|
|
119
362
|
type: 'boolean',
|
|
120
363
|
alias: 'C',
|
|
@@ -188,6 +431,14 @@ yargs
|
|
|
188
431
|
runCommand(() => previewStack(name, template, params, require('../dist/cli/parseParamOverrides').parseParamOverrides(set).overrides));
|
|
189
432
|
}
|
|
190
433
|
)
|
|
434
|
+
.command(
|
|
435
|
+
'inspect-stack',
|
|
436
|
+
'Inspect a deployed stack in interactive panes (with fallback)',
|
|
437
|
+
(cmd) => cmd.options({ ...nameOpt, ...eventsLimitOpt, ...pagerOpt }),
|
|
438
|
+
({ name, events, pager }) => {
|
|
439
|
+
runCommand(() => inspectStack(name, { eventsLimit: Number(events), usePager: Boolean(pager) }));
|
|
440
|
+
}
|
|
441
|
+
)
|
|
191
442
|
.completion(
|
|
192
443
|
'completion',
|
|
193
444
|
'Generate shell completion script',
|
|
@@ -210,5 +461,12 @@ yargs
|
|
|
210
461
|
.help()
|
|
211
462
|
.alias('h', 'help')
|
|
212
463
|
.version(pkg.version)
|
|
213
|
-
.alias('v', 'version')
|
|
214
|
-
|
|
464
|
+
.alias('v', 'version');
|
|
465
|
+
|
|
466
|
+
if (process.argv.length <= 2) {
|
|
467
|
+
printLandingHeader();
|
|
468
|
+
cli.showHelp();
|
|
469
|
+
process.exit(0);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
cli.argv;
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -14,9 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.previewStack = void 0;
|
|
17
|
+
exports.inspectStack = exports.previewStack = void 0;
|
|
18
18
|
__exportStar(require("./lib/cfn"), exports);
|
|
19
19
|
__exportStar(require("./lib/output"), exports);
|
|
20
20
|
var previewStack_1 = require("./previewStack");
|
|
21
21
|
Object.defineProperty(exports, "previewStack", { enumerable: true, get: function () { return previewStack_1.previewStack; } });
|
|
22
|
+
var inspectStack_1 = require("./inspectStack");
|
|
23
|
+
Object.defineProperty(exports, "inspectStack", { enumerable: true, get: function () { return inspectStack_1.inspectStack; } });
|
|
22
24
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,4CAA0B;AAC1B,+CAA6B;AAC7B,+CAA4C;AAApC,4GAAA,YAAY,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,4CAA0B;AAC1B,+CAA6B;AAC7B,+CAA4C;AAApC,4GAAA,YAAY,OAAA;AACpB,+CAA4C;AAApC,4GAAA,YAAY,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspectStack.d.ts","sourceRoot":"","sources":["../src/inspectStack.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,mBAAmB;IAChC,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,OAAO,CAAA;CACpB;AAwOD,wBAAsB,YAAY,CAC9B,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,GACvC,OAAO,CAAC,IAAI,CAAC,CAwCf"}
|
|
@@ -0,0 +1,211 @@
|
|
|
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.inspectStack = inspectStack;
|
|
37
|
+
const cfn = __importStar(require("./lib/cfn"));
|
|
38
|
+
const viewText_1 = require("./lib/viewText");
|
|
39
|
+
const viewInspectTui_1 = require("./lib/viewInspectTui");
|
|
40
|
+
const DEFAULT_OPTIONS = {
|
|
41
|
+
eventsLimit: 500,
|
|
42
|
+
usePager: true,
|
|
43
|
+
};
|
|
44
|
+
const GENERIC_FAILURE_PATTERNS = [
|
|
45
|
+
/resource creation cancelled/i,
|
|
46
|
+
/resource update cancelled/i,
|
|
47
|
+
/the following resource\(s\) failed/i,
|
|
48
|
+
/user initiated/i,
|
|
49
|
+
];
|
|
50
|
+
function toIso(value) {
|
|
51
|
+
if (!value) {
|
|
52
|
+
return '—';
|
|
53
|
+
}
|
|
54
|
+
return value.toISOString();
|
|
55
|
+
}
|
|
56
|
+
function toTimestamp(event) {
|
|
57
|
+
return event.Timestamp?.getTime() ?? 0;
|
|
58
|
+
}
|
|
59
|
+
function toChronological(events) {
|
|
60
|
+
return events.slice().sort((left, right) => toTimestamp(left) - toTimestamp(right));
|
|
61
|
+
}
|
|
62
|
+
function isFailureStatus(status) {
|
|
63
|
+
return status.includes('FAILED') || status.includes('ROLLBACK');
|
|
64
|
+
}
|
|
65
|
+
function isGenericFailureReason(reason) {
|
|
66
|
+
return GENERIC_FAILURE_PATTERNS.some((pattern) => pattern.test(reason));
|
|
67
|
+
}
|
|
68
|
+
function getFailureEvents(events) {
|
|
69
|
+
const out = [];
|
|
70
|
+
for (const event of events) {
|
|
71
|
+
const status = event.ResourceStatus ?? '';
|
|
72
|
+
const reason = event.ResourceStatusReason ?? '';
|
|
73
|
+
if (!isFailureStatus(status) || !reason)
|
|
74
|
+
continue;
|
|
75
|
+
out.push({
|
|
76
|
+
timestamp: toIso(event.Timestamp),
|
|
77
|
+
resource: `${event.LogicalResourceId ?? 'Unknown'} (${event.ResourceType ?? 'Unknown'})`,
|
|
78
|
+
status,
|
|
79
|
+
reason,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
function uniqueRootCauseCandidates(failures) {
|
|
85
|
+
const seenReasons = new Set();
|
|
86
|
+
const rootCauses = [];
|
|
87
|
+
for (const failure of failures) {
|
|
88
|
+
if (isGenericFailureReason(failure.reason) || seenReasons.has(failure.reason))
|
|
89
|
+
continue;
|
|
90
|
+
seenReasons.add(failure.reason);
|
|
91
|
+
rootCauses.push(failure);
|
|
92
|
+
}
|
|
93
|
+
return rootCauses;
|
|
94
|
+
}
|
|
95
|
+
function formatSection(title, body) {
|
|
96
|
+
return `${title}\n${'-'.repeat(title.length)}\n${body}`;
|
|
97
|
+
}
|
|
98
|
+
function formatParameters(stack) {
|
|
99
|
+
const params = stack.Parameters ?? [];
|
|
100
|
+
if (params.length === 0)
|
|
101
|
+
return 'No parameters on stack.';
|
|
102
|
+
return params
|
|
103
|
+
.map((param) => `${param.ParameterKey ?? 'Unknown'}: ${param.ParameterValue ?? '(no value returned)'}`)
|
|
104
|
+
.join('\n');
|
|
105
|
+
}
|
|
106
|
+
function formatOutputs(stack) {
|
|
107
|
+
const outputs = stack.Outputs ?? [];
|
|
108
|
+
if (outputs.length === 0)
|
|
109
|
+
return 'No outputs on stack.';
|
|
110
|
+
return outputs.map((output) => `${output.OutputKey ?? 'Unknown'}: ${output.OutputValue ?? ''}`).join('\n');
|
|
111
|
+
}
|
|
112
|
+
function formatRootCauses(failures) {
|
|
113
|
+
const rootCauses = uniqueRootCauseCandidates(failures).slice(0, 10);
|
|
114
|
+
if (rootCauses.length === 0)
|
|
115
|
+
return 'No specific root-cause errors detected.';
|
|
116
|
+
return rootCauses
|
|
117
|
+
.map((failure) => `[${failure.timestamp}] ${failure.status} ${failure.resource}\n Reason: ${failure.reason}`)
|
|
118
|
+
.join('\n\n');
|
|
119
|
+
}
|
|
120
|
+
function formatFailureEvents(failures) {
|
|
121
|
+
if (failures.length === 0)
|
|
122
|
+
return 'No failure events found.';
|
|
123
|
+
return failures
|
|
124
|
+
.slice(-50)
|
|
125
|
+
.map((failure) => `[${failure.timestamp}] ${failure.status} ${failure.resource}\n Reason: ${failure.reason}`)
|
|
126
|
+
.join('\n\n');
|
|
127
|
+
}
|
|
128
|
+
function formatEvent(event) {
|
|
129
|
+
const timestamp = toIso(event.Timestamp);
|
|
130
|
+
const status = event.ResourceStatus ?? 'UNKNOWN';
|
|
131
|
+
const logical = event.LogicalResourceId ?? 'Unknown';
|
|
132
|
+
const type = event.ResourceType ?? 'Unknown';
|
|
133
|
+
const reason = event.ResourceStatusReason ? `\n Reason: ${event.ResourceStatusReason}` : '';
|
|
134
|
+
return `[${timestamp}] ${status} ${logical} (${type})${reason}`;
|
|
135
|
+
}
|
|
136
|
+
function formatEvents(events, eventsLimit) {
|
|
137
|
+
if (events.length === 0)
|
|
138
|
+
return 'No stack events found.';
|
|
139
|
+
const chronological = toChronological(events);
|
|
140
|
+
const header = eventsLimit > 0
|
|
141
|
+
? `Showing up to ${eventsLimit} events in chronological order.`
|
|
142
|
+
: 'Showing all events in chronological order.';
|
|
143
|
+
return `${header}\n\n${chronological.map((event) => formatEvent(event)).join('\n\n')}`;
|
|
144
|
+
}
|
|
145
|
+
function stackDetailsJson(stack) {
|
|
146
|
+
return JSON.stringify(stack, (_key, value) => value instanceof Date ? value.toISOString() : value, 2);
|
|
147
|
+
}
|
|
148
|
+
function stackSummary(stack) {
|
|
149
|
+
const lines = [
|
|
150
|
+
`StackName: ${stack.StackName ?? '—'}`,
|
|
151
|
+
`StackId: ${stack.StackId ?? '—'}`,
|
|
152
|
+
`Status: ${stack.StackStatus ?? '—'}`,
|
|
153
|
+
`StatusReason: ${stack.StackStatusReason ?? '—'}`,
|
|
154
|
+
`CreatedAt: ${toIso(stack.CreationTime)}`,
|
|
155
|
+
`UpdatedAt: ${toIso(stack.LastUpdatedTime)}`,
|
|
156
|
+
`DriftStatus: ${stack.DriftInformation?.StackDriftStatus ?? '—'}`,
|
|
157
|
+
`EnableTerminationProtection: ${stack.EnableTerminationProtection ?? false}`,
|
|
158
|
+
];
|
|
159
|
+
return lines.join('\n');
|
|
160
|
+
}
|
|
161
|
+
function buildSections(stack, templateBody, events, options) {
|
|
162
|
+
const failures = getFailureEvents(toChronological(events));
|
|
163
|
+
const sections = [
|
|
164
|
+
{ title: 'Stack Summary', body: stackSummary(stack) },
|
|
165
|
+
{ title: 'Stack Details (Raw JSON)', body: stackDetailsJson(stack) },
|
|
166
|
+
{ title: 'Parameters', body: formatParameters(stack) },
|
|
167
|
+
{ title: 'Outputs', body: formatOutputs(stack) },
|
|
168
|
+
{ title: 'Likely Root Causes', body: formatRootCauses(failures) },
|
|
169
|
+
{ title: 'Failure Events', body: formatFailureEvents(failures) },
|
|
170
|
+
{ title: 'Events', body: formatEvents(events, options.eventsLimit) },
|
|
171
|
+
{ title: 'Full Deployed Template', body: templateBody || 'Template body is empty.' },
|
|
172
|
+
];
|
|
173
|
+
return sections;
|
|
174
|
+
}
|
|
175
|
+
function buildReport(sections) {
|
|
176
|
+
return [
|
|
177
|
+
'awscfn inspect-stack',
|
|
178
|
+
'='.repeat(20),
|
|
179
|
+
'',
|
|
180
|
+
...sections.map((section) => formatSection(section.title, section.body)),
|
|
181
|
+
].join('\n\n');
|
|
182
|
+
}
|
|
183
|
+
async function inspectStack(stackName, options) {
|
|
184
|
+
cfn.initCloudFormationClient();
|
|
185
|
+
const resolvedOptions = { ...DEFAULT_OPTIONS, ...options };
|
|
186
|
+
const stack = await cfn.getStackByName(stackName, true);
|
|
187
|
+
if (!stack)
|
|
188
|
+
throw new Error(`stack ${stackName} does not exist`);
|
|
189
|
+
const [templateBody, events] = await Promise.all([
|
|
190
|
+
cfn.getStackTemplateBody(stackName),
|
|
191
|
+
cfn.listStackEvents(stackName, resolvedOptions.eventsLimit),
|
|
192
|
+
]);
|
|
193
|
+
const sections = buildSections(stack, templateBody, events, resolvedOptions);
|
|
194
|
+
if (resolvedOptions.usePager) {
|
|
195
|
+
const didShowTui = await (0, viewInspectTui_1.viewInspectTui)(sections, {
|
|
196
|
+
title: `awscfn inspect-stack: ${stackName}`,
|
|
197
|
+
subtitle: [
|
|
198
|
+
'Tab switches focus.',
|
|
199
|
+
'Up/Down navigates.',
|
|
200
|
+
'PgUp/PgDn scrolls.',
|
|
201
|
+
'q quits.',
|
|
202
|
+
].join(' '),
|
|
203
|
+
});
|
|
204
|
+
if (didShowTui) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
const report = buildReport(sections);
|
|
209
|
+
(0, viewText_1.viewText)(`inspect-${stackName}`, report, { usePager: resolvedOptions.usePager });
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=inspectStack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspectStack.js","sourceRoot":"","sources":["../src/inspectStack.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgPA,oCA2CC;AA1RD,+CAAiC;AACjC,6CAAwC;AACxC,yDAAuE;AAcvE,MAAM,eAAe,GAAwB;IACzC,WAAW,EAAE,GAAG;IAChB,QAAQ,EAAE,IAAI;CACjB,CAAC;AAEF,MAAM,wBAAwB,GAAG;IAC7B,8BAA8B;IAC9B,4BAA4B;IAC5B,qCAAqC;IACrC,iBAAiB;CACpB,CAAC;AAEF,SAAS,KAAK,CAAC,KAAY;IAEvB,IAAI,CAAC,KAAK,EAAE,CAAC;QAET,OAAO,GAAG,CAAC;IAEf,CAAC;IAED,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;AAE/B,CAAC;AAED,SAAS,WAAW,CAAC,KAAiB;IAElC,OAAO,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AAE3C,CAAC;AAED,SAAS,eAAe,CAAC,MAAoB;IAEzC,OAAO,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;AAExF,CAAC;AAED,SAAS,eAAe,CAAC,MAAc;IAEnC,OAAO,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AAEpE,CAAC;AAED,SAAS,sBAAsB,CAAC,MAAc;IAE1C,OAAO,wBAAwB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAE5E,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAoB;IAE1C,MAAM,GAAG,GAA0B,EAAE,CAAC;IAEtC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAEzB,MAAM,MAAM,GAAG,KAAK,CAAC,cAAc,IAAI,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,oBAAoB,IAAI,EAAE,CAAC;QAEhD,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM;YAAE,SAAS;QAElD,GAAG,CAAC,IAAI,CAAC;YACL,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC;YACjC,QAAQ,EAAE,GAAG,KAAK,CAAC,iBAAiB,IAAI,SAAS,KAAK,KAAK,CAAC,YAAY,IAAI,SAAS,GAAG;YACxF,MAAM;YACN,MAAM;SACT,CAAC,CAAC;IAEP,CAAC;IAED,OAAO,GAAG,CAAC;AAEf,CAAC;AAED,SAAS,yBAAyB,CAAC,QAA+B;IAE9D,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,MAAM,UAAU,GAA0B,EAAE,CAAC;IAE7C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAE7B,IAAI,sBAAsB,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,SAAS;QAExF,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAChC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAE7B,CAAC;IAED,OAAO,UAAU,CAAC;AAEtB,CAAC;AAED,SAAS,aAAa,CAAC,KAAa,EAAE,IAAY;IAE9C,OAAO,GAAG,KAAK,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;AAE5D,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAY;IAElC,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC;IAEtC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,yBAAyB,CAAC;IAE1D,OAAO,MAAM;SACR,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,YAAY,IAAI,SAAS,KAAK,KAAK,CAAC,cAAc,IAAI,qBAAqB,EAAE,CAAC;SACtG,IAAI,CAAC,IAAI,CAAC,CAAC;AAEpB,CAAC;AAED,SAAS,aAAa,CAAC,KAAY;IAE/B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;IAEpC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,sBAAsB,CAAC;IAExD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,SAAS,IAAI,SAAS,KAAK,MAAM,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAE/G,CAAC;AAED,SAAS,gBAAgB,CAAC,QAA+B;IAErD,MAAM,UAAU,GAAG,yBAAyB,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEpE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,yCAAyC,CAAC;IAE9E,OAAO,UAAU;SACZ,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,eAAe,OAAO,CAAC,MAAM,EAAE,CAAC;SAC7G,IAAI,CAAC,MAAM,CAAC,CAAC;AAEtB,CAAC;AAED,SAAS,mBAAmB,CAAC,QAA+B;IAExD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,0BAA0B,CAAC;IAE7D,OAAO,QAAQ;SACV,KAAK,CAAC,CAAC,EAAE,CAAC;SACV,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,eAAe,OAAO,CAAC,MAAM,EAAE,CAAC;SAC7G,IAAI,CAAC,MAAM,CAAC,CAAC;AAEtB,CAAC;AAED,SAAS,WAAW,CAAC,KAAiB;IAElC,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,KAAK,CAAC,cAAc,IAAI,SAAS,CAAC;IACjD,MAAM,OAAO,GAAG,KAAK,CAAC,iBAAiB,IAAI,SAAS,CAAC;IACrD,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,IAAI,SAAS,CAAC;IAC7C,MAAM,MAAM,GAAG,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC,eAAe,KAAK,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAE7F,OAAO,IAAI,SAAS,KAAK,MAAM,IAAI,OAAO,KAAK,IAAI,IAAI,MAAM,EAAE,CAAC;AAEpE,CAAC;AAED,SAAS,YAAY,CAAC,MAAoB,EAAE,WAAmB;IAE3D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,wBAAwB,CAAC;IAEzD,MAAM,aAAa,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,WAAW,GAAG,CAAC;QAC1B,CAAC,CAAC,iBAAiB,WAAW,iCAAiC;QAC/D,CAAC,CAAC,4CAA4C,CAAC;IAEnD,OAAO,GAAG,MAAM,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;AAE3F,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAY;IAElC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAE1G,CAAC;AAED,SAAS,YAAY,CAAC,KAAY;IAE9B,MAAM,KAAK,GAAG;QACV,cAAc,KAAK,CAAC,SAAS,IAAI,GAAG,EAAE;QACtC,YAAY,KAAK,CAAC,OAAO,IAAI,GAAG,EAAE;QAClC,WAAW,KAAK,CAAC,WAAW,IAAI,GAAG,EAAE;QACrC,iBAAiB,KAAK,CAAC,iBAAiB,IAAI,GAAG,EAAE;QACjD,cAAc,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;QACzC,cAAc,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE;QAC5C,gBAAgB,KAAK,CAAC,gBAAgB,EAAE,gBAAgB,IAAI,GAAG,EAAE;QACjE,gCAAgC,KAAK,CAAC,2BAA2B,IAAI,KAAK,EAAE;KAC/E,CAAC;IAEF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAE5B,CAAC;AAED,SAAS,aAAa,CAClB,KAAY,EACZ,YAAoB,EACpB,MAAoB,EACpB,OAA4B;IAG5B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAwB;QAClC,EAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,EAAC;QACnD,EAAC,KAAK,EAAE,0BAA0B,EAAE,IAAI,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAAC;QAClE,EAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAAC;QACpD,EAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,EAAC;QAC9C,EAAC,KAAK,EAAE,oBAAoB,EAAE,IAAI,EAAE,gBAAgB,CAAC,QAAQ,CAAC,EAAC;QAC/D,EAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,mBAAmB,CAAC,QAAQ,CAAC,EAAC;QAC9D,EAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,EAAC;QAClE,EAAC,KAAK,EAAE,wBAAwB,EAAE,IAAI,EAAE,YAAY,IAAI,yBAAyB,EAAC;KACrF,CAAC;IAEF,OAAO,QAAQ,CAAC;AAEpB,CAAC;AAED,SAAS,WAAW,CAAC,QAA6B;IAE9C,OAAO;QACH,sBAAsB;QACtB,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACd,EAAE;QACF,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;KAC3E,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAEnB,CAAC;AAEM,KAAK,UAAU,YAAY,CAC9B,SAAiB,EACjB,OAAsC;IAGtC,GAAG,CAAC,wBAAwB,EAAE,CAAC;IAE/B,MAAM,eAAe,GAAG,EAAC,GAAG,eAAe,EAAE,GAAG,OAAO,EAAC,CAAC;IACzD,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAExD,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,SAAS,SAAS,iBAAiB,CAAC,CAAC;IAEjE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC7C,GAAG,CAAC,oBAAoB,CAAC,SAAS,CAAC;QACnC,GAAG,CAAC,eAAe,CAAC,SAAS,EAAE,eAAe,CAAC,WAAW,CAAC;KAC9D,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;IAE7E,IAAI,eAAe,CAAC,QAAQ,EAAE,CAAC;QAE3B,MAAM,UAAU,GAAG,MAAM,IAAA,+BAAc,EAAC,QAAQ,EAAE;YAC9C,KAAK,EAAE,yBAAyB,SAAS,EAAE;YAC3C,QAAQ,EAAE;gBACN,qBAAqB;gBACrB,oBAAoB;gBACpB,oBAAoB;gBACpB,UAAU;aACb,CAAC,IAAI,CAAC,GAAG,CAAC;SACd,CAAC,CAAC;QAEH,IAAI,UAAU,EAAE,CAAC;YAEb,OAAO;QAEX,CAAC;IAEL,CAAC;IAED,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IAErC,IAAA,mBAAQ,EAAC,WAAW,SAAS,EAAE,EAAE,MAAM,EAAE,EAAC,QAAQ,EAAE,eAAe,CAAC,QAAQ,EAAC,CAAC,CAAC;AAEnF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getStackTemplate.d.ts","sourceRoot":"","sources":["../../../src/lib/cfn/getStackTemplate.ts"],"names":[],"mappings":"AAiCA,wBAAsB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAY7E"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getStackTemplateBody = getStackTemplateBody;
|
|
4
|
+
const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
|
|
5
|
+
const _1 = require(".");
|
|
6
|
+
function toTemplateString(templateBody) {
|
|
7
|
+
if (typeof templateBody === 'string') {
|
|
8
|
+
return templateBody;
|
|
9
|
+
}
|
|
10
|
+
if (!templateBody) {
|
|
11
|
+
return '';
|
|
12
|
+
}
|
|
13
|
+
return JSON.stringify(templateBody, null, 2);
|
|
14
|
+
}
|
|
15
|
+
async function fetchTemplate(stage, stackName) {
|
|
16
|
+
const cf = (0, _1.getCfClient)();
|
|
17
|
+
const response = await cf.send(new client_cloudformation_1.GetTemplateCommand({
|
|
18
|
+
StackName: stackName,
|
|
19
|
+
TemplateStage: stage,
|
|
20
|
+
}));
|
|
21
|
+
return toTemplateString(response.TemplateBody);
|
|
22
|
+
}
|
|
23
|
+
async function getStackTemplateBody(stackName) {
|
|
24
|
+
const original = await fetchTemplate('Original', stackName);
|
|
25
|
+
if (original) {
|
|
26
|
+
return original;
|
|
27
|
+
}
|
|
28
|
+
return fetchTemplate('Processed', stackName);
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=getStackTemplate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getStackTemplate.js","sourceRoot":"","sources":["../../../src/lib/cfn/getStackTemplate.ts"],"names":[],"mappings":";;AAiCA,oDAYC;AA7CD,0EAAkE;AAClE,wBAA8B;AAE9B,SAAS,gBAAgB,CAAC,YAAqB;IAE3C,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;QAEnC,OAAO,YAAY,CAAC;IAExB,CAAC;IAED,IAAI,CAAC,YAAY,EAAE,CAAC;QAEhB,OAAO,EAAE,CAAC;IAEd,CAAC;IAED,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAEjD,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,KAA6B,EAAE,SAAiB;IAEzE,MAAM,EAAE,GAAG,IAAA,cAAW,GAAE,CAAC;IACzB,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,0CAAkB,CAAC;QAClD,SAAS,EAAE,SAAS;QACpB,aAAa,EAAE,KAAK;KACvB,CAAC,CAAC,CAAC;IAEJ,OAAO,gBAAgB,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;AAEnD,CAAC;AAEM,KAAK,UAAU,oBAAoB,CAAC,SAAiB;IAExD,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAE5D,IAAI,QAAQ,EAAE,CAAC;QAEX,OAAO,QAAQ,CAAC;IAEpB,CAAC;IAED,OAAO,aAAa,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;AAEjD,CAAC"}
|
package/dist/lib/cfn/index.d.ts
CHANGED
|
@@ -18,4 +18,6 @@ export * from './isStackTerminal';
|
|
|
18
18
|
export * from './waitUntilStackTerminal';
|
|
19
19
|
export * from './getParamFromStack';
|
|
20
20
|
export * from './streamStackEvents';
|
|
21
|
+
export * from './getStackTemplate';
|
|
22
|
+
export * from './listStackEvents';
|
|
21
23
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/cfn/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,oBAAoB,EAAC,MAAM,gCAAgC,CAAC;AAEpE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACjD,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,cAAc,IAAI;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,CAAC,CAAA;CACZ,GAAG,MAAM,CAAC;AAIX,wBAAgB,wBAAwB,IAAI,IAAI,CAI/C;AAED,wBAAgB,WAAW,IAAI,oBAAoB,CAMlD;AAED,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/cfn/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,oBAAoB,EAAC,MAAM,gCAAgC,CAAC;AAEpE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACjD,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,cAAc,IAAI;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,CAAC,CAAA;CACZ,GAAG,MAAM,CAAC;AAIX,wBAAgB,wBAAwB,IAAI,IAAI,CAI/C;AAED,wBAAgB,WAAW,IAAI,oBAAoB,CAMlD;AAED,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC"}
|
package/dist/lib/cfn/index.js
CHANGED
|
@@ -38,4 +38,6 @@ __exportStar(require("./isStackTerminal"), exports);
|
|
|
38
38
|
__exportStar(require("./waitUntilStackTerminal"), exports);
|
|
39
39
|
__exportStar(require("./getParamFromStack"), exports);
|
|
40
40
|
__exportStar(require("./streamStackEvents"), exports);
|
|
41
|
+
__exportStar(require("./getStackTemplate"), exports);
|
|
42
|
+
__exportStar(require("./listStackEvents"), exports);
|
|
41
43
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/cfn/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAUA,4DAIC;AAED,kCAMC;AAtBD,0EAAoE;AAQpE,IAAI,EAAkC,CAAC;AAEvC,SAAgB,wBAAwB;IAEpC,EAAE,GAAG,IAAI,4CAAoB,EAAE,CAAC;AAEpC,CAAC;AAED,SAAgB,WAAW;IAEvB,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAElE,OAAO,EAAE,CAAC;AAEd,CAAC;AAED,gDAA8B;AAC9B,mDAAiC;AACjC,+CAA6B;AAC7B,qDAAmC;AACnC,gDAA8B;AAC9B,gDAA8B;AAC9B,qDAAmC;AACnC,sDAAoC;AACpC,oDAAkC;AAClC,2DAAyC;AACzC,sDAAoC;AACpC,sDAAoC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/cfn/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAUA,4DAIC;AAED,kCAMC;AAtBD,0EAAoE;AAQpE,IAAI,EAAkC,CAAC;AAEvC,SAAgB,wBAAwB;IAEpC,EAAE,GAAG,IAAI,4CAAoB,EAAE,CAAC;AAEpC,CAAC;AAED,SAAgB,WAAW;IAEvB,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAElE,OAAO,EAAE,CAAC;AAEd,CAAC;AAED,gDAA8B;AAC9B,mDAAiC;AACjC,+CAA6B;AAC7B,qDAAmC;AACnC,gDAA8B;AAC9B,gDAA8B;AAC9B,qDAAmC;AACnC,sDAAoC;AACpC,oDAAkC;AAClC,2DAAyC;AACzC,sDAAoC;AACpC,sDAAoC;AACpC,qDAAmC;AACnC,oDAAkC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listStackEvents.d.ts","sourceRoot":"","sources":["../../../src/lib/cfn/listStackEvents.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,UAAU,EAAC,MAAM,gCAAgC,CAAC;AAetF,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,GAAE,MAAY,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAoBnG"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listStackEvents = listStackEvents;
|
|
4
|
+
const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
|
|
5
|
+
const _1 = require(".");
|
|
6
|
+
function trimToLimit(events, limit) {
|
|
7
|
+
if (limit <= 0) {
|
|
8
|
+
return events;
|
|
9
|
+
}
|
|
10
|
+
return events.slice(0, limit);
|
|
11
|
+
}
|
|
12
|
+
async function listStackEvents(stackName, limit = 500) {
|
|
13
|
+
const cf = (0, _1.getCfClient)();
|
|
14
|
+
const events = [];
|
|
15
|
+
let nextToken;
|
|
16
|
+
do {
|
|
17
|
+
const response = await cf.send(new client_cloudformation_1.DescribeStackEventsCommand({
|
|
18
|
+
StackName: stackName,
|
|
19
|
+
NextToken: nextToken,
|
|
20
|
+
}));
|
|
21
|
+
events.push(...(response.StackEvents ?? []));
|
|
22
|
+
nextToken = response.NextToken;
|
|
23
|
+
} while (nextToken && (limit <= 0 || events.length < limit));
|
|
24
|
+
return trimToLimit(events, limit);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=listStackEvents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listStackEvents.js","sourceRoot":"","sources":["../../../src/lib/cfn/listStackEvents.ts"],"names":[],"mappings":";;AAeA,0CAoBC;AAnCD,0EAAsF;AACtF,wBAA8B;AAE9B,SAAS,WAAW,CAAC,MAAoB,EAAE,KAAa;IAEpD,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QAEb,OAAO,MAAM,CAAC;IAElB,CAAC;IAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AAElC,CAAC;AAEM,KAAK,UAAU,eAAe,CAAC,SAAiB,EAAE,QAAgB,GAAG;IAExE,MAAM,EAAE,GAAG,IAAA,cAAW,GAAE,CAAC;IACzB,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,IAAI,SAA2B,CAAC;IAEhC,GAAG,CAAC;QAEA,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,kDAA0B,CAAC;YAC1D,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,SAAS;SACvB,CAAC,CAAC,CAAC;QAEJ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC;QAC7C,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC;IAEnC,CAAC,QAAQ,SAAS,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,EAAE;IAE7D,OAAO,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAEtC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface InspectTuiSection {
|
|
2
|
+
title: string;
|
|
3
|
+
body: string;
|
|
4
|
+
}
|
|
5
|
+
export interface InspectTuiOptions {
|
|
6
|
+
title: string;
|
|
7
|
+
subtitle: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function viewInspectTui(sections: InspectTuiSection[], options: InspectTuiOptions): Promise<boolean>;
|
|
10
|
+
//# sourceMappingURL=viewInspectTui.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewInspectTui.d.ts","sourceRoot":"","sources":["../../src/lib/viewInspectTui.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,iBAAiB;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACnB;AAugBD,wBAAsB,cAAc,CAChC,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,OAAO,EAAE,iBAAiB,GAC3B,OAAO,CAAC,OAAO,CAAC,CAYlB"}
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.viewInspectTui = viewInspectTui;
|
|
4
|
+
const node_process_1 = require("node:process");
|
|
5
|
+
const MIN_WIDTH = 70;
|
|
6
|
+
const MIN_HEIGHT = 16;
|
|
7
|
+
const KEY_PAGE_UP = '\u001b[5~';
|
|
8
|
+
const KEY_PAGE_DOWN = '\u001b[6~';
|
|
9
|
+
const KEY_ARROW_UP = '\u001b[A';
|
|
10
|
+
const KEY_ARROW_DOWN = '\u001b[B';
|
|
11
|
+
const KEY_ARROW_LEFT = '\u001b[D';
|
|
12
|
+
const KEY_ARROW_RIGHT = '\u001b[C';
|
|
13
|
+
function supportsInteractiveTui() {
|
|
14
|
+
return node_process_1.stdin.isTTY === true
|
|
15
|
+
&& node_process_1.stdout.isTTY === true
|
|
16
|
+
&& process.env.CI !== 'true'
|
|
17
|
+
&& process.env.GITHUB_ACTIONS !== 'true';
|
|
18
|
+
}
|
|
19
|
+
function colorize(text, ansiCode, enabled) {
|
|
20
|
+
if (!enabled)
|
|
21
|
+
return text;
|
|
22
|
+
return `${ansiCode}${text}\x1b[0m`;
|
|
23
|
+
}
|
|
24
|
+
function highlightStatusToken(token, useColor) {
|
|
25
|
+
if (/FAILED|ROLLBACK/.test(token)) {
|
|
26
|
+
return colorize(token, '\x1b[31m', useColor);
|
|
27
|
+
}
|
|
28
|
+
if (/COMPLETE|SUCCEEDED/.test(token)) {
|
|
29
|
+
return colorize(token, '\x1b[32m', useColor);
|
|
30
|
+
}
|
|
31
|
+
if (/IN_PROGRESS|PENDING/.test(token)) {
|
|
32
|
+
return colorize(token, '\x1b[33m', useColor);
|
|
33
|
+
}
|
|
34
|
+
return token;
|
|
35
|
+
}
|
|
36
|
+
function highlightStatusTerms(line, useColor) {
|
|
37
|
+
return line.replace(/\b[A-Z]+(?:_[A-Z]+)+\b/g, (token) => highlightStatusToken(token, useColor));
|
|
38
|
+
}
|
|
39
|
+
function highlightTimestamp(line, useColor) {
|
|
40
|
+
return line.replace(/\[(\d{4}-\d{2}-\d{2}T[^\]]+)\]/g, (_match, timestamp) => colorize(`[${timestamp}]`, '\x1b[90m', useColor));
|
|
41
|
+
}
|
|
42
|
+
function highlightKeyValueLine(line, useColor) {
|
|
43
|
+
const jsonMatch = line.match(/^(\s*)"([^"]+)"(\s*:.*)$/);
|
|
44
|
+
if (jsonMatch) {
|
|
45
|
+
const [, indent, key, suffix] = jsonMatch;
|
|
46
|
+
return `${indent}${colorize(`"${key}"`, '\x1b[36m', useColor)}${suffix}`;
|
|
47
|
+
}
|
|
48
|
+
const kvMatch = line.match(/^(\s*)([A-Za-z][A-Za-z0-9_\-. ()/]*)(:\s*.*)$/);
|
|
49
|
+
if (!kvMatch)
|
|
50
|
+
return line;
|
|
51
|
+
const [, indent, key, suffix] = kvMatch;
|
|
52
|
+
return `${indent}${colorize(key, '\x1b[36m', useColor)}${suffix}`;
|
|
53
|
+
}
|
|
54
|
+
function highlightLabels(line, useColor) {
|
|
55
|
+
return line.replace(/\bReason:/g, () => colorize('Reason:', '\x1b[33m', useColor));
|
|
56
|
+
}
|
|
57
|
+
function styleContentLine(line, sectionTitle, useColor) {
|
|
58
|
+
let styled = line;
|
|
59
|
+
if (sectionTitle.includes('Raw JSON') || sectionTitle.includes('Template') || line.includes(':')) {
|
|
60
|
+
styled = highlightKeyValueLine(styled, useColor);
|
|
61
|
+
}
|
|
62
|
+
styled = highlightTimestamp(styled, useColor);
|
|
63
|
+
styled = highlightStatusTerms(styled, useColor);
|
|
64
|
+
styled = highlightLabels(styled, useColor);
|
|
65
|
+
return styled;
|
|
66
|
+
}
|
|
67
|
+
function truncateText(text, width) {
|
|
68
|
+
if (width <= 0)
|
|
69
|
+
return '';
|
|
70
|
+
if (text.length <= width)
|
|
71
|
+
return text;
|
|
72
|
+
if (width <= 3)
|
|
73
|
+
return text.slice(0, width);
|
|
74
|
+
return `${text.slice(0, width - 3)}...`;
|
|
75
|
+
}
|
|
76
|
+
function padText(text, width) {
|
|
77
|
+
if (text.length >= width)
|
|
78
|
+
return text;
|
|
79
|
+
return `${text}${' '.repeat(width - text.length)}`;
|
|
80
|
+
}
|
|
81
|
+
function fitLine(text, width) {
|
|
82
|
+
return padText(truncateText(text, width), width);
|
|
83
|
+
}
|
|
84
|
+
function wrapLine(line, width) {
|
|
85
|
+
if (line.length === 0)
|
|
86
|
+
return [''];
|
|
87
|
+
const out = [];
|
|
88
|
+
let offset = 0;
|
|
89
|
+
while (offset < line.length) {
|
|
90
|
+
out.push(line.slice(offset, offset + width));
|
|
91
|
+
offset += width;
|
|
92
|
+
}
|
|
93
|
+
return out;
|
|
94
|
+
}
|
|
95
|
+
function wrapBody(body, width) {
|
|
96
|
+
const lines = body.replace(/\r\n/g, '\n').split('\n');
|
|
97
|
+
const wrapped = [];
|
|
98
|
+
for (const line of lines) {
|
|
99
|
+
wrapped.push(...wrapLine(line, width));
|
|
100
|
+
}
|
|
101
|
+
return wrapped;
|
|
102
|
+
}
|
|
103
|
+
function getLayout() {
|
|
104
|
+
const width = Math.max(40, node_process_1.stdout.columns ?? 80);
|
|
105
|
+
const height = Math.max(10, node_process_1.stdout.rows ?? 24);
|
|
106
|
+
const sidebarWidth = Math.max(18, Math.min(30, Math.floor(width * 0.28)));
|
|
107
|
+
const contentWidth = Math.max(20, width - sidebarWidth - 3);
|
|
108
|
+
const bodyHeight = Math.max(3, height - 5);
|
|
109
|
+
return { width, height, sidebarWidth, contentWidth, bodyHeight };
|
|
110
|
+
}
|
|
111
|
+
function isLayoutTooSmall(layout) {
|
|
112
|
+
return layout.width < MIN_WIDTH || layout.height < MIN_HEIGHT;
|
|
113
|
+
}
|
|
114
|
+
function currentContentLines(state, layout) {
|
|
115
|
+
const section = state.sections[state.activeSectionIndex];
|
|
116
|
+
return wrapBody(section.body, layout.contentWidth);
|
|
117
|
+
}
|
|
118
|
+
function maxScrollOffset(contentLines, layout) {
|
|
119
|
+
return Math.max(0, contentLines.length - layout.bodyHeight);
|
|
120
|
+
}
|
|
121
|
+
function sectionWindowStart(state, layout) {
|
|
122
|
+
const maxStart = Math.max(0, state.sections.length - layout.bodyHeight);
|
|
123
|
+
const preferred = Math.max(0, state.activeSectionIndex - Math.floor(layout.bodyHeight / 2));
|
|
124
|
+
return Math.min(preferred, maxStart);
|
|
125
|
+
}
|
|
126
|
+
function renderSidebarLine(title, isActive, hasFocus, width, useColor) {
|
|
127
|
+
const marker = isActive ? '>' : ' ';
|
|
128
|
+
const content = fitLine(`${marker} ${title}`, width);
|
|
129
|
+
if (!isActive)
|
|
130
|
+
return content;
|
|
131
|
+
if (hasFocus)
|
|
132
|
+
return colorize(content, '\x1b[1;36m', useColor);
|
|
133
|
+
return colorize(content, '\x1b[36m', useColor);
|
|
134
|
+
}
|
|
135
|
+
function renderHeader(state, layout) {
|
|
136
|
+
const title = colorize(fitLine(state.options.title, layout.width), '\x1b[1;37m', state.useColor);
|
|
137
|
+
const subtitle = colorize(fitLine(state.options.subtitle, layout.width), '\x1b[90m', state.useColor);
|
|
138
|
+
const divider = colorize('-'.repeat(layout.width), '\x1b[90m', state.useColor);
|
|
139
|
+
return [title, subtitle, divider];
|
|
140
|
+
}
|
|
141
|
+
function renderBody(state, layout, contentLines) {
|
|
142
|
+
const start = sectionWindowStart(state, layout);
|
|
143
|
+
const visibleContent = contentLines.slice(state.scrollOffset, state.scrollOffset + layout.bodyHeight);
|
|
144
|
+
const rows = [];
|
|
145
|
+
const activeSection = state.sections[state.activeSectionIndex];
|
|
146
|
+
const divider = colorize('|', '\x1b[90m', state.useColor);
|
|
147
|
+
for (let row = 0; row < layout.bodyHeight; row++) {
|
|
148
|
+
const section = state.sections[start + row];
|
|
149
|
+
const left = section
|
|
150
|
+
? renderSidebarLine(section.title, start + row === state.activeSectionIndex, state.focusMode === 'sections', layout.sidebarWidth, state.useColor)
|
|
151
|
+
: fitLine('', layout.sidebarWidth);
|
|
152
|
+
const rightPlain = fitLine(visibleContent[row] ?? '', layout.contentWidth);
|
|
153
|
+
const right = styleContentLine(rightPlain, activeSection.title, state.useColor);
|
|
154
|
+
rows.push(`${left} ${divider} ${right}`);
|
|
155
|
+
}
|
|
156
|
+
return rows;
|
|
157
|
+
}
|
|
158
|
+
function renderFooter(state, layout, contentLines) {
|
|
159
|
+
const divider = colorize('-'.repeat(layout.width), '\x1b[90m', state.useColor);
|
|
160
|
+
const maxScroll = maxScrollOffset(contentLines, layout);
|
|
161
|
+
const startLine = contentLines.length === 0 ? 0 : state.scrollOffset + 1;
|
|
162
|
+
const endLine = Math.min(contentLines.length, state.scrollOffset + layout.bodyHeight);
|
|
163
|
+
const status = [
|
|
164
|
+
`Section ${state.activeSectionIndex + 1}/${state.sections.length}`,
|
|
165
|
+
`Lines ${startLine}-${endLine}/${Math.max(contentLines.length, 1)}`,
|
|
166
|
+
`Focus ${state.focusMode}`,
|
|
167
|
+
'Tab switch focus',
|
|
168
|
+
'Arrows navigate',
|
|
169
|
+
'PgUp/PgDn scroll',
|
|
170
|
+
'q quit',
|
|
171
|
+
maxScroll > 0 ? '' : 'No scroll',
|
|
172
|
+
].filter(Boolean).join(' | ');
|
|
173
|
+
return [divider, colorize(fitLine(status, layout.width), '\x1b[90m', state.useColor)];
|
|
174
|
+
}
|
|
175
|
+
function smallTerminalFrame(layout) {
|
|
176
|
+
const lines = [
|
|
177
|
+
fitLine('awscfn inspect-stack', layout.width),
|
|
178
|
+
fitLine('', layout.width),
|
|
179
|
+
fitLine(`Terminal too small (${layout.width}x${layout.height}) for interactive mode.`, layout.width),
|
|
180
|
+
fitLine(`Resize to at least ${MIN_WIDTH}x${MIN_HEIGHT}, or use --no-pager.`, layout.width),
|
|
181
|
+
fitLine('', layout.width),
|
|
182
|
+
fitLine('Press q to quit.', layout.width),
|
|
183
|
+
];
|
|
184
|
+
return lines.join('\n');
|
|
185
|
+
}
|
|
186
|
+
function buildFrame(state) {
|
|
187
|
+
const layout = getLayout();
|
|
188
|
+
if (isLayoutTooSmall(layout)) {
|
|
189
|
+
return smallTerminalFrame(layout);
|
|
190
|
+
}
|
|
191
|
+
const contentLines = currentContentLines(state, layout);
|
|
192
|
+
const lines = [
|
|
193
|
+
...renderHeader(state, layout),
|
|
194
|
+
...renderBody(state, layout, contentLines),
|
|
195
|
+
...renderFooter(state, layout, contentLines),
|
|
196
|
+
];
|
|
197
|
+
return lines.join('\n');
|
|
198
|
+
}
|
|
199
|
+
function normalizeKey(input) {
|
|
200
|
+
if (input === '\u0003')
|
|
201
|
+
return 'QUIT';
|
|
202
|
+
if (input === '\u001b' || input === 'q')
|
|
203
|
+
return 'QUIT';
|
|
204
|
+
if (input === '\t')
|
|
205
|
+
return 'TAB';
|
|
206
|
+
if (input === KEY_ARROW_UP || input === 'k')
|
|
207
|
+
return 'UP';
|
|
208
|
+
if (input === KEY_ARROW_DOWN || input === 'j')
|
|
209
|
+
return 'DOWN';
|
|
210
|
+
if (input === KEY_ARROW_LEFT || input === 'h')
|
|
211
|
+
return 'LEFT';
|
|
212
|
+
if (input === KEY_ARROW_RIGHT || input === 'l')
|
|
213
|
+
return 'RIGHT';
|
|
214
|
+
if (input === KEY_PAGE_UP)
|
|
215
|
+
return 'PGUP';
|
|
216
|
+
if (input === KEY_PAGE_DOWN)
|
|
217
|
+
return 'PGDN';
|
|
218
|
+
if (input === 'g')
|
|
219
|
+
return 'HOME';
|
|
220
|
+
if (input === 'G')
|
|
221
|
+
return 'END';
|
|
222
|
+
return 'UNKNOWN';
|
|
223
|
+
}
|
|
224
|
+
function updateActiveSection(state, nextIndex) {
|
|
225
|
+
const clamped = Math.max(0, Math.min(state.sections.length - 1, nextIndex));
|
|
226
|
+
if (clamped === state.activeSectionIndex)
|
|
227
|
+
return false;
|
|
228
|
+
state.activeSectionIndex = clamped;
|
|
229
|
+
state.scrollOffset = 0;
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
232
|
+
function updateScroll(state, delta) {
|
|
233
|
+
const layout = getLayout();
|
|
234
|
+
const contentLines = currentContentLines(state, layout);
|
|
235
|
+
const max = maxScrollOffset(contentLines, layout);
|
|
236
|
+
const next = Math.max(0, Math.min(max, state.scrollOffset + delta));
|
|
237
|
+
if (next === state.scrollOffset)
|
|
238
|
+
return false;
|
|
239
|
+
state.scrollOffset = next;
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
function applyKey(state, key) {
|
|
243
|
+
if (key === 'QUIT')
|
|
244
|
+
return 'quit';
|
|
245
|
+
if (key === 'TAB') {
|
|
246
|
+
state.focusMode = state.focusMode === 'sections' ? 'content' : 'sections';
|
|
247
|
+
return 'rerender';
|
|
248
|
+
}
|
|
249
|
+
if (key === 'LEFT')
|
|
250
|
+
return updateActiveSection(state, state.activeSectionIndex - 1) ? 'rerender' : 'noop';
|
|
251
|
+
if (key === 'RIGHT')
|
|
252
|
+
return updateActiveSection(state, state.activeSectionIndex + 1) ? 'rerender' : 'noop';
|
|
253
|
+
if (key === 'HOME')
|
|
254
|
+
return updateScroll(state, Number.MIN_SAFE_INTEGER) ? 'rerender' : 'noop';
|
|
255
|
+
if (key === 'END')
|
|
256
|
+
return updateScroll(state, Number.MAX_SAFE_INTEGER) ? 'rerender' : 'noop';
|
|
257
|
+
if (key === 'PGUP')
|
|
258
|
+
return updateScroll(state, -Math.max(1, getLayout().bodyHeight - 1)) ? 'rerender' : 'noop';
|
|
259
|
+
if (key === 'PGDN')
|
|
260
|
+
return updateScroll(state, Math.max(1, getLayout().bodyHeight - 1)) ? 'rerender' : 'noop';
|
|
261
|
+
if (key === 'UP') {
|
|
262
|
+
return state.focusMode === 'sections'
|
|
263
|
+
? (updateActiveSection(state, state.activeSectionIndex - 1) ? 'rerender' : 'noop')
|
|
264
|
+
: (updateScroll(state, -1) ? 'rerender' : 'noop');
|
|
265
|
+
}
|
|
266
|
+
if (key === 'DOWN') {
|
|
267
|
+
return state.focusMode === 'sections'
|
|
268
|
+
? (updateActiveSection(state, state.activeSectionIndex + 1) ? 'rerender' : 'noop')
|
|
269
|
+
: (updateScroll(state, 1) ? 'rerender' : 'noop');
|
|
270
|
+
}
|
|
271
|
+
return 'noop';
|
|
272
|
+
}
|
|
273
|
+
function enterScreen() {
|
|
274
|
+
node_process_1.stdout.write('\x1b[?1049h');
|
|
275
|
+
node_process_1.stdout.write('\x1b[?25l');
|
|
276
|
+
node_process_1.stdout.write('\x1b[2J\x1b[H');
|
|
277
|
+
}
|
|
278
|
+
function leaveScreen() {
|
|
279
|
+
node_process_1.stdout.write('\x1b[?25h');
|
|
280
|
+
node_process_1.stdout.write('\x1b[?1049l');
|
|
281
|
+
}
|
|
282
|
+
function render(state) {
|
|
283
|
+
node_process_1.stdout.write('\x1b[2J\x1b[H');
|
|
284
|
+
node_process_1.stdout.write(buildFrame(state));
|
|
285
|
+
}
|
|
286
|
+
function createState(sections, options) {
|
|
287
|
+
return {
|
|
288
|
+
sections,
|
|
289
|
+
activeSectionIndex: 0,
|
|
290
|
+
scrollOffset: 0,
|
|
291
|
+
focusMode: 'sections',
|
|
292
|
+
options,
|
|
293
|
+
useColor: process.env.NO_COLOR === undefined,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
// eslint-disable-next-line max-lines-per-function
|
|
297
|
+
function startTuiSession(state, resolve) {
|
|
298
|
+
let finished = false;
|
|
299
|
+
function finish(value) {
|
|
300
|
+
if (finished)
|
|
301
|
+
return;
|
|
302
|
+
finished = true;
|
|
303
|
+
node_process_1.stdin.removeListener('data', onData);
|
|
304
|
+
node_process_1.stdout.removeListener('resize', onResize);
|
|
305
|
+
node_process_1.stdin.setRawMode(false);
|
|
306
|
+
node_process_1.stdin.pause();
|
|
307
|
+
leaveScreen();
|
|
308
|
+
resolve(value);
|
|
309
|
+
}
|
|
310
|
+
function onData(chunk) {
|
|
311
|
+
const key = normalizeKey(typeof chunk === 'string' ? chunk : chunk.toString('utf8'));
|
|
312
|
+
const action = applyKey(state, key);
|
|
313
|
+
if (action === 'quit') {
|
|
314
|
+
finish(true);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
if (action === 'rerender')
|
|
318
|
+
render(state);
|
|
319
|
+
}
|
|
320
|
+
function onResize() {
|
|
321
|
+
render(state);
|
|
322
|
+
}
|
|
323
|
+
try {
|
|
324
|
+
enterScreen();
|
|
325
|
+
node_process_1.stdin.setRawMode(true);
|
|
326
|
+
node_process_1.stdin.resume();
|
|
327
|
+
node_process_1.stdin.setEncoding('utf8');
|
|
328
|
+
node_process_1.stdin.on('data', onData);
|
|
329
|
+
node_process_1.stdout.on('resize', onResize);
|
|
330
|
+
render(state);
|
|
331
|
+
}
|
|
332
|
+
catch {
|
|
333
|
+
finish(false);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
async function viewInspectTui(sections, options) {
|
|
337
|
+
if (!supportsInteractiveTui() || sections.length === 0 || typeof node_process_1.stdin.setRawMode !== 'function') {
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
const state = createState(sections, options);
|
|
341
|
+
return new Promise((resolve) => startTuiSession(state, resolve));
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=viewInspectTui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewInspectTui.js","sourceRoot":"","sources":["../../src/lib/viewInspectTui.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewText.d.ts","sourceRoot":"","sources":["../../src/lib/viewText.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,eAAe;IAC5B,QAAQ,EAAE,OAAO,CAAA;CACpB;AA2DD,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CAyB5F"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.viewText = viewText;
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_os_1 = require("node:os");
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const node_child_process_1 = require("node:child_process");
|
|
11
|
+
function runViewerCommand(command, args) {
|
|
12
|
+
const result = (0, node_child_process_1.spawnSync)(command, args, { stdio: 'inherit' });
|
|
13
|
+
return !result.error && result.status === 0;
|
|
14
|
+
}
|
|
15
|
+
function runPagerExpression(pagerExpression, filePath) {
|
|
16
|
+
const result = (0, node_child_process_1.spawnSync)(`${pagerExpression} "${filePath}"`, {
|
|
17
|
+
shell: true,
|
|
18
|
+
stdio: 'inherit',
|
|
19
|
+
});
|
|
20
|
+
return !result.error && result.status === 0;
|
|
21
|
+
}
|
|
22
|
+
function openWithPager(filePath) {
|
|
23
|
+
const pagerExpression = process.env.GIT_PAGER ?? process.env.PAGER;
|
|
24
|
+
if (pagerExpression && runPagerExpression(pagerExpression, filePath)) {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
return runViewerCommand('less', ['-R', filePath]) || runViewerCommand('more', [filePath]);
|
|
28
|
+
}
|
|
29
|
+
function writeTempReport(reportName, content) {
|
|
30
|
+
const tempDir = (0, node_fs_1.mkdtempSync)(node_path_1.default.join((0, node_os_1.tmpdir)(), 'awscfn-'));
|
|
31
|
+
const safeName = reportName.replace(/[^a-zA-Z0-9-]/g, '-');
|
|
32
|
+
const filePath = node_path_1.default.join(tempDir, `${safeName}.txt`);
|
|
33
|
+
(0, node_fs_1.writeFileSync)(filePath, content, 'utf8');
|
|
34
|
+
return filePath;
|
|
35
|
+
}
|
|
36
|
+
function readAndPrint(filePath) {
|
|
37
|
+
console.log((0, node_fs_1.readFileSync)(filePath, 'utf8'));
|
|
38
|
+
}
|
|
39
|
+
function shouldPrintInline(usePager) {
|
|
40
|
+
return !usePager || !process.stdout.isTTY || process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true';
|
|
41
|
+
}
|
|
42
|
+
function viewText(reportName, content, options) {
|
|
43
|
+
if (shouldPrintInline(options.usePager)) {
|
|
44
|
+
console.log(content);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const filePath = writeTempReport(reportName, content);
|
|
48
|
+
try {
|
|
49
|
+
if (!openWithPager(filePath)) {
|
|
50
|
+
readAndPrint(filePath);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
(0, node_fs_1.rmSync)(node_path_1.default.dirname(filePath), { recursive: true, force: true });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=viewText.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewText.js","sourceRoot":"","sources":["../../src/lib/viewText.ts"],"names":[],"mappings":";;;;;AAkEA,4BAyBC;AA3FD,qCAAyE;AACzE,qCAA+B;AAC/B,0DAA6B;AAC7B,2DAA6C;AAM7C,SAAS,gBAAgB,CAAC,OAAe,EAAE,IAAc;IAErD,MAAM,MAAM,GAAG,IAAA,8BAAS,EAAC,OAAO,EAAE,IAAI,EAAE,EAAC,KAAK,EAAE,SAAS,EAAC,CAAC,CAAC;IAE5D,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;AAEhD,CAAC;AAED,SAAS,kBAAkB,CAAC,eAAuB,EAAE,QAAgB;IAEjE,MAAM,MAAM,GAAG,IAAA,8BAAS,EAAC,GAAG,eAAe,KAAK,QAAQ,GAAG,EAAE;QACzD,KAAK,EAAE,IAAI;QACX,KAAK,EAAE,SAAS;KACnB,CAAC,CAAC;IAEH,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;AAEhD,CAAC;AAED,SAAS,aAAa,CAAC,QAAgB;IAEnC,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;IAEnE,IAAI,eAAe,IAAI,kBAAkB,CAAC,eAAe,EAAE,QAAQ,CAAC,EAAE,CAAC;QAEnE,OAAO,IAAI,CAAC;IAEhB,CAAC;IAED,OAAO,gBAAgB,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,IAAI,gBAAgB,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AAE9F,CAAC;AAED,SAAS,eAAe,CAAC,UAAkB,EAAE,OAAe;IAExD,MAAM,OAAO,GAAG,IAAA,qBAAW,EAAC,mBAAI,CAAC,IAAI,CAAC,IAAA,gBAAM,GAAE,EAAE,SAAS,CAAC,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAG,mBAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,QAAQ,MAAM,CAAC,CAAC;IAEvD,IAAA,uBAAa,EAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAEzC,OAAO,QAAQ,CAAC;AAEpB,CAAC;AAED,SAAS,YAAY,CAAC,QAAgB;IAElC,OAAO,CAAC,GAAG,CAAC,IAAA,sBAAY,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAEhD,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAiB;IAExC,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM,CAAC;AAEpH,CAAC;AAED,SAAgB,QAAQ,CAAC,UAAkB,EAAE,OAAe,EAAE,OAAwB;IAElF,IAAI,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAEtC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrB,OAAO;IAEX,CAAC;IAED,MAAM,QAAQ,GAAG,eAAe,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAEtD,IAAI,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;YAE3B,YAAY,CAAC,QAAQ,CAAC,CAAC;QAE3B,CAAC;IAEL,CAAC;YAAS,CAAC;QAEP,IAAA,gBAAM,EAAC,mBAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAC,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAC,CAAC,CAAC;IAEnE,CAAC;AAEL,CAAC"}
|
package/package.json
CHANGED