@go-to-k/cdkd 0.67.0 → 0.68.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 CHANGED
@@ -581,8 +581,9 @@ Lambda Runtime Interface Emulator (RIE). Modeled on `sam local invoke`
581
581
  but reusing cdkd's synthesis / asset / construct-path plumbing — no
582
582
  `template.yaml` to maintain, no `cdk synth | sam ...` round-trip.
583
583
 
584
- Requires Docker. v1 supports Node.js runtimes only (`nodejs18.x` /
585
- `nodejs20.x` / `nodejs22.x`); other runtimes follow in subsequent PRs.
584
+ Requires Docker. v1 supports Node.js and Python runtimes (`nodejs18.x` /
585
+ `nodejs20.x` / `nodejs22.x` / `python3.11` / `python3.12` / `python3.13`);
586
+ other runtimes follow in subsequent PRs.
586
587
 
587
588
  ```bash
588
589
  # Invoke by CDK display path (single-stack apps may omit the prefix)
package/dist/cli.js CHANGED
@@ -70178,10 +70178,13 @@ function isLiteralEnvValue(value) {
70178
70178
  }
70179
70179
 
70180
70180
  // src/local-invoke/runtime-image.ts
70181
- var NODEJS_RUNTIMES = {
70182
- "nodejs18.x": "public.ecr.aws/lambda/nodejs:18",
70183
- "nodejs20.x": "public.ecr.aws/lambda/nodejs:20",
70184
- "nodejs22.x": "public.ecr.aws/lambda/nodejs:22"
70181
+ var SUPPORTED_RUNTIMES = {
70182
+ "nodejs18.x": { image: "public.ecr.aws/lambda/nodejs:18", fileExtension: ".js" },
70183
+ "nodejs20.x": { image: "public.ecr.aws/lambda/nodejs:20", fileExtension: ".js" },
70184
+ "nodejs22.x": { image: "public.ecr.aws/lambda/nodejs:22", fileExtension: ".js" },
70185
+ "python3.11": { image: "public.ecr.aws/lambda/python:3.11", fileExtension: ".py" },
70186
+ "python3.12": { image: "public.ecr.aws/lambda/python:3.12", fileExtension: ".py" },
70187
+ "python3.13": { image: "public.ecr.aws/lambda/python:3.13", fileExtension: ".py" }
70185
70188
  };
70186
70189
  var UnsupportedRuntimeError = class _UnsupportedRuntimeError extends Error {
70187
70190
  constructor(runtime, message) {
@@ -70192,24 +70195,30 @@ var UnsupportedRuntimeError = class _UnsupportedRuntimeError extends Error {
70192
70195
  }
70193
70196
  };
70194
70197
  function resolveRuntimeImage(runtime) {
70198
+ return resolveRuntimeSpec(runtime).image;
70199
+ }
70200
+ function resolveRuntimeFileExtension(runtime) {
70201
+ return resolveRuntimeSpec(runtime).fileExtension;
70202
+ }
70203
+ function resolveRuntimeSpec(runtime) {
70195
70204
  if (typeof runtime !== "string" || runtime.length === 0) {
70196
70205
  throw new UnsupportedRuntimeError(
70197
70206
  String(runtime),
70198
70207
  "Lambda function has no Runtime property. Container-image Lambdas (Code.ImageUri) are not supported in cdkd local invoke v1."
70199
70208
  );
70200
70209
  }
70201
- const image = NODEJS_RUNTIMES[runtime];
70202
- if (image)
70203
- return image;
70204
- if (runtime.startsWith("python") || runtime.startsWith("java") || runtime.startsWith("dotnet") || runtime.startsWith("ruby") || runtime.startsWith("go") || runtime.startsWith("provided")) {
70210
+ const spec = SUPPORTED_RUNTIMES[runtime];
70211
+ if (spec)
70212
+ return spec;
70213
+ if (runtime.startsWith("java") || runtime.startsWith("dotnet") || runtime.startsWith("ruby") || runtime.startsWith("go") || runtime.startsWith("provided")) {
70205
70214
  throw new UnsupportedRuntimeError(
70206
70215
  runtime,
70207
- `Runtime '${runtime}' is not supported in cdkd local invoke v1. Only Node.js runtimes (nodejs18.x / nodejs20.x / nodejs22.x) are supported. Python is planned for the next iteration; other runtimes follow.`
70216
+ `Runtime '${runtime}' is not supported in cdkd local invoke v1. Only Node.js (nodejs18.x / nodejs20.x / nodejs22.x) and Python (python3.11 / python3.12 / python3.13) runtimes are supported. Other runtimes follow in subsequent PRs.`
70208
70217
  );
70209
70218
  }
70210
70219
  throw new UnsupportedRuntimeError(
70211
70220
  runtime,
70212
- `Unknown runtime '${runtime}'. cdkd local invoke v1 supports nodejs18.x / nodejs20.x / nodejs22.x.`
70221
+ `Unknown runtime '${runtime}'. cdkd local invoke v1 supports nodejs18.x / nodejs20.x / nodejs22.x / python3.11 / python3.12 / python3.13.`
70213
70222
  );
70214
70223
  }
70215
70224
 
@@ -70343,7 +70352,7 @@ async function waitForRieReady(host, port, timeoutMs = 5e3) {
70343
70352
  let lastError;
70344
70353
  while (Date.now() < deadline) {
70345
70354
  try {
70346
- const ok = await tcpProbe(host, port, 500);
70355
+ const ok = await httpProbe(host, port, 500);
70347
70356
  if (ok)
70348
70357
  return;
70349
70358
  } catch (err) {
@@ -70356,6 +70365,42 @@ async function waitForRieReady(host, port, timeoutMs = 5e3) {
70356
70365
  `RIE did not become ready on ${host}:${port} within ${timeoutMs}ms${tail}. The container may have exited early \u2014 check 'docker logs' output.`
70357
70366
  );
70358
70367
  }
70368
+ async function httpProbe(host, port, timeoutMs) {
70369
+ const controller = new AbortController();
70370
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
70371
+ try {
70372
+ const response = await fetch(`http://${host}:${port}/`, {
70373
+ method: "POST",
70374
+ headers: { "Content-Type": "application/json" },
70375
+ body: "{}",
70376
+ signal: controller.signal
70377
+ });
70378
+ await response.text().catch(() => void 0);
70379
+ return true;
70380
+ } catch (err) {
70381
+ if (isTransientNetworkError(err))
70382
+ return false;
70383
+ throw err;
70384
+ } finally {
70385
+ clearTimeout(timer);
70386
+ }
70387
+ }
70388
+ function isTransientNetworkError(err) {
70389
+ if (!(err instanceof Error))
70390
+ return false;
70391
+ if (err.name === "AbortError")
70392
+ return true;
70393
+ if (err.name === "TypeError" && err.message === "fetch failed")
70394
+ return true;
70395
+ const cause = err.cause;
70396
+ if (cause?.code === "ECONNRESET")
70397
+ return true;
70398
+ if (cause?.code === "ECONNREFUSED")
70399
+ return true;
70400
+ if (cause?.code === "UND_ERR_SOCKET")
70401
+ return true;
70402
+ return false;
70403
+ }
70359
70404
  async function invokeRie(host, port, event, timeoutMs) {
70360
70405
  const url = `http://${host}:${port}${INVOKE_PATH}`;
70361
70406
  const body = JSON.stringify(event ?? {});
@@ -70387,34 +70432,6 @@ async function invokeRie(host, port, event, timeoutMs) {
70387
70432
  }
70388
70433
  return { payload, raw };
70389
70434
  }
70390
- async function tcpProbe(host, port, timeoutMs) {
70391
- const { Socket } = await import("node:net");
70392
- return new Promise((resolveProbe, rejectProbe) => {
70393
- const socket = new Socket();
70394
- const cleanup = () => {
70395
- socket.removeAllListeners();
70396
- socket.destroy();
70397
- };
70398
- socket.setTimeout(timeoutMs);
70399
- socket.once("connect", () => {
70400
- cleanup();
70401
- resolveProbe(true);
70402
- });
70403
- socket.once("timeout", () => {
70404
- cleanup();
70405
- resolveProbe(false);
70406
- });
70407
- socket.once("error", (err) => {
70408
- cleanup();
70409
- if (err.code === "ECONNREFUSED" || err.code === "ECONNRESET") {
70410
- resolveProbe(false);
70411
- return;
70412
- }
70413
- rejectProbe(err);
70414
- });
70415
- socket.connect(port, host);
70416
- });
70417
- }
70418
70435
 
70419
70436
  // src/cli/commands/local-invoke.ts
70420
70437
  async function localInvokeCommand(target, options) {
@@ -70442,7 +70459,11 @@ async function localInvokeCommand(target, options) {
70442
70459
  const { stacks } = await synthesizer.synthesize(synthOpts);
70443
70460
  const lambda = resolveLambdaTarget(target, stacks);
70444
70461
  logger.info(`Target: ${lambda.stack.stackName}/${lambda.logicalId} (${lambda.runtime})`);
70445
- const codeDir = lambda.codePath ?? materializeInlineCode(lambda.handler, lambda.inlineCode ?? "");
70462
+ const codeDir = lambda.codePath ?? materializeInlineCode(
70463
+ lambda.handler,
70464
+ lambda.inlineCode ?? "",
70465
+ resolveRuntimeFileExtension(lambda.runtime)
70466
+ );
70446
70467
  const overrides = readEnvOverridesFile(options.envVars);
70447
70468
  const envResult = resolveEnvVars(lambda.logicalId, getTemplateEnv(lambda.resource), overrides);
70448
70469
  for (const key of envResult.unresolved) {
@@ -70616,14 +70637,14 @@ function forwardAwsEnv(env) {
70616
70637
  env[key] = value;
70617
70638
  }
70618
70639
  }
70619
- function materializeInlineCode(handler, source) {
70640
+ function materializeInlineCode(handler, source, fileExtension) {
70620
70641
  const lastDot = handler.lastIndexOf(".");
70621
70642
  if (lastDot <= 0) {
70622
70643
  throw new Error(`Handler '${handler}' is malformed: expected '<modulePath>.<exportName>'.`);
70623
70644
  }
70624
70645
  const modulePath = handler.substring(0, lastDot);
70625
70646
  const dir = mkdtempSync2(path.join(tmpdir2(), "cdkd-local-invoke-"));
70626
- const filePath = path.join(dir, `${modulePath}.js`);
70647
+ const filePath = path.join(dir, `${modulePath}${fileExtension}`);
70627
70648
  mkdirSync2(path.dirname(filePath), { recursive: true });
70628
70649
  writeFileSync5(filePath, source, "utf-8");
70629
70650
  return dir;
@@ -70682,7 +70703,7 @@ function reorderArgs(argv) {
70682
70703
  }
70683
70704
  async function main() {
70684
70705
  const program = new Command15();
70685
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.67.0");
70706
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.68.0");
70686
70707
  program.addCommand(createBootstrapCommand());
70687
70708
  program.addCommand(createSynthCommand());
70688
70709
  program.addCommand(createListCommand());