cdk-local 0.2.0 → 0.3.1
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 +24 -0
- package/dist/cli.js +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{local-start-service-BydO4FOA.js → local-start-service-EZy1JNYK.js} +56 -5
- package/dist/{local-start-service-BydO4FOA.js.map → local-start-service-EZy1JNYK.js.map} +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Local runner for your CDK app's Lambda functions, API Gateway, and ECS tasks/services. Run it with no AWS account, or bind it to your deployed stack to hit real AWS resources and data. A native, CDK-first alternative to `sam local`.
|
|
4
4
|
|
|
5
|
+

|
|
6
|
+
|
|
5
7
|
## Why cdk-local
|
|
6
8
|
|
|
7
9
|
Two pains, one tool:
|
|
@@ -62,6 +64,8 @@ Invoke a single Lambda function with an event payload.
|
|
|
62
64
|
cdkl invoke MyStack/MyFunction --event ./event.json
|
|
63
65
|
```
|
|
64
66
|
|
|
67
|
+

|
|
68
|
+
|
|
65
69
|
#### API Gateway — `start-api`
|
|
66
70
|
|
|
67
71
|
Serve your API Gateway routes (REST v1 / HTTP v2 / Function URL / WebSocket) on a local HTTP server.
|
|
@@ -91,6 +95,11 @@ A local API talking to real AWS — point a frontend at it for end-to-end debugg
|
|
|
91
95
|
|
|
92
96
|
```bash
|
|
93
97
|
cdkl start-api MyStack/MyApi --from-cfn-stack MyStack
|
|
98
|
+
|
|
99
|
+
# Typical shape — the bare flag auto-resolves to the routed stack's
|
|
100
|
+
# name (here `MyStack`). Pass an explicit value only when the deployed
|
|
101
|
+
# CFn stack name differs from the CDK stack name.
|
|
102
|
+
cdkl start-api MyStack/MyApi --from-cfn-stack
|
|
94
103
|
```
|
|
95
104
|
|
|
96
105
|
#### Lambda — `invoke`
|
|
@@ -112,6 +121,21 @@ cdkl start-service MyStack/MyService --from-cfn-stack MyStack
|
|
|
112
121
|
|
|
113
122
|
Use this for production debugging, integration verification with real AWS resources, and validating real IAM permissions before deploy.
|
|
114
123
|
|
|
124
|
+
## `--watch` (hot reload)
|
|
125
|
+
|
|
126
|
+
Pass `--watch` to `cdkl start-api` and the server hot-reloads when your CDK app's synth output (or any routed Lambda's asset directory) changes:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
cdkl start-api MyStack/MyApi --watch
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
- 500 ms debounced [chokidar](https://github.com/paulmillr/chokidar) file watcher on `cdk.out/` + every routed Lambda's asset dir.
|
|
133
|
+
- Re-synths and re-discovers routes on each firing — adding a new route to your CDK app shows up locally on save.
|
|
134
|
+
- Synth failures keep the previous version serving (warn-and-continue, never crashes the server).
|
|
135
|
+
- Compatible with `--from-cfn-stack`: each reload re-reads the deployed CloudFormation stack so a deploy event picks up new ARNs without restarting the server.
|
|
136
|
+
|
|
137
|
+
See [docs/local-emulation.md](docs/local-emulation.md#hot-reload---watch) for the full lifecycle, file-list update semantics, and known limitations.
|
|
138
|
+
|
|
115
139
|
## Override env vars without a state source
|
|
116
140
|
|
|
117
141
|
When env-var values in your CDK template are CloudFormation intrinsics (`Ref`, `Fn::GetAtt`, `Fn::ImportValue`), cdk-local cannot resolve them without a state source — it drops them with a warning that names the affected key. To inject literal values instead, use `--env-vars <file>` (SAM-compatible JSON shape):
|
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { i as createLocalInvokeCommand, n as createLocalRunTaskCommand, r as createLocalStartApiCommand, t as createLocalStartServiceCommand } from "./local-start-service-
|
|
2
|
+
import { i as createLocalInvokeCommand, n as createLocalRunTaskCommand, r as createLocalStartApiCommand, t as createLocalStartServiceCommand } from "./local-start-service-EZy1JNYK.js";
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
|
|
5
5
|
//#region src/cli/index.ts
|
|
6
6
|
const program = new Command();
|
|
7
|
-
program.name("cdkl").description("Run AWS CDK stacks locally with Docker.").version("0.
|
|
7
|
+
program.name("cdkl").description("Run AWS CDK stacks locally with Docker.").version("0.3.1");
|
|
8
8
|
program.addCommand(createLocalInvokeCommand());
|
|
9
9
|
program.addCommand(createLocalStartApiCommand());
|
|
10
10
|
program.addCommand(createLocalRunTaskCommand());
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types/state.ts","../src/local/state-resolver.ts","../src/local/local-state-provider.ts","../src/cli/commands/local-state-source.ts","../src/cli/commands/local-invoke.ts","../src/cli/commands/local-start-api.ts","../src/cli/commands/local-run-task.ts","../src/cli/commands/local-start-service.ts","../src/local/cfn-local-state-provider.ts"],"mappings":";;;;UAuLiB,aAAA;EAEf,UAAA;EAGA,YAAA;EAGA,UAAA,EAAY,MAAA;EAcZ,kBAAA,GAAqB,MAAA;EAGrB,UAAA,GAAa,MAAA;EAGb,YAAA;EAGA,QAAA,GAAW,MAAA;EAmBX,cAAA;EAMA,mBAAA;EAyBA,aAAA;AAAA;;;UCxIe,gBAAA;EACf,SAAA;EACA,MAAA;EACA,SAAA;EACA,SAAA;AAAA;AAAA,UAqBe,kBAAA;EAOf,aAAA,CAAc,UAAA,WAAqB,OAAA;EAQnC,qBAAA,CACE,aAAA,UACA,cAAA,UACA,UAAA,WACC,OAAA;AAAA;AAAA,UAGY,mBAAA;EAEf,SAAA,EAAW,MAAA,SAAe,aAAA;EAE1B,gBAAA,GAAmB,gBAAA;EAOnB,kBAAA,GAAqB,kBAAA;EAOrB,cAAA;AAAA;;;UCrJe,gBAAA;EAQf,SAAA,EAAW,MAAA,SAAe,aAAA;EAO1B,OAAA,EAAS,MAAA;EAOT,MAAA;AAAA;AAAA,UAsBe,kBAAA;EAAA,SAMN,KAAA;EAQT,IAAA,CAAK,SAAA,UAAmB,WAAA,uBAAkC,OAAA,CAAQ,gBAAA;EAalE,uBAAA,CAAwB,cAAA,WAAyB,OAAA,CAAQ,kBAAA;EAKzD,OAAA;AAAA;;;UC/Ee,uBAAA;EAOf,YAAA;EAEA,MAAA;EAEA,OAAA;EAMA,WAAA;EAAA,CAEC,GAAA;AAAA;AAAA,KAQS,yBAAA,IAA6B,OAAA,EAAS,uBAAA,KAA4B,kBAAA;AAAA,KAUlE,mBAAA,GAAsB,MAAA,SAAe,yBAAA;AAAA,iBAUjC,mBAAA,CAAoB,YAAA,oBAAgC,SAAA;AAAA,iBAapD,gBAAA,CAAiB,IAAA,EAAM,IAAA,CAAK,uBAAA;AAAA,iBAgB5B,gBAAA,CACd,OAAA,EAAS,IAAA,CAAK,uBAAA,6BACd,WAAA;AAAA,cAqBW,qBAAA,SAA8B,KAAA;cAC7B,OAAA;AAAA;AAAA,iBAkBE,wCAAA,CACd,OAAA,EAAS,IAAA,CAAK,uBAAA,mBACd,gBAAA;AAAA,iBAiCc,wBAAA,CACd,OAAA,EAAS,uBAAA,EACT,SAAA,UACA,WAAA,sBACA,mBAAA,GAAsB,mBAAA,GACrB,kBAAA;;;UCtEc,+BAAA;EACf,mBAAA,GAAsB,mBAAA;AAAA;AAAA,iBAu2BR,wBAAA,CAAyB,IAAA,GAAM,+BAAA,GAAuC,OAAA;;;UC5vBrE,iCAAA;EACf,mBAAA,GAAsB,mBAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types/state.ts","../src/local/state-resolver.ts","../src/local/local-state-provider.ts","../src/cli/commands/local-state-source.ts","../src/cli/commands/local-invoke.ts","../src/cli/commands/local-start-api.ts","../src/cli/commands/local-run-task.ts","../src/cli/commands/local-start-service.ts","../src/local/cfn-local-state-provider.ts"],"mappings":";;;;UAuLiB,aAAA;EAEf,UAAA;EAGA,YAAA;EAGA,UAAA,EAAY,MAAA;EAcZ,kBAAA,GAAqB,MAAA;EAGrB,UAAA,GAAa,MAAA;EAGb,YAAA;EAGA,QAAA,GAAW,MAAA;EAmBX,cAAA;EAMA,mBAAA;EAyBA,aAAA;AAAA;;;UCxIe,gBAAA;EACf,SAAA;EACA,MAAA;EACA,SAAA;EACA,SAAA;AAAA;AAAA,UAqBe,kBAAA;EAOf,aAAA,CAAc,UAAA,WAAqB,OAAA;EAQnC,qBAAA,CACE,aAAA,UACA,cAAA,UACA,UAAA,WACC,OAAA;AAAA;AAAA,UAGY,mBAAA;EAEf,SAAA,EAAW,MAAA,SAAe,aAAA;EAE1B,gBAAA,GAAmB,gBAAA;EAOnB,kBAAA,GAAqB,kBAAA;EAOrB,cAAA;AAAA;;;UCrJe,gBAAA;EAQf,SAAA,EAAW,MAAA,SAAe,aAAA;EAO1B,OAAA,EAAS,MAAA;EAOT,MAAA;AAAA;AAAA,UAsBe,kBAAA;EAAA,SAMN,KAAA;EAQT,IAAA,CAAK,SAAA,UAAmB,WAAA,uBAAkC,OAAA,CAAQ,gBAAA;EAalE,uBAAA,CAAwB,cAAA,WAAyB,OAAA,CAAQ,kBAAA;EAKzD,OAAA;AAAA;;;UC/Ee,uBAAA;EAOf,YAAA;EAEA,MAAA;EAEA,OAAA;EAMA,WAAA;EAAA,CAEC,GAAA;AAAA;AAAA,KAQS,yBAAA,IAA6B,OAAA,EAAS,uBAAA,KAA4B,kBAAA;AAAA,KAUlE,mBAAA,GAAsB,MAAA,SAAe,yBAAA;AAAA,iBAUjC,mBAAA,CAAoB,YAAA,oBAAgC,SAAA;AAAA,iBAapD,gBAAA,CAAiB,IAAA,EAAM,IAAA,CAAK,uBAAA;AAAA,iBAgB5B,gBAAA,CACd,OAAA,EAAS,IAAA,CAAK,uBAAA,6BACd,WAAA;AAAA,cAqBW,qBAAA,SAA8B,KAAA;cAC7B,OAAA;AAAA;AAAA,iBAkBE,wCAAA,CACd,OAAA,EAAS,IAAA,CAAK,uBAAA,mBACd,gBAAA;AAAA,iBAiCc,wBAAA,CACd,OAAA,EAAS,uBAAA,EACT,SAAA,UACA,WAAA,sBACA,mBAAA,GAAsB,mBAAA,GACrB,kBAAA;;;UCtEc,+BAAA;EACf,mBAAA,GAAsB,mBAAA;AAAA;AAAA,iBAu2BR,wBAAA,CAAyB,IAAA,GAAM,+BAAA,GAAuC,OAAA;;;UC5vBrE,iCAAA;EACf,mBAAA,GAAsB,mBAAA;AAAA;AAAA,iBA0wFR,0BAAA,CAA2B,IAAA,GAAM,iCAAA,GAAyC,OAAA;;;UC35FzE,gCAAA;EACf,mBAAA,GAAsB,mBAAA;AAAA;AAAA,iBAkeR,yBAAA,CAA0B,IAAA,GAAM,gCAAA,GAAwC,OAAA;;;UCtevE,qCAAA;EACf,mBAAA,GAAsB,mBAAA;AAAA;AAAA,iBA+oBR,8BAAA,CACd,IAAA,GAAM,qCAAA,GACL,OAAA;;;UC5qBc,4BAAA;EAOf,YAAA;EAKA,MAAA;EAiBA,OAAA;AAAA;AAAA,cAGW,qBAAA,YAAiC,kBAAA;EAAA,SAG5B,KAAA;EAAA,iBACC,YAAA;EAAA,iBACA,MAAA;EAAA,QAKT,MAAA;EAAA,iBACS,aAAA;EAAA,QAQT,QAAA;cAEI,IAAA,EAAM,4BAAA;EAAA,QAOV,SAAA;EA+BK,IAAA,CACX,UAAA,UACA,YAAA,uBACC,OAAA,CAAQ,gBAAA;EA8DE,uBAAA,CACX,eAAA,WACC,OAAA,CAAQ,kBAAA;EAiEJ,OAAA,CAAA;AAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as LocalStateSourceError, c as rejectExplicitCfnStackWithMultipleStacks, d as CfnLocalStateProvider, i as createLocalInvokeCommand, l as resolveCfnRegion, n as createLocalRunTaskCommand, o as createLocalStateProvider, r as createLocalStartApiCommand, s as isCfnFlagPresent, t as createLocalStartServiceCommand, u as resolveCfnStackName } from "./local-start-service-
|
|
1
|
+
import { a as LocalStateSourceError, c as rejectExplicitCfnStackWithMultipleStacks, d as CfnLocalStateProvider, i as createLocalInvokeCommand, l as resolveCfnRegion, n as createLocalRunTaskCommand, o as createLocalStateProvider, r as createLocalStartApiCommand, s as isCfnFlagPresent, t as createLocalStartServiceCommand, u as resolveCfnStackName } from "./local-start-service-EZy1JNYK.js";
|
|
2
2
|
|
|
3
3
|
export { CfnLocalStateProvider, LocalStateSourceError, createLocalInvokeCommand, createLocalRunTaskCommand, createLocalStartApiCommand, createLocalStartServiceCommand, createLocalStateProvider, isCfnFlagPresent, rejectExplicitCfnStackWithMultipleStacks, resolveCfnRegion, resolveCfnStackName };
|
|
@@ -13936,6 +13936,7 @@ async function localStartApiCommand(target, options, extraStateProviders) {
|
|
|
13936
13936
|
const jwksWarnedUrls = /* @__PURE__ */ new Set();
|
|
13937
13937
|
let sigV4CredentialsLoader;
|
|
13938
13938
|
const sigV4WarnedForeignIds = /* @__PURE__ */ new Set();
|
|
13939
|
+
const fromCfnTipEmitted = { value: false };
|
|
13939
13940
|
/**
|
|
13940
13941
|
* One synth + discover + build pass. Returns the next-state
|
|
13941
13942
|
* material. Reused on initial boot AND every hot-reload firing.
|
|
@@ -13960,8 +13961,13 @@ async function localStartApiCommand(target, options, extraStateProviders) {
|
|
|
13960
13961
|
};
|
|
13961
13962
|
const { stacks } = await synthesizer.synthesize(synthOpts);
|
|
13962
13963
|
const cfnStackFallback = typeof options.fromCfnStack === "string" ? options.fromCfnStack : void 0;
|
|
13963
|
-
const
|
|
13964
|
+
const targetStackPrefix = target?.includes("/") === true ? target.slice(0, target.indexOf("/")) : void 0;
|
|
13965
|
+
const targetStacks = pickTargetStacks(stacks, options.stack, cfnStackFallback, targetStackPrefix);
|
|
13964
13966
|
if (targetStacks.length === 0) throw new Error("No stacks matched. Pass --stack <name> (or --from-cfn-stack <name>) or run from a single-stack app.");
|
|
13967
|
+
const routedStackNames = targetStacks.map((s) => s.stackName);
|
|
13968
|
+
tryEmitFromCfnRedundancyTipOnce(options.fromCfnStack, routedStackNames, fromCfnTipEmitted, (routedStackName) => {
|
|
13969
|
+
logger.info(`tip: --from-cfn-stack value matches the routed stack name (${routedStackName}); you can omit the value: \`cdkl start-api ... --from-cfn-stack\` (bare flag) resolves to the same value.`);
|
|
13970
|
+
});
|
|
13965
13971
|
const routes = discoverRoutes(targetStacks);
|
|
13966
13972
|
const wsDiscovery = discoverWebSocketApis(targetStacks);
|
|
13967
13973
|
if (wsDiscovery.errors.length > 0) for (const e of wsDiscovery.errors) logger.warn(`WebSocket discovery: ${e}`);
|
|
@@ -14338,12 +14344,57 @@ async function localStartApiCommand(target, options, extraStateProviders) {
|
|
|
14338
14344
|
* routing rules.
|
|
14339
14345
|
*/
|
|
14340
14346
|
/** @internal exported for unit tests. */
|
|
14341
|
-
function pickTargetStacks(stacks, pattern, cfnStackFallback) {
|
|
14342
|
-
const effective = pattern ?? cfnStackFallback;
|
|
14347
|
+
function pickTargetStacks(stacks, pattern, cfnStackFallback, targetFallback) {
|
|
14348
|
+
const effective = pattern ?? cfnStackFallback ?? targetFallback;
|
|
14343
14349
|
if (effective) return matchStacks(stacks, [effective]);
|
|
14344
14350
|
if (stacks.length === 1) return stacks;
|
|
14345
14351
|
if (stacks.length === 0) return [];
|
|
14346
|
-
throw new Error(`Multi-stack app: pass --stack <name
|
|
14352
|
+
throw new Error(`Multi-stack app: pass --stack <name>, --from-cfn-stack <name>, or a stack-qualified target like "<StackName>/<construct>" to pick a target. Available stacks: ${stacks.map((s) => s.stackName).join(", ")}.`);
|
|
14353
|
+
}
|
|
14354
|
+
/**
|
|
14355
|
+
* Decide whether the `--from-cfn-stack <name>` redundancy tip should
|
|
14356
|
+
* fire for the current invocation. Fires only when:
|
|
14357
|
+
* - `fromCfnStack` is a non-empty STRING (explicit value, not bare `true`)
|
|
14358
|
+
* - exactly ONE stack is routed
|
|
14359
|
+
* - the explicit value equals the routed stack's `stackName`
|
|
14360
|
+
*
|
|
14361
|
+
* Extracted as a pure function so it can be unit-tested without booting
|
|
14362
|
+
* the full server. See improvement A in the start-api UX PR.
|
|
14363
|
+
*
|
|
14364
|
+
* @internal exported for unit tests.
|
|
14365
|
+
*/
|
|
14366
|
+
function shouldEmitFromCfnRedundancyTip(fromCfnStack, routedStackNames) {
|
|
14367
|
+
if (typeof fromCfnStack !== "string") return false;
|
|
14368
|
+
if (fromCfnStack.length === 0) return false;
|
|
14369
|
+
if (routedStackNames.length !== 1) return false;
|
|
14370
|
+
return fromCfnStack === routedStackNames[0];
|
|
14371
|
+
}
|
|
14372
|
+
/**
|
|
14373
|
+
* One-shot wrapper around `shouldEmitFromCfnRedundancyTip` for the
|
|
14374
|
+
* `--watch` hot-reload path. `synthesizeAndBuild` re-runs on every
|
|
14375
|
+
* reload firing, so without a gate the tip would re-emit on every
|
|
14376
|
+
* reload — noisy. This helper consults the caller-supplied ref:
|
|
14377
|
+
* - If the predicate fires AND the ref is still `false`, calls `emit`
|
|
14378
|
+
* and flips the ref to `true`.
|
|
14379
|
+
* - On subsequent invocations the ref is `true` and the helper is a
|
|
14380
|
+
* no-op for the rest of the ref's lifetime.
|
|
14381
|
+
* - When the predicate does NOT fire (no `--from-cfn-stack` value /
|
|
14382
|
+
* intentionally-different value / multi-stack run), the ref stays
|
|
14383
|
+
* `false` so a future reload whose synthesized stacks change in a
|
|
14384
|
+
* way that DOES make the value redundant still emits the tip once.
|
|
14385
|
+
*
|
|
14386
|
+
* The ref is owned by `localStartApiCommand` (one per server boot), so
|
|
14387
|
+
* independent server invocations get independent flags.
|
|
14388
|
+
*
|
|
14389
|
+
* @internal exported for unit tests.
|
|
14390
|
+
*/
|
|
14391
|
+
function tryEmitFromCfnRedundancyTipOnce(fromCfnStack, routedStackNames, emittedRef, emit) {
|
|
14392
|
+
if (emittedRef.value) return;
|
|
14393
|
+
if (!shouldEmitFromCfnRedundancyTip(fromCfnStack, routedStackNames)) return;
|
|
14394
|
+
const routedStackName = routedStackNames[0];
|
|
14395
|
+
if (routedStackName === void 0) return;
|
|
14396
|
+
emit(routedStackName);
|
|
14397
|
+
emittedRef.value = true;
|
|
14347
14398
|
}
|
|
14348
14399
|
/**
|
|
14349
14400
|
* Distinct, stable list of Lambda logical IDs reachable through any
|
|
@@ -17837,4 +17888,4 @@ function createLocalStartServiceCommand(opts = {}) {
|
|
|
17837
17888
|
|
|
17838
17889
|
//#endregion
|
|
17839
17890
|
export { LocalStateSourceError as a, rejectExplicitCfnStackWithMultipleStacks as c, CfnLocalStateProvider as d, createLocalInvokeCommand as i, resolveCfnRegion as l, createLocalRunTaskCommand as n, createLocalStateProvider as o, createLocalStartApiCommand as r, isCfnFlagPresent as s, createLocalStartServiceCommand as t, resolveCfnStackName as u };
|
|
17840
|
-
//# sourceMappingURL=local-start-service-
|
|
17891
|
+
//# sourceMappingURL=local-start-service-EZy1JNYK.js.map
|