@go-to-k/cdkd 0.70.0 → 0.72.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 +44 -4
- package/dist/cli.js +2007 -284
- package/dist/cli.js.map +4 -4
- package/dist/go-to-k-cdkd-0.72.0.tgz +0 -0
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
- package/dist/go-to-k-cdkd-0.70.0.tgz +0 -0
package/dist/cli.js
CHANGED
|
@@ -708,10 +708,10 @@ var require_GraphQLError = __commonJS({
|
|
|
708
708
|
*/
|
|
709
709
|
constructor(message, ...rawArgs) {
|
|
710
710
|
var _this$nodes, _nodeLocations$, _ref;
|
|
711
|
-
const { nodes, source, positions, path:
|
|
711
|
+
const { nodes, source, positions, path: path3, originalError, extensions } = toNormalizedOptions(rawArgs);
|
|
712
712
|
super(message);
|
|
713
713
|
this.name = "GraphQLError";
|
|
714
|
-
this.path =
|
|
714
|
+
this.path = path3 !== null && path3 !== void 0 ? path3 : void 0;
|
|
715
715
|
this.originalError = originalError !== null && originalError !== void 0 ? originalError : void 0;
|
|
716
716
|
this.nodes = undefinedIfEmpty(
|
|
717
717
|
Array.isArray(nodes) ? nodes : nodes ? [nodes] : void 0
|
|
@@ -4173,14 +4173,14 @@ var require_visitor = __commonJS({
|
|
|
4173
4173
|
let node = root;
|
|
4174
4174
|
let key = void 0;
|
|
4175
4175
|
let parent = void 0;
|
|
4176
|
-
const
|
|
4176
|
+
const path3 = [];
|
|
4177
4177
|
const ancestors = [];
|
|
4178
4178
|
do {
|
|
4179
4179
|
index++;
|
|
4180
4180
|
const isLeaving = index === keys.length;
|
|
4181
4181
|
const isEdited = isLeaving && edits.length !== 0;
|
|
4182
4182
|
if (isLeaving) {
|
|
4183
|
-
key = ancestors.length === 0 ? void 0 :
|
|
4183
|
+
key = ancestors.length === 0 ? void 0 : path3[path3.length - 1];
|
|
4184
4184
|
node = parent;
|
|
4185
4185
|
parent = ancestors.pop();
|
|
4186
4186
|
if (isEdited) {
|
|
@@ -4214,7 +4214,7 @@ var require_visitor = __commonJS({
|
|
|
4214
4214
|
if (node === null || node === void 0) {
|
|
4215
4215
|
continue;
|
|
4216
4216
|
}
|
|
4217
|
-
|
|
4217
|
+
path3.push(key);
|
|
4218
4218
|
}
|
|
4219
4219
|
let result;
|
|
4220
4220
|
if (!Array.isArray(node)) {
|
|
@@ -4224,13 +4224,13 @@ var require_visitor = __commonJS({
|
|
|
4224
4224
|
`Invalid AST Node: ${(0, _inspect.inspect)(node)}.`
|
|
4225
4225
|
);
|
|
4226
4226
|
const visitFn = isLeaving ? (_enterLeaveMap$get = enterLeaveMap.get(node.kind)) === null || _enterLeaveMap$get === void 0 ? void 0 : _enterLeaveMap$get.leave : (_enterLeaveMap$get2 = enterLeaveMap.get(node.kind)) === null || _enterLeaveMap$get2 === void 0 ? void 0 : _enterLeaveMap$get2.enter;
|
|
4227
|
-
result = visitFn === null || visitFn === void 0 ? void 0 : visitFn.call(visitor, node, key, parent,
|
|
4227
|
+
result = visitFn === null || visitFn === void 0 ? void 0 : visitFn.call(visitor, node, key, parent, path3, ancestors);
|
|
4228
4228
|
if (result === BREAK) {
|
|
4229
4229
|
break;
|
|
4230
4230
|
}
|
|
4231
4231
|
if (result === false) {
|
|
4232
4232
|
if (!isLeaving) {
|
|
4233
|
-
|
|
4233
|
+
path3.pop();
|
|
4234
4234
|
continue;
|
|
4235
4235
|
}
|
|
4236
4236
|
} else if (result !== void 0) {
|
|
@@ -4239,7 +4239,7 @@ var require_visitor = __commonJS({
|
|
|
4239
4239
|
if ((0, _ast.isNode)(result)) {
|
|
4240
4240
|
node = result;
|
|
4241
4241
|
} else {
|
|
4242
|
-
|
|
4242
|
+
path3.pop();
|
|
4243
4243
|
continue;
|
|
4244
4244
|
}
|
|
4245
4245
|
}
|
|
@@ -4249,7 +4249,7 @@ var require_visitor = __commonJS({
|
|
|
4249
4249
|
edits.push([key, node]);
|
|
4250
4250
|
}
|
|
4251
4251
|
if (isLeaving) {
|
|
4252
|
-
|
|
4252
|
+
path3.pop();
|
|
4253
4253
|
} else {
|
|
4254
4254
|
var _node$kind;
|
|
4255
4255
|
stack = {
|
|
@@ -4374,16 +4374,16 @@ var require_printer = __commonJS({
|
|
|
4374
4374
|
},
|
|
4375
4375
|
// Document
|
|
4376
4376
|
Document: {
|
|
4377
|
-
leave: (node) =>
|
|
4377
|
+
leave: (node) => join9(node.definitions, "\n\n")
|
|
4378
4378
|
},
|
|
4379
4379
|
OperationDefinition: {
|
|
4380
4380
|
leave(node) {
|
|
4381
|
-
const varDefs = hasMultilineItems(node.variableDefinitions) ? wrap("(\n",
|
|
4382
|
-
const prefix = wrap("", node.description, "\n") +
|
|
4381
|
+
const varDefs = hasMultilineItems(node.variableDefinitions) ? wrap("(\n", join9(node.variableDefinitions, "\n"), "\n)") : wrap("(", join9(node.variableDefinitions, ", "), ")");
|
|
4382
|
+
const prefix = wrap("", node.description, "\n") + join9(
|
|
4383
4383
|
[
|
|
4384
4384
|
node.operation,
|
|
4385
|
-
|
|
4386
|
-
|
|
4385
|
+
join9([node.name, varDefs]),
|
|
4386
|
+
join9(node.directives, " ")
|
|
4387
4387
|
],
|
|
4388
4388
|
" "
|
|
4389
4389
|
);
|
|
@@ -4391,7 +4391,7 @@ var require_printer = __commonJS({
|
|
|
4391
4391
|
}
|
|
4392
4392
|
},
|
|
4393
4393
|
VariableDefinition: {
|
|
4394
|
-
leave: ({ variable, type, defaultValue, directives, description }) => wrap("", description, "\n") + variable + ": " + type + wrap(" = ", defaultValue) + wrap(" ",
|
|
4394
|
+
leave: ({ variable, type, defaultValue, directives, description }) => wrap("", description, "\n") + variable + ": " + type + wrap(" = ", defaultValue) + wrap(" ", join9(directives, " "))
|
|
4395
4395
|
},
|
|
4396
4396
|
SelectionSet: {
|
|
4397
4397
|
leave: ({ selections }) => block(selections)
|
|
@@ -4399,11 +4399,11 @@ var require_printer = __commonJS({
|
|
|
4399
4399
|
Field: {
|
|
4400
4400
|
leave({ alias, name, arguments: args, directives, selectionSet }) {
|
|
4401
4401
|
const prefix = wrap("", alias, ": ") + name;
|
|
4402
|
-
let argsLine = prefix + wrap("(",
|
|
4402
|
+
let argsLine = prefix + wrap("(", join9(args, ", "), ")");
|
|
4403
4403
|
if (argsLine.length > MAX_LINE_LENGTH) {
|
|
4404
|
-
argsLine = prefix + wrap("(\n", indent(
|
|
4404
|
+
argsLine = prefix + wrap("(\n", indent(join9(args, "\n")), "\n)");
|
|
4405
4405
|
}
|
|
4406
|
-
return
|
|
4406
|
+
return join9([argsLine, join9(directives, " "), selectionSet], " ");
|
|
4407
4407
|
}
|
|
4408
4408
|
},
|
|
4409
4409
|
Argument: {
|
|
@@ -4411,14 +4411,14 @@ var require_printer = __commonJS({
|
|
|
4411
4411
|
},
|
|
4412
4412
|
// Fragments
|
|
4413
4413
|
FragmentSpread: {
|
|
4414
|
-
leave: ({ name, directives }) => "..." + name + wrap(" ",
|
|
4414
|
+
leave: ({ name, directives }) => "..." + name + wrap(" ", join9(directives, " "))
|
|
4415
4415
|
},
|
|
4416
4416
|
InlineFragment: {
|
|
4417
|
-
leave: ({ typeCondition, directives, selectionSet }) =>
|
|
4417
|
+
leave: ({ typeCondition, directives, selectionSet }) => join9(
|
|
4418
4418
|
[
|
|
4419
4419
|
"...",
|
|
4420
4420
|
wrap("on ", typeCondition),
|
|
4421
|
-
|
|
4421
|
+
join9(directives, " "),
|
|
4422
4422
|
selectionSet
|
|
4423
4423
|
],
|
|
4424
4424
|
" "
|
|
@@ -4434,7 +4434,7 @@ var require_printer = __commonJS({
|
|
|
4434
4434
|
description
|
|
4435
4435
|
}) => wrap("", description, "\n") + // Note: fragment variable definitions are experimental and may be changed
|
|
4436
4436
|
// or removed in the future.
|
|
4437
|
-
`fragment ${name}${wrap("(",
|
|
4437
|
+
`fragment ${name}${wrap("(", join9(variableDefinitions, ", "), ")")} on ${typeCondition} ${wrap("", join9(directives, " "), " ")}` + selectionSet
|
|
4438
4438
|
},
|
|
4439
4439
|
// Value
|
|
4440
4440
|
IntValue: {
|
|
@@ -4456,17 +4456,17 @@ var require_printer = __commonJS({
|
|
|
4456
4456
|
leave: ({ value }) => value
|
|
4457
4457
|
},
|
|
4458
4458
|
ListValue: {
|
|
4459
|
-
leave: ({ values }) => "[" +
|
|
4459
|
+
leave: ({ values }) => "[" + join9(values, ", ") + "]"
|
|
4460
4460
|
},
|
|
4461
4461
|
ObjectValue: {
|
|
4462
|
-
leave: ({ fields }) => "{" +
|
|
4462
|
+
leave: ({ fields }) => "{" + join9(fields, ", ") + "}"
|
|
4463
4463
|
},
|
|
4464
4464
|
ObjectField: {
|
|
4465
4465
|
leave: ({ name, value }) => name + ": " + value
|
|
4466
4466
|
},
|
|
4467
4467
|
// Directive
|
|
4468
4468
|
Directive: {
|
|
4469
|
-
leave: ({ name, arguments: args }) => "@" + name + wrap("(",
|
|
4469
|
+
leave: ({ name, arguments: args }) => "@" + name + wrap("(", join9(args, ", "), ")")
|
|
4470
4470
|
},
|
|
4471
4471
|
// Type
|
|
4472
4472
|
NamedType: {
|
|
@@ -4480,61 +4480,61 @@ var require_printer = __commonJS({
|
|
|
4480
4480
|
},
|
|
4481
4481
|
// Type System Definitions
|
|
4482
4482
|
SchemaDefinition: {
|
|
4483
|
-
leave: ({ description, directives, operationTypes }) => wrap("", description, "\n") +
|
|
4483
|
+
leave: ({ description, directives, operationTypes }) => wrap("", description, "\n") + join9(["schema", join9(directives, " "), block(operationTypes)], " ")
|
|
4484
4484
|
},
|
|
4485
4485
|
OperationTypeDefinition: {
|
|
4486
4486
|
leave: ({ operation, type }) => operation + ": " + type
|
|
4487
4487
|
},
|
|
4488
4488
|
ScalarTypeDefinition: {
|
|
4489
|
-
leave: ({ description, name, directives }) => wrap("", description, "\n") +
|
|
4489
|
+
leave: ({ description, name, directives }) => wrap("", description, "\n") + join9(["scalar", name, join9(directives, " ")], " ")
|
|
4490
4490
|
},
|
|
4491
4491
|
ObjectTypeDefinition: {
|
|
4492
|
-
leave: ({ description, name, interfaces, directives, fields }) => wrap("", description, "\n") +
|
|
4492
|
+
leave: ({ description, name, interfaces, directives, fields }) => wrap("", description, "\n") + join9(
|
|
4493
4493
|
[
|
|
4494
4494
|
"type",
|
|
4495
4495
|
name,
|
|
4496
|
-
wrap("implements ",
|
|
4497
|
-
|
|
4496
|
+
wrap("implements ", join9(interfaces, " & ")),
|
|
4497
|
+
join9(directives, " "),
|
|
4498
4498
|
block(fields)
|
|
4499
4499
|
],
|
|
4500
4500
|
" "
|
|
4501
4501
|
)
|
|
4502
4502
|
},
|
|
4503
4503
|
FieldDefinition: {
|
|
4504
|
-
leave: ({ description, name, arguments: args, type, directives }) => wrap("", description, "\n") + name + (hasMultilineItems(args) ? wrap("(\n", indent(
|
|
4504
|
+
leave: ({ description, name, arguments: args, type, directives }) => wrap("", description, "\n") + name + (hasMultilineItems(args) ? wrap("(\n", indent(join9(args, "\n")), "\n)") : wrap("(", join9(args, ", "), ")")) + ": " + type + wrap(" ", join9(directives, " "))
|
|
4505
4505
|
},
|
|
4506
4506
|
InputValueDefinition: {
|
|
4507
|
-
leave: ({ description, name, type, defaultValue, directives }) => wrap("", description, "\n") +
|
|
4508
|
-
[name + ": " + type, wrap("= ", defaultValue),
|
|
4507
|
+
leave: ({ description, name, type, defaultValue, directives }) => wrap("", description, "\n") + join9(
|
|
4508
|
+
[name + ": " + type, wrap("= ", defaultValue), join9(directives, " ")],
|
|
4509
4509
|
" "
|
|
4510
4510
|
)
|
|
4511
4511
|
},
|
|
4512
4512
|
InterfaceTypeDefinition: {
|
|
4513
|
-
leave: ({ description, name, interfaces, directives, fields }) => wrap("", description, "\n") +
|
|
4513
|
+
leave: ({ description, name, interfaces, directives, fields }) => wrap("", description, "\n") + join9(
|
|
4514
4514
|
[
|
|
4515
4515
|
"interface",
|
|
4516
4516
|
name,
|
|
4517
|
-
wrap("implements ",
|
|
4518
|
-
|
|
4517
|
+
wrap("implements ", join9(interfaces, " & ")),
|
|
4518
|
+
join9(directives, " "),
|
|
4519
4519
|
block(fields)
|
|
4520
4520
|
],
|
|
4521
4521
|
" "
|
|
4522
4522
|
)
|
|
4523
4523
|
},
|
|
4524
4524
|
UnionTypeDefinition: {
|
|
4525
|
-
leave: ({ description, name, directives, types }) => wrap("", description, "\n") +
|
|
4526
|
-
["union", name,
|
|
4525
|
+
leave: ({ description, name, directives, types }) => wrap("", description, "\n") + join9(
|
|
4526
|
+
["union", name, join9(directives, " "), wrap("= ", join9(types, " | "))],
|
|
4527
4527
|
" "
|
|
4528
4528
|
)
|
|
4529
4529
|
},
|
|
4530
4530
|
EnumTypeDefinition: {
|
|
4531
|
-
leave: ({ description, name, directives, values }) => wrap("", description, "\n") +
|
|
4531
|
+
leave: ({ description, name, directives, values }) => wrap("", description, "\n") + join9(["enum", name, join9(directives, " "), block(values)], " ")
|
|
4532
4532
|
},
|
|
4533
4533
|
EnumValueDefinition: {
|
|
4534
|
-
leave: ({ description, name, directives }) => wrap("", description, "\n") +
|
|
4534
|
+
leave: ({ description, name, directives }) => wrap("", description, "\n") + join9([name, join9(directives, " ")], " ")
|
|
4535
4535
|
},
|
|
4536
4536
|
InputObjectTypeDefinition: {
|
|
4537
|
-
leave: ({ description, name, directives, fields }) => wrap("", description, "\n") +
|
|
4537
|
+
leave: ({ description, name, directives, fields }) => wrap("", description, "\n") + join9(["input", name, join9(directives, " "), block(fields)], " ")
|
|
4538
4538
|
},
|
|
4539
4539
|
DirectiveDefinition: {
|
|
4540
4540
|
leave: ({
|
|
@@ -4544,84 +4544,84 @@ var require_printer = __commonJS({
|
|
|
4544
4544
|
directives,
|
|
4545
4545
|
repeatable,
|
|
4546
4546
|
locations
|
|
4547
|
-
}) => wrap("", description, "\n") + "directive @" + name + (hasMultilineItems(args) ? wrap("(\n", indent(
|
|
4547
|
+
}) => wrap("", description, "\n") + "directive @" + name + (hasMultilineItems(args) ? wrap("(\n", indent(join9(args, "\n")), "\n)") : wrap("(", join9(args, ", "), ")")) + wrap(" ", join9(directives, " ")) + (repeatable ? " repeatable" : "") + " on " + join9(locations, " | ")
|
|
4548
4548
|
},
|
|
4549
4549
|
SchemaExtension: {
|
|
4550
|
-
leave: ({ directives, operationTypes }) =>
|
|
4551
|
-
["extend schema",
|
|
4550
|
+
leave: ({ directives, operationTypes }) => join9(
|
|
4551
|
+
["extend schema", join9(directives, " "), block(operationTypes)],
|
|
4552
4552
|
" "
|
|
4553
4553
|
)
|
|
4554
4554
|
},
|
|
4555
4555
|
ScalarTypeExtension: {
|
|
4556
|
-
leave: ({ name, directives }) =>
|
|
4556
|
+
leave: ({ name, directives }) => join9(["extend scalar", name, join9(directives, " ")], " ")
|
|
4557
4557
|
},
|
|
4558
4558
|
ObjectTypeExtension: {
|
|
4559
|
-
leave: ({ name, interfaces, directives, fields }) =>
|
|
4559
|
+
leave: ({ name, interfaces, directives, fields }) => join9(
|
|
4560
4560
|
[
|
|
4561
4561
|
"extend type",
|
|
4562
4562
|
name,
|
|
4563
|
-
wrap("implements ",
|
|
4564
|
-
|
|
4563
|
+
wrap("implements ", join9(interfaces, " & ")),
|
|
4564
|
+
join9(directives, " "),
|
|
4565
4565
|
block(fields)
|
|
4566
4566
|
],
|
|
4567
4567
|
" "
|
|
4568
4568
|
)
|
|
4569
4569
|
},
|
|
4570
4570
|
InterfaceTypeExtension: {
|
|
4571
|
-
leave: ({ name, interfaces, directives, fields }) =>
|
|
4571
|
+
leave: ({ name, interfaces, directives, fields }) => join9(
|
|
4572
4572
|
[
|
|
4573
4573
|
"extend interface",
|
|
4574
4574
|
name,
|
|
4575
|
-
wrap("implements ",
|
|
4576
|
-
|
|
4575
|
+
wrap("implements ", join9(interfaces, " & ")),
|
|
4576
|
+
join9(directives, " "),
|
|
4577
4577
|
block(fields)
|
|
4578
4578
|
],
|
|
4579
4579
|
" "
|
|
4580
4580
|
)
|
|
4581
4581
|
},
|
|
4582
4582
|
UnionTypeExtension: {
|
|
4583
|
-
leave: ({ name, directives, types }) =>
|
|
4583
|
+
leave: ({ name, directives, types }) => join9(
|
|
4584
4584
|
[
|
|
4585
4585
|
"extend union",
|
|
4586
4586
|
name,
|
|
4587
|
-
|
|
4588
|
-
wrap("= ",
|
|
4587
|
+
join9(directives, " "),
|
|
4588
|
+
wrap("= ", join9(types, " | "))
|
|
4589
4589
|
],
|
|
4590
4590
|
" "
|
|
4591
4591
|
)
|
|
4592
4592
|
},
|
|
4593
4593
|
EnumTypeExtension: {
|
|
4594
|
-
leave: ({ name, directives, values }) =>
|
|
4594
|
+
leave: ({ name, directives, values }) => join9(["extend enum", name, join9(directives, " "), block(values)], " ")
|
|
4595
4595
|
},
|
|
4596
4596
|
InputObjectTypeExtension: {
|
|
4597
|
-
leave: ({ name, directives, fields }) =>
|
|
4597
|
+
leave: ({ name, directives, fields }) => join9(["extend input", name, join9(directives, " "), block(fields)], " ")
|
|
4598
4598
|
},
|
|
4599
4599
|
DirectiveExtension: {
|
|
4600
|
-
leave: ({ name, directives }) =>
|
|
4600
|
+
leave: ({ name, directives }) => join9(["extend directive @" + name, join9(directives, " ")], " ")
|
|
4601
4601
|
},
|
|
4602
4602
|
// Schema Coordinates
|
|
4603
4603
|
TypeCoordinate: {
|
|
4604
4604
|
leave: ({ name }) => name
|
|
4605
4605
|
},
|
|
4606
4606
|
MemberCoordinate: {
|
|
4607
|
-
leave: ({ name, memberName }) =>
|
|
4607
|
+
leave: ({ name, memberName }) => join9([name, wrap(".", memberName)])
|
|
4608
4608
|
},
|
|
4609
4609
|
ArgumentCoordinate: {
|
|
4610
|
-
leave: ({ name, fieldName, argumentName }) =>
|
|
4610
|
+
leave: ({ name, fieldName, argumentName }) => join9([name, wrap(".", fieldName), wrap("(", argumentName, ":)")])
|
|
4611
4611
|
},
|
|
4612
4612
|
DirectiveCoordinate: {
|
|
4613
|
-
leave: ({ name }) =>
|
|
4613
|
+
leave: ({ name }) => join9(["@", name])
|
|
4614
4614
|
},
|
|
4615
4615
|
DirectiveArgumentCoordinate: {
|
|
4616
|
-
leave: ({ name, argumentName }) =>
|
|
4616
|
+
leave: ({ name, argumentName }) => join9(["@", name, wrap("(", argumentName, ":)")])
|
|
4617
4617
|
}
|
|
4618
4618
|
};
|
|
4619
|
-
function
|
|
4619
|
+
function join9(maybeArray, separator = "") {
|
|
4620
4620
|
var _maybeArray$filter$jo;
|
|
4621
4621
|
return (_maybeArray$filter$jo = maybeArray === null || maybeArray === void 0 ? void 0 : maybeArray.filter((x) => x).join(separator)) !== null && _maybeArray$filter$jo !== void 0 ? _maybeArray$filter$jo : "";
|
|
4622
4622
|
}
|
|
4623
4623
|
function block(array) {
|
|
4624
|
-
return wrap("{\n", indent(
|
|
4624
|
+
return wrap("{\n", indent(join9(array, "\n")), "\n}");
|
|
4625
4625
|
}
|
|
4626
4626
|
function wrap(start, maybeString, end = "") {
|
|
4627
4627
|
return maybeString != null && maybeString !== "" ? start + maybeString + end : "";
|
|
@@ -9578,8 +9578,8 @@ var require_printPathArray = __commonJS({
|
|
|
9578
9578
|
value: true
|
|
9579
9579
|
});
|
|
9580
9580
|
exports.printPathArray = printPathArray;
|
|
9581
|
-
function printPathArray(
|
|
9582
|
-
return
|
|
9581
|
+
function printPathArray(path3) {
|
|
9582
|
+
return path3.map(
|
|
9583
9583
|
(key) => typeof key === "number" ? "[" + key.toString() + "]" : "." + key
|
|
9584
9584
|
).join("");
|
|
9585
9585
|
}
|
|
@@ -9602,9 +9602,9 @@ var require_Path = __commonJS({
|
|
|
9602
9602
|
typename
|
|
9603
9603
|
};
|
|
9604
9604
|
}
|
|
9605
|
-
function pathToArray(
|
|
9605
|
+
function pathToArray(path3) {
|
|
9606
9606
|
const flattened = [];
|
|
9607
|
-
let curr =
|
|
9607
|
+
let curr = path3;
|
|
9608
9608
|
while (curr) {
|
|
9609
9609
|
flattened.push(curr.key);
|
|
9610
9610
|
curr = curr.prev;
|
|
@@ -9635,21 +9635,21 @@ var require_coerceInputValue = __commonJS({
|
|
|
9635
9635
|
function coerceInputValue(inputValue, type, onError = defaultOnError) {
|
|
9636
9636
|
return coerceInputValueImpl(inputValue, type, onError, void 0);
|
|
9637
9637
|
}
|
|
9638
|
-
function defaultOnError(
|
|
9638
|
+
function defaultOnError(path3, invalidValue, error) {
|
|
9639
9639
|
let errorPrefix = "Invalid value " + (0, _inspect.inspect)(invalidValue);
|
|
9640
|
-
if (
|
|
9641
|
-
errorPrefix += ` at "value${(0, _printPathArray.printPathArray)(
|
|
9640
|
+
if (path3.length > 0) {
|
|
9641
|
+
errorPrefix += ` at "value${(0, _printPathArray.printPathArray)(path3)}"`;
|
|
9642
9642
|
}
|
|
9643
9643
|
error.message = errorPrefix + ": " + error.message;
|
|
9644
9644
|
throw error;
|
|
9645
9645
|
}
|
|
9646
|
-
function coerceInputValueImpl(inputValue, type, onError,
|
|
9646
|
+
function coerceInputValueImpl(inputValue, type, onError, path3) {
|
|
9647
9647
|
if ((0, _definition.isNonNullType)(type)) {
|
|
9648
9648
|
if (inputValue != null) {
|
|
9649
|
-
return coerceInputValueImpl(inputValue, type.ofType, onError,
|
|
9649
|
+
return coerceInputValueImpl(inputValue, type.ofType, onError, path3);
|
|
9650
9650
|
}
|
|
9651
9651
|
onError(
|
|
9652
|
-
(0, _Path.pathToArray)(
|
|
9652
|
+
(0, _Path.pathToArray)(path3),
|
|
9653
9653
|
inputValue,
|
|
9654
9654
|
new _GraphQLError.GraphQLError(
|
|
9655
9655
|
`Expected non-nullable type "${(0, _inspect.inspect)(
|
|
@@ -9666,16 +9666,16 @@ var require_coerceInputValue = __commonJS({
|
|
|
9666
9666
|
const itemType = type.ofType;
|
|
9667
9667
|
if ((0, _isIterableObject.isIterableObject)(inputValue)) {
|
|
9668
9668
|
return Array.from(inputValue, (itemValue, index) => {
|
|
9669
|
-
const itemPath = (0, _Path.addPath)(
|
|
9669
|
+
const itemPath = (0, _Path.addPath)(path3, index, void 0);
|
|
9670
9670
|
return coerceInputValueImpl(itemValue, itemType, onError, itemPath);
|
|
9671
9671
|
});
|
|
9672
9672
|
}
|
|
9673
|
-
return [coerceInputValueImpl(inputValue, itemType, onError,
|
|
9673
|
+
return [coerceInputValueImpl(inputValue, itemType, onError, path3)];
|
|
9674
9674
|
}
|
|
9675
9675
|
if ((0, _definition.isInputObjectType)(type)) {
|
|
9676
9676
|
if (!(0, _isObjectLike.isObjectLike)(inputValue) || Array.isArray(inputValue)) {
|
|
9677
9677
|
onError(
|
|
9678
|
-
(0, _Path.pathToArray)(
|
|
9678
|
+
(0, _Path.pathToArray)(path3),
|
|
9679
9679
|
inputValue,
|
|
9680
9680
|
new _GraphQLError.GraphQLError(
|
|
9681
9681
|
`Expected type "${type.name}" to be an object.`
|
|
@@ -9693,7 +9693,7 @@ var require_coerceInputValue = __commonJS({
|
|
|
9693
9693
|
} else if ((0, _definition.isNonNullType)(field.type)) {
|
|
9694
9694
|
const typeStr = (0, _inspect.inspect)(field.type);
|
|
9695
9695
|
onError(
|
|
9696
|
-
(0, _Path.pathToArray)(
|
|
9696
|
+
(0, _Path.pathToArray)(path3),
|
|
9697
9697
|
inputValue,
|
|
9698
9698
|
new _GraphQLError.GraphQLError(
|
|
9699
9699
|
`Field "${field.name}" of required type "${typeStr}" was not provided.`
|
|
@@ -9706,7 +9706,7 @@ var require_coerceInputValue = __commonJS({
|
|
|
9706
9706
|
fieldValue,
|
|
9707
9707
|
field.type,
|
|
9708
9708
|
onError,
|
|
9709
|
-
(0, _Path.addPath)(
|
|
9709
|
+
(0, _Path.addPath)(path3, field.name, type.name)
|
|
9710
9710
|
);
|
|
9711
9711
|
}
|
|
9712
9712
|
for (const fieldName of Object.keys(inputValue)) {
|
|
@@ -9716,7 +9716,7 @@ var require_coerceInputValue = __commonJS({
|
|
|
9716
9716
|
Object.keys(type.getFields())
|
|
9717
9717
|
);
|
|
9718
9718
|
onError(
|
|
9719
|
-
(0, _Path.pathToArray)(
|
|
9719
|
+
(0, _Path.pathToArray)(path3),
|
|
9720
9720
|
inputValue,
|
|
9721
9721
|
new _GraphQLError.GraphQLError(
|
|
9722
9722
|
`Field "${fieldName}" is not defined by type "${type.name}".` + (0, _didYouMean.didYouMean)(suggestions)
|
|
@@ -9728,7 +9728,7 @@ var require_coerceInputValue = __commonJS({
|
|
|
9728
9728
|
const keys = Object.keys(coercedValue);
|
|
9729
9729
|
if (keys.length !== 1) {
|
|
9730
9730
|
onError(
|
|
9731
|
-
(0, _Path.pathToArray)(
|
|
9731
|
+
(0, _Path.pathToArray)(path3),
|
|
9732
9732
|
inputValue,
|
|
9733
9733
|
new _GraphQLError.GraphQLError(
|
|
9734
9734
|
`Exactly one key must be specified for OneOf type "${type.name}".`
|
|
@@ -9739,7 +9739,7 @@ var require_coerceInputValue = __commonJS({
|
|
|
9739
9739
|
const value = coercedValue[key];
|
|
9740
9740
|
if (value === null) {
|
|
9741
9741
|
onError(
|
|
9742
|
-
(0, _Path.pathToArray)(
|
|
9742
|
+
(0, _Path.pathToArray)(path3).concat(key),
|
|
9743
9743
|
value,
|
|
9744
9744
|
new _GraphQLError.GraphQLError(`Field "${key}" must be non-null.`)
|
|
9745
9745
|
);
|
|
@@ -9753,10 +9753,10 @@ var require_coerceInputValue = __commonJS({
|
|
|
9753
9753
|
parseResult = type.parseValue(inputValue);
|
|
9754
9754
|
} catch (error) {
|
|
9755
9755
|
if (error instanceof _GraphQLError.GraphQLError) {
|
|
9756
|
-
onError((0, _Path.pathToArray)(
|
|
9756
|
+
onError((0, _Path.pathToArray)(path3), inputValue, error);
|
|
9757
9757
|
} else {
|
|
9758
9758
|
onError(
|
|
9759
|
-
(0, _Path.pathToArray)(
|
|
9759
|
+
(0, _Path.pathToArray)(path3),
|
|
9760
9760
|
inputValue,
|
|
9761
9761
|
new _GraphQLError.GraphQLError(
|
|
9762
9762
|
`Expected type "${type.name}". ` + error.message,
|
|
@@ -9770,7 +9770,7 @@ var require_coerceInputValue = __commonJS({
|
|
|
9770
9770
|
}
|
|
9771
9771
|
if (parseResult === void 0) {
|
|
9772
9772
|
onError(
|
|
9773
|
-
(0, _Path.pathToArray)(
|
|
9773
|
+
(0, _Path.pathToArray)(path3),
|
|
9774
9774
|
inputValue,
|
|
9775
9775
|
new _GraphQLError.GraphQLError(`Expected type "${type.name}".`)
|
|
9776
9776
|
);
|
|
@@ -10011,11 +10011,11 @@ var require_values = __commonJS({
|
|
|
10011
10011
|
coercedValues[varName] = (0, _coerceInputValue.coerceInputValue)(
|
|
10012
10012
|
value,
|
|
10013
10013
|
varType,
|
|
10014
|
-
(
|
|
10014
|
+
(path3, invalidValue, error) => {
|
|
10015
10015
|
let prefix = `Variable "$${varName}" got invalid value ` + (0, _inspect.inspect)(invalidValue);
|
|
10016
|
-
if (
|
|
10016
|
+
if (path3.length > 0) {
|
|
10017
10017
|
prefix += ` at "${varName}${(0, _printPathArray.printPathArray)(
|
|
10018
|
-
|
|
10018
|
+
path3
|
|
10019
10019
|
)}"`;
|
|
10020
10020
|
}
|
|
10021
10021
|
onError(
|
|
@@ -11745,7 +11745,7 @@ var require_locatedError = __commonJS({
|
|
|
11745
11745
|
exports.locatedError = locatedError;
|
|
11746
11746
|
var _toError = require_toError();
|
|
11747
11747
|
var _GraphQLError = require_GraphQLError();
|
|
11748
|
-
function locatedError(rawOriginalError, nodes,
|
|
11748
|
+
function locatedError(rawOriginalError, nodes, path3) {
|
|
11749
11749
|
var _nodes;
|
|
11750
11750
|
const originalError = (0, _toError.toError)(rawOriginalError);
|
|
11751
11751
|
if (isLocatedGraphQLError(originalError)) {
|
|
@@ -11755,7 +11755,7 @@ var require_locatedError = __commonJS({
|
|
|
11755
11755
|
nodes: (_nodes = originalError.nodes) !== null && _nodes !== void 0 ? _nodes : nodes,
|
|
11756
11756
|
source: originalError.source,
|
|
11757
11757
|
positions: originalError.positions,
|
|
11758
|
-
path:
|
|
11758
|
+
path: path3,
|
|
11759
11759
|
originalError
|
|
11760
11760
|
});
|
|
11761
11761
|
}
|
|
@@ -11815,20 +11815,20 @@ var require_execute = __commonJS({
|
|
|
11815
11815
|
get errors() {
|
|
11816
11816
|
return this._errors;
|
|
11817
11817
|
}
|
|
11818
|
-
add(error,
|
|
11819
|
-
if (this._hasNulledPosition(
|
|
11818
|
+
add(error, path3) {
|
|
11819
|
+
if (this._hasNulledPosition(path3)) {
|
|
11820
11820
|
return;
|
|
11821
11821
|
}
|
|
11822
|
-
this._errorPositions.add(
|
|
11822
|
+
this._errorPositions.add(path3);
|
|
11823
11823
|
this._errors.push(error);
|
|
11824
11824
|
}
|
|
11825
11825
|
_hasNulledPosition(startPath) {
|
|
11826
|
-
let
|
|
11827
|
-
while (
|
|
11828
|
-
if (this._errorPositions.has(
|
|
11826
|
+
let path3 = startPath;
|
|
11827
|
+
while (path3 !== void 0) {
|
|
11828
|
+
if (this._errorPositions.has(path3)) {
|
|
11829
11829
|
return true;
|
|
11830
11830
|
}
|
|
11831
|
-
|
|
11831
|
+
path3 = path3.prev;
|
|
11832
11832
|
}
|
|
11833
11833
|
return this._errorPositions.has(void 0);
|
|
11834
11834
|
}
|
|
@@ -11977,27 +11977,27 @@ var require_execute = __commonJS({
|
|
|
11977
11977
|
rootType,
|
|
11978
11978
|
operation.selectionSet
|
|
11979
11979
|
);
|
|
11980
|
-
const
|
|
11980
|
+
const path3 = void 0;
|
|
11981
11981
|
switch (operation.operation) {
|
|
11982
11982
|
case _ast.OperationTypeNode.QUERY:
|
|
11983
|
-
return executeFields(exeContext, rootType, rootValue,
|
|
11983
|
+
return executeFields(exeContext, rootType, rootValue, path3, rootFields);
|
|
11984
11984
|
case _ast.OperationTypeNode.MUTATION:
|
|
11985
11985
|
return executeFieldsSerially(
|
|
11986
11986
|
exeContext,
|
|
11987
11987
|
rootType,
|
|
11988
11988
|
rootValue,
|
|
11989
|
-
|
|
11989
|
+
path3,
|
|
11990
11990
|
rootFields
|
|
11991
11991
|
);
|
|
11992
11992
|
case _ast.OperationTypeNode.SUBSCRIPTION:
|
|
11993
|
-
return executeFields(exeContext, rootType, rootValue,
|
|
11993
|
+
return executeFields(exeContext, rootType, rootValue, path3, rootFields);
|
|
11994
11994
|
}
|
|
11995
11995
|
}
|
|
11996
|
-
function executeFieldsSerially(exeContext, parentType, sourceValue,
|
|
11996
|
+
function executeFieldsSerially(exeContext, parentType, sourceValue, path3, fields) {
|
|
11997
11997
|
return (0, _promiseReduce.promiseReduce)(
|
|
11998
11998
|
fields.entries(),
|
|
11999
11999
|
(results, [responseName, fieldNodes]) => {
|
|
12000
|
-
const fieldPath = (0, _Path.addPath)(
|
|
12000
|
+
const fieldPath = (0, _Path.addPath)(path3, responseName, parentType.name);
|
|
12001
12001
|
const result = executeField(
|
|
12002
12002
|
exeContext,
|
|
12003
12003
|
parentType,
|
|
@@ -12020,12 +12020,12 @@ var require_execute = __commonJS({
|
|
|
12020
12020
|
/* @__PURE__ */ Object.create(null)
|
|
12021
12021
|
);
|
|
12022
12022
|
}
|
|
12023
|
-
function executeFields(exeContext, parentType, sourceValue,
|
|
12023
|
+
function executeFields(exeContext, parentType, sourceValue, path3, fields) {
|
|
12024
12024
|
const results = /* @__PURE__ */ Object.create(null);
|
|
12025
12025
|
let containsPromise = false;
|
|
12026
12026
|
try {
|
|
12027
12027
|
for (const [responseName, fieldNodes] of fields.entries()) {
|
|
12028
|
-
const fieldPath = (0, _Path.addPath)(
|
|
12028
|
+
const fieldPath = (0, _Path.addPath)(path3, responseName, parentType.name);
|
|
12029
12029
|
const result = executeField(
|
|
12030
12030
|
exeContext,
|
|
12031
12031
|
parentType,
|
|
@@ -12053,7 +12053,7 @@ var require_execute = __commonJS({
|
|
|
12053
12053
|
}
|
|
12054
12054
|
return (0, _promiseForObject.promiseForObject)(results);
|
|
12055
12055
|
}
|
|
12056
|
-
function executeField(exeContext, parentType, source, fieldNodes,
|
|
12056
|
+
function executeField(exeContext, parentType, source, fieldNodes, path3) {
|
|
12057
12057
|
var _fieldDef$resolve;
|
|
12058
12058
|
const fieldDef = getFieldDef(exeContext.schema, parentType, fieldNodes[0]);
|
|
12059
12059
|
if (!fieldDef) {
|
|
@@ -12066,7 +12066,7 @@ var require_execute = __commonJS({
|
|
|
12066
12066
|
fieldDef,
|
|
12067
12067
|
fieldNodes,
|
|
12068
12068
|
parentType,
|
|
12069
|
-
|
|
12069
|
+
path3
|
|
12070
12070
|
);
|
|
12071
12071
|
try {
|
|
12072
12072
|
const args = (0, _values.getArgumentValues)(
|
|
@@ -12079,7 +12079,7 @@ var require_execute = __commonJS({
|
|
|
12079
12079
|
let completed;
|
|
12080
12080
|
if ((0, _isPromise.isPromise)(result)) {
|
|
12081
12081
|
completed = result.then(
|
|
12082
|
-
(resolved) => completeValue(exeContext, returnType, fieldNodes, info,
|
|
12082
|
+
(resolved) => completeValue(exeContext, returnType, fieldNodes, info, path3, resolved)
|
|
12083
12083
|
);
|
|
12084
12084
|
} else {
|
|
12085
12085
|
completed = completeValue(
|
|
@@ -12087,7 +12087,7 @@ var require_execute = __commonJS({
|
|
|
12087
12087
|
returnType,
|
|
12088
12088
|
fieldNodes,
|
|
12089
12089
|
info,
|
|
12090
|
-
|
|
12090
|
+
path3,
|
|
12091
12091
|
result
|
|
12092
12092
|
);
|
|
12093
12093
|
}
|
|
@@ -12096,9 +12096,9 @@ var require_execute = __commonJS({
|
|
|
12096
12096
|
const error = (0, _locatedError.locatedError)(
|
|
12097
12097
|
rawError,
|
|
12098
12098
|
fieldNodes,
|
|
12099
|
-
(0, _Path.pathToArray)(
|
|
12099
|
+
(0, _Path.pathToArray)(path3)
|
|
12100
12100
|
);
|
|
12101
|
-
return handleFieldError(error, returnType,
|
|
12101
|
+
return handleFieldError(error, returnType, path3, exeContext);
|
|
12102
12102
|
});
|
|
12103
12103
|
}
|
|
12104
12104
|
return completed;
|
|
@@ -12106,18 +12106,18 @@ var require_execute = __commonJS({
|
|
|
12106
12106
|
const error = (0, _locatedError.locatedError)(
|
|
12107
12107
|
rawError,
|
|
12108
12108
|
fieldNodes,
|
|
12109
|
-
(0, _Path.pathToArray)(
|
|
12109
|
+
(0, _Path.pathToArray)(path3)
|
|
12110
12110
|
);
|
|
12111
|
-
return handleFieldError(error, returnType,
|
|
12111
|
+
return handleFieldError(error, returnType, path3, exeContext);
|
|
12112
12112
|
}
|
|
12113
12113
|
}
|
|
12114
|
-
function buildResolveInfo(exeContext, fieldDef, fieldNodes, parentType,
|
|
12114
|
+
function buildResolveInfo(exeContext, fieldDef, fieldNodes, parentType, path3) {
|
|
12115
12115
|
return {
|
|
12116
12116
|
fieldName: fieldDef.name,
|
|
12117
12117
|
fieldNodes,
|
|
12118
12118
|
returnType: fieldDef.type,
|
|
12119
12119
|
parentType,
|
|
12120
|
-
path:
|
|
12120
|
+
path: path3,
|
|
12121
12121
|
schema: exeContext.schema,
|
|
12122
12122
|
fragments: exeContext.fragments,
|
|
12123
12123
|
rootValue: exeContext.rootValue,
|
|
@@ -12125,14 +12125,14 @@ var require_execute = __commonJS({
|
|
|
12125
12125
|
variableValues: exeContext.variableValues
|
|
12126
12126
|
};
|
|
12127
12127
|
}
|
|
12128
|
-
function handleFieldError(error, returnType,
|
|
12128
|
+
function handleFieldError(error, returnType, path3, exeContext) {
|
|
12129
12129
|
if ((0, _definition.isNonNullType)(returnType)) {
|
|
12130
12130
|
throw error;
|
|
12131
12131
|
}
|
|
12132
|
-
exeContext.collectedErrors.add(error,
|
|
12132
|
+
exeContext.collectedErrors.add(error, path3);
|
|
12133
12133
|
return null;
|
|
12134
12134
|
}
|
|
12135
|
-
function completeValue(exeContext, returnType, fieldNodes, info,
|
|
12135
|
+
function completeValue(exeContext, returnType, fieldNodes, info, path3, result) {
|
|
12136
12136
|
if (result instanceof Error) {
|
|
12137
12137
|
throw result;
|
|
12138
12138
|
}
|
|
@@ -12142,7 +12142,7 @@ var require_execute = __commonJS({
|
|
|
12142
12142
|
returnType.ofType,
|
|
12143
12143
|
fieldNodes,
|
|
12144
12144
|
info,
|
|
12145
|
-
|
|
12145
|
+
path3,
|
|
12146
12146
|
result
|
|
12147
12147
|
);
|
|
12148
12148
|
if (completed === null) {
|
|
@@ -12161,7 +12161,7 @@ var require_execute = __commonJS({
|
|
|
12161
12161
|
returnType,
|
|
12162
12162
|
fieldNodes,
|
|
12163
12163
|
info,
|
|
12164
|
-
|
|
12164
|
+
path3,
|
|
12165
12165
|
result
|
|
12166
12166
|
);
|
|
12167
12167
|
}
|
|
@@ -12174,7 +12174,7 @@ var require_execute = __commonJS({
|
|
|
12174
12174
|
returnType,
|
|
12175
12175
|
fieldNodes,
|
|
12176
12176
|
info,
|
|
12177
|
-
|
|
12177
|
+
path3,
|
|
12178
12178
|
result
|
|
12179
12179
|
);
|
|
12180
12180
|
}
|
|
@@ -12184,7 +12184,7 @@ var require_execute = __commonJS({
|
|
|
12184
12184
|
returnType,
|
|
12185
12185
|
fieldNodes,
|
|
12186
12186
|
info,
|
|
12187
|
-
|
|
12187
|
+
path3,
|
|
12188
12188
|
result
|
|
12189
12189
|
);
|
|
12190
12190
|
}
|
|
@@ -12193,7 +12193,7 @@ var require_execute = __commonJS({
|
|
|
12193
12193
|
"Cannot complete value of unexpected output type: " + (0, _inspect.inspect)(returnType)
|
|
12194
12194
|
);
|
|
12195
12195
|
}
|
|
12196
|
-
function completeListValue(exeContext, returnType, fieldNodes, info,
|
|
12196
|
+
function completeListValue(exeContext, returnType, fieldNodes, info, path3, result) {
|
|
12197
12197
|
if (!(0, _isIterableObject.isIterableObject)(result)) {
|
|
12198
12198
|
throw new _GraphQLError.GraphQLError(
|
|
12199
12199
|
`Expected Iterable, but did not find one for field "${info.parentType.name}.${info.fieldName}".`
|
|
@@ -12202,7 +12202,7 @@ var require_execute = __commonJS({
|
|
|
12202
12202
|
const itemType = returnType.ofType;
|
|
12203
12203
|
let containsPromise = false;
|
|
12204
12204
|
const completedResults = Array.from(result, (item, index) => {
|
|
12205
|
-
const itemPath = (0, _Path.addPath)(
|
|
12205
|
+
const itemPath = (0, _Path.addPath)(path3, index, void 0);
|
|
12206
12206
|
try {
|
|
12207
12207
|
let completedItem;
|
|
12208
12208
|
if ((0, _isPromise.isPromise)(item)) {
|
|
@@ -12260,7 +12260,7 @@ var require_execute = __commonJS({
|
|
|
12260
12260
|
}
|
|
12261
12261
|
return serializedResult;
|
|
12262
12262
|
}
|
|
12263
|
-
function completeAbstractValue(exeContext, returnType, fieldNodes, info,
|
|
12263
|
+
function completeAbstractValue(exeContext, returnType, fieldNodes, info, path3, result) {
|
|
12264
12264
|
var _returnType$resolveTy;
|
|
12265
12265
|
const resolveTypeFn = (_returnType$resolveTy = returnType.resolveType) !== null && _returnType$resolveTy !== void 0 ? _returnType$resolveTy : exeContext.typeResolver;
|
|
12266
12266
|
const contextValue = exeContext.contextValue;
|
|
@@ -12279,7 +12279,7 @@ var require_execute = __commonJS({
|
|
|
12279
12279
|
),
|
|
12280
12280
|
fieldNodes,
|
|
12281
12281
|
info,
|
|
12282
|
-
|
|
12282
|
+
path3,
|
|
12283
12283
|
result
|
|
12284
12284
|
)
|
|
12285
12285
|
);
|
|
@@ -12296,7 +12296,7 @@ var require_execute = __commonJS({
|
|
|
12296
12296
|
),
|
|
12297
12297
|
fieldNodes,
|
|
12298
12298
|
info,
|
|
12299
|
-
|
|
12299
|
+
path3,
|
|
12300
12300
|
result
|
|
12301
12301
|
);
|
|
12302
12302
|
}
|
|
@@ -12344,7 +12344,7 @@ var require_execute = __commonJS({
|
|
|
12344
12344
|
}
|
|
12345
12345
|
return runtimeType;
|
|
12346
12346
|
}
|
|
12347
|
-
function completeObjectValue(exeContext, returnType, fieldNodes, info,
|
|
12347
|
+
function completeObjectValue(exeContext, returnType, fieldNodes, info, path3, result) {
|
|
12348
12348
|
const subFieldNodes = collectSubfields(exeContext, returnType, fieldNodes);
|
|
12349
12349
|
if (returnType.isTypeOf) {
|
|
12350
12350
|
const isTypeOf = returnType.isTypeOf(result, exeContext.contextValue, info);
|
|
@@ -12357,7 +12357,7 @@ var require_execute = __commonJS({
|
|
|
12357
12357
|
exeContext,
|
|
12358
12358
|
returnType,
|
|
12359
12359
|
result,
|
|
12360
|
-
|
|
12360
|
+
path3,
|
|
12361
12361
|
subFieldNodes
|
|
12362
12362
|
);
|
|
12363
12363
|
});
|
|
@@ -12366,7 +12366,7 @@ var require_execute = __commonJS({
|
|
|
12366
12366
|
throw invalidReturnTypeError(returnType, result, fieldNodes);
|
|
12367
12367
|
}
|
|
12368
12368
|
}
|
|
12369
|
-
return executeFields(exeContext, returnType, result,
|
|
12369
|
+
return executeFields(exeContext, returnType, result, path3, subFieldNodes);
|
|
12370
12370
|
}
|
|
12371
12371
|
function invalidReturnTypeError(returnType, result, fieldNodes) {
|
|
12372
12372
|
return new _GraphQLError.GraphQLError(
|
|
@@ -12448,7 +12448,7 @@ var require_graphql = __commonJS({
|
|
|
12448
12448
|
var _validate2 = require_validate2();
|
|
12449
12449
|
var _execute = require_execute();
|
|
12450
12450
|
function graphql(args) {
|
|
12451
|
-
return new Promise((
|
|
12451
|
+
return new Promise((resolve6) => resolve6(graphqlImpl(args)));
|
|
12452
12452
|
}
|
|
12453
12453
|
function graphqlSync(args) {
|
|
12454
12454
|
const result = graphqlImpl(args);
|
|
@@ -13450,13 +13450,13 @@ var require_subscribe = __commonJS({
|
|
|
13450
13450
|
}
|
|
13451
13451
|
);
|
|
13452
13452
|
}
|
|
13453
|
-
const
|
|
13453
|
+
const path3 = (0, _Path.addPath)(void 0, responseName, rootType.name);
|
|
13454
13454
|
const info = (0, _execute.buildResolveInfo)(
|
|
13455
13455
|
exeContext,
|
|
13456
13456
|
fieldDef,
|
|
13457
13457
|
fieldNodes,
|
|
13458
13458
|
rootType,
|
|
13459
|
-
|
|
13459
|
+
path3
|
|
13460
13460
|
);
|
|
13461
13461
|
try {
|
|
13462
13462
|
var _fieldDef$subscribe;
|
|
@@ -13476,7 +13476,7 @@ var require_subscribe = __commonJS({
|
|
|
13476
13476
|
throw (0, _locatedError.locatedError)(
|
|
13477
13477
|
error,
|
|
13478
13478
|
fieldNodes,
|
|
13479
|
-
(0, _Path.pathToArray)(
|
|
13479
|
+
(0, _Path.pathToArray)(path3)
|
|
13480
13480
|
);
|
|
13481
13481
|
}
|
|
13482
13482
|
}
|
|
@@ -17797,7 +17797,7 @@ var require_graphql2 = __commonJS({
|
|
|
17797
17797
|
});
|
|
17798
17798
|
|
|
17799
17799
|
// src/cli/index.ts
|
|
17800
|
-
import { Command as
|
|
17800
|
+
import { Command as Command16 } from "commander";
|
|
17801
17801
|
|
|
17802
17802
|
// src/cli/commands/bootstrap.ts
|
|
17803
17803
|
import { Command, Option as Option2 } from "commander";
|
|
@@ -18412,6 +18412,13 @@ var StackTerminationProtectionError = class _StackTerminationProtectionError ext
|
|
|
18412
18412
|
Object.setPrototypeOf(this, _StackTerminationProtectionError.prototype);
|
|
18413
18413
|
}
|
|
18414
18414
|
};
|
|
18415
|
+
var RouteDiscoveryError = class _RouteDiscoveryError extends CdkdError {
|
|
18416
|
+
constructor(message, cause) {
|
|
18417
|
+
super(message, "ROUTE_DISCOVERY_ERROR", cause);
|
|
18418
|
+
this.name = "RouteDiscoveryError";
|
|
18419
|
+
Object.setPrototypeOf(this, _RouteDiscoveryError.prototype);
|
|
18420
|
+
}
|
|
18421
|
+
};
|
|
18415
18422
|
function isCdkdError(error) {
|
|
18416
18423
|
return error instanceof CdkdError;
|
|
18417
18424
|
}
|
|
@@ -18862,7 +18869,7 @@ var IntrinsicFunctionResolver = class {
|
|
|
18862
18869
|
this.logger.debug(
|
|
18863
18870
|
`VPC ${physicalId} IPv6 CIDR still associating (attempt ${attempt}/${maxAttempts}), waiting...`
|
|
18864
18871
|
);
|
|
18865
|
-
await new Promise((
|
|
18872
|
+
await new Promise((resolve6) => setTimeout(resolve6, 2e3));
|
|
18866
18873
|
}
|
|
18867
18874
|
this.logger.warn(
|
|
18868
18875
|
`VPC ${physicalId} IPv6 CIDR did not reach 'associated' state after ${maxAttempts} attempts`
|
|
@@ -19747,7 +19754,7 @@ var DagExecutor = class {
|
|
|
19747
19754
|
async execute(concurrency, fn, cancelled = () => false) {
|
|
19748
19755
|
let active = 0;
|
|
19749
19756
|
const errors = [];
|
|
19750
|
-
return new Promise((
|
|
19757
|
+
return new Promise((resolve6, reject) => {
|
|
19751
19758
|
const dispatch = () => {
|
|
19752
19759
|
let changed = true;
|
|
19753
19760
|
while (changed) {
|
|
@@ -19809,7 +19816,7 @@ var DagExecutor = class {
|
|
|
19809
19816
|
);
|
|
19810
19817
|
return;
|
|
19811
19818
|
}
|
|
19812
|
-
|
|
19819
|
+
resolve6();
|
|
19813
19820
|
}
|
|
19814
19821
|
};
|
|
19815
19822
|
dispatch();
|
|
@@ -20490,7 +20497,7 @@ Error: ${err.message || "Unknown error"}`,
|
|
|
20490
20497
|
* Sleep for specified milliseconds
|
|
20491
20498
|
*/
|
|
20492
20499
|
sleep(ms) {
|
|
20493
|
-
return new Promise((
|
|
20500
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
20494
20501
|
}
|
|
20495
20502
|
/**
|
|
20496
20503
|
* Check if a resource type is supported by Cloud Control API
|
|
@@ -21224,7 +21231,7 @@ var CustomResourceProvider = class _CustomResourceProvider {
|
|
|
21224
21231
|
return result;
|
|
21225
21232
|
}
|
|
21226
21233
|
sleep(ms) {
|
|
21227
|
-
return new Promise((
|
|
21234
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
21228
21235
|
}
|
|
21229
21236
|
/**
|
|
21230
21237
|
* Adopt an existing custom resource into cdkd state.
|
|
@@ -21654,7 +21661,7 @@ function isRetryableTransientError(error, message) {
|
|
|
21654
21661
|
}
|
|
21655
21662
|
|
|
21656
21663
|
// src/deployment/retry.ts
|
|
21657
|
-
var defaultSleep = (ms) => new Promise((
|
|
21664
|
+
var defaultSleep = (ms) => new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
21658
21665
|
async function withRetry(operation, logicalId, opts = {}) {
|
|
21659
21666
|
const maxRetries = opts.maxRetries ?? 8;
|
|
21660
21667
|
const initialDelayMs = opts.initialDelayMs ?? 1e3;
|
|
@@ -21709,7 +21716,7 @@ function validateOptions(opts) {
|
|
|
21709
21716
|
async function withResourceDeadline(operation, opts) {
|
|
21710
21717
|
validateOptions(opts);
|
|
21711
21718
|
const startedAt = Date.now();
|
|
21712
|
-
return new Promise((
|
|
21719
|
+
return new Promise((resolve6, reject) => {
|
|
21713
21720
|
let settled = false;
|
|
21714
21721
|
let warnTimer;
|
|
21715
21722
|
let timeoutTimer;
|
|
@@ -21749,7 +21756,7 @@ async function withResourceDeadline(operation, opts) {
|
|
|
21749
21756
|
return;
|
|
21750
21757
|
settled = true;
|
|
21751
21758
|
cleanup();
|
|
21752
|
-
|
|
21759
|
+
resolve6(value);
|
|
21753
21760
|
},
|
|
21754
21761
|
(err) => {
|
|
21755
21762
|
if (settled)
|
|
@@ -23320,6 +23327,41 @@ var contextOptions = [
|
|
|
23320
23327
|
"Set context values (can be specified multiple times)"
|
|
23321
23328
|
)
|
|
23322
23329
|
];
|
|
23330
|
+
var IAM_ROLE_ARN_REGEX = /^arn:[^:]+:iam::\d+:role\//;
|
|
23331
|
+
function parseAssumeRoleToken(raw, previous) {
|
|
23332
|
+
const acc = previous ?? { perLambda: {} };
|
|
23333
|
+
if (!acc.perLambda)
|
|
23334
|
+
acc.perLambda = {};
|
|
23335
|
+
const eqIndex = raw.indexOf("=");
|
|
23336
|
+
if (eqIndex === -1) {
|
|
23337
|
+
if (!IAM_ROLE_ARN_REGEX.test(raw)) {
|
|
23338
|
+
throw new Error(
|
|
23339
|
+
`Invalid --assume-role value "${raw}": expected an IAM role ARN like arn:aws:iam::123456789012:role/MyRole, or LogicalId=<arn>.`
|
|
23340
|
+
);
|
|
23341
|
+
}
|
|
23342
|
+
acc.globalArn = raw;
|
|
23343
|
+
return acc;
|
|
23344
|
+
}
|
|
23345
|
+
const logicalId = raw.substring(0, eqIndex).trim();
|
|
23346
|
+
const arn = raw.substring(eqIndex + 1).trim();
|
|
23347
|
+
if (!/^[A-Za-z][A-Za-z0-9]*$/.test(logicalId)) {
|
|
23348
|
+
throw new Error(
|
|
23349
|
+
`Invalid --assume-role value "${raw}": left-hand side "${logicalId}" must be a CloudFormation logical ID (alphanumeric, leading letter).`
|
|
23350
|
+
);
|
|
23351
|
+
}
|
|
23352
|
+
if (!IAM_ROLE_ARN_REGEX.test(arn)) {
|
|
23353
|
+
throw new Error(
|
|
23354
|
+
`Invalid --assume-role value "${raw}": right-hand side "${arn}" must be an IAM role ARN like arn:aws:iam::123456789012:role/MyRole.`
|
|
23355
|
+
);
|
|
23356
|
+
}
|
|
23357
|
+
acc.perLambda[logicalId] = arn;
|
|
23358
|
+
return acc;
|
|
23359
|
+
}
|
|
23360
|
+
function effectiveAssumeRoleArn(logicalId, opt) {
|
|
23361
|
+
if (!opt)
|
|
23362
|
+
return void 0;
|
|
23363
|
+
return opt.perLambda?.[logicalId] ?? opt.globalArn;
|
|
23364
|
+
}
|
|
23323
23365
|
var destroyOptions = [
|
|
23324
23366
|
new Option("-f, --force", "Do not ask for confirmation before destroying the stacks").default(
|
|
23325
23367
|
false
|
|
@@ -23749,7 +23791,7 @@ var AppExecutor = class {
|
|
|
23749
23791
|
* Spawn subprocess and wait for completion
|
|
23750
23792
|
*/
|
|
23751
23793
|
spawn(commandLine, env) {
|
|
23752
|
-
return new Promise((
|
|
23794
|
+
return new Promise((resolve6, reject) => {
|
|
23753
23795
|
const proc = spawn(commandLine, {
|
|
23754
23796
|
stdio: ["ignore", "pipe", "pipe"],
|
|
23755
23797
|
shell: true,
|
|
@@ -23775,7 +23817,7 @@ var AppExecutor = class {
|
|
|
23775
23817
|
});
|
|
23776
23818
|
proc.on("close", (code) => {
|
|
23777
23819
|
if (code === 0) {
|
|
23778
|
-
|
|
23820
|
+
resolve6();
|
|
23779
23821
|
} else {
|
|
23780
23822
|
const stderr = stderrChunks.join("\n");
|
|
23781
23823
|
reject(
|
|
@@ -24487,8 +24529,8 @@ var CcApiContextProvider = class {
|
|
|
24487
24529
|
/**
|
|
24488
24530
|
* Get nested property value using dot notation
|
|
24489
24531
|
*/
|
|
24490
|
-
getNestedProperty(obj,
|
|
24491
|
-
const parts =
|
|
24532
|
+
getNestedProperty(obj, path3) {
|
|
24533
|
+
const parts = path3.split(".");
|
|
24492
24534
|
let current = obj;
|
|
24493
24535
|
for (const part of parts) {
|
|
24494
24536
|
if (current === null || current === void 0 || typeof current !== "object") {
|
|
@@ -25297,11 +25339,11 @@ var FileAssetPublisher = class {
|
|
|
25297
25339
|
*/
|
|
25298
25340
|
async uploadZip(client, dirPath, bucket, key) {
|
|
25299
25341
|
const archiver = await import("archiver");
|
|
25300
|
-
const body = await new Promise((
|
|
25342
|
+
const body = await new Promise((resolve6, reject) => {
|
|
25301
25343
|
const chunks = [];
|
|
25302
25344
|
const archive = archiver.default("zip", { zlib: { level: 9 } });
|
|
25303
25345
|
archive.on("data", (chunk) => chunks.push(chunk));
|
|
25304
|
-
archive.on("end", () =>
|
|
25346
|
+
archive.on("end", () => resolve6(Buffer.concat(chunks)));
|
|
25305
25347
|
archive.on("error", reject);
|
|
25306
25348
|
const stat = statSync2(dirPath);
|
|
25307
25349
|
if (stat.isDirectory()) {
|
|
@@ -25486,7 +25528,7 @@ var DockerAssetPublisher = class {
|
|
|
25486
25528
|
const token = Buffer.from(authData.authorizationToken, "base64").toString();
|
|
25487
25529
|
const [username, password] = token.split(":");
|
|
25488
25530
|
const endpoint = authData.proxyEndpoint || `https://${accountId}.dkr.ecr.${region}.amazonaws.com`;
|
|
25489
|
-
await new Promise((
|
|
25531
|
+
await new Promise((resolve6, reject) => {
|
|
25490
25532
|
const proc = spawn2(
|
|
25491
25533
|
"docker",
|
|
25492
25534
|
["login", "--username", username, "--password-stdin", endpoint],
|
|
@@ -25500,7 +25542,7 @@ var DockerAssetPublisher = class {
|
|
|
25500
25542
|
});
|
|
25501
25543
|
proc.on("close", (code) => {
|
|
25502
25544
|
if (code === 0) {
|
|
25503
|
-
|
|
25545
|
+
resolve6();
|
|
25504
25546
|
} else {
|
|
25505
25547
|
reject(new AssetError(`ECR login failed: ${stderr.trim()}`));
|
|
25506
25548
|
}
|
|
@@ -25553,7 +25595,7 @@ var WorkGraph = class {
|
|
|
25553
25595
|
async execute(concurrency, fn) {
|
|
25554
25596
|
const active = { "asset-build": 0, "asset-publish": 0, stack: 0 };
|
|
25555
25597
|
const errors = [];
|
|
25556
|
-
return new Promise((
|
|
25598
|
+
return new Promise((resolve6, reject) => {
|
|
25557
25599
|
const dispatch = () => {
|
|
25558
25600
|
const ready = [];
|
|
25559
25601
|
for (const node of this.nodes.values()) {
|
|
@@ -25625,7 +25667,7 @@ ${msg}`
|
|
|
25625
25667
|
);
|
|
25626
25668
|
return;
|
|
25627
25669
|
}
|
|
25628
|
-
|
|
25670
|
+
resolve6();
|
|
25629
25671
|
}
|
|
25630
25672
|
};
|
|
25631
25673
|
dispatch();
|
|
@@ -26616,7 +26658,7 @@ var LockManager = class {
|
|
|
26616
26658
|
this.logger.info(
|
|
26617
26659
|
`Stack '${stackName}' (${region}) is locked by ${lockInfo2.owner}${lockInfo2.operation ? ` (operation: ${lockInfo2.operation})` : ""}. Lock expires in ${this.formatDuration(remainingMs)}. Retrying in ${this.formatDuration(retryDelay)}... (attempt ${attempt + 1}/${maxRetries})`
|
|
26618
26660
|
);
|
|
26619
|
-
await new Promise((
|
|
26661
|
+
await new Promise((resolve6) => setTimeout(resolve6, retryDelay));
|
|
26620
26662
|
continue;
|
|
26621
26663
|
}
|
|
26622
26664
|
}
|
|
@@ -26864,11 +26906,11 @@ var DagBuilder = class {
|
|
|
26864
26906
|
const cycles = [];
|
|
26865
26907
|
const visited = /* @__PURE__ */ new Set();
|
|
26866
26908
|
const recursionStack = /* @__PURE__ */ new Set();
|
|
26867
|
-
const
|
|
26909
|
+
const path3 = [];
|
|
26868
26910
|
const dfs = (node) => {
|
|
26869
26911
|
visited.add(node);
|
|
26870
26912
|
recursionStack.add(node);
|
|
26871
|
-
|
|
26913
|
+
path3.push(node);
|
|
26872
26914
|
const successors = graph.successors(node) || [];
|
|
26873
26915
|
for (const successor of successors) {
|
|
26874
26916
|
if (!visited.has(successor)) {
|
|
@@ -26876,14 +26918,14 @@ var DagBuilder = class {
|
|
|
26876
26918
|
return true;
|
|
26877
26919
|
}
|
|
26878
26920
|
} else if (recursionStack.has(successor)) {
|
|
26879
|
-
const cycleStart =
|
|
26880
|
-
const cycle =
|
|
26921
|
+
const cycleStart = path3.indexOf(successor);
|
|
26922
|
+
const cycle = path3.slice(cycleStart);
|
|
26881
26923
|
cycle.push(successor);
|
|
26882
26924
|
cycles.push(cycle);
|
|
26883
26925
|
return true;
|
|
26884
26926
|
}
|
|
26885
26927
|
}
|
|
26886
|
-
|
|
26928
|
+
path3.pop();
|
|
26887
26929
|
recursionStack.delete(node);
|
|
26888
26930
|
return false;
|
|
26889
26931
|
};
|
|
@@ -28911,13 +28953,13 @@ var IAMInstanceProfileProvider = class {
|
|
|
28911
28953
|
properties["InstanceProfileName"] || logicalId,
|
|
28912
28954
|
{ maxLength: 128 }
|
|
28913
28955
|
);
|
|
28914
|
-
const
|
|
28956
|
+
const path3 = properties["Path"] || "/";
|
|
28915
28957
|
const roles = properties["Roles"];
|
|
28916
28958
|
try {
|
|
28917
28959
|
const response = await this.iamClient.send(
|
|
28918
28960
|
new CreateInstanceProfileCommand({
|
|
28919
28961
|
InstanceProfileName: instanceProfileName,
|
|
28920
|
-
Path:
|
|
28962
|
+
Path: path3
|
|
28921
28963
|
})
|
|
28922
28964
|
);
|
|
28923
28965
|
this.logger.debug(`Created IAM instance profile: ${instanceProfileName}`);
|
|
@@ -35110,7 +35152,7 @@ var LambdaFunctionProvider = class {
|
|
|
35110
35152
|
return enis;
|
|
35111
35153
|
}
|
|
35112
35154
|
sleep(ms) {
|
|
35113
|
-
return new Promise((
|
|
35155
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
35114
35156
|
}
|
|
35115
35157
|
/**
|
|
35116
35158
|
* Build Lambda Code parameter from CDK properties
|
|
@@ -36987,7 +37029,7 @@ var DynamoDBTableProvider = class {
|
|
|
36987
37029
|
if (status !== "CREATING") {
|
|
36988
37030
|
throw new Error(`Unexpected table status: ${status}`);
|
|
36989
37031
|
}
|
|
36990
|
-
await new Promise((
|
|
37032
|
+
await new Promise((resolve6) => setTimeout(resolve6, 1e3));
|
|
36991
37033
|
}
|
|
36992
37034
|
throw new Error(`Table ${tableName} did not reach ACTIVE status within ${maxAttempts} seconds`);
|
|
36993
37035
|
}
|
|
@@ -37007,7 +37049,7 @@ var DynamoDBTableProvider = class {
|
|
|
37007
37049
|
if (status === "ACTIVE") {
|
|
37008
37050
|
return;
|
|
37009
37051
|
}
|
|
37010
|
-
await new Promise((
|
|
37052
|
+
await new Promise((resolve6) => setTimeout(resolve6, 1e3));
|
|
37011
37053
|
}
|
|
37012
37054
|
throw new Error(
|
|
37013
37055
|
`Table ${tableName} did not reach ACTIVE status within ${maxAttempts} seconds after UpdateTable`
|
|
@@ -40187,7 +40229,7 @@ var EC2Provider = class {
|
|
|
40187
40229
|
this.logger.debug(
|
|
40188
40230
|
`VPC ${physicalId} has dependencies (attempt ${attempt}/${maxAttempts}), retrying in ${attempt * 5}s...`
|
|
40189
40231
|
);
|
|
40190
|
-
await new Promise((
|
|
40232
|
+
await new Promise((resolve6) => setTimeout(resolve6, attempt * 5e3));
|
|
40191
40233
|
continue;
|
|
40192
40234
|
}
|
|
40193
40235
|
const cause = error instanceof Error ? error : void 0;
|
|
@@ -40351,7 +40393,7 @@ var EC2Provider = class {
|
|
|
40351
40393
|
this.logger.debug(
|
|
40352
40394
|
`Subnet ${physicalId} has dependencies (attempt ${attempt}/${maxAttempts}), retrying in ${attempt * 5}s...`
|
|
40353
40395
|
);
|
|
40354
|
-
await new Promise((
|
|
40396
|
+
await new Promise((resolve6) => setTimeout(resolve6, attempt * 5e3));
|
|
40355
40397
|
continue;
|
|
40356
40398
|
}
|
|
40357
40399
|
const cause = error instanceof Error ? error : void 0;
|
|
@@ -41109,7 +41151,7 @@ var EC2Provider = class {
|
|
|
41109
41151
|
this.logger.debug(
|
|
41110
41152
|
`SecurityGroup ${physicalId} has dependent objects (attempt ${attempt}/${maxAttempts}), retrying in ${attempt * 5}s...`
|
|
41111
41153
|
);
|
|
41112
|
-
await new Promise((
|
|
41154
|
+
await new Promise((resolve6) => setTimeout(resolve6, attempt * 5e3));
|
|
41113
41155
|
continue;
|
|
41114
41156
|
}
|
|
41115
41157
|
const cause = error instanceof Error ? error : void 0;
|
|
@@ -42053,7 +42095,7 @@ var EC2Provider = class {
|
|
|
42053
42095
|
* `setTimeout` globally.
|
|
42054
42096
|
*/
|
|
42055
42097
|
sleep(ms) {
|
|
42056
|
-
return new Promise((
|
|
42098
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
42057
42099
|
}
|
|
42058
42100
|
/**
|
|
42059
42101
|
* Check if an error indicates the resource was not found
|
|
@@ -43334,13 +43376,13 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
43334
43376
|
{ key: "IdentityValidationExpression", path: "/identityValidationExpression" },
|
|
43335
43377
|
{ key: "AuthorizerResultTtlInSeconds", path: "/authorizerResultTtlInSeconds" }
|
|
43336
43378
|
];
|
|
43337
|
-
for (const { key, path:
|
|
43379
|
+
for (const { key, path: path3 } of primitiveFields) {
|
|
43338
43380
|
const newVal = properties[key];
|
|
43339
43381
|
const prevVal = previousProperties[key];
|
|
43340
43382
|
if (newVal !== prevVal) {
|
|
43341
43383
|
patchOperations.push({
|
|
43342
43384
|
op: "replace",
|
|
43343
|
-
path:
|
|
43385
|
+
path: path3,
|
|
43344
43386
|
value: newVal !== void 0 ? String(newVal) : ""
|
|
43345
43387
|
});
|
|
43346
43388
|
}
|
|
@@ -43976,13 +44018,13 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
43976
44018
|
{ key: "OperationName", path: "/operationName" },
|
|
43977
44019
|
{ key: "RequestValidatorId", path: "/requestValidatorId" }
|
|
43978
44020
|
];
|
|
43979
|
-
for (const { key, path:
|
|
44021
|
+
for (const { key, path: path3 } of primitiveFields) {
|
|
43980
44022
|
const newVal = properties[key];
|
|
43981
44023
|
const prevVal = previousProperties[key];
|
|
43982
44024
|
if (newVal !== prevVal) {
|
|
43983
44025
|
patchOperations.push({
|
|
43984
44026
|
op: "replace",
|
|
43985
|
-
path:
|
|
44027
|
+
path: path3,
|
|
43986
44028
|
value: newVal !== void 0 ? String(newVal) : ""
|
|
43987
44029
|
});
|
|
43988
44030
|
}
|
|
@@ -44153,7 +44195,7 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
44153
44195
|
* Sleep for specified milliseconds
|
|
44154
44196
|
*/
|
|
44155
44197
|
sleep(ms) {
|
|
44156
|
-
return new Promise((
|
|
44198
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
44157
44199
|
}
|
|
44158
44200
|
/**
|
|
44159
44201
|
* Convert CloudFormation Tags (Array<{Key, Value}>) to SDK tags (Record<string, string>).
|
|
@@ -44355,12 +44397,12 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
44355
44397
|
function appendMapPatchOps(ops, basePath, next, prev) {
|
|
44356
44398
|
const escape = (k) => k.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
44357
44399
|
for (const [key, val] of Object.entries(next)) {
|
|
44358
|
-
const
|
|
44400
|
+
const path3 = `${basePath}/${escape(key)}`;
|
|
44359
44401
|
const stringValue = String(val);
|
|
44360
44402
|
if (!(key in prev)) {
|
|
44361
|
-
ops.push({ op: "add", path:
|
|
44403
|
+
ops.push({ op: "add", path: path3, value: stringValue });
|
|
44362
44404
|
} else if (String(prev[key]) !== stringValue) {
|
|
44363
|
-
ops.push({ op: "replace", path:
|
|
44405
|
+
ops.push({ op: "replace", path: path3, value: stringValue });
|
|
44364
44406
|
}
|
|
44365
44407
|
}
|
|
44366
44408
|
for (const key of Object.keys(prev)) {
|
|
@@ -46045,7 +46087,7 @@ var CloudFrontDistributionProvider = class {
|
|
|
46045
46087
|
);
|
|
46046
46088
|
const sleepEnd = Date.now() + delay2;
|
|
46047
46089
|
while (Date.now() < sleepEnd && !interrupted) {
|
|
46048
|
-
await new Promise((
|
|
46090
|
+
await new Promise((resolve6) => setTimeout(resolve6, 1e3));
|
|
46049
46091
|
}
|
|
46050
46092
|
delay2 = Math.min(delay2 * 1.5, maxDelay);
|
|
46051
46093
|
}
|
|
@@ -46165,17 +46207,17 @@ var CloudFrontDistributionProvider = class {
|
|
|
46165
46207
|
/**
|
|
46166
46208
|
* Apply Quantity wrapping at a nested path (e.g., "ForwardedValues.Headers").
|
|
46167
46209
|
*/
|
|
46168
|
-
applyQuantityAtPath(obj,
|
|
46169
|
-
if (
|
|
46210
|
+
applyQuantityAtPath(obj, path3) {
|
|
46211
|
+
if (path3.length === 0)
|
|
46170
46212
|
return;
|
|
46171
|
-
if (
|
|
46172
|
-
const key =
|
|
46213
|
+
if (path3.length === 1) {
|
|
46214
|
+
const key = path3[0];
|
|
46173
46215
|
if (obj[key] !== void 0) {
|
|
46174
46216
|
obj[key] = this.wrapWithQuantity(obj[key]);
|
|
46175
46217
|
}
|
|
46176
46218
|
return;
|
|
46177
46219
|
}
|
|
46178
|
-
const [head, ...rest] =
|
|
46220
|
+
const [head, ...rest] = path3;
|
|
46179
46221
|
const headKey = head;
|
|
46180
46222
|
if (obj[headKey] && typeof obj[headKey] === "object") {
|
|
46181
46223
|
const nested = { ...obj[headKey] };
|
|
@@ -49857,7 +49899,7 @@ var RDSProvider = class {
|
|
|
49857
49899
|
throw new Error(`Timed out waiting for DBInstance ${dbInstanceIdentifier} to be deleted`);
|
|
49858
49900
|
}
|
|
49859
49901
|
sleep(ms) {
|
|
49860
|
-
return new Promise((
|
|
49902
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
49861
49903
|
}
|
|
49862
49904
|
/**
|
|
49863
49905
|
* Adopt an existing RDS resource into cdkd state.
|
|
@@ -50842,7 +50884,7 @@ var DocDBProvider = class {
|
|
|
50842
50884
|
throw new Error(`Timed out waiting for DocDB DBInstance ${dbInstanceIdentifier} to be deleted`);
|
|
50843
50885
|
}
|
|
50844
50886
|
sleep(ms) {
|
|
50845
|
-
return new Promise((
|
|
50887
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
50846
50888
|
}
|
|
50847
50889
|
/**
|
|
50848
50890
|
* Adopt an existing DocDB resource into cdkd state.
|
|
@@ -51832,7 +51874,7 @@ var NeptuneProvider = class {
|
|
|
51832
51874
|
);
|
|
51833
51875
|
}
|
|
51834
51876
|
sleep(ms) {
|
|
51835
|
-
return new Promise((
|
|
51877
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
51836
51878
|
}
|
|
51837
51879
|
/**
|
|
51838
51880
|
* Adopt an existing Neptune resource into cdkd state.
|
|
@@ -54372,7 +54414,7 @@ var ElastiCacheProvider = class {
|
|
|
54372
54414
|
throw new Error(`Timed out waiting for CacheCluster ${cacheClusterId} to be deleted`);
|
|
54373
54415
|
}
|
|
54374
54416
|
sleep(ms) {
|
|
54375
|
-
return new Promise((
|
|
54417
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
54376
54418
|
}
|
|
54377
54419
|
/**
|
|
54378
54420
|
* Read the AWS-current ElastiCache resource configuration in CFn-property shape.
|
|
@@ -55087,7 +55129,7 @@ var ServiceDiscoveryProvider = class {
|
|
|
55087
55129
|
logicalId
|
|
55088
55130
|
);
|
|
55089
55131
|
}
|
|
55090
|
-
await new Promise((
|
|
55132
|
+
await new Promise((resolve6) => setTimeout(resolve6, delay2));
|
|
55091
55133
|
delay2 = Math.min(delay2 * 2, 1e4);
|
|
55092
55134
|
}
|
|
55093
55135
|
throw new ProvisioningError(
|
|
@@ -59612,7 +59654,7 @@ var KinesisStreamProvider = class {
|
|
|
59612
59654
|
if (status !== "CREATING" && status !== "UPDATING") {
|
|
59613
59655
|
throw new Error(`Unexpected stream status: ${status}`);
|
|
59614
59656
|
}
|
|
59615
|
-
await new Promise((
|
|
59657
|
+
await new Promise((resolve6) => setTimeout(resolve6, 2e3));
|
|
59616
59658
|
}
|
|
59617
59659
|
throw new Error(
|
|
59618
59660
|
`Stream ${streamName} did not reach ACTIVE status within ${maxAttempts * 2} seconds`
|
|
@@ -59945,7 +59987,7 @@ var KinesisStreamConsumerProvider = class {
|
|
|
59945
59987
|
if (status !== "CREATING") {
|
|
59946
59988
|
throw new Error(`Unexpected consumer status: ${status}`);
|
|
59947
59989
|
}
|
|
59948
|
-
await new Promise((
|
|
59990
|
+
await new Promise((resolve6) => setTimeout(resolve6, 1e3));
|
|
59949
59991
|
}
|
|
59950
59992
|
throw new Error(
|
|
59951
59993
|
`Consumer ${consumerArn} did not reach ACTIVE status within ${maxAttempts} seconds`
|
|
@@ -60250,7 +60292,7 @@ var EFSProvider = class {
|
|
|
60250
60292
|
this.logger.debug(
|
|
60251
60293
|
`FileSystem ${fileSystemId} state: ${fs?.LifeCycleState ?? "unknown"}, waiting...`
|
|
60252
60294
|
);
|
|
60253
|
-
await new Promise((
|
|
60295
|
+
await new Promise((resolve6) => setTimeout(resolve6, pollIntervalMs));
|
|
60254
60296
|
}
|
|
60255
60297
|
throw new ProvisioningError(
|
|
60256
60298
|
`Timed out waiting for EFS FileSystem ${fileSystemId} to become available (60s)`,
|
|
@@ -60328,7 +60370,7 @@ var EFSProvider = class {
|
|
|
60328
60370
|
this.logger.debug(
|
|
60329
60371
|
`MountTarget ${mountTargetId} state: ${mountTarget?.LifeCycleState ?? "unknown"}, waiting...`
|
|
60330
60372
|
);
|
|
60331
|
-
await new Promise((
|
|
60373
|
+
await new Promise((resolve6) => setTimeout(resolve6, pollIntervalMs));
|
|
60332
60374
|
}
|
|
60333
60375
|
throw new ProvisioningError(
|
|
60334
60376
|
`Timed out waiting for EFS MountTarget ${mountTargetId} to become available (120s)`,
|
|
@@ -60394,7 +60436,7 @@ var EFSProvider = class {
|
|
|
60394
60436
|
}
|
|
60395
60437
|
throw error;
|
|
60396
60438
|
}
|
|
60397
|
-
await new Promise((
|
|
60439
|
+
await new Promise((resolve6) => setTimeout(resolve6, pollIntervalMs));
|
|
60398
60440
|
}
|
|
60399
60441
|
this.logger.warn(
|
|
60400
60442
|
`Timed out waiting for EFS MountTarget ${mountTargetId} deletion for ${logicalId} (120s)`
|
|
@@ -61352,7 +61394,7 @@ var FirehoseProvider = class {
|
|
|
61352
61394
|
this.logger.debug(
|
|
61353
61395
|
`Firehose ${logicalId} status: ${status} (attempt ${attempt}/${maxAttempts})`
|
|
61354
61396
|
);
|
|
61355
|
-
await new Promise((
|
|
61397
|
+
await new Promise((resolve6) => setTimeout(resolve6, 2e3));
|
|
61356
61398
|
}
|
|
61357
61399
|
this.logger.warn(`Firehose ${logicalId} did not reach ACTIVE after ${maxAttempts} attempts`);
|
|
61358
61400
|
}
|
|
@@ -64822,7 +64864,7 @@ var ASGProvider = class {
|
|
|
64822
64864
|
);
|
|
64823
64865
|
}
|
|
64824
64866
|
sleep(ms) {
|
|
64825
|
-
return new Promise((
|
|
64867
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
64826
64868
|
}
|
|
64827
64869
|
// ─── Sub-shape diff helpers ───────────────────────────────────────
|
|
64828
64870
|
// Each helper is a no-op when before/after JSON is identical (the cheap
|
|
@@ -65743,29 +65785,29 @@ function calculateResourceDrift(stateProperties, awsProperties, options) {
|
|
|
65743
65785
|
}
|
|
65744
65786
|
return drifts;
|
|
65745
65787
|
}
|
|
65746
|
-
function isIgnoredPath(
|
|
65788
|
+
function isIgnoredPath(path3, ignorePaths) {
|
|
65747
65789
|
for (const entry of ignorePaths) {
|
|
65748
|
-
if (
|
|
65790
|
+
if (path3 === entry)
|
|
65749
65791
|
return true;
|
|
65750
|
-
if (
|
|
65792
|
+
if (path3.startsWith(`${entry}.`))
|
|
65751
65793
|
return true;
|
|
65752
65794
|
}
|
|
65753
65795
|
return false;
|
|
65754
65796
|
}
|
|
65755
|
-
function diffAt(
|
|
65797
|
+
function diffAt(path3, stateValue, awsValue, out, ignorePaths, unionWalkObjects) {
|
|
65756
65798
|
if (deepEqual(stateValue, awsValue))
|
|
65757
65799
|
return;
|
|
65758
65800
|
if (isPlainObject(stateValue) && isPlainObject(awsValue) && !Array.isArray(stateValue) && !Array.isArray(awsValue)) {
|
|
65759
65801
|
const keys = unionWalkObjects ? /* @__PURE__ */ new Set([...Object.keys(stateValue), ...Object.keys(awsValue)]) : Object.keys(stateValue);
|
|
65760
65802
|
for (const key of keys) {
|
|
65761
|
-
const childPath = `${
|
|
65803
|
+
const childPath = `${path3}.${key}`;
|
|
65762
65804
|
if (isIgnoredPath(childPath, ignorePaths))
|
|
65763
65805
|
continue;
|
|
65764
65806
|
diffAt(childPath, stateValue[key], awsValue[key], out, ignorePaths, unionWalkObjects);
|
|
65765
65807
|
}
|
|
65766
65808
|
return;
|
|
65767
65809
|
}
|
|
65768
|
-
out.push({ path:
|
|
65810
|
+
out.push({ path: path3, stateValue, awsValue });
|
|
65769
65811
|
}
|
|
65770
65812
|
function deepEqual(a, b) {
|
|
65771
65813
|
if (a === b)
|
|
@@ -66168,11 +66210,11 @@ async function runDriftForStack(stackName, region, stateBackend, providerRegistr
|
|
|
66168
66210
|
};
|
|
66169
66211
|
});
|
|
66170
66212
|
}
|
|
66171
|
-
function setAtPath(target,
|
|
66172
|
-
if (
|
|
66213
|
+
function setAtPath(target, path3, value) {
|
|
66214
|
+
if (path3.length === 0) {
|
|
66173
66215
|
return;
|
|
66174
66216
|
}
|
|
66175
|
-
const segments =
|
|
66217
|
+
const segments = path3.split(".");
|
|
66176
66218
|
let cursor = target;
|
|
66177
66219
|
for (let i = 0; i < segments.length - 1; i++) {
|
|
66178
66220
|
const key = segments[i];
|
|
@@ -66762,7 +66804,7 @@ Acquiring lock for stack ${stackName}...`);
|
|
|
66762
66804
|
logger.debug(
|
|
66763
66805
|
` \u23F3 Retrying delete ${logicalId} in ${delay2 / 1e3}s (attempt ${attempt + 1}/${maxAttempts})`
|
|
66764
66806
|
);
|
|
66765
|
-
await new Promise((
|
|
66807
|
+
await new Promise((resolve6) => setTimeout(resolve6, delay2));
|
|
66766
66808
|
}
|
|
66767
66809
|
}
|
|
66768
66810
|
if (lastDeleteError)
|
|
@@ -67072,19 +67114,19 @@ function buildCdkPathIndex(template) {
|
|
|
67072
67114
|
for (const [logicalId, resource] of Object.entries(template.Resources)) {
|
|
67073
67115
|
if (resource.Type === "AWS::CDK::Metadata")
|
|
67074
67116
|
continue;
|
|
67075
|
-
const
|
|
67076
|
-
if (
|
|
67077
|
-
index.set(
|
|
67117
|
+
const path3 = readCdkPath(resource);
|
|
67118
|
+
if (path3)
|
|
67119
|
+
index.set(path3, logicalId);
|
|
67078
67120
|
}
|
|
67079
67121
|
return index;
|
|
67080
67122
|
}
|
|
67081
67123
|
function resolveCdkPathToLogicalIds(input, index) {
|
|
67082
67124
|
const seen = /* @__PURE__ */ new Map();
|
|
67083
67125
|
const prefix = `${input}/`;
|
|
67084
|
-
for (const [
|
|
67085
|
-
if (
|
|
67126
|
+
for (const [path3, logicalId] of index) {
|
|
67127
|
+
if (path3 === input || path3.startsWith(prefix)) {
|
|
67086
67128
|
if (!seen.has(logicalId))
|
|
67087
|
-
seen.set(logicalId,
|
|
67129
|
+
seen.set(logicalId, path3);
|
|
67088
67130
|
}
|
|
67089
67131
|
}
|
|
67090
67132
|
return [...seen.entries()].map(([logicalId, cdkPath]) => ({ logicalId, cdkPath }));
|
|
@@ -69992,11 +70034,11 @@ async function captureObservedForImportedResources(stackState, providerRegistry,
|
|
|
69992
70034
|
}
|
|
69993
70035
|
|
|
69994
70036
|
// src/cli/commands/local-invoke.ts
|
|
69995
|
-
import { mkdtempSync as
|
|
69996
|
-
import { tmpdir as
|
|
69997
|
-
import { dirname as
|
|
69998
|
-
import * as
|
|
69999
|
-
import { Command as
|
|
70037
|
+
import { mkdtempSync as mkdtempSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync7, rmSync as rmSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
70038
|
+
import { tmpdir as tmpdir3 } from "node:os";
|
|
70039
|
+
import { dirname as dirname3 } from "node:path";
|
|
70040
|
+
import * as path2 from "node:path";
|
|
70041
|
+
import { Command as Command15, Option as Option8 } from "commander";
|
|
70000
70042
|
|
|
70001
70043
|
// src/local/lambda-resolver.ts
|
|
70002
70044
|
import { existsSync as existsSync4, statSync as statSync3 } from "node:fs";
|
|
@@ -70661,41 +70703,6 @@ function runForeground(cmd, args) {
|
|
|
70661
70703
|
|
|
70662
70704
|
// src/local/docker-image-builder.ts
|
|
70663
70705
|
import { createHash as createHash2 } from "node:crypto";
|
|
70664
|
-
async function buildContainerImage(asset, cdkOutDir, options) {
|
|
70665
|
-
const tag = computeLocalTag(asset.source);
|
|
70666
|
-
const platform = architectureToPlatform(options.architecture);
|
|
70667
|
-
const logger = getLogger().child("local-invoke-build");
|
|
70668
|
-
logger.info(`Building container image (platform=${platform})...`);
|
|
70669
|
-
logger.debug(`Local tag: ${tag}`);
|
|
70670
|
-
await buildDockerImage(asset, cdkOutDir, tag, {
|
|
70671
|
-
platform,
|
|
70672
|
-
wrapError: (stderr) => new LocalInvokeBuildError(
|
|
70673
|
-
`docker build failed for container Lambda asset (${asset.source.directory}): ${stderr}`
|
|
70674
|
-
)
|
|
70675
|
-
});
|
|
70676
|
-
return tag;
|
|
70677
|
-
}
|
|
70678
|
-
function architectureToPlatform(architecture) {
|
|
70679
|
-
return architecture === "arm64" ? "linux/arm64" : "linux/amd64";
|
|
70680
|
-
}
|
|
70681
|
-
function computeLocalTag(source) {
|
|
70682
|
-
const hash = createHash2("sha256");
|
|
70683
|
-
hash.update(source.directory);
|
|
70684
|
-
hash.update("\0");
|
|
70685
|
-
hash.update(source.dockerFile ?? "");
|
|
70686
|
-
hash.update("\0");
|
|
70687
|
-
hash.update(source.dockerBuildTarget ?? "");
|
|
70688
|
-
hash.update("\0");
|
|
70689
|
-
if (source.dockerBuildArgs) {
|
|
70690
|
-
for (const [k, v] of Object.entries(source.dockerBuildArgs)) {
|
|
70691
|
-
hash.update(k);
|
|
70692
|
-
hash.update("=");
|
|
70693
|
-
hash.update(v);
|
|
70694
|
-
hash.update("\0");
|
|
70695
|
-
}
|
|
70696
|
-
}
|
|
70697
|
-
return `cdkd-local-invoke-${hash.digest("hex").slice(0, 16)}`;
|
|
70698
|
-
}
|
|
70699
70706
|
|
|
70700
70707
|
// src/local/ecr-puller.ts
|
|
70701
70708
|
import { execFile as execFile4, spawn as spawn4 } from "node:child_process";
|
|
@@ -70773,7 +70780,7 @@ async function ecrLogin(client, accountId, region) {
|
|
|
70773
70780
|
const token = Buffer.from(authData.authorizationToken, "base64").toString();
|
|
70774
70781
|
const [username, password] = token.split(":");
|
|
70775
70782
|
const endpoint = authData.proxyEndpoint || `https://${accountId}.dkr.ecr.${region}.amazonaws.com`;
|
|
70776
|
-
await new Promise((
|
|
70783
|
+
await new Promise((resolve6, reject) => {
|
|
70777
70784
|
const proc = spawn4("docker", ["login", "--username", username, "--password-stdin", endpoint], {
|
|
70778
70785
|
stdio: ["pipe", "pipe", "pipe"]
|
|
70779
70786
|
});
|
|
@@ -70783,7 +70790,7 @@ async function ecrLogin(client, accountId, region) {
|
|
|
70783
70790
|
});
|
|
70784
70791
|
proc.on("close", (code) => {
|
|
70785
70792
|
if (code === 0)
|
|
70786
|
-
|
|
70793
|
+
resolve6();
|
|
70787
70794
|
else
|
|
70788
70795
|
reject(new LocalInvokeBuildError(`ECR login failed: ${stderr.trim()}`));
|
|
70789
70796
|
});
|
|
@@ -70803,19 +70810,74 @@ async function verifyImageInLocalCache(imageUri) {
|
|
|
70803
70810
|
);
|
|
70804
70811
|
}
|
|
70805
70812
|
}
|
|
70813
|
+
async function isImageInLocalCache(imageRef) {
|
|
70814
|
+
try {
|
|
70815
|
+
await execFileAsync4("docker", ["image", "inspect", imageRef]);
|
|
70816
|
+
return true;
|
|
70817
|
+
} catch {
|
|
70818
|
+
return false;
|
|
70819
|
+
}
|
|
70820
|
+
}
|
|
70806
70821
|
function runForeground2(cmd, args) {
|
|
70807
|
-
return new Promise((
|
|
70822
|
+
return new Promise((resolve6, reject) => {
|
|
70808
70823
|
const proc = spawn4(cmd, args, { stdio: "inherit" });
|
|
70809
70824
|
proc.on("error", (err) => reject(new LocalInvokeBuildError(`${cmd} failed: ${err.message}`)));
|
|
70810
70825
|
proc.on("close", (code) => {
|
|
70811
70826
|
if (code === 0)
|
|
70812
|
-
|
|
70827
|
+
resolve6();
|
|
70813
70828
|
else
|
|
70814
70829
|
reject(new LocalInvokeBuildError(`${cmd} exited with code ${code}`));
|
|
70815
70830
|
});
|
|
70816
70831
|
});
|
|
70817
70832
|
}
|
|
70818
70833
|
|
|
70834
|
+
// src/local/docker-image-builder.ts
|
|
70835
|
+
async function buildContainerImage(asset, cdkOutDir, options) {
|
|
70836
|
+
const tag = computeLocalTag(asset.source);
|
|
70837
|
+
const platform = architectureToPlatform(options.architecture);
|
|
70838
|
+
const logger = getLogger().child("local-invoke-build");
|
|
70839
|
+
if (options.noBuild === true) {
|
|
70840
|
+
logger.info(`Skipping docker build (--no-build). Verifying ${tag} is in local registry...`);
|
|
70841
|
+
if (!await isImageInLocalCache(tag)) {
|
|
70842
|
+
throw new LocalInvokeBuildError(
|
|
70843
|
+
`image '${tag}' not in local registry and --no-build is set; remove --no-build or run \`docker build\` manually first.`
|
|
70844
|
+
);
|
|
70845
|
+
}
|
|
70846
|
+
logger.debug(`Local tag ${tag} is cached; skipping build.`);
|
|
70847
|
+
return tag;
|
|
70848
|
+
}
|
|
70849
|
+
logger.info(`Building container image (platform=${platform})...`);
|
|
70850
|
+
logger.debug(`Local tag: ${tag}`);
|
|
70851
|
+
await buildDockerImage(asset, cdkOutDir, tag, {
|
|
70852
|
+
platform,
|
|
70853
|
+
wrapError: (stderr) => new LocalInvokeBuildError(
|
|
70854
|
+
`docker build failed for container Lambda asset (${asset.source.directory}): ${stderr}`
|
|
70855
|
+
)
|
|
70856
|
+
});
|
|
70857
|
+
return tag;
|
|
70858
|
+
}
|
|
70859
|
+
function architectureToPlatform(architecture) {
|
|
70860
|
+
return architecture === "arm64" ? "linux/arm64" : "linux/amd64";
|
|
70861
|
+
}
|
|
70862
|
+
function computeLocalTag(source) {
|
|
70863
|
+
const hash = createHash2("sha256");
|
|
70864
|
+
hash.update(source.directory);
|
|
70865
|
+
hash.update("\0");
|
|
70866
|
+
hash.update(source.dockerFile ?? "");
|
|
70867
|
+
hash.update("\0");
|
|
70868
|
+
hash.update(source.dockerBuildTarget ?? "");
|
|
70869
|
+
hash.update("\0");
|
|
70870
|
+
if (source.dockerBuildArgs) {
|
|
70871
|
+
for (const [k, v] of Object.entries(source.dockerBuildArgs)) {
|
|
70872
|
+
hash.update(k);
|
|
70873
|
+
hash.update("=");
|
|
70874
|
+
hash.update(v);
|
|
70875
|
+
hash.update("\0");
|
|
70876
|
+
}
|
|
70877
|
+
}
|
|
70878
|
+
return `cdkd-local-invoke-${hash.digest("hex").slice(0, 16)}`;
|
|
70879
|
+
}
|
|
70880
|
+
|
|
70819
70881
|
// src/local/rie-client.ts
|
|
70820
70882
|
import { setTimeout as delay } from "node:timers/promises";
|
|
70821
70883
|
var INVOKE_PATH = "/2015-03-31/functions/function/invocations";
|
|
@@ -71025,6 +71087,1657 @@ function extractHashFromImageUri(imageUri) {
|
|
|
71025
71087
|
|
|
71026
71088
|
// src/cli/commands/local-invoke.ts
|
|
71027
71089
|
init_aws_clients();
|
|
71090
|
+
|
|
71091
|
+
// src/cli/commands/local-start-api.ts
|
|
71092
|
+
import { mkdirSync as mkdirSync2, mkdtempSync as mkdtempSync2, readFileSync as readFileSync6, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "node:fs";
|
|
71093
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
71094
|
+
import * as path from "node:path";
|
|
71095
|
+
import { Command as Command14, Option as Option7 } from "commander";
|
|
71096
|
+
|
|
71097
|
+
// src/local/route-discovery.ts
|
|
71098
|
+
function discoverRoutes(stacks) {
|
|
71099
|
+
const routes = [];
|
|
71100
|
+
const errors = [];
|
|
71101
|
+
for (const stack of stacks) {
|
|
71102
|
+
const template = stack.template;
|
|
71103
|
+
const resources = template.Resources ?? {};
|
|
71104
|
+
for (const [logicalId, resource] of Object.entries(resources)) {
|
|
71105
|
+
try {
|
|
71106
|
+
switch (resource.Type) {
|
|
71107
|
+
case "AWS::ApiGateway::Method":
|
|
71108
|
+
routes.push(...discoverRestV1Method(logicalId, resource, template, stack.stackName));
|
|
71109
|
+
break;
|
|
71110
|
+
case "AWS::ApiGatewayV2::Route":
|
|
71111
|
+
routes.push(...discoverHttpApiRoute(logicalId, resource, template, stack.stackName));
|
|
71112
|
+
break;
|
|
71113
|
+
case "AWS::Lambda::Url":
|
|
71114
|
+
routes.push(...discoverFunctionUrl(logicalId, resource, stack.stackName));
|
|
71115
|
+
break;
|
|
71116
|
+
default:
|
|
71117
|
+
break;
|
|
71118
|
+
}
|
|
71119
|
+
} catch (err) {
|
|
71120
|
+
errors.push(err instanceof Error ? err.message : String(err));
|
|
71121
|
+
}
|
|
71122
|
+
}
|
|
71123
|
+
}
|
|
71124
|
+
if (errors.length > 0) {
|
|
71125
|
+
throw new RouteDiscoveryError(
|
|
71126
|
+
`cdkd local start-api: ${errors.length} unsupported route(s) in the synthesized template:
|
|
71127
|
+
` + errors.map((e) => ` - ${e}`).join("\n")
|
|
71128
|
+
);
|
|
71129
|
+
}
|
|
71130
|
+
return routes;
|
|
71131
|
+
}
|
|
71132
|
+
function discoverRestV1Method(logicalId, resource, template, stackName) {
|
|
71133
|
+
const props = resource.Properties ?? {};
|
|
71134
|
+
const integration = props["Integration"];
|
|
71135
|
+
if (!integration) {
|
|
71136
|
+
throw new Error(
|
|
71137
|
+
`${stackName}/${logicalId} (AWS::ApiGateway::Method): missing Integration property`
|
|
71138
|
+
);
|
|
71139
|
+
}
|
|
71140
|
+
const integrationType = integration["Type"];
|
|
71141
|
+
if (integrationType !== "AWS_PROXY") {
|
|
71142
|
+
throw new Error(
|
|
71143
|
+
`${stackName}/${logicalId} (AWS::ApiGateway::Method): integration type '${String(
|
|
71144
|
+
integrationType
|
|
71145
|
+
)}' is not supported (only AWS_PROXY). MOCK / AWS / HTTP / HTTP_PROXY require mapping templates that cdkd cannot emulate.`
|
|
71146
|
+
);
|
|
71147
|
+
}
|
|
71148
|
+
const integrationUri = integration["Uri"];
|
|
71149
|
+
const lambdaLogicalId = resolveLambdaArnIntrinsic(
|
|
71150
|
+
integrationUri,
|
|
71151
|
+
`${stackName}/${logicalId}.Integration.Uri`
|
|
71152
|
+
);
|
|
71153
|
+
const restApiId = props["RestApiId"];
|
|
71154
|
+
const restApiLogicalId = pickRefLogicalId(restApiId);
|
|
71155
|
+
if (!restApiLogicalId) {
|
|
71156
|
+
throw new Error(
|
|
71157
|
+
`${stackName}/${logicalId} (AWS::ApiGateway::Method): RestApiId must be a { Ref: '...' } reference (got ${shortJson(
|
|
71158
|
+
restApiId
|
|
71159
|
+
)}).`
|
|
71160
|
+
);
|
|
71161
|
+
}
|
|
71162
|
+
const resourceId = props["ResourceId"];
|
|
71163
|
+
const path3 = buildRestV1Path(resourceId, restApiLogicalId, template, stackName, logicalId);
|
|
71164
|
+
const httpMethod = String(props["HttpMethod"] ?? "ANY");
|
|
71165
|
+
const stage = pickRestV1Stage(restApiLogicalId, template);
|
|
71166
|
+
return [
|
|
71167
|
+
{
|
|
71168
|
+
method: httpMethod,
|
|
71169
|
+
pathPattern: path3,
|
|
71170
|
+
lambdaLogicalId,
|
|
71171
|
+
source: "rest-v1",
|
|
71172
|
+
apiVersion: "v1",
|
|
71173
|
+
stage,
|
|
71174
|
+
declaredAt: `${stackName}/${logicalId}`
|
|
71175
|
+
}
|
|
71176
|
+
];
|
|
71177
|
+
}
|
|
71178
|
+
function buildRestV1Path(resourceIdIntrinsic, restApiLogicalId, template, stackName, methodLogicalId) {
|
|
71179
|
+
if (resourceIdIntrinsic && typeof resourceIdIntrinsic === "object" && !Array.isArray(resourceIdIntrinsic)) {
|
|
71180
|
+
const obj = resourceIdIntrinsic;
|
|
71181
|
+
if ("Fn::GetAtt" in obj) {
|
|
71182
|
+
const arg = obj["Fn::GetAtt"];
|
|
71183
|
+
if (Array.isArray(arg) && arg.length === 2 && arg[1] === "RootResourceId") {
|
|
71184
|
+
return "/";
|
|
71185
|
+
}
|
|
71186
|
+
}
|
|
71187
|
+
}
|
|
71188
|
+
const resourceLogicalId = pickRefLogicalId(resourceIdIntrinsic);
|
|
71189
|
+
if (!resourceLogicalId) {
|
|
71190
|
+
throw new Error(
|
|
71191
|
+
`${stackName}/${methodLogicalId}: ResourceId must be { Ref: '...' } or { 'Fn::GetAtt': [..., 'RootResourceId'] } (got ${shortJson(
|
|
71192
|
+
resourceIdIntrinsic
|
|
71193
|
+
)}).`
|
|
71194
|
+
);
|
|
71195
|
+
}
|
|
71196
|
+
const segments = [];
|
|
71197
|
+
const visited = /* @__PURE__ */ new Set();
|
|
71198
|
+
let cursor = resourceLogicalId;
|
|
71199
|
+
while (cursor && cursor !== restApiLogicalId) {
|
|
71200
|
+
if (visited.has(cursor)) {
|
|
71201
|
+
throw new Error(
|
|
71202
|
+
`${stackName}/${methodLogicalId}: cycle detected in AWS::ApiGateway::Resource ParentId chain at ${cursor}`
|
|
71203
|
+
);
|
|
71204
|
+
}
|
|
71205
|
+
visited.add(cursor);
|
|
71206
|
+
const node = template.Resources?.[cursor];
|
|
71207
|
+
if (!node) {
|
|
71208
|
+
throw new Error(
|
|
71209
|
+
`${stackName}/${methodLogicalId}: ParentId chain references missing resource '${cursor}'`
|
|
71210
|
+
);
|
|
71211
|
+
}
|
|
71212
|
+
if (node.Type !== "AWS::ApiGateway::Resource") {
|
|
71213
|
+
throw new Error(
|
|
71214
|
+
`${stackName}/${methodLogicalId}: ParentId chain hit ${node.Type} (expected AWS::ApiGateway::Resource or RestApi root)`
|
|
71215
|
+
);
|
|
71216
|
+
}
|
|
71217
|
+
const nodeProps = node.Properties ?? {};
|
|
71218
|
+
const pathPart = nodeProps["PathPart"];
|
|
71219
|
+
if (typeof pathPart !== "string") {
|
|
71220
|
+
throw new Error(
|
|
71221
|
+
`${stackName}/${methodLogicalId}: AWS::ApiGateway::Resource '${cursor}' missing PathPart`
|
|
71222
|
+
);
|
|
71223
|
+
}
|
|
71224
|
+
segments.unshift(pathPart);
|
|
71225
|
+
const parentId = nodeProps["ParentId"];
|
|
71226
|
+
if (parentId && typeof parentId === "object" && !Array.isArray(parentId) && "Fn::GetAtt" in parentId) {
|
|
71227
|
+
const arg = parentId["Fn::GetAtt"];
|
|
71228
|
+
if (Array.isArray(arg) && arg[1] === "RootResourceId")
|
|
71229
|
+
break;
|
|
71230
|
+
}
|
|
71231
|
+
cursor = pickRefLogicalId(parentId) ?? void 0;
|
|
71232
|
+
}
|
|
71233
|
+
return "/" + segments.join("/");
|
|
71234
|
+
}
|
|
71235
|
+
function pickRestV1Stage(restApiLogicalId, template) {
|
|
71236
|
+
const resources = template.Resources ?? {};
|
|
71237
|
+
for (const [, resource] of Object.entries(resources)) {
|
|
71238
|
+
if (resource.Type !== "AWS::ApiGateway::Stage")
|
|
71239
|
+
continue;
|
|
71240
|
+
const props = resource.Properties ?? {};
|
|
71241
|
+
const ref = pickRefLogicalId(props["RestApiId"]);
|
|
71242
|
+
if (ref === restApiLogicalId) {
|
|
71243
|
+
const stageName = props["StageName"];
|
|
71244
|
+
if (typeof stageName === "string")
|
|
71245
|
+
return stageName;
|
|
71246
|
+
}
|
|
71247
|
+
}
|
|
71248
|
+
return "$default";
|
|
71249
|
+
}
|
|
71250
|
+
function discoverHttpApiRoute(logicalId, resource, template, stackName) {
|
|
71251
|
+
const props = resource.Properties ?? {};
|
|
71252
|
+
const apiId = props["ApiId"];
|
|
71253
|
+
const apiLogicalId = pickRefLogicalId(apiId);
|
|
71254
|
+
if (!apiLogicalId) {
|
|
71255
|
+
throw new Error(
|
|
71256
|
+
`${stackName}/${logicalId} (AWS::ApiGatewayV2::Route): ApiId must be { Ref: '...' } (got ${shortJson(
|
|
71257
|
+
apiId
|
|
71258
|
+
)}).`
|
|
71259
|
+
);
|
|
71260
|
+
}
|
|
71261
|
+
const apiResource = template.Resources?.[apiLogicalId];
|
|
71262
|
+
if (apiResource?.Type === "AWS::ApiGatewayV2::Api") {
|
|
71263
|
+
const protocolType = (apiResource.Properties ?? {})["ProtocolType"];
|
|
71264
|
+
if (protocolType === "WEBSOCKET") {
|
|
71265
|
+
throw new Error(
|
|
71266
|
+
`${stackName}/${logicalId} (AWS::ApiGatewayV2::Route): WebSocket APIs are not supported in cdkd local start-api (deferred follow-up PR).`
|
|
71267
|
+
);
|
|
71268
|
+
}
|
|
71269
|
+
}
|
|
71270
|
+
const routeKey = props["RouteKey"];
|
|
71271
|
+
if (typeof routeKey !== "string" || routeKey.length === 0) {
|
|
71272
|
+
throw new Error(
|
|
71273
|
+
`${stackName}/${logicalId} (AWS::ApiGatewayV2::Route): RouteKey must be a string`
|
|
71274
|
+
);
|
|
71275
|
+
}
|
|
71276
|
+
const target = props["Target"];
|
|
71277
|
+
const integrationLogicalId = parseHttpApiTargetIntegration(
|
|
71278
|
+
target,
|
|
71279
|
+
`${stackName}/${logicalId}.Target`
|
|
71280
|
+
);
|
|
71281
|
+
const integration = template.Resources?.[integrationLogicalId];
|
|
71282
|
+
if (!integration || integration.Type !== "AWS::ApiGatewayV2::Integration") {
|
|
71283
|
+
throw new Error(
|
|
71284
|
+
`${stackName}/${logicalId} (AWS::ApiGatewayV2::Route): Target points at '${integrationLogicalId}' which is not an AWS::ApiGatewayV2::Integration`
|
|
71285
|
+
);
|
|
71286
|
+
}
|
|
71287
|
+
const integrationProps = integration.Properties ?? {};
|
|
71288
|
+
const integrationType = integrationProps["IntegrationType"];
|
|
71289
|
+
if (integrationType !== "AWS_PROXY") {
|
|
71290
|
+
throw new Error(
|
|
71291
|
+
`${stackName}/${logicalId} (AWS::ApiGatewayV2::Route): integration type '${String(
|
|
71292
|
+
integrationType
|
|
71293
|
+
)}' is not supported (only AWS_PROXY).`
|
|
71294
|
+
);
|
|
71295
|
+
}
|
|
71296
|
+
if (integrationProps["IntegrationSubtype"] !== void 0) {
|
|
71297
|
+
throw new Error(
|
|
71298
|
+
`${stackName}/${logicalId} (AWS::ApiGatewayV2::Route): IntegrationSubtype '${String(
|
|
71299
|
+
integrationProps["IntegrationSubtype"]
|
|
71300
|
+
)}' is not supported (ApiGatewayV2 service integrations like SQS/EventBridge cannot run locally).`
|
|
71301
|
+
);
|
|
71302
|
+
}
|
|
71303
|
+
const lambdaLogicalId = resolveLambdaArnIntrinsic(
|
|
71304
|
+
integrationProps["IntegrationUri"],
|
|
71305
|
+
`${stackName}/${integrationLogicalId}.IntegrationUri`
|
|
71306
|
+
);
|
|
71307
|
+
const { method, pathPattern } = parseRouteKey(routeKey);
|
|
71308
|
+
return [
|
|
71309
|
+
{
|
|
71310
|
+
method,
|
|
71311
|
+
pathPattern,
|
|
71312
|
+
lambdaLogicalId,
|
|
71313
|
+
source: "http-api",
|
|
71314
|
+
apiVersion: "v2",
|
|
71315
|
+
stage: "$default",
|
|
71316
|
+
declaredAt: `${stackName}/${logicalId}`
|
|
71317
|
+
}
|
|
71318
|
+
];
|
|
71319
|
+
}
|
|
71320
|
+
function discoverFunctionUrl(logicalId, resource, stackName) {
|
|
71321
|
+
const props = resource.Properties ?? {};
|
|
71322
|
+
const authType = props["AuthType"];
|
|
71323
|
+
if (authType !== "NONE") {
|
|
71324
|
+
throw new Error(
|
|
71325
|
+
`${stackName}/${logicalId} (AWS::Lambda::Url): AuthType '${String(
|
|
71326
|
+
authType
|
|
71327
|
+
)}' is not supported (only NONE \u2014 IAM auth requires SigV4 verification cdkd cannot emulate locally; deferred follow-up PR).`
|
|
71328
|
+
);
|
|
71329
|
+
}
|
|
71330
|
+
const invokeMode = props["InvokeMode"];
|
|
71331
|
+
if (invokeMode === "RESPONSE_STREAM") {
|
|
71332
|
+
throw new Error(
|
|
71333
|
+
`${stackName}/${logicalId} (AWS::Lambda::Url): InvokeMode RESPONSE_STREAM is not supported (deferred follow-up PR).`
|
|
71334
|
+
);
|
|
71335
|
+
}
|
|
71336
|
+
const targetArn = props["TargetFunctionArn"];
|
|
71337
|
+
const lambdaLogicalId = resolveLambdaArnIntrinsic(
|
|
71338
|
+
targetArn,
|
|
71339
|
+
`${stackName}/${logicalId}.TargetFunctionArn`
|
|
71340
|
+
);
|
|
71341
|
+
return [
|
|
71342
|
+
{
|
|
71343
|
+
method: "ANY",
|
|
71344
|
+
pathPattern: "/{proxy+}",
|
|
71345
|
+
lambdaLogicalId,
|
|
71346
|
+
source: "function-url",
|
|
71347
|
+
apiVersion: "v2",
|
|
71348
|
+
stage: "$default",
|
|
71349
|
+
declaredAt: `${stackName}/${logicalId}`
|
|
71350
|
+
}
|
|
71351
|
+
];
|
|
71352
|
+
}
|
|
71353
|
+
function resolveLambdaArnIntrinsic(value, location) {
|
|
71354
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
71355
|
+
const obj = value;
|
|
71356
|
+
if ("Ref" in obj && typeof obj["Ref"] === "string") {
|
|
71357
|
+
return obj["Ref"];
|
|
71358
|
+
}
|
|
71359
|
+
if ("Fn::GetAtt" in obj) {
|
|
71360
|
+
const arg = obj["Fn::GetAtt"];
|
|
71361
|
+
if (Array.isArray(arg) && arg.length === 2 && typeof arg[0] === "string" && arg[1] === "Arn") {
|
|
71362
|
+
return arg[0];
|
|
71363
|
+
}
|
|
71364
|
+
}
|
|
71365
|
+
if ("Fn::Join" in obj) {
|
|
71366
|
+
const join9 = obj["Fn::Join"];
|
|
71367
|
+
if (Array.isArray(join9) && join9.length === 2 && Array.isArray(join9[1])) {
|
|
71368
|
+
const parts = join9[1];
|
|
71369
|
+
const literalParts = parts.filter((p) => typeof p === "string").join("");
|
|
71370
|
+
if (literalParts.includes(":lambda:path/2015-03-31/functions/")) {
|
|
71371
|
+
for (const p of parts) {
|
|
71372
|
+
if (p && typeof p === "object" && !Array.isArray(p)) {
|
|
71373
|
+
const inner = p;
|
|
71374
|
+
const arg = inner["Fn::GetAtt"];
|
|
71375
|
+
if (Array.isArray(arg) && arg.length === 2 && typeof arg[0] === "string" && arg[1] === "Arn") {
|
|
71376
|
+
return arg[0];
|
|
71377
|
+
}
|
|
71378
|
+
}
|
|
71379
|
+
}
|
|
71380
|
+
}
|
|
71381
|
+
}
|
|
71382
|
+
}
|
|
71383
|
+
}
|
|
71384
|
+
throw new Error(
|
|
71385
|
+
`${location}: only { Ref: <LambdaLogicalId> }, { 'Fn::GetAtt': [<LambdaLogicalId>, 'Arn'] }, or the REST v1 invoke-ARN Fn::Join wrapper are supported (got ${shortJson(
|
|
71386
|
+
value
|
|
71387
|
+
)}). Other intrinsics (Fn::Sub against arbitrary templates, etc.) require deploy-state and are not supported in cdkd local start-api.`
|
|
71388
|
+
);
|
|
71389
|
+
}
|
|
71390
|
+
function parseHttpApiTargetIntegration(target, location) {
|
|
71391
|
+
if (typeof target === "string") {
|
|
71392
|
+
const m = /^integrations\/(.+)$/.exec(target);
|
|
71393
|
+
if (m)
|
|
71394
|
+
return m[1];
|
|
71395
|
+
throw new Error(`${location}: literal Target '${target}' must start with 'integrations/'`);
|
|
71396
|
+
}
|
|
71397
|
+
if (target && typeof target === "object" && !Array.isArray(target)) {
|
|
71398
|
+
const obj = target;
|
|
71399
|
+
const join9 = obj["Fn::Join"];
|
|
71400
|
+
if (Array.isArray(join9) && join9.length === 2 && Array.isArray(join9[1])) {
|
|
71401
|
+
const sep = join9[0];
|
|
71402
|
+
const parts = join9[1];
|
|
71403
|
+
if (sep === "/" && parts.length === 2 && parts[0] === "integrations") {
|
|
71404
|
+
const ref = pickRefLogicalId(parts[1]);
|
|
71405
|
+
if (ref)
|
|
71406
|
+
return ref;
|
|
71407
|
+
}
|
|
71408
|
+
if (sep === "" && parts.length === 2 && parts[0] === "integrations/") {
|
|
71409
|
+
const ref = pickRefLogicalId(parts[1]);
|
|
71410
|
+
if (ref)
|
|
71411
|
+
return ref;
|
|
71412
|
+
}
|
|
71413
|
+
}
|
|
71414
|
+
}
|
|
71415
|
+
throw new Error(
|
|
71416
|
+
`${location}: Target must be 'integrations/<id>' or Fn::Join with one of the documented shapes (got ${shortJson(
|
|
71417
|
+
target
|
|
71418
|
+
)}).`
|
|
71419
|
+
);
|
|
71420
|
+
}
|
|
71421
|
+
function parseRouteKey(routeKey) {
|
|
71422
|
+
if (routeKey === "$default") {
|
|
71423
|
+
return { method: "ANY", pathPattern: "$default" };
|
|
71424
|
+
}
|
|
71425
|
+
const m = /^([A-Za-z]+)\s+(\S+)$/.exec(routeKey);
|
|
71426
|
+
if (!m) {
|
|
71427
|
+
throw new Error(
|
|
71428
|
+
`RouteKey '${routeKey}' is malformed: expected '<METHOD> <path>' (e.g. 'GET /items/{id}') or '$default'.`
|
|
71429
|
+
);
|
|
71430
|
+
}
|
|
71431
|
+
return { method: m[1].toUpperCase(), pathPattern: m[2] };
|
|
71432
|
+
}
|
|
71433
|
+
function pickRefLogicalId(value) {
|
|
71434
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
71435
|
+
const ref = value["Ref"];
|
|
71436
|
+
if (typeof ref === "string")
|
|
71437
|
+
return ref;
|
|
71438
|
+
}
|
|
71439
|
+
return null;
|
|
71440
|
+
}
|
|
71441
|
+
function shortJson(value) {
|
|
71442
|
+
try {
|
|
71443
|
+
const s = JSON.stringify(value);
|
|
71444
|
+
return s.length > 200 ? `${s.slice(0, 200)}\u2026` : s;
|
|
71445
|
+
} catch {
|
|
71446
|
+
return String(value);
|
|
71447
|
+
}
|
|
71448
|
+
}
|
|
71449
|
+
|
|
71450
|
+
// src/local/container-pool.ts
|
|
71451
|
+
var DEFAULT_IDLE_MS = 6e4;
|
|
71452
|
+
var MAX_PER_LAMBDA_CONCURRENCY = 4;
|
|
71453
|
+
var MIN_PER_LAMBDA_CONCURRENCY = 1;
|
|
71454
|
+
function createContainerPool(specs, options) {
|
|
71455
|
+
const logger = getLogger().child("container-pool");
|
|
71456
|
+
const concurrencyCap = clampConcurrency(options.perLambdaConcurrency);
|
|
71457
|
+
const idleMs = options.idleMs ?? DEFAULT_IDLE_MS;
|
|
71458
|
+
const streamingEnabled = options.streamLogs !== false;
|
|
71459
|
+
const entries = /* @__PURE__ */ new Map();
|
|
71460
|
+
const inFlightStarts = /* @__PURE__ */ new Set();
|
|
71461
|
+
for (const logicalId of specs.keys()) {
|
|
71462
|
+
entries.set(logicalId, emptyEntry(logicalId));
|
|
71463
|
+
}
|
|
71464
|
+
function emptyEntry(logicalId) {
|
|
71465
|
+
return {
|
|
71466
|
+
logicalId,
|
|
71467
|
+
warm: [],
|
|
71468
|
+
inUse: /* @__PURE__ */ new Set(),
|
|
71469
|
+
waitQueue: [],
|
|
71470
|
+
idleTimer: null,
|
|
71471
|
+
growthMutex: Promise.resolve()
|
|
71472
|
+
};
|
|
71473
|
+
}
|
|
71474
|
+
async function startOne(spec) {
|
|
71475
|
+
const image = resolveRuntimeImage(spec.lambda.runtime);
|
|
71476
|
+
const hostPort = await pickFreePort();
|
|
71477
|
+
const name = `cdkd-local-${spec.lambda.logicalId}-${process.pid}-${Math.floor(
|
|
71478
|
+
Math.random() * 1e6
|
|
71479
|
+
)}`;
|
|
71480
|
+
logger.debug(
|
|
71481
|
+
`Starting container ${name} for ${spec.lambda.logicalId} on ${spec.containerHost}:${hostPort}`
|
|
71482
|
+
);
|
|
71483
|
+
const containerId = await runDetached({
|
|
71484
|
+
image,
|
|
71485
|
+
mounts: [{ hostPath: spec.codeDir, containerPath: "/var/task", readOnly: true }],
|
|
71486
|
+
env: spec.env,
|
|
71487
|
+
cmd: [spec.lambda.handler],
|
|
71488
|
+
hostPort,
|
|
71489
|
+
host: spec.containerHost,
|
|
71490
|
+
name,
|
|
71491
|
+
...spec.debugPort !== void 0 && { debugPort: spec.debugPort }
|
|
71492
|
+
});
|
|
71493
|
+
const stopLogStream = streamingEnabled ? streamLogs(containerId) : () => void 0;
|
|
71494
|
+
try {
|
|
71495
|
+
await waitForRieReady(spec.containerHost, hostPort, 3e4);
|
|
71496
|
+
} catch (err) {
|
|
71497
|
+
stopLogStream();
|
|
71498
|
+
await removeContainer(containerId).catch(() => void 0);
|
|
71499
|
+
throw err;
|
|
71500
|
+
}
|
|
71501
|
+
return {
|
|
71502
|
+
logicalId: spec.lambda.logicalId,
|
|
71503
|
+
containerId,
|
|
71504
|
+
containerName: name,
|
|
71505
|
+
hostPort,
|
|
71506
|
+
containerHost: spec.containerHost,
|
|
71507
|
+
stopLogStream
|
|
71508
|
+
};
|
|
71509
|
+
}
|
|
71510
|
+
async function withMutex(entry, body) {
|
|
71511
|
+
const previous = entry.growthMutex;
|
|
71512
|
+
let release;
|
|
71513
|
+
entry.growthMutex = new Promise((r) => release = r);
|
|
71514
|
+
try {
|
|
71515
|
+
await previous;
|
|
71516
|
+
return await body();
|
|
71517
|
+
} finally {
|
|
71518
|
+
release();
|
|
71519
|
+
}
|
|
71520
|
+
}
|
|
71521
|
+
async function tearDown(handle) {
|
|
71522
|
+
try {
|
|
71523
|
+
handle.stopLogStream();
|
|
71524
|
+
} catch (err) {
|
|
71525
|
+
logger.debug(
|
|
71526
|
+
`stopLogStream(${handle.containerName}) failed: ${err instanceof Error ? err.message : String(err)}`
|
|
71527
|
+
);
|
|
71528
|
+
}
|
|
71529
|
+
try {
|
|
71530
|
+
await removeContainer(handle.containerId);
|
|
71531
|
+
} catch (err) {
|
|
71532
|
+
logger.warn(
|
|
71533
|
+
`Failed to remove container ${handle.containerName}: ${err instanceof Error ? err.message : String(err)}. Continuing cleanup.`
|
|
71534
|
+
);
|
|
71535
|
+
}
|
|
71536
|
+
}
|
|
71537
|
+
function poolSize(entry) {
|
|
71538
|
+
return entry.warm.length + entry.inUse.size;
|
|
71539
|
+
}
|
|
71540
|
+
function resetIdleTimer(entry) {
|
|
71541
|
+
if (entry.idleTimer) {
|
|
71542
|
+
clearTimeout(entry.idleTimer);
|
|
71543
|
+
entry.idleTimer = null;
|
|
71544
|
+
}
|
|
71545
|
+
if (entry.warm.length === 0)
|
|
71546
|
+
return;
|
|
71547
|
+
entry.idleTimer = setTimeout(() => {
|
|
71548
|
+
void gcIdle(entry);
|
|
71549
|
+
}, idleMs);
|
|
71550
|
+
entry.idleTimer.unref?.();
|
|
71551
|
+
}
|
|
71552
|
+
async function gcIdle(entry) {
|
|
71553
|
+
const handles = entry.warm.splice(0, entry.warm.length);
|
|
71554
|
+
entry.idleTimer = null;
|
|
71555
|
+
if (handles.length === 0)
|
|
71556
|
+
return;
|
|
71557
|
+
logger.debug(`Idle GC: tearing down ${handles.length} container(s) for ${entry.logicalId}`);
|
|
71558
|
+
await Promise.allSettled(handles.map((h) => tearDown(h)));
|
|
71559
|
+
}
|
|
71560
|
+
return {
|
|
71561
|
+
async acquire(logicalId) {
|
|
71562
|
+
const entry = entries.get(logicalId);
|
|
71563
|
+
if (!entry) {
|
|
71564
|
+
throw new Error(
|
|
71565
|
+
`containerPool.acquire: no spec registered for Lambda '${logicalId}'. This is a bug \u2014 every reachable route's Lambda should be registered at server boot.`
|
|
71566
|
+
);
|
|
71567
|
+
}
|
|
71568
|
+
if (entry.warm.length > 0) {
|
|
71569
|
+
const handle = entry.warm.shift();
|
|
71570
|
+
entry.inUse.add(handle);
|
|
71571
|
+
if (entry.idleTimer) {
|
|
71572
|
+
clearTimeout(entry.idleTimer);
|
|
71573
|
+
entry.idleTimer = null;
|
|
71574
|
+
}
|
|
71575
|
+
return handle;
|
|
71576
|
+
}
|
|
71577
|
+
return await withMutex(entry, async () => {
|
|
71578
|
+
if (entry.warm.length > 0) {
|
|
71579
|
+
const handle = entry.warm.shift();
|
|
71580
|
+
entry.inUse.add(handle);
|
|
71581
|
+
return handle;
|
|
71582
|
+
}
|
|
71583
|
+
if (poolSize(entry) < concurrencyCap) {
|
|
71584
|
+
const spec = specs.get(logicalId);
|
|
71585
|
+
const startPromise = startOne(spec);
|
|
71586
|
+
inFlightStarts.add(startPromise);
|
|
71587
|
+
let handle;
|
|
71588
|
+
try {
|
|
71589
|
+
handle = await startPromise;
|
|
71590
|
+
} finally {
|
|
71591
|
+
inFlightStarts.delete(startPromise);
|
|
71592
|
+
}
|
|
71593
|
+
entry.inUse.add(handle);
|
|
71594
|
+
return handle;
|
|
71595
|
+
}
|
|
71596
|
+
return await new Promise((resolveAcquire, rejectAcquire) => {
|
|
71597
|
+
entry.waitQueue.push({ resolve: resolveAcquire, reject: rejectAcquire });
|
|
71598
|
+
});
|
|
71599
|
+
});
|
|
71600
|
+
},
|
|
71601
|
+
release(handle) {
|
|
71602
|
+
const entry = entries.get(handle.logicalId);
|
|
71603
|
+
if (!entry)
|
|
71604
|
+
return;
|
|
71605
|
+
entry.inUse.delete(handle);
|
|
71606
|
+
const waiter = entry.waitQueue.shift();
|
|
71607
|
+
if (waiter) {
|
|
71608
|
+
entry.inUse.add(handle);
|
|
71609
|
+
waiter.resolve(handle);
|
|
71610
|
+
return;
|
|
71611
|
+
}
|
|
71612
|
+
entry.warm.push(handle);
|
|
71613
|
+
resetIdleTimer(entry);
|
|
71614
|
+
},
|
|
71615
|
+
async dispose() {
|
|
71616
|
+
logger.debug("Disposing container pool");
|
|
71617
|
+
const allHandles = [];
|
|
71618
|
+
for (const entry of entries.values()) {
|
|
71619
|
+
if (entry.idleTimer) {
|
|
71620
|
+
clearTimeout(entry.idleTimer);
|
|
71621
|
+
entry.idleTimer = null;
|
|
71622
|
+
}
|
|
71623
|
+
for (const waiter of entry.waitQueue.splice(0, entry.waitQueue.length)) {
|
|
71624
|
+
try {
|
|
71625
|
+
waiter.reject(
|
|
71626
|
+
new Error(`Container pool disposed while ${entry.logicalId} was waiting`)
|
|
71627
|
+
);
|
|
71628
|
+
} catch {
|
|
71629
|
+
}
|
|
71630
|
+
}
|
|
71631
|
+
allHandles.push(...entry.warm.splice(0, entry.warm.length));
|
|
71632
|
+
for (const h of entry.inUse)
|
|
71633
|
+
allHandles.push(h);
|
|
71634
|
+
entry.inUse.clear();
|
|
71635
|
+
}
|
|
71636
|
+
const startPromises = [...inFlightStarts];
|
|
71637
|
+
if (startPromises.length > 0) {
|
|
71638
|
+
logger.debug(
|
|
71639
|
+
`Waiting for ${startPromises.length} in-flight container start(s) to settle before teardown`
|
|
71640
|
+
);
|
|
71641
|
+
const drainTimeoutMs = 5e3;
|
|
71642
|
+
const wrapped = startPromises.map(
|
|
71643
|
+
(p) => Promise.race([
|
|
71644
|
+
p.then((h) => ({ kind: "ok", handle: h })),
|
|
71645
|
+
new Promise((r) => {
|
|
71646
|
+
const t = setTimeout(() => r({ kind: "timeout" }), drainTimeoutMs);
|
|
71647
|
+
t.unref?.();
|
|
71648
|
+
})
|
|
71649
|
+
]).catch((err) => {
|
|
71650
|
+
logger.debug(
|
|
71651
|
+
`In-flight startOne rejected during dispose: ${err instanceof Error ? err.message : String(err)}`
|
|
71652
|
+
);
|
|
71653
|
+
return { kind: "rejected" };
|
|
71654
|
+
})
|
|
71655
|
+
);
|
|
71656
|
+
const results = await Promise.all(wrapped);
|
|
71657
|
+
let timedOut = 0;
|
|
71658
|
+
for (const r of results) {
|
|
71659
|
+
if (r.kind === "ok") {
|
|
71660
|
+
allHandles.push(r.handle);
|
|
71661
|
+
} else if (r.kind === "timeout") {
|
|
71662
|
+
timedOut++;
|
|
71663
|
+
}
|
|
71664
|
+
}
|
|
71665
|
+
if (timedOut > 0) {
|
|
71666
|
+
logger.warn(
|
|
71667
|
+
`Container pool disposed with ${timedOut} in-flight start(s) still pending after ${drainTimeoutMs}ms; relying on docker --rm + the verify.sh sweep to clean up.`
|
|
71668
|
+
);
|
|
71669
|
+
}
|
|
71670
|
+
inFlightStarts.clear();
|
|
71671
|
+
}
|
|
71672
|
+
await Promise.allSettled(allHandles.map((h) => tearDown(h)));
|
|
71673
|
+
entries.clear();
|
|
71674
|
+
}
|
|
71675
|
+
};
|
|
71676
|
+
}
|
|
71677
|
+
function clampConcurrency(input) {
|
|
71678
|
+
if (!Number.isFinite(input))
|
|
71679
|
+
return 2;
|
|
71680
|
+
return Math.min(
|
|
71681
|
+
MAX_PER_LAMBDA_CONCURRENCY,
|
|
71682
|
+
Math.max(MIN_PER_LAMBDA_CONCURRENCY, Math.trunc(input))
|
|
71683
|
+
);
|
|
71684
|
+
}
|
|
71685
|
+
|
|
71686
|
+
// src/local/http-server.ts
|
|
71687
|
+
import { createServer as createServer2 } from "node:http";
|
|
71688
|
+
|
|
71689
|
+
// src/local/api-gateway-event.ts
|
|
71690
|
+
import { randomUUID } from "node:crypto";
|
|
71691
|
+
var MOCK_ACCOUNT_ID = "123456789012";
|
|
71692
|
+
var MOCK_DOMAIN_PREFIX = "local";
|
|
71693
|
+
var MOCK_DOMAIN_NAME = "localhost";
|
|
71694
|
+
var MOCK_API_ID = "local";
|
|
71695
|
+
function buildHttpApiV2Event(req, ctx, opts = {}) {
|
|
71696
|
+
const { rawPath, rawQueryString } = splitRawUrl(req.rawUrl);
|
|
71697
|
+
const { headers, cookies } = normalizeHeadersV2(req.headers);
|
|
71698
|
+
const queryStringParameters = parseQueryStringV2(rawQueryString);
|
|
71699
|
+
const userAgent = headers["user-agent"] ?? "";
|
|
71700
|
+
const contentType = headers["content-type"] ?? "";
|
|
71701
|
+
const { body, isBase64Encoded } = encodeBody(req.body, contentType);
|
|
71702
|
+
const now = opts.now ? opts.now() : /* @__PURE__ */ new Date();
|
|
71703
|
+
const routeKey = ctx.route.pathPattern === "$default" ? "$default" : `${ctx.route.method} ${ctx.route.pathPattern}`;
|
|
71704
|
+
const event = {
|
|
71705
|
+
version: "2.0",
|
|
71706
|
+
routeKey,
|
|
71707
|
+
rawPath,
|
|
71708
|
+
rawQueryString,
|
|
71709
|
+
cookies,
|
|
71710
|
+
headers,
|
|
71711
|
+
queryStringParameters,
|
|
71712
|
+
pathParameters: decodePathParameters(ctx.pathParameters),
|
|
71713
|
+
stageVariables: null,
|
|
71714
|
+
requestContext: {
|
|
71715
|
+
accountId: MOCK_ACCOUNT_ID,
|
|
71716
|
+
apiId: MOCK_API_ID,
|
|
71717
|
+
domainName: MOCK_DOMAIN_NAME,
|
|
71718
|
+
domainPrefix: MOCK_DOMAIN_PREFIX,
|
|
71719
|
+
http: {
|
|
71720
|
+
method: req.method.toUpperCase(),
|
|
71721
|
+
path: ctx.matchedPath,
|
|
71722
|
+
protocol: "HTTP/1.1",
|
|
71723
|
+
sourceIp: req.sourceIp ?? "127.0.0.1",
|
|
71724
|
+
userAgent
|
|
71725
|
+
},
|
|
71726
|
+
requestId: randomUUID(),
|
|
71727
|
+
routeKey,
|
|
71728
|
+
stage: ctx.route.stage,
|
|
71729
|
+
time: formatRequestTime(now),
|
|
71730
|
+
timeEpoch: now.getTime(),
|
|
71731
|
+
authentication: null,
|
|
71732
|
+
authorizer: null
|
|
71733
|
+
},
|
|
71734
|
+
body,
|
|
71735
|
+
isBase64Encoded
|
|
71736
|
+
};
|
|
71737
|
+
return event;
|
|
71738
|
+
}
|
|
71739
|
+
function buildRestV1Event(req, ctx, opts = {}) {
|
|
71740
|
+
const { rawPath, rawQueryString } = splitRawUrl(req.rawUrl);
|
|
71741
|
+
const { singular: headers, multi: multiValueHeaders } = normalizeHeadersV1(req.headers);
|
|
71742
|
+
const { singular: queryStringParameters, multi: multiValueQueryStringParameters } = parseQueryStringV1(rawQueryString);
|
|
71743
|
+
const contentType = headers["content-type"] ?? "";
|
|
71744
|
+
const { body, isBase64Encoded } = encodeBody(req.body, contentType);
|
|
71745
|
+
const now = opts.now ? opts.now() : /* @__PURE__ */ new Date();
|
|
71746
|
+
const pathParams = decodePathParameters(ctx.pathParameters);
|
|
71747
|
+
const event = {
|
|
71748
|
+
resource: ctx.route.pathPattern,
|
|
71749
|
+
path: ctx.matchedPath,
|
|
71750
|
+
httpMethod: req.method.toUpperCase(),
|
|
71751
|
+
headers,
|
|
71752
|
+
multiValueHeaders,
|
|
71753
|
+
queryStringParameters: Object.keys(queryStringParameters).length > 0 ? queryStringParameters : null,
|
|
71754
|
+
multiValueQueryStringParameters: Object.keys(multiValueQueryStringParameters).length > 0 ? multiValueQueryStringParameters : null,
|
|
71755
|
+
pathParameters: Object.keys(pathParams).length > 0 ? pathParams : null,
|
|
71756
|
+
stageVariables: null,
|
|
71757
|
+
requestContext: {
|
|
71758
|
+
accountId: MOCK_ACCOUNT_ID,
|
|
71759
|
+
apiId: MOCK_API_ID,
|
|
71760
|
+
domainName: MOCK_DOMAIN_NAME,
|
|
71761
|
+
domainPrefix: MOCK_DOMAIN_PREFIX,
|
|
71762
|
+
httpMethod: req.method.toUpperCase(),
|
|
71763
|
+
identity: {
|
|
71764
|
+
sourceIp: req.sourceIp ?? "127.0.0.1",
|
|
71765
|
+
userAgent: headers["user-agent"] ?? ""
|
|
71766
|
+
},
|
|
71767
|
+
path: `/${ctx.route.stage}${ctx.matchedPath}`,
|
|
71768
|
+
protocol: "HTTP/1.1",
|
|
71769
|
+
requestId: randomUUID(),
|
|
71770
|
+
requestTime: formatRequestTime(now),
|
|
71771
|
+
requestTimeEpoch: now.getTime(),
|
|
71772
|
+
resourcePath: ctx.route.pathPattern,
|
|
71773
|
+
stage: ctx.route.stage,
|
|
71774
|
+
authorizer: null
|
|
71775
|
+
},
|
|
71776
|
+
body: req.body.length === 0 ? null : body,
|
|
71777
|
+
isBase64Encoded
|
|
71778
|
+
};
|
|
71779
|
+
return event;
|
|
71780
|
+
}
|
|
71781
|
+
function splitRawUrl(rawUrl) {
|
|
71782
|
+
const q = rawUrl.indexOf("?");
|
|
71783
|
+
if (q === -1)
|
|
71784
|
+
return { rawPath: rawUrl, rawQueryString: "" };
|
|
71785
|
+
return { rawPath: rawUrl.slice(0, q), rawQueryString: rawUrl.slice(q + 1) };
|
|
71786
|
+
}
|
|
71787
|
+
function normalizeHeadersV2(rawHeaders) {
|
|
71788
|
+
const headers = {};
|
|
71789
|
+
let cookies = [];
|
|
71790
|
+
for (const [name, values] of Object.entries(rawHeaders)) {
|
|
71791
|
+
const lower = name.toLowerCase();
|
|
71792
|
+
if (lower === "cookie") {
|
|
71793
|
+
cookies = values.flatMap((v) => v.split(";")).map((s) => s.trim()).filter((s) => s.length > 0);
|
|
71794
|
+
continue;
|
|
71795
|
+
}
|
|
71796
|
+
headers[lower] = values.join(",");
|
|
71797
|
+
}
|
|
71798
|
+
return { headers, cookies };
|
|
71799
|
+
}
|
|
71800
|
+
function normalizeHeadersV1(rawHeaders) {
|
|
71801
|
+
const singular = {};
|
|
71802
|
+
const multi = {};
|
|
71803
|
+
for (const [name, values] of Object.entries(rawHeaders)) {
|
|
71804
|
+
const lower = name.toLowerCase();
|
|
71805
|
+
if (values.length === 0)
|
|
71806
|
+
continue;
|
|
71807
|
+
multi[lower] = [...values];
|
|
71808
|
+
singular[lower] = values[values.length - 1];
|
|
71809
|
+
}
|
|
71810
|
+
return { singular, multi };
|
|
71811
|
+
}
|
|
71812
|
+
function parseQueryStringV2(rawQueryString) {
|
|
71813
|
+
if (rawQueryString.length === 0)
|
|
71814
|
+
return {};
|
|
71815
|
+
const out = {};
|
|
71816
|
+
for (const pair of rawQueryString.split("&")) {
|
|
71817
|
+
if (pair.length === 0)
|
|
71818
|
+
continue;
|
|
71819
|
+
const eq = pair.indexOf("=");
|
|
71820
|
+
const rawKey = eq === -1 ? pair : pair.slice(0, eq);
|
|
71821
|
+
const rawValue = eq === -1 ? "" : pair.slice(eq + 1);
|
|
71822
|
+
const key = safeDecode(rawKey);
|
|
71823
|
+
const value = safeDecode(rawValue);
|
|
71824
|
+
if (!out[key])
|
|
71825
|
+
out[key] = [];
|
|
71826
|
+
out[key].push(value);
|
|
71827
|
+
}
|
|
71828
|
+
const result = {};
|
|
71829
|
+
for (const [k, vs] of Object.entries(out))
|
|
71830
|
+
result[k] = vs.join(",");
|
|
71831
|
+
return result;
|
|
71832
|
+
}
|
|
71833
|
+
function parseQueryStringV1(rawQueryString) {
|
|
71834
|
+
const multi = {};
|
|
71835
|
+
if (rawQueryString.length > 0) {
|
|
71836
|
+
for (const pair of rawQueryString.split("&")) {
|
|
71837
|
+
if (pair.length === 0)
|
|
71838
|
+
continue;
|
|
71839
|
+
const eq = pair.indexOf("=");
|
|
71840
|
+
const rawKey = eq === -1 ? pair : pair.slice(0, eq);
|
|
71841
|
+
const rawValue = eq === -1 ? "" : pair.slice(eq + 1);
|
|
71842
|
+
const key = safeDecode(rawKey);
|
|
71843
|
+
const value = safeDecode(rawValue);
|
|
71844
|
+
if (!multi[key])
|
|
71845
|
+
multi[key] = [];
|
|
71846
|
+
multi[key].push(value);
|
|
71847
|
+
}
|
|
71848
|
+
}
|
|
71849
|
+
const singular = {};
|
|
71850
|
+
for (const [k, vs] of Object.entries(multi)) {
|
|
71851
|
+
if (vs.length > 0)
|
|
71852
|
+
singular[k] = vs[vs.length - 1];
|
|
71853
|
+
}
|
|
71854
|
+
return { singular, multi };
|
|
71855
|
+
}
|
|
71856
|
+
function decodePathParameters(pathParameters) {
|
|
71857
|
+
const out = {};
|
|
71858
|
+
for (const [k, v] of Object.entries(pathParameters)) {
|
|
71859
|
+
out[k] = safeDecode(v);
|
|
71860
|
+
}
|
|
71861
|
+
return out;
|
|
71862
|
+
}
|
|
71863
|
+
function safeDecode(s) {
|
|
71864
|
+
try {
|
|
71865
|
+
return decodeURIComponent(s);
|
|
71866
|
+
} catch {
|
|
71867
|
+
return s;
|
|
71868
|
+
}
|
|
71869
|
+
}
|
|
71870
|
+
function encodeBody(body, contentType) {
|
|
71871
|
+
if (body.length === 0) {
|
|
71872
|
+
return { body: "", isBase64Encoded: false };
|
|
71873
|
+
}
|
|
71874
|
+
if (isTextualContentType(contentType)) {
|
|
71875
|
+
return { body: body.toString("utf-8"), isBase64Encoded: false };
|
|
71876
|
+
}
|
|
71877
|
+
return { body: body.toString("base64"), isBase64Encoded: true };
|
|
71878
|
+
}
|
|
71879
|
+
var TEXT_PREFIXES = [
|
|
71880
|
+
"text/",
|
|
71881
|
+
"application/json",
|
|
71882
|
+
"application/xml",
|
|
71883
|
+
"application/javascript",
|
|
71884
|
+
"application/x-www-form-urlencoded",
|
|
71885
|
+
"application/graphql"
|
|
71886
|
+
];
|
|
71887
|
+
function isTextualContentType(contentType) {
|
|
71888
|
+
if (!contentType)
|
|
71889
|
+
return false;
|
|
71890
|
+
const lower = contentType.toLowerCase();
|
|
71891
|
+
return TEXT_PREFIXES.some((p) => lower.startsWith(p));
|
|
71892
|
+
}
|
|
71893
|
+
function formatRequestTime(d) {
|
|
71894
|
+
const months = [
|
|
71895
|
+
"Jan",
|
|
71896
|
+
"Feb",
|
|
71897
|
+
"Mar",
|
|
71898
|
+
"Apr",
|
|
71899
|
+
"May",
|
|
71900
|
+
"Jun",
|
|
71901
|
+
"Jul",
|
|
71902
|
+
"Aug",
|
|
71903
|
+
"Sep",
|
|
71904
|
+
"Oct",
|
|
71905
|
+
"Nov",
|
|
71906
|
+
"Dec"
|
|
71907
|
+
];
|
|
71908
|
+
const dd = String(d.getUTCDate()).padStart(2, "0");
|
|
71909
|
+
const mmm = months[d.getUTCMonth()];
|
|
71910
|
+
const yyyy = d.getUTCFullYear();
|
|
71911
|
+
const HH = String(d.getUTCHours()).padStart(2, "0");
|
|
71912
|
+
const MM = String(d.getUTCMinutes()).padStart(2, "0");
|
|
71913
|
+
const SS = String(d.getUTCSeconds()).padStart(2, "0");
|
|
71914
|
+
return `${dd}/${mmm}/${yyyy}:${HH}:${MM}:${SS} +0000`;
|
|
71915
|
+
}
|
|
71916
|
+
|
|
71917
|
+
// src/local/api-gateway-response.ts
|
|
71918
|
+
function translateLambdaResponse(payload, version) {
|
|
71919
|
+
if (isErrorEnvelope(payload)) {
|
|
71920
|
+
return errorEnvelopeResponse();
|
|
71921
|
+
}
|
|
71922
|
+
if (isShapedResponse(payload)) {
|
|
71923
|
+
return translateShapedResponse(payload, version);
|
|
71924
|
+
}
|
|
71925
|
+
return autoFormatResponse(payload);
|
|
71926
|
+
}
|
|
71927
|
+
function isErrorEnvelope(payload) {
|
|
71928
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload))
|
|
71929
|
+
return false;
|
|
71930
|
+
const obj = payload;
|
|
71931
|
+
if ("statusCode" in obj)
|
|
71932
|
+
return false;
|
|
71933
|
+
return typeof obj["errorMessage"] === "string";
|
|
71934
|
+
}
|
|
71935
|
+
function isShapedResponse(payload) {
|
|
71936
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload))
|
|
71937
|
+
return false;
|
|
71938
|
+
const status = payload["statusCode"];
|
|
71939
|
+
return typeof status === "number";
|
|
71940
|
+
}
|
|
71941
|
+
function errorEnvelopeResponse() {
|
|
71942
|
+
const body = Buffer.from('{"message":"Internal server error"}', "utf-8");
|
|
71943
|
+
return {
|
|
71944
|
+
statusCode: 502,
|
|
71945
|
+
headers: {
|
|
71946
|
+
"content-type": "application/json",
|
|
71947
|
+
"content-length": String(body.length)
|
|
71948
|
+
},
|
|
71949
|
+
cookies: [],
|
|
71950
|
+
body
|
|
71951
|
+
};
|
|
71952
|
+
}
|
|
71953
|
+
function translateShapedResponse(payload, version) {
|
|
71954
|
+
const statusCode = Number(payload["statusCode"]);
|
|
71955
|
+
const isBase64 = payload["isBase64Encoded"] === true;
|
|
71956
|
+
const rawBody = payload["body"];
|
|
71957
|
+
let body;
|
|
71958
|
+
if (rawBody === void 0 || rawBody === null) {
|
|
71959
|
+
body = Buffer.alloc(0);
|
|
71960
|
+
} else if (typeof rawBody === "string") {
|
|
71961
|
+
body = isBase64 ? Buffer.from(rawBody, "base64") : Buffer.from(rawBody, "utf-8");
|
|
71962
|
+
} else {
|
|
71963
|
+
body = Buffer.from(JSON.stringify(rawBody), "utf-8");
|
|
71964
|
+
}
|
|
71965
|
+
const headers = {};
|
|
71966
|
+
const cookies = [];
|
|
71967
|
+
const headersIn = payload["headers"];
|
|
71968
|
+
if (headersIn && typeof headersIn === "object" && !Array.isArray(headersIn)) {
|
|
71969
|
+
for (const [name, value] of Object.entries(headersIn)) {
|
|
71970
|
+
const lower = name.toLowerCase();
|
|
71971
|
+
const stringValue = stringifyHeaderValue(value);
|
|
71972
|
+
if (lower === "set-cookie") {
|
|
71973
|
+
cookies.push(stringValue);
|
|
71974
|
+
continue;
|
|
71975
|
+
}
|
|
71976
|
+
headers[lower] = stringValue;
|
|
71977
|
+
}
|
|
71978
|
+
}
|
|
71979
|
+
if (version === "v1") {
|
|
71980
|
+
const mvh = payload["multiValueHeaders"];
|
|
71981
|
+
if (mvh && typeof mvh === "object" && !Array.isArray(mvh)) {
|
|
71982
|
+
for (const [name, values] of Object.entries(mvh)) {
|
|
71983
|
+
if (!Array.isArray(values))
|
|
71984
|
+
continue;
|
|
71985
|
+
const lower = name.toLowerCase();
|
|
71986
|
+
const stringified = values.map((v) => stringifyHeaderValue(v));
|
|
71987
|
+
if (lower === "set-cookie") {
|
|
71988
|
+
for (const c of stringified)
|
|
71989
|
+
cookies.push(c);
|
|
71990
|
+
continue;
|
|
71991
|
+
}
|
|
71992
|
+
headers[lower] = stringified.join(",");
|
|
71993
|
+
}
|
|
71994
|
+
}
|
|
71995
|
+
}
|
|
71996
|
+
if (version === "v2") {
|
|
71997
|
+
const cookieList = payload["cookies"];
|
|
71998
|
+
if (Array.isArray(cookieList)) {
|
|
71999
|
+
for (const c of cookieList) {
|
|
72000
|
+
if (typeof c === "string")
|
|
72001
|
+
cookies.push(c);
|
|
72002
|
+
}
|
|
72003
|
+
}
|
|
72004
|
+
}
|
|
72005
|
+
if (!("content-length" in headers)) {
|
|
72006
|
+
headers["content-length"] = String(body.length);
|
|
72007
|
+
}
|
|
72008
|
+
return { statusCode, headers, cookies, body };
|
|
72009
|
+
}
|
|
72010
|
+
function autoFormatResponse(payload) {
|
|
72011
|
+
const body = payload === void 0 ? Buffer.alloc(0) : Buffer.from(JSON.stringify(payload), "utf-8");
|
|
72012
|
+
return {
|
|
72013
|
+
statusCode: 200,
|
|
72014
|
+
headers: {
|
|
72015
|
+
"content-type": "application/json",
|
|
72016
|
+
"content-length": String(body.length)
|
|
72017
|
+
},
|
|
72018
|
+
cookies: [],
|
|
72019
|
+
body
|
|
72020
|
+
};
|
|
72021
|
+
}
|
|
72022
|
+
function stringifyHeaderValue(value) {
|
|
72023
|
+
if (value === null || value === void 0)
|
|
72024
|
+
return "";
|
|
72025
|
+
if (Array.isArray(value))
|
|
72026
|
+
return value.map((v) => String(v)).join(",");
|
|
72027
|
+
return String(value);
|
|
72028
|
+
}
|
|
72029
|
+
|
|
72030
|
+
// src/local/route-matcher.ts
|
|
72031
|
+
function matchRoute(method, requestPath, routes) {
|
|
72032
|
+
const methodUpper = method.toUpperCase();
|
|
72033
|
+
const normalizedPath = requestPath.length > 1 ? requestPath.replace(/\/+$/, "") : requestPath;
|
|
72034
|
+
const requestSegments = splitPath(normalizedPath);
|
|
72035
|
+
let bestFull = null;
|
|
72036
|
+
for (const route of routes) {
|
|
72037
|
+
if (!methodMatches(route.method, methodUpper))
|
|
72038
|
+
continue;
|
|
72039
|
+
if (route.pathPattern === "$default")
|
|
72040
|
+
continue;
|
|
72041
|
+
if (isProxyRoute(route.pathPattern))
|
|
72042
|
+
continue;
|
|
72043
|
+
const result = matchFullPattern(requestSegments, route.pathPattern);
|
|
72044
|
+
if (!result)
|
|
72045
|
+
continue;
|
|
72046
|
+
if (!bestFull || result.literalCount > bestFull.literalCount) {
|
|
72047
|
+
bestFull = {
|
|
72048
|
+
route,
|
|
72049
|
+
pathParameters: result.pathParameters,
|
|
72050
|
+
literalCount: result.literalCount
|
|
72051
|
+
};
|
|
72052
|
+
}
|
|
72053
|
+
}
|
|
72054
|
+
if (bestFull)
|
|
72055
|
+
return { route: bestFull.route, pathParameters: bestFull.pathParameters };
|
|
72056
|
+
let bestProxy = null;
|
|
72057
|
+
for (const route of routes) {
|
|
72058
|
+
if (!methodMatches(route.method, methodUpper))
|
|
72059
|
+
continue;
|
|
72060
|
+
if (route.pathPattern === "$default")
|
|
72061
|
+
continue;
|
|
72062
|
+
if (!isProxyRoute(route.pathPattern))
|
|
72063
|
+
continue;
|
|
72064
|
+
const result = matchProxyPattern(requestSegments, route.pathPattern);
|
|
72065
|
+
if (!result)
|
|
72066
|
+
continue;
|
|
72067
|
+
if (!bestProxy || result.literalCount > bestProxy.literalCount) {
|
|
72068
|
+
bestProxy = {
|
|
72069
|
+
route,
|
|
72070
|
+
pathParameters: result.pathParameters,
|
|
72071
|
+
literalCount: result.literalCount
|
|
72072
|
+
};
|
|
72073
|
+
}
|
|
72074
|
+
}
|
|
72075
|
+
if (bestProxy)
|
|
72076
|
+
return { route: bestProxy.route, pathParameters: bestProxy.pathParameters };
|
|
72077
|
+
for (const route of routes) {
|
|
72078
|
+
if (!methodMatches(route.method, methodUpper))
|
|
72079
|
+
continue;
|
|
72080
|
+
if (route.pathPattern === "$default")
|
|
72081
|
+
return { route, pathParameters: {} };
|
|
72082
|
+
}
|
|
72083
|
+
return null;
|
|
72084
|
+
}
|
|
72085
|
+
function splitPath(path3) {
|
|
72086
|
+
return path3.split("/").filter((s) => s.length > 0);
|
|
72087
|
+
}
|
|
72088
|
+
function methodMatches(routeMethod, requestMethodUpper) {
|
|
72089
|
+
if (routeMethod === "ANY")
|
|
72090
|
+
return true;
|
|
72091
|
+
return routeMethod.toUpperCase() === requestMethodUpper;
|
|
72092
|
+
}
|
|
72093
|
+
function isProxyRoute(pattern) {
|
|
72094
|
+
return /\/\{[^/{}]+\+\}$/.test(pattern) || pattern === "/{proxy+}";
|
|
72095
|
+
}
|
|
72096
|
+
function matchFullPattern(requestSegments, pattern) {
|
|
72097
|
+
const patternSegments = splitPath(pattern);
|
|
72098
|
+
if (patternSegments.length !== requestSegments.length)
|
|
72099
|
+
return null;
|
|
72100
|
+
const pathParameters = {};
|
|
72101
|
+
let literalCount = 0;
|
|
72102
|
+
for (let i = 0; i < patternSegments.length; i++) {
|
|
72103
|
+
const ps = patternSegments[i];
|
|
72104
|
+
const rs = requestSegments[i];
|
|
72105
|
+
if (isPlaceholder(ps)) {
|
|
72106
|
+
const name = ps.slice(1, -1);
|
|
72107
|
+
pathParameters[name] = rs;
|
|
72108
|
+
} else if (ps === rs) {
|
|
72109
|
+
literalCount++;
|
|
72110
|
+
} else {
|
|
72111
|
+
return null;
|
|
72112
|
+
}
|
|
72113
|
+
}
|
|
72114
|
+
return { pathParameters, literalCount };
|
|
72115
|
+
}
|
|
72116
|
+
function matchProxyPattern(requestSegments, pattern) {
|
|
72117
|
+
const patternSegments = splitPath(pattern);
|
|
72118
|
+
if (patternSegments.length === 0)
|
|
72119
|
+
return null;
|
|
72120
|
+
const tail = patternSegments[patternSegments.length - 1];
|
|
72121
|
+
if (!/^\{[^/{}]+\+\}$/.test(tail))
|
|
72122
|
+
return null;
|
|
72123
|
+
const proxyName = tail.slice(1, -2);
|
|
72124
|
+
const fixedPrefixLen = patternSegments.length - 1;
|
|
72125
|
+
if (requestSegments.length < fixedPrefixLen)
|
|
72126
|
+
return null;
|
|
72127
|
+
const pathParameters = {};
|
|
72128
|
+
let literalCount = 0;
|
|
72129
|
+
for (let i = 0; i < fixedPrefixLen; i++) {
|
|
72130
|
+
const ps = patternSegments[i];
|
|
72131
|
+
const rs = requestSegments[i];
|
|
72132
|
+
if (isPlaceholder(ps)) {
|
|
72133
|
+
pathParameters[ps.slice(1, -1)] = rs;
|
|
72134
|
+
} else if (ps === rs) {
|
|
72135
|
+
literalCount++;
|
|
72136
|
+
} else {
|
|
72137
|
+
return null;
|
|
72138
|
+
}
|
|
72139
|
+
}
|
|
72140
|
+
pathParameters[proxyName] = requestSegments.slice(fixedPrefixLen).join("/");
|
|
72141
|
+
return { pathParameters, literalCount };
|
|
72142
|
+
}
|
|
72143
|
+
function isPlaceholder(segment) {
|
|
72144
|
+
return /^\{[^/{}+]+\}$/.test(segment);
|
|
72145
|
+
}
|
|
72146
|
+
|
|
72147
|
+
// src/local/http-server.ts
|
|
72148
|
+
async function startApiServer(opts) {
|
|
72149
|
+
const logger = getLogger().child("start-api");
|
|
72150
|
+
const server = createServer2((req, res) => {
|
|
72151
|
+
handleRequest(req, res, opts).catch((err) => {
|
|
72152
|
+
logger.error(
|
|
72153
|
+
`Unhandled request error: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
|
|
72154
|
+
);
|
|
72155
|
+
if (!res.headersSent) {
|
|
72156
|
+
writeError(res, 502);
|
|
72157
|
+
}
|
|
72158
|
+
});
|
|
72159
|
+
});
|
|
72160
|
+
server.on("connection", (socket) => {
|
|
72161
|
+
socket.setNoDelay(true);
|
|
72162
|
+
});
|
|
72163
|
+
const { actualPort, actualHost } = await new Promise(
|
|
72164
|
+
(resolveListen, rejectListen) => {
|
|
72165
|
+
server.once("error", rejectListen);
|
|
72166
|
+
server.listen(opts.port, opts.host, () => {
|
|
72167
|
+
const addr = server.address();
|
|
72168
|
+
if (addr === null || typeof addr === "string") {
|
|
72169
|
+
rejectListen(new Error("Could not determine listening address"));
|
|
72170
|
+
return;
|
|
72171
|
+
}
|
|
72172
|
+
resolveListen({ actualPort: addr.port, actualHost: opts.host });
|
|
72173
|
+
});
|
|
72174
|
+
}
|
|
72175
|
+
);
|
|
72176
|
+
let closed = false;
|
|
72177
|
+
return {
|
|
72178
|
+
port: actualPort,
|
|
72179
|
+
host: actualHost,
|
|
72180
|
+
server,
|
|
72181
|
+
close: async () => {
|
|
72182
|
+
if (closed)
|
|
72183
|
+
return;
|
|
72184
|
+
closed = true;
|
|
72185
|
+
await new Promise((resolveClose) => {
|
|
72186
|
+
server.close(() => resolveClose());
|
|
72187
|
+
server.closeAllConnections?.();
|
|
72188
|
+
});
|
|
72189
|
+
}
|
|
72190
|
+
};
|
|
72191
|
+
}
|
|
72192
|
+
async function handleRequest(req, res, opts) {
|
|
72193
|
+
const logger = getLogger().child("start-api");
|
|
72194
|
+
const bodyBuf = await readBody(req);
|
|
72195
|
+
const rawUrl = req.url ?? "/";
|
|
72196
|
+
const method = (req.method ?? "GET").toUpperCase();
|
|
72197
|
+
const requestPath = rawUrl.split("?")[0] ?? "/";
|
|
72198
|
+
const match = matchRoute(method, requestPath, opts.routes);
|
|
72199
|
+
if (!match) {
|
|
72200
|
+
writeError(res, 404, '{"message":"Not Found"}');
|
|
72201
|
+
return;
|
|
72202
|
+
}
|
|
72203
|
+
const snapshot = {
|
|
72204
|
+
method,
|
|
72205
|
+
rawUrl,
|
|
72206
|
+
headers: collectHeaders(req),
|
|
72207
|
+
body: bodyBuf,
|
|
72208
|
+
...req.socket.remoteAddress !== void 0 && { sourceIp: req.socket.remoteAddress }
|
|
72209
|
+
};
|
|
72210
|
+
const matchCtx = {
|
|
72211
|
+
route: match.route,
|
|
72212
|
+
pathParameters: match.pathParameters,
|
|
72213
|
+
matchedPath: requestPath
|
|
72214
|
+
};
|
|
72215
|
+
const event = match.route.apiVersion === "v1" ? buildRestV1Event(snapshot, matchCtx) : buildHttpApiV2Event(snapshot, matchCtx);
|
|
72216
|
+
let handle;
|
|
72217
|
+
try {
|
|
72218
|
+
handle = await opts.pool.acquire(match.route.lambdaLogicalId);
|
|
72219
|
+
} catch (err) {
|
|
72220
|
+
logger.error(
|
|
72221
|
+
`Failed to acquire container for ${match.route.lambdaLogicalId}: ${err instanceof Error ? err.message : String(err)}`
|
|
72222
|
+
);
|
|
72223
|
+
writeError(res, 502);
|
|
72224
|
+
return;
|
|
72225
|
+
}
|
|
72226
|
+
try {
|
|
72227
|
+
const invokeResult = await invokeRie(
|
|
72228
|
+
handle.containerHost,
|
|
72229
|
+
handle.hostPort,
|
|
72230
|
+
event,
|
|
72231
|
+
opts.rieTimeoutMs
|
|
72232
|
+
);
|
|
72233
|
+
const translated = translateLambdaResponse(invokeResult.payload, match.route.apiVersion);
|
|
72234
|
+
res.statusCode = translated.statusCode;
|
|
72235
|
+
for (const [name, value] of Object.entries(translated.headers)) {
|
|
72236
|
+
res.setHeader(name, value);
|
|
72237
|
+
}
|
|
72238
|
+
if (translated.cookies.length > 0) {
|
|
72239
|
+
res.setHeader("set-cookie", translated.cookies);
|
|
72240
|
+
}
|
|
72241
|
+
res.end(translated.body);
|
|
72242
|
+
} catch (err) {
|
|
72243
|
+
logger.error(
|
|
72244
|
+
`RIE invoke failed for ${match.route.lambdaLogicalId}: ${err instanceof Error ? err.message : String(err)}`
|
|
72245
|
+
);
|
|
72246
|
+
if (!res.headersSent) {
|
|
72247
|
+
writeError(res, 502);
|
|
72248
|
+
} else {
|
|
72249
|
+
res.end();
|
|
72250
|
+
}
|
|
72251
|
+
} finally {
|
|
72252
|
+
opts.pool.release(handle);
|
|
72253
|
+
}
|
|
72254
|
+
}
|
|
72255
|
+
function readBody(req) {
|
|
72256
|
+
return new Promise((resolveBody, rejectBody) => {
|
|
72257
|
+
const chunks = [];
|
|
72258
|
+
req.on("data", (chunk) => {
|
|
72259
|
+
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
72260
|
+
});
|
|
72261
|
+
req.on("end", () => resolveBody(Buffer.concat(chunks)));
|
|
72262
|
+
req.on("error", rejectBody);
|
|
72263
|
+
});
|
|
72264
|
+
}
|
|
72265
|
+
function collectHeaders(req) {
|
|
72266
|
+
const out = {};
|
|
72267
|
+
for (const [name, value] of Object.entries(req.headers)) {
|
|
72268
|
+
if (Array.isArray(value)) {
|
|
72269
|
+
out[name] = value;
|
|
72270
|
+
} else if (typeof value === "string") {
|
|
72271
|
+
out[name] = [value];
|
|
72272
|
+
}
|
|
72273
|
+
}
|
|
72274
|
+
return out;
|
|
72275
|
+
}
|
|
72276
|
+
function writeError(res, statusCode, body = '{"message":"Internal server error"}') {
|
|
72277
|
+
res.statusCode = statusCode;
|
|
72278
|
+
res.setHeader("content-type", "application/json");
|
|
72279
|
+
res.setHeader("content-length", String(Buffer.byteLength(body, "utf-8")));
|
|
72280
|
+
res.end(body);
|
|
72281
|
+
}
|
|
72282
|
+
|
|
72283
|
+
// src/cli/commands/local-start-api.ts
|
|
72284
|
+
async function localStartApiCommand(options) {
|
|
72285
|
+
const logger = getLogger();
|
|
72286
|
+
if (options.verbose) {
|
|
72287
|
+
logger.setLevel("debug");
|
|
72288
|
+
}
|
|
72289
|
+
warnIfDeprecatedRegion(options);
|
|
72290
|
+
await applyRoleArnIfSet({ roleArn: options.roleArn, region: options.region });
|
|
72291
|
+
await ensureDockerAvailable();
|
|
72292
|
+
const appCmd = resolveApp(options.app);
|
|
72293
|
+
if (!appCmd) {
|
|
72294
|
+
throw new Error('No CDK app specified. Pass --app, set CDKD_APP, or add "app" to cdk.json.');
|
|
72295
|
+
}
|
|
72296
|
+
logger.info("Synthesizing CDK app...");
|
|
72297
|
+
const synthesizer = new Synthesizer();
|
|
72298
|
+
const context = parseContextOptions(options.context);
|
|
72299
|
+
const synthOpts = {
|
|
72300
|
+
app: appCmd,
|
|
72301
|
+
output: options.output,
|
|
72302
|
+
...options.region && { region: options.region },
|
|
72303
|
+
...options.profile && { profile: options.profile },
|
|
72304
|
+
...Object.keys(context).length > 0 && { context }
|
|
72305
|
+
};
|
|
72306
|
+
const { stacks } = await synthesizer.synthesize(synthOpts);
|
|
72307
|
+
const targetStacks = pickTargetStacks(stacks, options.stack);
|
|
72308
|
+
if (targetStacks.length === 0) {
|
|
72309
|
+
throw new Error("No stacks matched. Pass --stack <name> or run from a single-stack app.");
|
|
72310
|
+
}
|
|
72311
|
+
const routes = discoverRoutes(targetStacks);
|
|
72312
|
+
if (routes.length === 0) {
|
|
72313
|
+
throw new Error(
|
|
72314
|
+
"No supported API routes were discovered. cdkd local start-api supports AWS::ApiGateway::* (REST v1), AWS::ApiGatewayV2::* (HTTP), and AWS::Lambda::Url (Function URL) with AWS_PROXY integrations only."
|
|
72315
|
+
);
|
|
72316
|
+
}
|
|
72317
|
+
const lambdaIds = uniqueLambdaIds(routes);
|
|
72318
|
+
const overrides = readEnvOverridesFile(options.envVars);
|
|
72319
|
+
const debugPortBase = options.debugPortBase ? parseDebugPort(options.debugPortBase) : void 0;
|
|
72320
|
+
const specs = /* @__PURE__ */ new Map();
|
|
72321
|
+
const inlineTmpDirs = /* @__PURE__ */ new Set();
|
|
72322
|
+
for (let i = 0; i < lambdaIds.length; i++) {
|
|
72323
|
+
const logicalId = lambdaIds[i];
|
|
72324
|
+
const spec = await buildContainerSpec({
|
|
72325
|
+
logicalId,
|
|
72326
|
+
stacks: targetStacks,
|
|
72327
|
+
overrides,
|
|
72328
|
+
assumeRole: options.assumeRole,
|
|
72329
|
+
containerHost: options.containerHost,
|
|
72330
|
+
...debugPortBase !== void 0 && { debugPort: debugPortBase + i },
|
|
72331
|
+
stsRegion: options.region ?? process.env["AWS_REGION"] ?? process.env["AWS_DEFAULT_REGION"],
|
|
72332
|
+
inlineTmpDirs
|
|
72333
|
+
});
|
|
72334
|
+
specs.set(logicalId, spec);
|
|
72335
|
+
}
|
|
72336
|
+
const distinctImages = /* @__PURE__ */ new Set();
|
|
72337
|
+
for (const spec of specs.values()) {
|
|
72338
|
+
distinctImages.add(resolveRuntimeImage(spec.lambda.runtime));
|
|
72339
|
+
}
|
|
72340
|
+
for (const image of distinctImages) {
|
|
72341
|
+
await pullImage(image, options.pull === false);
|
|
72342
|
+
}
|
|
72343
|
+
const perLambdaConcurrency = parsePerLambdaConcurrency(options.perLambdaConcurrency);
|
|
72344
|
+
const pool = createContainerPool(specs, {
|
|
72345
|
+
perLambdaConcurrency,
|
|
72346
|
+
skipPull: options.pull === false
|
|
72347
|
+
});
|
|
72348
|
+
if (options.warm) {
|
|
72349
|
+
logger.info(`Pre-warming ${specs.size} container(s)...`);
|
|
72350
|
+
const handles = await Promise.allSettled([...specs.keys()].map((id) => pool.acquire(id)));
|
|
72351
|
+
for (const result of handles) {
|
|
72352
|
+
if (result.status === "fulfilled") {
|
|
72353
|
+
pool.release(result.value);
|
|
72354
|
+
} else {
|
|
72355
|
+
logger.warn(
|
|
72356
|
+
`Pre-warm failed for one Lambda (cold start cost will apply on first request): ${result.reason instanceof Error ? result.reason.message : String(result.reason)}`
|
|
72357
|
+
);
|
|
72358
|
+
}
|
|
72359
|
+
}
|
|
72360
|
+
}
|
|
72361
|
+
let maxTimeoutSec = 0;
|
|
72362
|
+
for (const spec of specs.values()) {
|
|
72363
|
+
if (spec.lambda.timeoutSec > maxTimeoutSec)
|
|
72364
|
+
maxTimeoutSec = spec.lambda.timeoutSec;
|
|
72365
|
+
}
|
|
72366
|
+
const rieTimeoutMs = Math.max(3e4, maxTimeoutSec * 2 * 1e3);
|
|
72367
|
+
const port = parseInt(options.port, 10);
|
|
72368
|
+
if (!Number.isFinite(port) || port < 0 || port > 65535) {
|
|
72369
|
+
throw new Error(`--port must be 0..65535 (got ${options.port}).`);
|
|
72370
|
+
}
|
|
72371
|
+
const server = await startApiServer({
|
|
72372
|
+
routes,
|
|
72373
|
+
pool,
|
|
72374
|
+
rieTimeoutMs,
|
|
72375
|
+
host: options.host,
|
|
72376
|
+
port
|
|
72377
|
+
});
|
|
72378
|
+
printRouteTable(routes);
|
|
72379
|
+
logger.info(
|
|
72380
|
+
`Per-Lambda concurrency: ${perLambdaConcurrency} (override with --per-lambda-concurrency)`
|
|
72381
|
+
);
|
|
72382
|
+
process.stdout.write(`Server listening on http://${server.host}:${server.port}
|
|
72383
|
+
`);
|
|
72384
|
+
process.stdout.write("^C to stop and clean up containers.\n");
|
|
72385
|
+
let shuttingDown = false;
|
|
72386
|
+
let forceExitArmed = false;
|
|
72387
|
+
const shutdown = async (signal, exitCode) => {
|
|
72388
|
+
if (shuttingDown) {
|
|
72389
|
+
if (!forceExitArmed) {
|
|
72390
|
+
forceExitArmed = true;
|
|
72391
|
+
logger.warn(
|
|
72392
|
+
`Received second ${signal}; force-exiting. Orphan containers may remain \u2014 run 'docker ps --filter name=cdkd-local-' and 'docker rm -f' to clean up.`
|
|
72393
|
+
);
|
|
72394
|
+
process.exit(130);
|
|
72395
|
+
}
|
|
72396
|
+
return;
|
|
72397
|
+
}
|
|
72398
|
+
shuttingDown = true;
|
|
72399
|
+
logger.info(`Received ${signal}, shutting down...`);
|
|
72400
|
+
try {
|
|
72401
|
+
await server.close();
|
|
72402
|
+
} catch (err) {
|
|
72403
|
+
logger.warn(`server.close() failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
72404
|
+
}
|
|
72405
|
+
try {
|
|
72406
|
+
await pool.dispose();
|
|
72407
|
+
} catch (err) {
|
|
72408
|
+
logger.warn(`pool.dispose() failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
72409
|
+
}
|
|
72410
|
+
for (const dir of inlineTmpDirs) {
|
|
72411
|
+
try {
|
|
72412
|
+
rmSync2(dir, { recursive: true, force: true });
|
|
72413
|
+
} catch (err) {
|
|
72414
|
+
logger.warn(
|
|
72415
|
+
`Failed to remove inline-code tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`
|
|
72416
|
+
);
|
|
72417
|
+
}
|
|
72418
|
+
}
|
|
72419
|
+
process.exit(exitCode);
|
|
72420
|
+
};
|
|
72421
|
+
process.on("SIGINT", () => {
|
|
72422
|
+
void shutdown("SIGINT", 130);
|
|
72423
|
+
});
|
|
72424
|
+
process.on("SIGTERM", () => {
|
|
72425
|
+
void shutdown("SIGTERM", 0);
|
|
72426
|
+
});
|
|
72427
|
+
process.on("uncaughtException", (err) => {
|
|
72428
|
+
logger.error(
|
|
72429
|
+
`Uncaught exception: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
|
|
72430
|
+
);
|
|
72431
|
+
void shutdown("uncaughtException", 1);
|
|
72432
|
+
});
|
|
72433
|
+
process.on("unhandledRejection", (reason) => {
|
|
72434
|
+
logger.error(
|
|
72435
|
+
`Unhandled rejection: ${reason instanceof Error ? reason.stack ?? reason.message : String(reason)}`
|
|
72436
|
+
);
|
|
72437
|
+
void shutdown("unhandledRejection", 1);
|
|
72438
|
+
});
|
|
72439
|
+
await new Promise(() => void 0);
|
|
72440
|
+
}
|
|
72441
|
+
function pickTargetStacks(stacks, pattern) {
|
|
72442
|
+
if (pattern) {
|
|
72443
|
+
return matchStacks(stacks, [pattern]);
|
|
72444
|
+
}
|
|
72445
|
+
if (stacks.length === 1)
|
|
72446
|
+
return stacks;
|
|
72447
|
+
if (stacks.length === 0)
|
|
72448
|
+
return [];
|
|
72449
|
+
throw new Error(
|
|
72450
|
+
`Multi-stack app: pass --stack <name> to pick a target. Available stacks: ${stacks.map((s) => s.stackName).join(", ")}.`
|
|
72451
|
+
);
|
|
72452
|
+
}
|
|
72453
|
+
function uniqueLambdaIds(routes) {
|
|
72454
|
+
const seen = /* @__PURE__ */ new Set();
|
|
72455
|
+
const out = [];
|
|
72456
|
+
for (const r of routes) {
|
|
72457
|
+
if (!seen.has(r.lambdaLogicalId)) {
|
|
72458
|
+
seen.add(r.lambdaLogicalId);
|
|
72459
|
+
out.push(r.lambdaLogicalId);
|
|
72460
|
+
}
|
|
72461
|
+
}
|
|
72462
|
+
return out;
|
|
72463
|
+
}
|
|
72464
|
+
async function buildContainerSpec(args) {
|
|
72465
|
+
const {
|
|
72466
|
+
logicalId,
|
|
72467
|
+
stacks,
|
|
72468
|
+
overrides,
|
|
72469
|
+
assumeRole,
|
|
72470
|
+
containerHost,
|
|
72471
|
+
debugPort,
|
|
72472
|
+
stsRegion,
|
|
72473
|
+
inlineTmpDirs
|
|
72474
|
+
} = args;
|
|
72475
|
+
const lambda = resolveLambdaByLogicalId(logicalId, stacks);
|
|
72476
|
+
const codeDir = lambda.codePath ?? materializeInlineCode(
|
|
72477
|
+
lambda.handler,
|
|
72478
|
+
lambda.inlineCode ?? "",
|
|
72479
|
+
resolveRuntimeFileExtension(lambda.runtime),
|
|
72480
|
+
inlineTmpDirs
|
|
72481
|
+
);
|
|
72482
|
+
const templateEnv = getTemplateEnv(lambda.resource);
|
|
72483
|
+
const envResult = resolveEnvVars(logicalId, templateEnv, overrides);
|
|
72484
|
+
for (const key of envResult.unresolved) {
|
|
72485
|
+
getLogger().warn(
|
|
72486
|
+
`Lambda ${logicalId}: env var ${key} contains a CloudFormation intrinsic and was dropped. Override it with --env-vars (e.g. {"${logicalId}":{"${key}":"<literal>"}}) to surface a literal value.`
|
|
72487
|
+
);
|
|
72488
|
+
}
|
|
72489
|
+
const dockerEnv = {
|
|
72490
|
+
AWS_LAMBDA_FUNCTION_NAME: logicalId,
|
|
72491
|
+
AWS_LAMBDA_FUNCTION_MEMORY_SIZE: String(lambda.memoryMb),
|
|
72492
|
+
AWS_LAMBDA_FUNCTION_TIMEOUT: String(lambda.timeoutSec),
|
|
72493
|
+
AWS_LAMBDA_FUNCTION_VERSION: "$LATEST",
|
|
72494
|
+
AWS_LAMBDA_LOG_GROUP_NAME: `/aws/lambda/${logicalId}`,
|
|
72495
|
+
AWS_LAMBDA_LOG_STREAM_NAME: "local",
|
|
72496
|
+
...envResult.resolved
|
|
72497
|
+
};
|
|
72498
|
+
const roleArn = effectiveAssumeRoleArn(logicalId, assumeRole);
|
|
72499
|
+
if (roleArn) {
|
|
72500
|
+
const creds = await assumeLambdaExecutionRole(roleArn, stsRegion);
|
|
72501
|
+
dockerEnv["AWS_ACCESS_KEY_ID"] = creds.accessKeyId;
|
|
72502
|
+
dockerEnv["AWS_SECRET_ACCESS_KEY"] = creds.secretAccessKey;
|
|
72503
|
+
dockerEnv["AWS_SESSION_TOKEN"] = creds.sessionToken;
|
|
72504
|
+
if (stsRegion)
|
|
72505
|
+
dockerEnv["AWS_REGION"] = stsRegion;
|
|
72506
|
+
} else {
|
|
72507
|
+
forwardAwsEnv(dockerEnv);
|
|
72508
|
+
}
|
|
72509
|
+
if (debugPort !== void 0) {
|
|
72510
|
+
dockerEnv["NODE_OPTIONS"] = `--inspect-brk=0.0.0.0:${debugPort}`;
|
|
72511
|
+
}
|
|
72512
|
+
const spec = {
|
|
72513
|
+
lambda,
|
|
72514
|
+
codeDir,
|
|
72515
|
+
env: dockerEnv,
|
|
72516
|
+
containerHost,
|
|
72517
|
+
...debugPort !== void 0 && { debugPort }
|
|
72518
|
+
};
|
|
72519
|
+
return spec;
|
|
72520
|
+
}
|
|
72521
|
+
function resolveLambdaByLogicalId(logicalId, stacks) {
|
|
72522
|
+
for (const stack of stacks) {
|
|
72523
|
+
const resource = stack.template.Resources?.[logicalId];
|
|
72524
|
+
if (!resource || resource.Type !== "AWS::Lambda::Function")
|
|
72525
|
+
continue;
|
|
72526
|
+
const props = resource.Properties ?? {};
|
|
72527
|
+
const runtime = typeof props["Runtime"] === "string" ? props["Runtime"] : "";
|
|
72528
|
+
const handler = typeof props["Handler"] === "string" ? props["Handler"] : "";
|
|
72529
|
+
const memoryMb = typeof props["MemorySize"] === "number" ? props["MemorySize"] : 128;
|
|
72530
|
+
const timeoutSec = typeof props["Timeout"] === "number" ? props["Timeout"] : 3;
|
|
72531
|
+
if (!runtime) {
|
|
72532
|
+
throw new Error(
|
|
72533
|
+
`Lambda '${logicalId}' has no Runtime property. Container-image Lambdas (Code.ImageUri) are not supported in cdkd local start-api v1.`
|
|
72534
|
+
);
|
|
72535
|
+
}
|
|
72536
|
+
if (!handler) {
|
|
72537
|
+
throw new Error(`Lambda '${logicalId}' has no Handler property.`);
|
|
72538
|
+
}
|
|
72539
|
+
const code = props["Code"] ?? {};
|
|
72540
|
+
const imageUri = code["ImageUri"];
|
|
72541
|
+
if (typeof imageUri === "string" || typeof imageUri === "object" && imageUri !== null && "Fn::Sub" in imageUri) {
|
|
72542
|
+
throw new Error(
|
|
72543
|
+
`Lambda '${logicalId}' uses Code.ImageUri (container-image Lambda). 'cdkd local start-api' v1 supports ZIP Lambdas only \u2014 container-image support is deferred to a follow-up PR. Use 'cdkd local invoke' to exercise this function locally.`
|
|
72544
|
+
);
|
|
72545
|
+
}
|
|
72546
|
+
const inlineCode = typeof code["ZipFile"] === "string" ? code["ZipFile"] : void 0;
|
|
72547
|
+
let codePath = null;
|
|
72548
|
+
if (!inlineCode) {
|
|
72549
|
+
codePath = resolveAssetCodePath2(stack, logicalId, resource);
|
|
72550
|
+
}
|
|
72551
|
+
return {
|
|
72552
|
+
kind: "zip",
|
|
72553
|
+
stack,
|
|
72554
|
+
logicalId,
|
|
72555
|
+
resource,
|
|
72556
|
+
runtime,
|
|
72557
|
+
handler,
|
|
72558
|
+
memoryMb,
|
|
72559
|
+
timeoutSec,
|
|
72560
|
+
codePath,
|
|
72561
|
+
...inlineCode !== void 0 && { inlineCode }
|
|
72562
|
+
};
|
|
72563
|
+
}
|
|
72564
|
+
throw new Error(
|
|
72565
|
+
`No AWS::Lambda::Function resource named '${logicalId}' found in target stacks. This is likely a synthesis bug \u2014 the route-discovery phase resolved a route to this logical ID.`
|
|
72566
|
+
);
|
|
72567
|
+
}
|
|
72568
|
+
function resolveAssetCodePath2(stack, logicalId, resource) {
|
|
72569
|
+
const meta = resource.Metadata;
|
|
72570
|
+
const assetPath = meta?.["aws:asset:path"];
|
|
72571
|
+
if (typeof assetPath !== "string" || assetPath.length === 0) {
|
|
72572
|
+
throw new Error(
|
|
72573
|
+
`Lambda '${logicalId}' has no Metadata['aws:asset:path']. cdkd local start-api needs this hint to find the local asset directory. Re-synthesize the app and retry.`
|
|
72574
|
+
);
|
|
72575
|
+
}
|
|
72576
|
+
const cdkOutDir = stack.assetManifestPath ? path.dirname(stack.assetManifestPath) : process.cwd();
|
|
72577
|
+
return path.isAbsolute(assetPath) ? assetPath : path.resolve(cdkOutDir, assetPath);
|
|
72578
|
+
}
|
|
72579
|
+
function printRouteTable(routes) {
|
|
72580
|
+
const sorted = [...routes].sort((a, b) => {
|
|
72581
|
+
if (a.pathPattern !== b.pathPattern)
|
|
72582
|
+
return a.pathPattern.localeCompare(b.pathPattern);
|
|
72583
|
+
return a.method.localeCompare(b.method);
|
|
72584
|
+
});
|
|
72585
|
+
const methodWidth = Math.max(...sorted.map((r) => r.method.length), 6);
|
|
72586
|
+
const pathWidth = Math.max(...sorted.map((r) => r.pathPattern.length), 8);
|
|
72587
|
+
process.stdout.write("Discovered routes:\n");
|
|
72588
|
+
for (const r of sorted) {
|
|
72589
|
+
const sourceLabel = r.source === "http-api" ? "HTTP API" : r.source === "rest-v1" ? `REST v1, stage '${r.stage}'` : "Function URL";
|
|
72590
|
+
process.stdout.write(
|
|
72591
|
+
` ${r.method.padEnd(methodWidth)} ${r.pathPattern.padEnd(pathWidth)} -> ${r.lambdaLogicalId} (${sourceLabel})
|
|
72592
|
+
`
|
|
72593
|
+
);
|
|
72594
|
+
}
|
|
72595
|
+
process.stdout.write("\n");
|
|
72596
|
+
}
|
|
72597
|
+
function materializeInlineCode(handler, source, fileExtension, tmpDirsOut) {
|
|
72598
|
+
const lastDot = handler.lastIndexOf(".");
|
|
72599
|
+
if (lastDot <= 0) {
|
|
72600
|
+
throw new Error(`Handler '${handler}' is malformed: expected '<modulePath>.<exportName>'.`);
|
|
72601
|
+
}
|
|
72602
|
+
const modulePath = handler.substring(0, lastDot);
|
|
72603
|
+
const dir = mkdtempSync2(path.join(tmpdir2(), "cdkd-local-start-api-"));
|
|
72604
|
+
tmpDirsOut.add(dir);
|
|
72605
|
+
const filePath = path.join(dir, `${modulePath}${fileExtension}`);
|
|
72606
|
+
mkdirSync2(path.dirname(filePath), { recursive: true });
|
|
72607
|
+
writeFileSync5(filePath, source, "utf-8");
|
|
72608
|
+
return dir;
|
|
72609
|
+
}
|
|
72610
|
+
function getTemplateEnv(resource) {
|
|
72611
|
+
const props = resource.Properties ?? {};
|
|
72612
|
+
const env = props["Environment"];
|
|
72613
|
+
if (!env || typeof env !== "object")
|
|
72614
|
+
return void 0;
|
|
72615
|
+
const vars = env["Variables"];
|
|
72616
|
+
if (!vars || typeof vars !== "object")
|
|
72617
|
+
return void 0;
|
|
72618
|
+
return vars;
|
|
72619
|
+
}
|
|
72620
|
+
function readEnvOverridesFile(filePath) {
|
|
72621
|
+
if (!filePath)
|
|
72622
|
+
return void 0;
|
|
72623
|
+
let raw;
|
|
72624
|
+
try {
|
|
72625
|
+
raw = readFileSync6(filePath, "utf-8");
|
|
72626
|
+
} catch (err) {
|
|
72627
|
+
throw new Error(
|
|
72628
|
+
`Failed to read --env-vars file '${filePath}': ${err instanceof Error ? err.message : String(err)}`
|
|
72629
|
+
);
|
|
72630
|
+
}
|
|
72631
|
+
let parsed;
|
|
72632
|
+
try {
|
|
72633
|
+
parsed = JSON.parse(raw);
|
|
72634
|
+
} catch (err) {
|
|
72635
|
+
throw new Error(
|
|
72636
|
+
`Failed to parse --env-vars file '${filePath}' as JSON: ${err instanceof Error ? err.message : String(err)}`
|
|
72637
|
+
);
|
|
72638
|
+
}
|
|
72639
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
72640
|
+
throw new Error(`--env-vars file '${filePath}' must contain a JSON object at the top level.`);
|
|
72641
|
+
}
|
|
72642
|
+
return parsed;
|
|
72643
|
+
}
|
|
72644
|
+
function forwardAwsEnv(env) {
|
|
72645
|
+
const passThrough = [
|
|
72646
|
+
"AWS_ACCESS_KEY_ID",
|
|
72647
|
+
"AWS_SECRET_ACCESS_KEY",
|
|
72648
|
+
"AWS_SESSION_TOKEN",
|
|
72649
|
+
"AWS_REGION",
|
|
72650
|
+
"AWS_DEFAULT_REGION"
|
|
72651
|
+
];
|
|
72652
|
+
for (const key of passThrough) {
|
|
72653
|
+
const value = process.env[key];
|
|
72654
|
+
if (value !== void 0)
|
|
72655
|
+
env[key] = value;
|
|
72656
|
+
}
|
|
72657
|
+
}
|
|
72658
|
+
async function assumeLambdaExecutionRole(roleArn, region) {
|
|
72659
|
+
const { STSClient: STSClient11, AssumeRoleCommand: AssumeRoleCommand2 } = await import("@aws-sdk/client-sts");
|
|
72660
|
+
const sts = new STSClient11({ ...region && { region } });
|
|
72661
|
+
try {
|
|
72662
|
+
const response = await sts.send(
|
|
72663
|
+
new AssumeRoleCommand2({
|
|
72664
|
+
RoleArn: roleArn,
|
|
72665
|
+
RoleSessionName: `cdkd-local-start-api-${Date.now()}`,
|
|
72666
|
+
DurationSeconds: 3600
|
|
72667
|
+
})
|
|
72668
|
+
);
|
|
72669
|
+
const creds = response.Credentials;
|
|
72670
|
+
if (!creds?.AccessKeyId || !creds.SecretAccessKey || !creds.SessionToken) {
|
|
72671
|
+
throw new Error(`AssumeRole(${roleArn}) returned no usable credentials.`);
|
|
72672
|
+
}
|
|
72673
|
+
return {
|
|
72674
|
+
accessKeyId: creds.AccessKeyId,
|
|
72675
|
+
secretAccessKey: creds.SecretAccessKey,
|
|
72676
|
+
sessionToken: creds.SessionToken
|
|
72677
|
+
};
|
|
72678
|
+
} finally {
|
|
72679
|
+
sts.destroy();
|
|
72680
|
+
}
|
|
72681
|
+
}
|
|
72682
|
+
function parsePerLambdaConcurrency(raw) {
|
|
72683
|
+
const parsed = parseInt(raw, 10);
|
|
72684
|
+
if (!Number.isFinite(parsed) || parsed < 1) {
|
|
72685
|
+
throw new Error(`--per-lambda-concurrency must be a positive integer (got '${raw}')`);
|
|
72686
|
+
}
|
|
72687
|
+
if (parsed > 4) {
|
|
72688
|
+
getLogger().warn(
|
|
72689
|
+
`--per-lambda-concurrency ${parsed} exceeds the v1 cap of 4; clamping to 4. (Raise this in a follow-up PR if your workload needs more.)`
|
|
72690
|
+
);
|
|
72691
|
+
return 4;
|
|
72692
|
+
}
|
|
72693
|
+
return parsed;
|
|
72694
|
+
}
|
|
72695
|
+
function parseDebugPort(raw) {
|
|
72696
|
+
const parsed = parseInt(raw, 10);
|
|
72697
|
+
if (!Number.isFinite(parsed) || parsed < 1 || parsed > 65535) {
|
|
72698
|
+
throw new Error(`--debug-port-base must be 1..65535 (got '${raw}')`);
|
|
72699
|
+
}
|
|
72700
|
+
return parsed;
|
|
72701
|
+
}
|
|
72702
|
+
function createLocalStartApiCommand() {
|
|
72703
|
+
const startApi = new Command14("start-api").description(
|
|
72704
|
+
"Run a long-running local HTTP server that maps API Gateway routes (REST v1, HTTP API, Function URL) to Lambda invocations against the AWS Lambda Runtime Interface Emulator (Docker required)."
|
|
72705
|
+
).addOption(
|
|
72706
|
+
new Option7("--port <port>", "HTTP server port (default: auto-allocate)").default("0")
|
|
72707
|
+
).addOption(new Option7("--host <host>", "Bind address").default("127.0.0.1")).addOption(new Option7("--stack <name>", "Stack to start (single-stack apps auto-detect)")).addOption(
|
|
72708
|
+
new Option7("--warm", "Pre-start one container per Lambda at server boot").default(false)
|
|
72709
|
+
).addOption(
|
|
72710
|
+
new Option7(
|
|
72711
|
+
"--per-lambda-concurrency <n>",
|
|
72712
|
+
"Pool size cap per Lambda (default 2, max 4)"
|
|
72713
|
+
).default("2")
|
|
72714
|
+
).addOption(new Option7("--no-pull", "Skip docker pull (cached image)")).addOption(
|
|
72715
|
+
new Option7(
|
|
72716
|
+
"--container-host <host>",
|
|
72717
|
+
"Hostname/IP the container reaches the host on"
|
|
72718
|
+
).default("host.docker.internal")
|
|
72719
|
+
).addOption(
|
|
72720
|
+
new Option7(
|
|
72721
|
+
"--debug-port-base <port>",
|
|
72722
|
+
"Reserve a contiguous --debug-port range (one per Lambda)"
|
|
72723
|
+
)
|
|
72724
|
+
).addOption(
|
|
72725
|
+
new Option7(
|
|
72726
|
+
"--env-vars <file>",
|
|
72727
|
+
'JSON env-var overrides (SAM-compatible: {"LogicalId":{"KEY":"VALUE"}, "Parameters": {...}})'
|
|
72728
|
+
)
|
|
72729
|
+
).addOption(
|
|
72730
|
+
new Option7(
|
|
72731
|
+
"--assume-role <arn-or-pair>",
|
|
72732
|
+
"Assume the Lambda's execution role and forward STS-issued temp creds. Bare <arn> = global default; <LogicalId>=<arn> = per-Lambda override (repeatable). Per-Lambda > global > unset (developer creds passed through)."
|
|
72733
|
+
).argParser((raw, prev) => parseAssumeRoleToken(raw, prev))
|
|
72734
|
+
).action(withErrorHandling(localStartApiCommand));
|
|
72735
|
+
[...commonOptions, ...appOptions, ...contextOptions].forEach((opt) => startApi.addOption(opt));
|
|
72736
|
+
startApi.addOption(deprecatedRegionOption);
|
|
72737
|
+
return startApi;
|
|
72738
|
+
}
|
|
72739
|
+
|
|
72740
|
+
// src/cli/commands/local-invoke.ts
|
|
71028
72741
|
async function localInvokeCommand(target, options) {
|
|
71029
72742
|
const logger = getLogger();
|
|
71030
72743
|
if (options.verbose) {
|
|
@@ -71053,7 +72766,7 @@ async function localInvokeCommand(target, options) {
|
|
|
71053
72766
|
logger.info(`Target: ${lambda.stack.stackName}/${lambda.logicalId} (${targetLabel})`);
|
|
71054
72767
|
const imagePlan = await resolveImagePlan(lambda, options);
|
|
71055
72768
|
let stateAudit;
|
|
71056
|
-
let templateEnv =
|
|
72769
|
+
let templateEnv = getTemplateEnv2(lambda.resource);
|
|
71057
72770
|
let stateForRoleHint;
|
|
71058
72771
|
if (options.fromState) {
|
|
71059
72772
|
const loaded = await loadStateForStack(lambda.stack.stackName, lambda.stack.region, {
|
|
@@ -71078,7 +72791,7 @@ async function localInvokeCommand(target, options) {
|
|
|
71078
72791
|
}
|
|
71079
72792
|
}
|
|
71080
72793
|
}
|
|
71081
|
-
const overrides =
|
|
72794
|
+
const overrides = readEnvOverridesFile2(options.envVars);
|
|
71082
72795
|
const envResult = resolveEnvVars(lambda.logicalId, templateEnv, overrides);
|
|
71083
72796
|
for (const key of envResult.unresolved) {
|
|
71084
72797
|
if (stateAudit && stateAudit.unresolved.some((u) => u.key === key))
|
|
@@ -71102,14 +72815,14 @@ async function localInvokeCommand(target, options) {
|
|
|
71102
72815
|
};
|
|
71103
72816
|
if (options.assumeRole) {
|
|
71104
72817
|
const stsRegion = options.region ?? process.env["AWS_REGION"] ?? process.env["AWS_DEFAULT_REGION"];
|
|
71105
|
-
const creds = await
|
|
72818
|
+
const creds = await assumeLambdaExecutionRole2(options.assumeRole, stsRegion);
|
|
71106
72819
|
dockerEnv["AWS_ACCESS_KEY_ID"] = creds.accessKeyId;
|
|
71107
72820
|
dockerEnv["AWS_SECRET_ACCESS_KEY"] = creds.secretAccessKey;
|
|
71108
72821
|
dockerEnv["AWS_SESSION_TOKEN"] = creds.sessionToken;
|
|
71109
72822
|
if (stsRegion)
|
|
71110
72823
|
dockerEnv["AWS_REGION"] = stsRegion;
|
|
71111
72824
|
} else {
|
|
71112
|
-
|
|
72825
|
+
forwardAwsEnv2(dockerEnv);
|
|
71113
72826
|
}
|
|
71114
72827
|
let debugPort;
|
|
71115
72828
|
if (options.debugPort) {
|
|
@@ -71160,7 +72873,7 @@ async function localInvokeCommand(target, options) {
|
|
|
71160
72873
|
await removeContainer(containerId);
|
|
71161
72874
|
if (imagePlan.inlineTmpDir) {
|
|
71162
72875
|
try {
|
|
71163
|
-
|
|
72876
|
+
rmSync3(imagePlan.inlineTmpDir, { recursive: true, force: true });
|
|
71164
72877
|
} catch (err) {
|
|
71165
72878
|
getLogger().debug(
|
|
71166
72879
|
`Failed to remove inline-code tmpdir ${imagePlan.inlineTmpDir}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -71179,7 +72892,7 @@ async function resolveZipImagePlan(lambda, options) {
|
|
|
71179
72892
|
let inlineTmpDir;
|
|
71180
72893
|
let codeDir = lambda.codePath;
|
|
71181
72894
|
if (codeDir === null) {
|
|
71182
|
-
inlineTmpDir =
|
|
72895
|
+
inlineTmpDir = materializeInlineCode2(
|
|
71183
72896
|
lambda.handler,
|
|
71184
72897
|
lambda.inlineCode ?? "",
|
|
71185
72898
|
resolveRuntimeFileExtension(lambda.runtime)
|
|
@@ -71202,7 +72915,11 @@ async function resolveContainerImagePlan(lambda, options) {
|
|
|
71202
72915
|
let imageRef;
|
|
71203
72916
|
if (localBuild) {
|
|
71204
72917
|
imageRef = await buildContainerImage(localBuild.asset, localBuild.cdkOutDir, {
|
|
71205
|
-
architecture: lambda.architecture
|
|
72918
|
+
architecture: lambda.architecture,
|
|
72919
|
+
// `options.build === false` triggers the no-build path: skip
|
|
72920
|
+
// `docker build` and verify the deterministic tag is already
|
|
72921
|
+
// cached. Default `true` (build as usual). Closes #233.
|
|
72922
|
+
noBuild: options.build === false
|
|
71206
72923
|
});
|
|
71207
72924
|
} else {
|
|
71208
72925
|
if (!parseEcrUri(lambda.imageUri)) {
|
|
@@ -71235,7 +72952,7 @@ async function resolveLocalBuildPlan(lambda) {
|
|
|
71235
72952
|
const manifestPath = lambda.stack.assetManifestPath;
|
|
71236
72953
|
if (!manifestPath)
|
|
71237
72954
|
return void 0;
|
|
71238
|
-
const cdkOutDir =
|
|
72955
|
+
const cdkOutDir = dirname3(manifestPath);
|
|
71239
72956
|
const loader = new AssetManifestLoader();
|
|
71240
72957
|
const manifest = await loader.loadManifest(cdkOutDir, lambda.stack.stackName);
|
|
71241
72958
|
if (!manifest)
|
|
@@ -71245,7 +72962,7 @@ async function resolveLocalBuildPlan(lambda) {
|
|
|
71245
72962
|
return void 0;
|
|
71246
72963
|
return { asset: entry.asset, cdkOutDir };
|
|
71247
72964
|
}
|
|
71248
|
-
function
|
|
72965
|
+
function getTemplateEnv2(resource) {
|
|
71249
72966
|
const props = resource.Properties ?? {};
|
|
71250
72967
|
const env = props["Environment"];
|
|
71251
72968
|
if (!env || typeof env !== "object")
|
|
@@ -71255,12 +72972,12 @@ function getTemplateEnv(resource) {
|
|
|
71255
72972
|
return void 0;
|
|
71256
72973
|
return vars;
|
|
71257
72974
|
}
|
|
71258
|
-
function
|
|
72975
|
+
function readEnvOverridesFile2(filePath) {
|
|
71259
72976
|
if (!filePath)
|
|
71260
72977
|
return void 0;
|
|
71261
72978
|
let raw;
|
|
71262
72979
|
try {
|
|
71263
|
-
raw =
|
|
72980
|
+
raw = readFileSync7(filePath, "utf-8");
|
|
71264
72981
|
} catch (err) {
|
|
71265
72982
|
throw new Error(
|
|
71266
72983
|
`Failed to read --env-vars file '${filePath}': ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -71288,7 +73005,7 @@ async function readEvent(options) {
|
|
|
71288
73005
|
return parseEvent(raw, "<stdin>");
|
|
71289
73006
|
}
|
|
71290
73007
|
if (options.event) {
|
|
71291
|
-
const raw =
|
|
73008
|
+
const raw = readFileSync7(options.event, "utf-8");
|
|
71292
73009
|
return parseEvent(raw, options.event);
|
|
71293
73010
|
}
|
|
71294
73011
|
return {};
|
|
@@ -71309,7 +73026,7 @@ async function readStdin() {
|
|
|
71309
73026
|
}
|
|
71310
73027
|
return Buffer.concat(chunks).toString("utf-8");
|
|
71311
73028
|
}
|
|
71312
|
-
async function
|
|
73029
|
+
async function assumeLambdaExecutionRole2(roleArn, region) {
|
|
71313
73030
|
const { STSClient: STSClient11, AssumeRoleCommand: AssumeRoleCommand2 } = await import("@aws-sdk/client-sts");
|
|
71314
73031
|
const sts = new STSClient11({ ...region && { region } });
|
|
71315
73032
|
try {
|
|
@@ -71333,7 +73050,7 @@ async function assumeLambdaExecutionRole(roleArn, region) {
|
|
|
71333
73050
|
sts.destroy();
|
|
71334
73051
|
}
|
|
71335
73052
|
}
|
|
71336
|
-
function
|
|
73053
|
+
function forwardAwsEnv2(env) {
|
|
71337
73054
|
const passThrough = [
|
|
71338
73055
|
"AWS_ACCESS_KEY_ID",
|
|
71339
73056
|
"AWS_SECRET_ACCESS_KEY",
|
|
@@ -71347,16 +73064,16 @@ function forwardAwsEnv(env) {
|
|
|
71347
73064
|
env[key] = value;
|
|
71348
73065
|
}
|
|
71349
73066
|
}
|
|
71350
|
-
function
|
|
73067
|
+
function materializeInlineCode2(handler, source, fileExtension) {
|
|
71351
73068
|
const lastDot = handler.lastIndexOf(".");
|
|
71352
73069
|
if (lastDot <= 0) {
|
|
71353
73070
|
throw new Error(`Handler '${handler}' is malformed: expected '<modulePath>.<exportName>'.`);
|
|
71354
73071
|
}
|
|
71355
73072
|
const modulePath = handler.substring(0, lastDot);
|
|
71356
|
-
const dir =
|
|
71357
|
-
const filePath =
|
|
71358
|
-
|
|
71359
|
-
|
|
73073
|
+
const dir = mkdtempSync3(path2.join(tmpdir3(), "cdkd-local-invoke-"));
|
|
73074
|
+
const filePath = path2.join(dir, `${modulePath}${fileExtension}`);
|
|
73075
|
+
mkdirSync3(path2.dirname(filePath), { recursive: true });
|
|
73076
|
+
writeFileSync6(filePath, source, "utf-8");
|
|
71360
73077
|
return dir;
|
|
71361
73078
|
}
|
|
71362
73079
|
async function loadStateForStack(stackName, synthRegion, opts) {
|
|
@@ -71463,35 +73180,40 @@ function pickReferencedLogicalId(intrinsic) {
|
|
|
71463
73180
|
return void 0;
|
|
71464
73181
|
}
|
|
71465
73182
|
function createLocalCommand() {
|
|
71466
|
-
const local = new
|
|
73183
|
+
const local = new Command15("local").description(
|
|
71467
73184
|
"Local Lambda execution against the AWS Lambda Runtime Interface Emulator (Docker required)"
|
|
71468
73185
|
);
|
|
71469
|
-
const invoke = new
|
|
73186
|
+
const invoke = new Command15("invoke").description(
|
|
71470
73187
|
"Run a Lambda function locally in a Docker container (RIE-backed). Target accepts a CDK display path (MyStack/MyApi/Handler) or stack-qualified logical ID (MyStack:MyApiHandler1234ABCD). Single-stack apps may omit the stack prefix."
|
|
71471
|
-
).argument("<target>", "CDK display path or stack-qualified logical ID of the Lambda to invoke").addOption(new
|
|
71472
|
-
new
|
|
73188
|
+
).argument("<target>", "CDK display path or stack-qualified logical ID of the Lambda to invoke").addOption(new Option8("-e, --event <file>", "JSON event payload file (default: {})")).addOption(new Option8("--event-stdin", "Read event JSON from stdin").default(false)).addOption(
|
|
73189
|
+
new Option8(
|
|
71473
73190
|
"--env-vars <file>",
|
|
71474
73191
|
'JSON env-var overrides (SAM-compatible: {"LogicalId":{"KEY":"VALUE"}})'
|
|
71475
73192
|
)
|
|
71476
73193
|
).addOption(
|
|
71477
|
-
new
|
|
73194
|
+
new Option8(
|
|
71478
73195
|
"--no-pull",
|
|
71479
73196
|
"Skip docker pull (use cached image) \u2014 no-op for IMAGE local-build path; `docker build` does not pull base layers by default"
|
|
71480
73197
|
)
|
|
71481
|
-
).addOption(new Option7("--debug-port <port>", "Node --inspect-brk port (default: off)")).addOption(
|
|
71482
|
-
new Option7("--container-host <host>", "Host to bind the RIE port to").default("127.0.0.1")
|
|
71483
73198
|
).addOption(
|
|
71484
|
-
new
|
|
73199
|
+
new Option8(
|
|
73200
|
+
"--no-build",
|
|
73201
|
+
"Skip docker build on the IMAGE local-build path (use the previously-built tag). Requires the deterministic tag to already be in the local registry; errors with an actionable message when missing. No-op for ZIP Lambdas and the IMAGE ECR-pull path. Compatible with --no-pull."
|
|
73202
|
+
)
|
|
73203
|
+
).addOption(new Option8("--debug-port <port>", "Node --inspect-brk port (default: off)")).addOption(
|
|
73204
|
+
new Option8("--container-host <host>", "Host to bind the RIE port to").default("127.0.0.1")
|
|
73205
|
+
).addOption(
|
|
73206
|
+
new Option8(
|
|
71485
73207
|
"--assume-role <arn>",
|
|
71486
73208
|
`Assume the Lambda's deployed execution role and forward STS-issued temp credentials to the container so the handler runs with the deployed function's narrow permissions (closes the "developer admin / function narrow" skew). Off by default \u2014 when omitted, the developer's shell credentials are forwarded unchanged (SAM-compatible default).`
|
|
71487
73209
|
)
|
|
71488
73210
|
).addOption(
|
|
71489
|
-
new
|
|
73211
|
+
new Option8(
|
|
71490
73212
|
"--from-state",
|
|
71491
73213
|
"Read cdkd S3 state for the target stack and substitute Ref / Fn::GetAtt / Fn::Sub in env vars with the deployed physical IDs / attributes. Off by default \u2014 keep PR 1 warn-and-drop semantics; turn on for stacks already deployed via cdkd deploy."
|
|
71492
73214
|
).default(false)
|
|
71493
73215
|
).addOption(
|
|
71494
|
-
new
|
|
73216
|
+
new Option8(
|
|
71495
73217
|
"--stack-region <region>",
|
|
71496
73218
|
"Region of the cdkd state record to read (used with --from-state when the same stack name has state in multiple regions)."
|
|
71497
73219
|
)
|
|
@@ -71501,6 +73223,7 @@ function createLocalCommand() {
|
|
|
71501
73223
|
);
|
|
71502
73224
|
invoke.addOption(deprecatedRegionOption);
|
|
71503
73225
|
local.addCommand(invoke);
|
|
73226
|
+
local.addCommand(createLocalStartApiCommand());
|
|
71504
73227
|
return local;
|
|
71505
73228
|
}
|
|
71506
73229
|
|
|
@@ -71532,8 +73255,8 @@ function reorderArgs(argv) {
|
|
|
71532
73255
|
return [...prefix, ...cmdAndAfter, ...beforeCmd];
|
|
71533
73256
|
}
|
|
71534
73257
|
async function main() {
|
|
71535
|
-
const program = new
|
|
71536
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
73258
|
+
const program = new Command16();
|
|
73259
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.72.0");
|
|
71537
73260
|
program.addCommand(createBootstrapCommand());
|
|
71538
73261
|
program.addCommand(createSynthCommand());
|
|
71539
73262
|
program.addCommand(createListCommand());
|