@intentius/chant-lexicon-aws 0.18.14 → 0.18.16
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/dist/components/cloud-executor.d.ts +8 -0
- package/dist/components/cloud-executor.d.ts.map +1 -1
- package/dist/generated/index.d.ts +11 -0
- package/dist/generated/index.d.ts.map +1 -1
- package/dist/integrity.json +4 -4
- package/dist/manifest.json +1 -1
- package/dist/meta.json +108 -3
- package/dist/plugin.d.ts +4 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/types/index.d.ts +109 -4
- package/package.json +2 -2
- package/src/components/cloud-executor.test.ts +20 -1
- package/src/components/cloud-executor.ts +12 -0
- package/src/generated/index.d.ts +109 -4
- package/src/generated/index.ts +11 -0
- package/src/generated/lexicon-aws.json +108 -3
- package/src/import/live-export-io.test.ts +14 -4
- package/src/plugin.test.ts +13 -1
- package/src/plugin.ts +30 -7
package/src/generated/index.ts
CHANGED
|
@@ -697,6 +697,7 @@ export const IntegrationResourceProperty = createResource("AWS::Glue::Integratio
|
|
|
697
697
|
export const IntegrationResponse = createResource("AWS::ApiGatewayV2::IntegrationResponse", "aws", {"IntegrationResponseId":"IntegrationResponseId"});
|
|
698
698
|
export const IntelligentPromptRouter = createResource("AWS::Bedrock::IntelligentPromptRouter", "aws", {"CreatedAt":"CreatedAt","PromptRouterArn":"PromptRouterArn","Status":"Status","Type":"Type","UpdatedAt":"UpdatedAt"});
|
|
699
699
|
export const InterconnectConnection = createResource("AWS::Interconnect::Connection", "aws", {"ConnectionId":"ConnectionId","Arn":"Arn","Provider":"Provider","Type":"Type","State":"State","SharedId":"SharedId","OwnerAccount":"OwnerAccount","BillingTier":"BillingTier"});
|
|
700
|
+
export const IntermediateTable = createResource("AWS::CleanRooms::IntermediateTable", "aws", {"IntermediateTableIdentifier":"IntermediateTableIdentifier","Arn":"Arn","MembershipArn":"MembershipArn","CollaborationIdentifier":"CollaborationIdentifier","CollaborationArn":"CollaborationArn","Status":"Status"});
|
|
700
701
|
export const InternetGateway = createResource("AWS::EC2::InternetGateway", "aws", {"InternetGatewayId":"InternetGatewayId"});
|
|
701
702
|
export const InternetMonitorMonitor = createResource("AWS::InternetMonitor::Monitor", "aws", {"CreatedAt":"CreatedAt","ModifiedAt":"ModifiedAt","MonitorArn":"MonitorArn","ProcessingStatus":"ProcessingStatus","ProcessingStatusInfo":"ProcessingStatusInfo"});
|
|
702
703
|
export const InvestigationGroup = createResource("AWS::AIOps::InvestigationGroup", "aws", {"CreatedBy":"CreatedBy","CreatedAt":"CreatedAt","LastModifiedBy":"LastModifiedBy","LastModifiedAt":"LastModifiedAt","Arn":"Arn"});
|
|
@@ -5873,6 +5874,13 @@ export const InterconnectConnection_Tag = createProperty("AWS::Interconnect::Con
|
|
|
5873
5874
|
export const Interface = createProperty("AWS::MediaConnect::FlowOutput.Interface", "aws");
|
|
5874
5875
|
export const InterfaceMapping = createProperty("AWS::MediaLive::Cluster.InterfaceMapping", "aws");
|
|
5875
5876
|
export const IntermediateStorage = createProperty("AWS::Bedrock::DataSource.IntermediateStorage", "aws");
|
|
5877
|
+
export const IntermediateTable_IntermediateTableAnalysisRule = createProperty("AWS::CleanRooms::IntermediateTable.IntermediateTableAnalysisRule", "aws");
|
|
5878
|
+
export const IntermediateTable_IntermediateTableAnalysisRulePolicy = createProperty("AWS::CleanRooms::IntermediateTable.IntermediateTableAnalysisRulePolicy", "aws");
|
|
5879
|
+
export const IntermediateTable_PopulationAnalysisConfiguration = createProperty("AWS::CleanRooms::IntermediateTable.PopulationAnalysisConfiguration", "aws");
|
|
5880
|
+
export const IntermediateTable_PopulationAnalysisSqlParameters = createProperty("AWS::CleanRooms::IntermediateTable.PopulationAnalysisSqlParameters", "aws");
|
|
5881
|
+
export const IntermediateTable_Tag = createProperty("AWS::CleanRooms::IntermediateTable.Tag", "aws");
|
|
5882
|
+
export const IntermediateTableAnalysisRule = createProperty("AWS::CleanRooms::IntermediateTable.IntermediateTableAnalysisRule", "aws");
|
|
5883
|
+
export const IntermediateTableAnalysisRulePolicy = createProperty("AWS::CleanRooms::IntermediateTable.IntermediateTableAnalysisRulePolicy", "aws");
|
|
5876
5884
|
export const InternetGateway_Tag = createProperty("AWS::EC2::InternetGateway.Tag", "aws");
|
|
5877
5885
|
export const InternetMeasurementsLogDelivery = createProperty("AWS::InternetMonitor::Monitor.InternetMeasurementsLogDelivery", "aws");
|
|
5878
5886
|
export const InternetMonitorMonitor_HealthEventsConfig = createProperty("AWS::InternetMonitor::Monitor.HealthEventsConfig", "aws");
|
|
@@ -6427,6 +6435,7 @@ export const Listener_JwtValidationConfig = createProperty("AWS::ElasticLoadBala
|
|
|
6427
6435
|
export const Listener_ListenerAttribute = createProperty("AWS::ElasticLoadBalancingV2::Listener.ListenerAttribute", "aws");
|
|
6428
6436
|
export const Listener_MutualAuthentication = createProperty("AWS::ElasticLoadBalancingV2::Listener.MutualAuthentication", "aws");
|
|
6429
6437
|
export const Listener_RedirectConfig = createProperty("AWS::ElasticLoadBalancingV2::Listener.RedirectConfig", "aws");
|
|
6438
|
+
export const Listener_Tag = createProperty("AWS::ElasticLoadBalancingV2::Listener.Tag", "aws");
|
|
6430
6439
|
export const Listener_TargetGroupStickinessConfig = createProperty("AWS::ElasticLoadBalancingV2::Listener.TargetGroupStickinessConfig", "aws");
|
|
6431
6440
|
export const Listener_TargetGroupTuple = createProperty("AWS::ElasticLoadBalancingV2::Listener.TargetGroupTuple", "aws");
|
|
6432
6441
|
export const ListenerAttribute = createProperty("AWS::ElasticLoadBalancingV2::Listener.ListenerAttribute", "aws");
|
|
@@ -7919,6 +7928,8 @@ export const PolicyStore_ValidationSettings = createProperty("AWS::VerifiedPermi
|
|
|
7919
7928
|
export const PolicyTag = createProperty("AWS::FMS::Policy.PolicyTag", "aws");
|
|
7920
7929
|
export const Pool_OptionalKeyword = createProperty("AWS::SMSVOICE::Pool.OptionalKeyword", "aws");
|
|
7921
7930
|
export const Pool_Tag = createProperty("AWS::SMSVOICE::Pool.Tag", "aws");
|
|
7931
|
+
export const PopulationAnalysisConfiguration = createProperty("AWS::CleanRooms::IntermediateTable.PopulationAnalysisConfiguration", "aws");
|
|
7932
|
+
export const PopulationAnalysisSqlParameters = createProperty("AWS::CleanRooms::IntermediateTable.PopulationAnalysisSqlParameters", "aws");
|
|
7922
7933
|
export const Port = createProperty("AWS::Lightsail::Instance.Port", "aws");
|
|
7923
7934
|
export const Portal = createProperty("AWS::IoTSiteWise::AccessPolicy.Portal", "aws");
|
|
7924
7935
|
export const PortalOptionsConfiguration = createProperty("AWS::SSO::Application.PortalOptionsConfiguration", "aws");
|
|
@@ -8347,8 +8347,7 @@
|
|
|
8347
8347
|
"KmsKeyArn": "KmsKeyArn"
|
|
8348
8348
|
},
|
|
8349
8349
|
"createOnly": [
|
|
8350
|
-
"KmsKeyId"
|
|
8351
|
-
"ForceDelete"
|
|
8350
|
+
"KmsKeyId"
|
|
8352
8351
|
],
|
|
8353
8352
|
"writeOnly": [
|
|
8354
8353
|
"KmsKeyId",
|
|
@@ -49451,6 +49450,92 @@
|
|
|
49451
49450
|
"kind": "property",
|
|
49452
49451
|
"lexicon": "aws"
|
|
49453
49452
|
},
|
|
49453
|
+
"IntermediateTable": {
|
|
49454
|
+
"resourceType": "AWS::CleanRooms::IntermediateTable",
|
|
49455
|
+
"kind": "resource",
|
|
49456
|
+
"lexicon": "aws",
|
|
49457
|
+
"attrs": {
|
|
49458
|
+
"IntermediateTableIdentifier": "IntermediateTableIdentifier",
|
|
49459
|
+
"Arn": "Arn",
|
|
49460
|
+
"MembershipArn": "MembershipArn",
|
|
49461
|
+
"CollaborationIdentifier": "CollaborationIdentifier",
|
|
49462
|
+
"CollaborationArn": "CollaborationArn",
|
|
49463
|
+
"Status": "Status"
|
|
49464
|
+
},
|
|
49465
|
+
"propertyConstraints": {
|
|
49466
|
+
"Arn": {
|
|
49467
|
+
"maxLength": 256
|
|
49468
|
+
},
|
|
49469
|
+
"MembershipArn": {
|
|
49470
|
+
"maxLength": 100
|
|
49471
|
+
},
|
|
49472
|
+
"CollaborationArn": {
|
|
49473
|
+
"maxLength": 100
|
|
49474
|
+
},
|
|
49475
|
+
"Name": {
|
|
49476
|
+
"pattern": "^(?!\\s*$)[\\u0020-\\uD7FF\\uE000-\\uFFFD\\uD800\\uDBFF-\\uDC00\\uDFFF\\t]*$",
|
|
49477
|
+
"minLength": 1,
|
|
49478
|
+
"maxLength": 100
|
|
49479
|
+
},
|
|
49480
|
+
"Description": {
|
|
49481
|
+
"pattern": "^[\\u0020-\\uD7FF\\uE000-\\uFFFD\\uD800\\uDBFF-\\uDC00\\uDFFF\\t\\r\\n]*$",
|
|
49482
|
+
"maxLength": 255
|
|
49483
|
+
},
|
|
49484
|
+
"KmsKeyArn": {
|
|
49485
|
+
"minLength": 4,
|
|
49486
|
+
"maxLength": 2048
|
|
49487
|
+
}
|
|
49488
|
+
},
|
|
49489
|
+
"createOnly": [
|
|
49490
|
+
"MembershipIdentifier",
|
|
49491
|
+
"Name",
|
|
49492
|
+
"PopulationAnalysisConfiguration"
|
|
49493
|
+
],
|
|
49494
|
+
"primaryIdentifier": [
|
|
49495
|
+
"IntermediateTableIdentifier",
|
|
49496
|
+
"MembershipIdentifier"
|
|
49497
|
+
],
|
|
49498
|
+
"tagging": {
|
|
49499
|
+
"taggable": true,
|
|
49500
|
+
"tagOnCreate": true,
|
|
49501
|
+
"tagUpdatable": true
|
|
49502
|
+
}
|
|
49503
|
+
},
|
|
49504
|
+
"IntermediateTableAnalysisRule": {
|
|
49505
|
+
"resourceType": "AWS::CleanRooms::IntermediateTable.IntermediateTableAnalysisRule",
|
|
49506
|
+
"kind": "property",
|
|
49507
|
+
"lexicon": "aws"
|
|
49508
|
+
},
|
|
49509
|
+
"IntermediateTableAnalysisRulePolicy": {
|
|
49510
|
+
"resourceType": "AWS::CleanRooms::IntermediateTable.IntermediateTableAnalysisRulePolicy",
|
|
49511
|
+
"kind": "property",
|
|
49512
|
+
"lexicon": "aws"
|
|
49513
|
+
},
|
|
49514
|
+
"IntermediateTable_IntermediateTableAnalysisRule": {
|
|
49515
|
+
"resourceType": "AWS::CleanRooms::IntermediateTable.IntermediateTableAnalysisRule",
|
|
49516
|
+
"kind": "property",
|
|
49517
|
+
"lexicon": "aws"
|
|
49518
|
+
},
|
|
49519
|
+
"IntermediateTable_IntermediateTableAnalysisRulePolicy": {
|
|
49520
|
+
"resourceType": "AWS::CleanRooms::IntermediateTable.IntermediateTableAnalysisRulePolicy",
|
|
49521
|
+
"kind": "property",
|
|
49522
|
+
"lexicon": "aws"
|
|
49523
|
+
},
|
|
49524
|
+
"IntermediateTable_PopulationAnalysisConfiguration": {
|
|
49525
|
+
"resourceType": "AWS::CleanRooms::IntermediateTable.PopulationAnalysisConfiguration",
|
|
49526
|
+
"kind": "property",
|
|
49527
|
+
"lexicon": "aws"
|
|
49528
|
+
},
|
|
49529
|
+
"IntermediateTable_PopulationAnalysisSqlParameters": {
|
|
49530
|
+
"resourceType": "AWS::CleanRooms::IntermediateTable.PopulationAnalysisSqlParameters",
|
|
49531
|
+
"kind": "property",
|
|
49532
|
+
"lexicon": "aws"
|
|
49533
|
+
},
|
|
49534
|
+
"IntermediateTable_Tag": {
|
|
49535
|
+
"resourceType": "AWS::CleanRooms::IntermediateTable.Tag",
|
|
49536
|
+
"kind": "property",
|
|
49537
|
+
"lexicon": "aws"
|
|
49538
|
+
},
|
|
49454
49539
|
"InternetGateway": {
|
|
49455
49540
|
"resourceType": "AWS::EC2::InternetGateway",
|
|
49456
49541
|
"kind": "resource",
|
|
@@ -54791,7 +54876,12 @@
|
|
|
54791
54876
|
],
|
|
54792
54877
|
"primaryIdentifier": [
|
|
54793
54878
|
"ListenerArn"
|
|
54794
|
-
]
|
|
54879
|
+
],
|
|
54880
|
+
"tagging": {
|
|
54881
|
+
"taggable": true,
|
|
54882
|
+
"tagOnCreate": true,
|
|
54883
|
+
"tagUpdatable": true
|
|
54884
|
+
}
|
|
54795
54885
|
},
|
|
54796
54886
|
"ListenerAttribute": {
|
|
54797
54887
|
"resourceType": "AWS::ElasticLoadBalancingV2::Listener.ListenerAttribute",
|
|
@@ -55022,6 +55112,11 @@
|
|
|
55022
55112
|
"kind": "property",
|
|
55023
55113
|
"lexicon": "aws"
|
|
55024
55114
|
},
|
|
55115
|
+
"Listener_Tag": {
|
|
55116
|
+
"resourceType": "AWS::ElasticLoadBalancingV2::Listener.Tag",
|
|
55117
|
+
"kind": "property",
|
|
55118
|
+
"lexicon": "aws"
|
|
55119
|
+
},
|
|
55025
55120
|
"Listener_TargetGroupStickinessConfig": {
|
|
55026
55121
|
"resourceType": "AWS::ElasticLoadBalancingV2::Listener.TargetGroupStickinessConfig",
|
|
55027
55122
|
"kind": "property",
|
|
@@ -71684,6 +71779,16 @@
|
|
|
71684
71779
|
"kind": "property",
|
|
71685
71780
|
"lexicon": "aws"
|
|
71686
71781
|
},
|
|
71782
|
+
"PopulationAnalysisConfiguration": {
|
|
71783
|
+
"resourceType": "AWS::CleanRooms::IntermediateTable.PopulationAnalysisConfiguration",
|
|
71784
|
+
"kind": "property",
|
|
71785
|
+
"lexicon": "aws"
|
|
71786
|
+
},
|
|
71787
|
+
"PopulationAnalysisSqlParameters": {
|
|
71788
|
+
"resourceType": "AWS::CleanRooms::IntermediateTable.PopulationAnalysisSqlParameters",
|
|
71789
|
+
"kind": "property",
|
|
71790
|
+
"lexicon": "aws"
|
|
71791
|
+
},
|
|
71687
71792
|
"Port": {
|
|
71688
71793
|
"resourceType": "AWS::Lightsail::Instance.Port",
|
|
71689
71794
|
"kind": "property",
|
|
@@ -41,14 +41,24 @@ describe("aws exportResources I/O glue (#160)", () => {
|
|
|
41
41
|
expect(ir.resources.map((r) => r.logicalId)).toEqual(["MyBucket"]);
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
-
test("a
|
|
44
|
+
test("a not-yet-deployed stack returns empty live state (pre-first-apply), not an error", async () => {
|
|
45
45
|
spawnMock.mockResolvedValue({
|
|
46
46
|
stdout: "",
|
|
47
|
-
stderr: "Stack with id ghost does not exist",
|
|
47
|
+
stderr: "An error occurred (ValidationError) …: Stack with id ghost does not exist",
|
|
48
48
|
exitCode: 254,
|
|
49
49
|
});
|
|
50
|
-
await
|
|
51
|
-
|
|
50
|
+
const ir = await awsPlugin.exportResources!({ environment: "ghost" });
|
|
51
|
+
expect(ir.resources).toEqual([]);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("a genuine failure (not 'does not exist') still throws with the stderr surfaced", async () => {
|
|
55
|
+
spawnMock.mockResolvedValue({
|
|
56
|
+
stdout: "",
|
|
57
|
+
stderr: "An error occurred (AccessDenied) …: not authorized",
|
|
58
|
+
exitCode: 254,
|
|
59
|
+
});
|
|
60
|
+
await expect(awsPlugin.exportResources!({ environment: "prod" })).rejects.toThrow(
|
|
61
|
+
/Failed to get template for stack "prod".*AccessDenied/,
|
|
52
62
|
);
|
|
53
63
|
});
|
|
54
64
|
|
package/src/plugin.test.ts
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import { describe, test, expect } from "vitest";
|
|
2
|
-
import { awsPlugin } from "./plugin";
|
|
2
|
+
import { awsPlugin, stackDoesNotExist } from "./plugin";
|
|
3
3
|
import { isLexiconPlugin } from "@intentius/chant/lexicon";
|
|
4
4
|
|
|
5
|
+
describe("stackDoesNotExist (pre-first-apply live state)", () => {
|
|
6
|
+
test("true for the CloudFormation 'does not exist' error", () => {
|
|
7
|
+
expect(stackDoesNotExist(
|
|
8
|
+
"An error occurred (ValidationError) when calling the DescribeStackResources operation: Stack with id prod does not exist",
|
|
9
|
+
)).toBe(true);
|
|
10
|
+
});
|
|
11
|
+
test("false for other failures (auth, network) — those still throw", () => {
|
|
12
|
+
expect(stackDoesNotExist("An error occurred (InvalidClientTokenId) ...")).toBe(false);
|
|
13
|
+
expect(stackDoesNotExist("Could not connect to the endpoint URL")).toBe(false);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
|
|
5
17
|
describe("awsPlugin", () => {
|
|
6
18
|
// -----------------------------------------------------------------------
|
|
7
19
|
// Basic interface
|
package/src/plugin.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { join, dirname } from "path";
|
|
|
15
15
|
import { fileURLToPath } from "url";
|
|
16
16
|
import { awsSerializer } from "./serializer";
|
|
17
17
|
import { FLOCI_EMULATOR } from "./op/activities/floci";
|
|
18
|
+
import { applyAwsEndpointArgv } from "./components/cloud-executor";
|
|
18
19
|
import { awsReferenceCatalog } from "./reference-catalog";
|
|
19
20
|
import { resolveTemplateAttrs } from "./live-attrs";
|
|
20
21
|
import { CFParser } from "./import/parser";
|
|
@@ -23,6 +24,13 @@ import { parseStackTemplate } from "./import/live-export";
|
|
|
23
24
|
import { awsCompletions } from "./lsp/completions";
|
|
24
25
|
import { awsHover } from "./lsp/hover";
|
|
25
26
|
|
|
27
|
+
/** True when a CloudFormation CLI error means the stack simply isn't there yet
|
|
28
|
+
* (`ValidationError … does not exist`) — the pre-first-apply state, which live
|
|
29
|
+
* queries should treat as "nothing deployed", not a failure. Exported for testing. */
|
|
30
|
+
export function stackDoesNotExist(stderr: string): boolean {
|
|
31
|
+
return /does not exist/i.test(stderr);
|
|
32
|
+
}
|
|
33
|
+
|
|
26
34
|
/**
|
|
27
35
|
* AWS CloudFormation lexicon plugin.
|
|
28
36
|
*
|
|
@@ -486,14 +494,23 @@ aws cloudformation wait stack-update-complete --stack-name my-app-prod`,
|
|
|
486
494
|
// Try to parse the build output to detect stack name from Metadata or use convention
|
|
487
495
|
const stackName = `${options.environment}`;
|
|
488
496
|
|
|
489
|
-
// Describe stack resources
|
|
490
|
-
|
|
497
|
+
// Describe stack resources. Inject --endpoint-url from AWS_ENDPOINT_URL so a
|
|
498
|
+
// local emulator (Floci) is observed instead of real AWS (#926) — behold
|
|
499
|
+
// serve --local relies on this for the overlay.
|
|
500
|
+
const listResult = await rt.spawn(applyAwsEndpointArgv([
|
|
491
501
|
"aws", "cloudformation", "describe-stack-resources",
|
|
492
502
|
"--stack-name", stackName,
|
|
493
503
|
"--output", "json",
|
|
494
|
-
]);
|
|
504
|
+
], process.env.AWS_ENDPOINT_URL));
|
|
495
505
|
|
|
496
506
|
if (listResult.exitCode !== 0) {
|
|
507
|
+
// A stack that doesn't exist yet is the pre-first-apply state: nothing is
|
|
508
|
+
// deployed for this env, so there are no live resources (every declared
|
|
509
|
+
// resource is "pending") — not an error. Returning empty lets `lifecycle
|
|
510
|
+
// diff --live` / the overlay show pending nodes instead of failing hard.
|
|
511
|
+
if (stackDoesNotExist(listResult.stderr)) {
|
|
512
|
+
return resources;
|
|
513
|
+
}
|
|
497
514
|
throw new Error(`Failed to describe stack "${stackName}": ${listResult.stderr}`);
|
|
498
515
|
}
|
|
499
516
|
|
|
@@ -514,11 +531,11 @@ aws cloudformation wait stack-update-complete --stack-name my-app-prod`,
|
|
|
514
531
|
}
|
|
515
532
|
|
|
516
533
|
// Get stack outputs
|
|
517
|
-
const describeResult = await rt.spawn([
|
|
534
|
+
const describeResult = await rt.spawn(applyAwsEndpointArgv([
|
|
518
535
|
"aws", "cloudformation", "describe-stacks",
|
|
519
536
|
"--stack-name", stackName,
|
|
520
537
|
"--output", "json",
|
|
521
|
-
]);
|
|
538
|
+
], process.env.AWS_ENDPOINT_URL));
|
|
522
539
|
|
|
523
540
|
let stackOutputs: Record<string, string> = {};
|
|
524
541
|
if (describeResult.exitCode === 0) {
|
|
@@ -569,13 +586,19 @@ aws cloudformation wait stack-update-complete --stack-name my-app-prod`,
|
|
|
569
586
|
// Same stack-name convention as describeResources.
|
|
570
587
|
const stackName = `${options.environment}`;
|
|
571
588
|
|
|
572
|
-
const result = await rt.spawn([
|
|
589
|
+
const result = await rt.spawn(applyAwsEndpointArgv([
|
|
573
590
|
"aws", "cloudformation", "get-template",
|
|
574
591
|
"--stack-name", stackName,
|
|
575
592
|
"--template-stage", "Original",
|
|
576
593
|
"--output", "json",
|
|
577
|
-
]);
|
|
594
|
+
], process.env.AWS_ENDPOINT_URL));
|
|
578
595
|
if (result.exitCode !== 0) {
|
|
596
|
+
// Not deployed yet → no template to export (nothing live), not an error.
|
|
597
|
+
// Keeps `chant graph --live` edge enrichment and `import --from` quiet
|
|
598
|
+
// before the first apply.
|
|
599
|
+
if (stackDoesNotExist(result.stderr)) {
|
|
600
|
+
return parseStackTemplate({ Resources: {} }, options.selector, options.owned);
|
|
601
|
+
}
|
|
579
602
|
throw new Error(`Failed to get template for stack "${stackName}": ${result.stderr}`);
|
|
580
603
|
}
|
|
581
604
|
|