local-serverless-stack 1.0.0 → 1.0.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 +18 -13
- package/bin/cli.js +137 -13
- package/bin/i18n.js +27 -0
- package/dist/server/engine/http/errors.js +1 -1
- package/dist/server/engine/http/errors.js.map +1 -1
- package/dist/server/routes/config.d.ts.map +1 -1
- package/dist/server/routes/config.js +6 -0
- package/dist/server/routes/config.js.map +1 -1
- package/dist/server/routes/lambdas.d.ts.map +1 -1
- package/dist/server/routes/lambdas.js +12 -0
- package/dist/server/routes/lambdas.js.map +1 -1
- package/dist/server/routes/services.d.ts.map +1 -1
- package/dist/server/routes/services.js +17 -4
- package/dist/server/routes/services.js.map +1 -1
- package/dist/server/runtime/runtime-worker.js +7 -0
- package/dist/server/runtime/runtime-worker.js.map +1 -1
- package/dist/server/services/cache-manager.d.ts +5 -0
- package/dist/server/services/cache-manager.d.ts.map +1 -1
- package/dist/server/services/cache-manager.js.map +1 -1
- package/dist/server/services/cloudformation-parser.js +3 -3
- package/dist/server/services/cloudformation-parser.js.map +1 -1
- package/dist/server/services/config-manager.d.ts +25 -0
- package/dist/server/services/config-manager.d.ts.map +1 -1
- package/dist/server/services/config-manager.js +146 -17
- package/dist/server/services/config-manager.js.map +1 -1
- package/dist/server/services/lambda-runtime-manager.d.ts +1 -0
- package/dist/server/services/lambda-runtime-manager.d.ts.map +1 -1
- package/dist/server/services/lambda-runtime-manager.js +13 -1
- package/dist/server/services/lambda-runtime-manager.js.map +1 -1
- package/dist/server/services/resource-provisioner.d.ts +19 -1
- package/dist/server/services/resource-provisioner.d.ts.map +1 -1
- package/dist/server/services/resource-provisioner.js +129 -12
- package/dist/server/services/resource-provisioner.js.map +1 -1
- package/dist/server/services/s3-explorer.js +1 -1
- package/dist/server/services/seed-manager.d.ts.map +1 -1
- package/dist/server/services/seed-manager.js +11 -6
- package/dist/server/services/seed-manager.js.map +1 -1
- package/dist/server/services/service-registrar.d.ts +13 -1
- package/dist/server/services/service-registrar.d.ts.map +1 -1
- package/dist/server/services/service-registrar.js +63 -13
- package/dist/server/services/service-registrar.js.map +1 -1
- package/dist/server/services/service-scanner.d.ts +7 -2
- package/dist/server/services/service-scanner.d.ts.map +1 -1
- package/dist/server/services/service-scanner.js +53 -7
- package/dist/server/services/service-scanner.js.map +1 -1
- package/dist/ui/assets/ApisPage-CTOcNna-.js +1 -0
- package/dist/ui/assets/BucketDetailPage-BXW8-FrE.js +1 -0
- package/dist/ui/assets/BucketsPage-DY_ITepb.js +1 -0
- package/dist/ui/assets/DynamoPage-BnFFKnIU.js +1 -0
- package/dist/ui/assets/DynamoTablePage-BLCuyJHU.js +3 -0
- package/dist/ui/assets/LambdaDetailPage-D4rZNLRT.js +4 -0
- package/dist/ui/assets/LambdasPage-Bg-MWFBb.js +1 -0
- package/dist/ui/assets/OnboardingPage-nnl313Fm.js +1 -0
- package/dist/ui/assets/OpenSearchCollectionPage-Dn15lH_F.js +1 -0
- package/dist/ui/assets/OpenSearchPage-CgD5isok.js +1 -0
- package/dist/ui/assets/{OverviewPage-C1pBJ8aP.css → OverviewPage-CSWY71vZ.css} +1 -1
- package/dist/ui/assets/OverviewPage-m5sUr8IN.js +1 -0
- package/dist/ui/assets/QueueDetailPage-Ch_FDDoN.js +1 -0
- package/dist/ui/assets/QueuesPage-C_yDuGDu.js +1 -0
- package/dist/ui/assets/SecretsPage-BSGMSoqy.js +1 -0
- package/dist/ui/assets/ServiceDetailPage-6KyohyjI.js +2 -0
- package/dist/ui/assets/{ServicesPage-2JuiIiRr.js → ServicesPage-BbSetOMo.js} +2 -2
- package/dist/ui/assets/SettingsPage-BgF1jFr6.js +1 -0
- package/dist/ui/assets/index-D627ZyYU.css +1 -0
- package/dist/ui/assets/index-DuSPnI19.js +37 -0
- package/dist/ui/index.html +2 -2
- package/package.json +1 -1
- package/dist/ui/assets/ApisPage-BOuimwWz.js +0 -1
- package/dist/ui/assets/BucketDetailPage-vLYwhoQt.js +0 -1
- package/dist/ui/assets/BucketsPage-Cu5lU1Hp.js +0 -1
- package/dist/ui/assets/DynamoPage-y3TTEPUL.js +0 -1
- package/dist/ui/assets/DynamoTablePage-BnmSRZjc.js +0 -3
- package/dist/ui/assets/LambdaDetailPage-B5q_d27t.js +0 -4
- package/dist/ui/assets/LambdasPage-CJpRoEDx.js +0 -1
- package/dist/ui/assets/OnboardingPage-D02dymQi.js +0 -1
- package/dist/ui/assets/OpenSearchCollectionPage-B_wWTlfL.js +0 -1
- package/dist/ui/assets/OpenSearchPage-BLEgfF_g.js +0 -1
- package/dist/ui/assets/OverviewPage-EdJWiAt6.js +0 -1
- package/dist/ui/assets/QueueDetailPage-ByEYHvHe.js +0 -1
- package/dist/ui/assets/QueuesPage-CvwYHSll.js +0 -1
- package/dist/ui/assets/SecretsPage-DASw8Ntf.js +0 -1
- package/dist/ui/assets/ServiceDetailPage-BMsUDg6L.js +0 -2
- package/dist/ui/assets/SettingsPage-DStO4bgN.js +0 -1
- package/dist/ui/assets/index-BIEznsi4.js +0 -37
- package/dist/ui/assets/index-BRMvNP3Y.css +0 -1
package/README.md
CHANGED
|
@@ -45,18 +45,18 @@ want it running.
|
|
|
45
45
|
<details>
|
|
46
46
|
<summary><b>Background orchestrator lifecycle</b> — <code>lss start</code> / <code>stop</code> / <code>status</code> run the whole stack as a detached process you can forget about</summary>
|
|
47
47
|
|
|
48
|
-
**How it works.** `start` checks the PID file first: if the recorded PID answers `kill(pid, 0)` it just reprints the URLs and returns; a dead PID file is deleted and boot continues. It resolves `dist/server/index.js`, opens the log file in append mode and `spawn`s `node` detached with stdio piped to that file, `unref`s the child and writes its PID. Ports come from config plus env (`serverPort` and the self engine both default to **14566**; the DynamoDB proxy is off, port **8000** when enabled), and they are passed down as `PORT`, `LSS_ENABLE_DYNAMO_PROXY`, `LSS_DYNAMO_PROXY_PORT`. Two seconds later it re-probes the PID
|
|
48
|
+
**How it works.** `start` checks the PID file first: if the recorded PID answers `kill(pid, 0)` it just reprints the URLs and returns; a dead PID file is deleted and boot continues. It resolves `dist/server/index.js`, opens the log file in append mode and `spawn`s `node` detached with stdio piped to that file, `unref`s the child and writes its PID. Ports come from config plus env (`serverPort` and the self engine both default to **14566**; the DynamoDB proxy is off, port **8000** when enabled), and they are passed down as `PORT`, `LSS_ENABLE_DYNAMO_PROXY`, `LSS_DYNAMO_PROXY_PORT`. Two seconds later it re-probes the PID: alive prints "Service is running", **dead prints the failure, the tail of the log, who holds the port — and exits 1**, because a daemonized boot discovers a busy port only after the CLI has printed a PID, and a step that fails must not report success. `lss start --wait[=<seconds>]` (default 30) goes further and blocks until `GET /api/health` answers, which is what a sequential chain needs so the next `register` isn't run against a stack that never came up. `stop` sends `SIGTERM` and then polls `kill(pid, 0)` every **200 ms for up to 10 s** before deleting the PID file — without that wait an immediate `lss start` would race the dying process for the port and die with `EADDRINUSE`. `status` prints PID, server URL, self engine URL, proxy URL (only when enabled) and log path, and self-heals a stale PID file. When there is **no** PID file for this project it asks `GET /api/config` who is on the port and reports `port 14566 is in use by the orchestrator of /other/project` instead of `NOT RUNNING` — under `--net=host` the port belongs to the whole machine, and a status that says "not running" about a port answering 200 sends you looking in the wrong place.
|
|
49
49
|
|
|
50
|
-
**Where it lives.** `bin/cli.js` — `startOrchestrator()`, `stopOrchestrator()`, `waitForExit()`, `showStatus()`, `runtimePaths()`. `src/server/index.ts` — the orchestrator entry point that gets spawned.
|
|
50
|
+
**Where it lives.** `bin/cli.js` — `startOrchestrator()`, `waitForHealthy()`, `reportStartFailure()`, `probePortOwner()`, `stopOrchestrator()`, `waitForExit()`, `showStatus()`, `runtimePaths()`. `src/server/index.ts` — the orchestrator entry point that gets spawned.
|
|
51
51
|
|
|
52
|
-
**Why it exists.** One command replaces "start LocalStack, then start one `serverless-offline` per service". Because the process is detached and PID-tracked, the stack survives closing the terminal, and `status` answers the "is it up?" question without grepping `ps`.
|
|
52
|
+
**Why it exists.** One command replaces "start LocalStack, then start one `serverless-offline` per service". Because the process is detached and PID-tracked, the stack survives closing the terminal, and `status` answers the "is it up?" question — and, when the answer is no, the "then who has my port?" question — without grepping `ps`.
|
|
53
53
|
|
|
54
54
|
</details>
|
|
55
55
|
|
|
56
56
|
<details>
|
|
57
57
|
<summary><b><code>lss register [path...]</code></b> — attach a service to the running stack without any Serverless plugin</summary>
|
|
58
58
|
|
|
59
|
-
**How it works.** It requires a running orchestrator (PID file present, otherwise it prints the start hint and exits 1), then resolves each positional argument to an absolute path — defaulting to `.` when none is given — and skips (counting as failed) any directory that does not exist. For each path it `POST`s `{ servicePath }` to `/api/services/register` on the server port; the orchestrator does everything else: packaging on demand via `autoPackage`, then reading name, region and `custom.lss` ports out of the packaged `serverless-state.json`. Each success prints resource/function/route counts plus any warnings the server returned; if any target failed, the process exits 1.
|
|
59
|
+
**How it works.** It requires a running orchestrator (PID file present, otherwise it prints the start hint and exits 1), then resolves each positional argument to an absolute path — defaulting to `.` when none is given — and skips (counting as failed) any directory that does not exist. For each path it `POST`s `{ servicePath }` to `/api/services/register` on the server port; the orchestrator does everything else: packaging on demand via `autoPackage`, then reading name, region and `custom.lss` ports out of the packaged `serverless-state.json`. Each success prints resource/function/route counts plus any warnings the server returned — including everything provisioning could **not** do (a resource that failed, a rule waiting for a bus, HTTP routes with no `apiPort`), which used to reach the daemon log only; if any target failed, the process exits 1.
|
|
60
60
|
|
|
61
61
|
**Where it lives.** `bin/cli.js` — `registerServices()`, `postJson()`, `allPositionals()`. `src/server/routes/services.ts` — `POST /register`, which validates the path and delegates to the registrar.
|
|
62
62
|
|
|
@@ -67,7 +67,7 @@ want it running.
|
|
|
67
67
|
<details>
|
|
68
68
|
<summary><b><code>lss scan</code></b> — list every Serverless/osls service under the project root with its readiness flags</summary>
|
|
69
69
|
|
|
70
|
-
**How it works.** It calls `GET /api/services/scan`, which walks the project root (skipping `node_modules`, `.git`, `.serverless`, `.lss`, `.build`, `.esbuild`) and returns one row per service. Each row prints three flags — `registered` (known to this orchestrator), `installed` (a `node_modules` is resolvable from the service dir upward to the root, so packaging can run without an install) and `packaged` (`.serverless/cloudformation-template-update-stack.json` exists) — followed by the resolved `api:`/`invoke:` ports when known. A second line shows the effective package command for that service (per-service `servicePackaging`, else the global one), and any scan warnings are listed underneath. Empty results print the root that was searched.
|
|
70
|
+
**How it works.** It calls `GET /api/services/scan`, which walks the project root (skipping `node_modules`, `.git`, `.serverless`, `.lss`, `.build`, `.esbuild`, plus any directory listed in `scanIgnore`) and returns one row per service. Each row prints three flags — `registered` (known to this orchestrator), `installed` (a `node_modules` is resolvable from the service dir upward to the root, so packaging can run without an install) and `packaged` (`.serverless/cloudformation-template-update-stack.json` exists) — followed by the resolved `api:`/`invoke:` ports when known. A second line shows the effective package command for that service (per-service `servicePackaging`, else the global one), and any scan warnings are listed underneath — the "not packaged" one worded from the **effective** `autoPackage`, so it never promises packaging a config with `autoPackage: false` will refuse. Empty results print the root that was searched.
|
|
71
71
|
|
|
72
72
|
**Where it lives.** `bin/cli.js` — `scanServices()` and the row formatting. `src/server/routes/services.ts` — `GET /scan`, which overlays runtime/packaging config on the raw scan. `src/server/services/service-scanner.ts` — the filesystem walk and the installed/packaged detection.
|
|
73
73
|
|
|
@@ -189,7 +189,7 @@ serverless | sls | osls package [args…]
|
|
|
189
189
|
npx [-y|--yes]… serverless|sls|osls[@version] package [args…]
|
|
190
190
|
```
|
|
191
191
|
|
|
192
|
-
`npx serverless package` (the default), `npm run package`, `yarn run package`, `sls package -c custom.yml` and `npx -y serverless@3.38.0 package` all pass. `/bin/sh -c …`, `node -e …`, `/usr/bin/env`, `./tool`, `npm exec -c …`, `npx -c …`, `yarn dlx …` and a bare `yarn package` (yarn 1's implicit `run`, which is what makes `yarn node -e` indistinguishable from a script name) are 400s. On top of the grammar, every token of the command **and every `packageArgs` element** is screened for flags that re-point an allowed program somewhere else — `--node-options`, `--script-shell`, `--shell`, `--call`, `--userconfig`, `--globalconfig`, `--use-yarnrc`, `--registry` (npx fetches the CLI when the service has no local copy, and npm reads its config flags from anywhere in the argv), `--prefix`, `--cwd`, `--dir` and node's own `--require`/`--eval`/`--print`/`--import`/`--loader`/`--input-type` — compared with dashes and underscores stripped, so `--nodeOptions` is the same flag. Serverless's short flags (`-c`, `-p`, `-r` = `--config`, `--package`, `--region`) are deliberately *not* screened: the grammar already makes them unreachable as npm/npx options. `packageEnv` likewise refuses keys the runtime or dynamic linker reads before `main()` — `NODE_OPTIONS`, `NODE_REPL_EXTERNAL_MODULE`, `LD_PRELOAD`, `LD_AUDIT`, `LD_LIBRARY_PATH`, `DYLD_INSERT_LIBRARIES`, `DYLD_LIBRARY_PATH`, compared case-insensitively — since `{"NODE_OPTIONS":"--require /tmp/x.js"}` turns an otherwise blameless `npx serverless package` into an arbitrary-code runner whichever runner passed. Two limits worth stating out loud: the fence is on the API and **not** the read path (a hand-edited `lss.config.json` and `LSS_PACKAGE_COMMAND` are the operator's own shell, and anyone who can write either already runs code here), and what stays expressible is the project's own build — `npm run <script>` runs whatever the service's `package.json` declares and `serverless package` reads its `serverless.yml`, plugins included. That is code the operator already trusts by pointing LSS at the directory, and forbidding it would mean the dashboard could not set a package command at all, which is what onboarding is built on. What is gone is the part that made the other allowlists worthless: through this API a caller can no longer choose the program, only ask the project's own build to run.
|
|
192
|
+
`npx serverless package` (the default), `npm run package`, `yarn run package`, `sls package -c custom.yml` and `npx -y serverless@3.38.0 package` all pass. `/bin/sh -c …`, `node -e …`, `/usr/bin/env`, `./tool`, `npm exec -c …`, `npx -c …`, `yarn dlx …` and a bare `yarn package` (yarn 1's implicit `run`, which is what makes `yarn node -e` indistinguishable from a script name) are 400s. On top of the grammar, every token of the command **and every `packageArgs` element** is screened for flags that re-point an allowed program somewhere else — `--node-options`, `--script-shell`, `--shell`, `--call`, `--userconfig`, `--globalconfig`, `--use-yarnrc`, `--registry` (npx fetches the CLI when the service has no local copy, and npm reads its config flags from anywhere in the argv), `--prefix`, `--cwd`, `--dir` and node's own `--require`/`--eval`/`--print`/`--import`/`--loader`/`--input-type` — compared with dashes and underscores stripped, so `--nodeOptions` is the same flag. Serverless's short flags (`-c`, `-p`, `-r` = `--config`, `--package`, `--region`) are deliberately *not* screened: the grammar already makes them unreachable as npm/npx options. `packageEnv` likewise refuses keys the runtime or dynamic linker reads before `main()` — `NODE_OPTIONS`, `NODE_REPL_EXTERNAL_MODULE`, `LD_PRELOAD`, `LD_AUDIT`, `LD_LIBRARY_PATH`, `DYLD_INSERT_LIBRARIES`, `DYLD_LIBRARY_PATH`, plus `PATH` and `NODE_PATH` (the child's `PATH` is what `execvp(3)` uses to pick which file named `npm` runs, so setting it names an arbitrary binary), compared case-insensitively — since `{"NODE_OPTIONS":"--require /tmp/x.js"}` turns an otherwise blameless `npx serverless package` into an arbitrary-code runner whichever runner passed. Two limits worth stating out loud: the fence is on the API and **not** the read path (a hand-edited `lss.config.json` and `LSS_PACKAGE_COMMAND` are the operator's own shell, and anyone who can write either already runs code here), and what stays expressible is the project's own build — `npm run <script>` runs whatever the service's `package.json` declares and `serverless package` reads its `serverless.yml`, plugins included. That is code the operator already trusts by pointing LSS at the directory, and forbidding it would mean the dashboard could not set a package command at all, which is what onboarding is built on. What is gone is the part that made the other allowlists worthless: through this API a caller can no longer choose the program, only ask the project's own build to run.
|
|
193
193
|
|
|
194
194
|
**Where it lives.** `src/server/services/serverless-packager.ts` — quote-aware command parsing, spawn, timeout, `ServerlessPackageError`. `src/server/services/service-registrar.ts` — `readTemplate()` fallback and `reregister()`. `src/server/services/config-manager.ts` — `getPackageConfigForService()` merges global config with a `servicePackaging` entry. `src/server/routes/services.ts` — `POST /package`.
|
|
195
195
|
|
|
@@ -734,18 +734,23 @@ npx [-y|--yes]… serverless|sls|osls[@version] package [args…]
|
|
|
734
734
|
**How it works.** The Overview polls `GET /api/lambdas/activity` every 5 s for a window you pick
|
|
735
735
|
(1/2/10 min). The server answers from a stack-wide ring of invocation spans (capped at 1000,
|
|
736
736
|
log-free) plus the current worker table and host counters. Three readings, coarse to fine: stat
|
|
737
|
-
tiles (resident workers against the `maxWarmWorkers` ceiling,
|
|
738
|
-
normalised by core count), a step area of
|
|
739
|
-
|
|
737
|
+
tiles (resident workers against the `maxWarmWorkers` ceiling, **lambdas loaded against lambdas
|
|
738
|
+
declared**, peak parallelism, host memory %, load normalised by core count), a step area of
|
|
739
|
+
parallelism over the window, and a timeline with one row **per lambda** and one bar per invocation —
|
|
740
|
+
overlapping bars in a vertical slice *are* the parallelism. Under it, each live worker lists the
|
|
741
|
+
handlers actually inside it: a worker is one process serving every function of its service, each
|
|
742
|
+
loaded on its own first invocation, so "the service is warm" answers a different question from
|
|
743
|
+
"which lambda is up" — with 1024 registered functions and 20 in use, the second one is the question.
|
|
740
744
|
Parallelism is the **peak** per bucket, never an average: a 300 ms burst that saturates the host is
|
|
741
745
|
the thing you are looking for, and an average erases it. A span still running when the window opens
|
|
742
746
|
is counted, so a long handler shows as load rather than as silence.
|
|
743
747
|
|
|
744
|
-
**Where it lives.** `src/ui/src/components/ActivityPanel.vue` — the panel
|
|
745
|
-
(a charting gap tracked as TREEUX-003 in `src/ui/treeUxPatterns.md`).
|
|
748
|
+
**Where it lives.** `src/ui/src/components/ActivityPanel.vue` — the panel.
|
|
746
749
|
`src/server/services/invocation-activity.ts` — the ring, the bucketing and the totals.
|
|
747
750
|
`src/server/routes/lambdas.ts` — `GET /activity`, which joins it to the worker table and host
|
|
748
|
-
counters. `src/server/services/lambda-runtime-manager.ts` — records one span per invocation
|
|
751
|
+
counters. `src/server/services/lambda-runtime-manager.ts` — records one span per invocation and
|
|
752
|
+
mirrors each worker's loaded-handler set. `src/server/runtime/runtime-worker.ts` — reports the
|
|
753
|
+
handler it loaded with every result, since the module cache is the worker's own state.
|
|
749
754
|
|
|
750
755
|
**Why it exists.** Lazy workers and an idle unload make the stack cheap, but they also make it
|
|
751
756
|
opaque: "is anything resident right now, and is my machine slow because of LSS?" had no answer short
|
|
@@ -1015,7 +1020,7 @@ red/green are 4.4 ΔE apart under deuteranopia.
|
|
|
1015
1020
|
<details>
|
|
1016
1021
|
<summary><b>Edit the config from the dashboard</b> — `PUT /api/config` writes the file and tells you what needs a restart</summary>
|
|
1017
1022
|
|
|
1018
|
-
**How it works.** `PUT /api/config` takes a partial patch and validates every key against a spec table (`port` = integer 1–65535, `positiveInt`, `nonNegativeInt`, `boolean`, `string` with optional enum, `packageCommand`, `packageArgs`, `stringRecord`, `envRecord`, `object` with fixed subkeys or per-entry subkeys); unknown keys and unknown subkeys are rejected, and **all** errors come back at once as a 400 with a `details[]` array. Three keys get more than a type check because they become arguments to `spawn()` and this route is unauthenticated: `packageCommand` (global and every `servicePackaging[*]` override) must match the packaging grammar — runner **and** subcommand, so `npm exec -c '<shell>'` and `yarn dlx <pkg>` are rejected alongside `/bin/sh`; `packageArgs` is screened for runner-redirecting flags because it reaches the same argv without a tokenizer; and `packageEnv` must carry no code-injection key (`NODE_OPTIONS`, `LD_PRELOAD`, `DYLD_*`, …). `secrets` is explicitly blocked — seed material must never cross the dashboard API. The write re-reads the raw file from disk and patches it key-by-key (never the env-resolved in-memory config, so env values are not baked in); object blocks merge one level deep, map blocks like `serviceRuntime` two levels, and a `null` deletes a key or subkey. The manager then reloads and answers with `restartRequired` — the diff of boot-materialized values (`serverPort`, `enableDynamoProxy`, `dynamoProxyPort`, `region`, `persistence`, `debug`, `stateDir`, and the `selfEngine` block), which keep their old value until `lss stop && lss start` — plus `envOverridden`, the patched keys currently masked by an env var. `POST /api/config/reload` runs the same reload after a hand edit; if the loaded file no longer parses it answers 400 and keeps the working config. `GET /api/config` returns the resolved snapshot with `packageEnv` collapsed to key names and secret seeds to a count, and `GET /api/config/ports` lists every port the stack exposes (orchestrator, engine, DynamoDB proxy, each service's API and invoke listener).
|
|
1023
|
+
**How it works.** `PUT /api/config` takes a partial patch and validates every key against a spec table (`port` = integer 1–65535, `positiveInt`, `nonNegativeInt`, `boolean`, `string` with optional enum, `packageCommand`, `packageArgs`, `stringRecord`, `envRecord`, `object` with fixed subkeys or per-entry subkeys); unknown keys and unknown subkeys are rejected, and **all** errors come back at once as a 400 with a `details[]` array. Three keys get more than a type check because they become arguments to `spawn()` and this route is unauthenticated: `packageCommand` (global and every `servicePackaging[*]` override) must match the packaging grammar — runner **and** subcommand, so `npm exec -c '<shell>'` and `yarn dlx <pkg>` are rejected alongside `/bin/sh`; `packageArgs` is screened for runner-redirecting flags because it reaches the same argv without a tokenizer; and `packageEnv` must carry no code-injection key (`NODE_OPTIONS`, `LD_PRELOAD`, `DYLD_*`, …). `secrets` is explicitly blocked — seed material must never cross the dashboard API. The write re-reads the raw file from disk and patches it key-by-key (never the env-resolved in-memory config, so env values are not baked in); object blocks merge one level deep, map blocks like `serviceRuntime` two levels, and a `null` deletes a key or subkey. **`packageEnv` — global and every `servicePackaging[*]` copy — merges one level deeper still, per variable**: `{"packageEnv":{"A":"v"}}` sets only `A` and leaves `B` and `C` alone, `{"packageEnv":{"A":null}}` removes only `A`, and `{"packageEnv":null}` still drops the whole block (a map left empty by a removal is dropped too, rather than written as `{}`). It is the one editable key whose values are **write-only** — `GET /api/config` reports `packageEnvKeys`, the names alone — so a dashboard that never received `B` and `C` has nothing to resend for them, and a replace-the-map write would have deleted them on the first save. Per-variable is what makes editing packaging env vars from the UI possible at all. The loader-hook denylist is unchanged for every variable a patch **sets**; *removing* one is always allowed, since it only takes capability away and is the one way to undo a hand-edited `NODE_OPTIONS` from the dashboard (the fence guards this API, never the file). The manager then reloads and answers with `restartRequired` — the diff of boot-materialized values (`serverPort`, `enableDynamoProxy`, `dynamoProxyPort`, `region`, `persistence`, `debug`, `stateDir`, and the `selfEngine` block), which keep their old value until `lss stop && lss start` — plus `envOverridden`, the patched keys currently masked by an env var. `POST /api/config/reload` runs the same reload after a hand edit; if the loaded file no longer parses it answers 400 and keeps the working config. `GET /api/config` returns the resolved snapshot with `packageEnv` collapsed to key names and secret seeds to a count, and `GET /api/config/ports` lists every port the stack exposes (orchestrator, engine, DynamoDB proxy, each service's API and invoke listener).
|
|
1019
1024
|
|
|
1020
1025
|
**Where it lives.** `src/server/routes/config.ts` — the four endpoints and the redacted snapshot builder. `src/server/services/config-manager.ts` — `EDITABLE_CONFIG_KEYS`, `updateConfig()`, `reloadFromDisk()`, `resolvedBootValues()`. `src/ui/src/pages/SettingsPage.vue` — the form, which PUTs only the fields actually changed and renders the restart / env-masked badges.
|
|
1021
1026
|
|
package/bin/cli.js
CHANGED
|
@@ -159,7 +159,47 @@ function getOrchestratorPath() {
|
|
|
159
159
|
return null;
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
/**
|
|
163
|
+
* Who is answering on our serverPort, if anyone: the `projectRoot` reported by
|
|
164
|
+
* `GET /api/config`. Under `--net=host` the port belongs to the whole machine,
|
|
165
|
+
* so "someone answers but it is not us" is a routine outcome — and the one the
|
|
166
|
+
* old `NOT RUNNING` turned into a wild goose chase. Returns null when nothing
|
|
167
|
+
* answers (or answers something else), because this only ever adds detail to a
|
|
168
|
+
* message; it must never become a reason to fail.
|
|
169
|
+
*/
|
|
170
|
+
async function probePortOwner() {
|
|
171
|
+
try {
|
|
172
|
+
const config = await getJson('/api/config');
|
|
173
|
+
return typeof config?.projectRoot === 'string' ? config.projectRoot : null;
|
|
174
|
+
} catch {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// The last `lines` lines of the orchestrator log — where the reason a boot died
|
|
180
|
+
// (EADDRINUSE, a bad config) is written, seconds before the CLI notices.
|
|
181
|
+
function tailLog(logFile, lines = 15) {
|
|
182
|
+
try {
|
|
183
|
+
const content = fs.readFileSync(logFile, 'utf8');
|
|
184
|
+
return content.split('\n').filter(Boolean).slice(-lines).join('\n');
|
|
185
|
+
} catch {
|
|
186
|
+
return '';
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Report a port held by a different project's orchestrator. Returns true when
|
|
191
|
+
// it printed something, so callers can skip their own vaguer message.
|
|
192
|
+
function reportPortOwner(owner, port, log = console.log) {
|
|
193
|
+
if (!owner) return false;
|
|
194
|
+
const here = process.cwd();
|
|
195
|
+
const mine = owner === here || here.startsWith(`${owner}${path.sep}`);
|
|
196
|
+
log(mine
|
|
197
|
+
? t('status.portAnsweringHere', { port })
|
|
198
|
+
: t('status.portOwnedByOther', { port, root: owner }));
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
async function startOrchestrator() {
|
|
163
203
|
// Before anything else — including the already-running short-circuit — so a
|
|
164
204
|
// stale 0.x flag or config value always fails loudly instead of looking like
|
|
165
205
|
// a successful no-op.
|
|
@@ -243,17 +283,88 @@ function startOrchestrator() {
|
|
|
243
283
|
}
|
|
244
284
|
console.log(t('start.logs', { path: logFile }));
|
|
245
285
|
|
|
246
|
-
|
|
286
|
+
// `--wait` blocks until the orchestrator actually answers, which is what a
|
|
287
|
+
// sequential chain (a VS Code task, a CI step, a boot script) needs: without
|
|
288
|
+
// it the next step's `register` fails fifteen times for a reason that is not
|
|
289
|
+
// the cause — the cause is in the first line of the log, minutes earlier.
|
|
290
|
+
if (process.argv.includes('--wait') || getArgValue('--wait') !== undefined) {
|
|
291
|
+
const seconds = Number.parseInt(getArgValue('--wait') || '', 10);
|
|
292
|
+
return waitForHealthy(child.pid, pidFile, logFile, Number.isInteger(seconds) && seconds > 0 ? seconds : 30);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Without --wait the CLI still has to answer honestly. Daemonizing means the
|
|
296
|
+
// child discovers a busy port AFTER this process has printed a PID, so the
|
|
297
|
+
// liveness check below is the only place a non-zero exit can come from — and
|
|
298
|
+
// it used to print the failure and exit 0 anyway, making a dead orchestrator
|
|
299
|
+
// count as a successful step.
|
|
300
|
+
return scheduleLivenessCheck(child.pid, pidFile, logFile);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Two seconds later: is the child still there? Resolves when it is, exits
|
|
304
|
+
// non-zero when it is not. Returned as a promise so the caller (and the tests)
|
|
305
|
+
// can observe the outcome instead of it happening in a detached timer.
|
|
306
|
+
function scheduleLivenessCheck(pid, pidFile, logFile) {
|
|
307
|
+
return new Promise((resolve, reject) => {
|
|
308
|
+
setTimeout(() => {
|
|
309
|
+
try {
|
|
310
|
+
process.kill(pid, 0);
|
|
311
|
+
} catch (e) {
|
|
312
|
+
// process.exit never returns in production; under test it throws, and
|
|
313
|
+
// the rejection is how a test asserts the exit code.
|
|
314
|
+
reportStartFailure(pidFile, logFile).then(() => process.exit(1)).then(resolve, reject);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
console.log(t('start.running'));
|
|
318
|
+
resolve();
|
|
319
|
+
}, 2000);
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Everything known about a boot that did not survive: the log tail, and whether
|
|
324
|
+
// the port it wanted is held by another project's orchestrator.
|
|
325
|
+
async function reportStartFailure(pidFile, logFile) {
|
|
326
|
+
console.error(t('start.failed', { path: logFile }));
|
|
327
|
+
if (fs.existsSync(pidFile)) {
|
|
328
|
+
fs.unlinkSync(pidFile);
|
|
329
|
+
}
|
|
330
|
+
const tail = tailLog(logFile);
|
|
331
|
+
if (tail) {
|
|
332
|
+
console.error(t('start.logTail'));
|
|
333
|
+
console.error(tail);
|
|
334
|
+
}
|
|
335
|
+
reportPortOwner(await probePortOwner(), getServerPort(), console.error);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Poll `GET /api/health` until the orchestrator answers, the child dies, or the
|
|
340
|
+
* deadline passes. Resolves on success; exits non-zero (after printing the log
|
|
341
|
+
* tail) on either failure — a `lss start --wait` that returns 0 means the stack
|
|
342
|
+
* is up and can be registered against.
|
|
343
|
+
*/
|
|
344
|
+
async function waitForHealthy(pid, pidFile, logFile, timeoutSeconds) {
|
|
345
|
+
const deadline = Date.now() + timeoutSeconds * 1000;
|
|
346
|
+
console.log(t('start.waiting', { seconds: timeoutSeconds }));
|
|
347
|
+
for (;;) {
|
|
247
348
|
try {
|
|
248
|
-
process.kill(
|
|
349
|
+
process.kill(pid, 0);
|
|
350
|
+
} catch {
|
|
351
|
+
await reportStartFailure(pidFile, logFile);
|
|
352
|
+
process.exit(1);
|
|
353
|
+
}
|
|
354
|
+
try {
|
|
355
|
+
await getJson('/api/health');
|
|
249
356
|
console.log(t('start.running'));
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
357
|
+
return;
|
|
358
|
+
} catch {
|
|
359
|
+
// Not up yet — the connection is refused until the listener binds.
|
|
360
|
+
}
|
|
361
|
+
if (Date.now() >= deadline) {
|
|
362
|
+
console.error(t('start.waitTimeout', { seconds: timeoutSeconds }));
|
|
363
|
+
await reportStartFailure(pidFile, logFile);
|
|
364
|
+
process.exit(1);
|
|
255
365
|
}
|
|
256
|
-
|
|
366
|
+
await new Promise(resolve => setTimeout(resolve, 250));
|
|
367
|
+
}
|
|
257
368
|
}
|
|
258
369
|
|
|
259
370
|
// Poll kill(pid, 0) until the process is gone. SIGTERM alone isn't enough to
|
|
@@ -317,10 +428,23 @@ async function stopOrchestrator() {
|
|
|
317
428
|
}
|
|
318
429
|
}
|
|
319
430
|
|
|
320
|
-
|
|
431
|
+
/**
|
|
432
|
+
* `lss status` — is THIS project's orchestrator running?
|
|
433
|
+
*
|
|
434
|
+
* The pid file answers that, and it used to answer nothing else: with
|
|
435
|
+
* `--net=host` the port belongs to the whole machine, so another project's
|
|
436
|
+
* orchestrator holding it produced `NOT RUNNING` from a port that answers 200 —
|
|
437
|
+
* a status that is not merely unhelpful but points the operator at the wrong
|
|
438
|
+
* place. Every "no" is now followed by asking WHO is on the port, which
|
|
439
|
+
* `GET /api/config` answers exactly (`projectRoot`).
|
|
440
|
+
*/
|
|
441
|
+
async function showStatus() {
|
|
321
442
|
const { pidFile, logFile } = runtimePaths();
|
|
443
|
+
const cfg = getConfig(loadConfig());
|
|
322
444
|
if (!fs.existsSync(pidFile)) {
|
|
323
|
-
|
|
445
|
+
if (!reportPortOwner(await probePortOwner(), cfg.serverPort)) {
|
|
446
|
+
console.log(t('status.notRunning'));
|
|
447
|
+
}
|
|
324
448
|
return;
|
|
325
449
|
}
|
|
326
450
|
|
|
@@ -328,8 +452,6 @@ function showStatus() {
|
|
|
328
452
|
|
|
329
453
|
try {
|
|
330
454
|
process.kill(pid, 0);
|
|
331
|
-
const config = loadConfig();
|
|
332
|
-
const cfg = getConfig(config);
|
|
333
455
|
console.log(t('status.running', { pid }));
|
|
334
456
|
console.log(t('status.server', { url: `http://localhost:${cfg.serverPort}` }));
|
|
335
457
|
console.log(t('status.engine', { url: `http://localhost:${cfg.selfEnginePort}` }));
|
|
@@ -340,6 +462,7 @@ function showStatus() {
|
|
|
340
462
|
} catch (e) {
|
|
341
463
|
console.log(t('status.stale'));
|
|
342
464
|
fs.unlinkSync(pidFile);
|
|
465
|
+
reportPortOwner(await probePortOwner(), cfg.serverPort);
|
|
343
466
|
}
|
|
344
467
|
}
|
|
345
468
|
|
|
@@ -810,6 +933,7 @@ function showHelp() {
|
|
|
810
933
|
t('help.options'),
|
|
811
934
|
opt('--config <path>', 'help.opt.config'),
|
|
812
935
|
opt('--enable-dynamo-proxy', 'help.opt.dynamoProxy'),
|
|
936
|
+
opt('--wait[=<seconds>]', 'help.opt.wait'),
|
|
813
937
|
opt('--yes, -y', 'help.opt.yes'),
|
|
814
938
|
'',
|
|
815
939
|
t('help.environment'),
|
package/bin/i18n.js
CHANGED
|
@@ -43,7 +43,11 @@ function detectLocale(env = process.env) {
|
|
|
43
43
|
const MESSAGES = {
|
|
44
44
|
en: {
|
|
45
45
|
'scan.warning.not-installed': 'dependencies not installed — packaging needs an install first',
|
|
46
|
+
// Two codes for one fact, because the fact depends on `autoPackage`: the
|
|
47
|
+
// single string that promised packaging was read as a promise by operators
|
|
48
|
+
// whose config had it off, and registering answered 400 instead.
|
|
46
49
|
'scan.warning.not-packaged': 'not packaged yet — registering packages it for you (autoPackage)',
|
|
50
|
+
'scan.warning.not-packaged-manual': 'not packaged yet — autoPackage is off, so run `serverless package` before registering',
|
|
47
51
|
'scan.warning.ts-config': 'TypeScript service config — name, region and ports resolve at packaging time',
|
|
48
52
|
'scan.warning.unreadable-config': 'could not read {file}',
|
|
49
53
|
'scan.warning.invalid-json': 'serverless.json is not valid JSON',
|
|
@@ -61,6 +65,9 @@ const MESSAGES = {
|
|
|
61
65
|
'start.logs': '📝 Logs: {path}',
|
|
62
66
|
'start.running': '✅ Service is running',
|
|
63
67
|
'start.failed': '❌ Service failed to start. Check logs: {path}',
|
|
68
|
+
'start.waiting': '⏳ Waiting for the orchestrator to answer (up to {seconds}s)...',
|
|
69
|
+
'start.waitTimeout': '❌ The orchestrator did not answer within {seconds}s',
|
|
70
|
+
'start.logTail': '--- last lines of the log ---',
|
|
64
71
|
'start.notBuilt': '❌ Orchestrator not found or not built.',
|
|
65
72
|
'start.notBuiltDev': 'If you are developing LSS, run:',
|
|
66
73
|
'start.notBuiltBug': 'If you installed via npm, please report this as a bug.',
|
|
@@ -75,6 +82,11 @@ const MESSAGES = {
|
|
|
75
82
|
'status.engine': ' Self Engine: {url}',
|
|
76
83
|
'status.dynamoProxy': ' DynamoDB Proxy: {url}',
|
|
77
84
|
'status.logs': ' Logs: {path}',
|
|
85
|
+
// A port answering from another checkout is the routine outcome under
|
|
86
|
+
// `--net=host`, and reporting it as NOT RUNNING sent people looking in the
|
|
87
|
+
// wrong place. `projectRoot` comes from GET /api/config on that port.
|
|
88
|
+
'status.portOwnedByOther': '🔶 Port {port} is in use by the orchestrator of {root}',
|
|
89
|
+
'status.portAnsweringHere': '🔶 Port {port} answers for this project, but no PID file is registered here (started from another shell?)',
|
|
78
90
|
'logs.missing': '⚠️ No log file at {path}',
|
|
79
91
|
'logs.from': '📝 Logs from: {path}',
|
|
80
92
|
|
|
@@ -169,6 +181,7 @@ const MESSAGES = {
|
|
|
169
181
|
'help.cmd.help': 'Show this help message',
|
|
170
182
|
'help.opt.config': 'Load config from this file (precedes the cwd/home search). Applies to start/stop/status/logs, so an isolated instance can be addressed without cd-ing into its folder.',
|
|
171
183
|
'help.opt.dynamoProxy': 'Enable the DynamoDB proxy on port 8000 (for the start command)',
|
|
184
|
+
'help.opt.wait': 'On start, block until the orchestrator answers GET /api/health (default 30s) and exit non-zero — with the log tail — if it never does. What a sequential chain needs so the next step is not run against a stack that is not up.',
|
|
172
185
|
'help.opt.yes': 'Skip the interactive confirmation on seed:clear (use only in CI)',
|
|
173
186
|
'help.env.dashboardPort': 'Orchestrator port (overrides serverPort)',
|
|
174
187
|
'help.env.enginePort': 'Self engine port (overrides selfEngine.port)',
|
|
@@ -195,6 +208,7 @@ const MESSAGES = {
|
|
|
195
208
|
'pt-BR': {
|
|
196
209
|
'scan.warning.not-installed': 'dependências não instaladas — empacotar exige instalar antes',
|
|
197
210
|
'scan.warning.not-packaged': 'ainda não empacotado — registrar empacota para você (autoPackage)',
|
|
211
|
+
'scan.warning.not-packaged-manual': 'ainda não empacotado — autoPackage está desligado, rode `serverless package` antes de registrar',
|
|
198
212
|
'scan.warning.ts-config': 'config em TypeScript — nome, região e portas só resolvem no empacotamento',
|
|
199
213
|
'scan.warning.unreadable-config': 'não consegui ler {file}',
|
|
200
214
|
'scan.warning.invalid-json': 'serverless.json não é um JSON válido',
|
|
@@ -210,6 +224,9 @@ const MESSAGES = {
|
|
|
210
224
|
'start.logs': '📝 Logs: {path}',
|
|
211
225
|
'start.running': '✅ Serviço no ar',
|
|
212
226
|
'start.failed': '❌ O serviço não subiu. Veja os logs: {path}',
|
|
227
|
+
'start.waiting': '⏳ Esperando o orquestrador responder (até {seconds}s)...',
|
|
228
|
+
'start.waitTimeout': '❌ O orquestrador não respondeu em {seconds}s',
|
|
229
|
+
'start.logTail': '--- últimas linhas do log ---',
|
|
213
230
|
'start.notBuilt': '❌ Orquestrador não encontrado ou sem build.',
|
|
214
231
|
'start.notBuiltDev': 'Se você está desenvolvendo o LSS, rode:',
|
|
215
232
|
'start.notBuiltBug': 'Se você instalou via npm, por favor abra um bug.',
|
|
@@ -224,6 +241,8 @@ const MESSAGES = {
|
|
|
224
241
|
'status.engine': ' Self Engine: {url}',
|
|
225
242
|
'status.dynamoProxy': ' Proxy DynamoDB: {url}',
|
|
226
243
|
'status.logs': ' Logs: {path}',
|
|
244
|
+
'status.portOwnedByOther': '🔶 A porta {port} está em uso pelo orquestrador de {root}',
|
|
245
|
+
'status.portAnsweringHere': '🔶 A porta {port} responde por este projeto, mas não há arquivo de PID registrado aqui (subiu de outro shell?)',
|
|
227
246
|
'logs.missing': '⚠️ Nenhum arquivo de log em {path}',
|
|
228
247
|
'logs.from': '📝 Logs de: {path}',
|
|
229
248
|
|
|
@@ -308,6 +327,7 @@ const MESSAGES = {
|
|
|
308
327
|
'help.cmd.help': 'Mostra esta ajuda',
|
|
309
328
|
'help.opt.config': 'Carrega a config deste arquivo (tem precedência sobre a busca em cwd/home). Vale para start/stop/status/logs, então dá para endereçar uma instância isolada sem entrar na pasta dela.',
|
|
310
329
|
'help.opt.dynamoProxy': 'Liga o proxy DynamoDB na porta 8000 (para o comando start)',
|
|
330
|
+
'help.opt.wait': 'No start, bloqueia até o orquestrador responder GET /api/health (padrão 30s) e sai com código diferente de zero — mostrando o fim do log — se ele não responder. É o que uma cadeia sequencial precisa para não rodar o passo seguinte contra um stack que não subiu.',
|
|
311
331
|
'help.opt.yes': 'Pula a confirmação interativa do seed:clear (use só em CI)',
|
|
312
332
|
'help.env.dashboardPort': 'Porta do orquestrador (sobrepõe serverPort)',
|
|
313
333
|
'help.env.enginePort': 'Porta do self engine (sobrepõe selfEngine.port)',
|
|
@@ -334,6 +354,7 @@ const MESSAGES = {
|
|
|
334
354
|
es: {
|
|
335
355
|
'scan.warning.not-installed': 'dependencias sin instalar — empaquetar requiere instalarlas antes',
|
|
336
356
|
'scan.warning.not-packaged': 'aún sin empaquetar — registrar lo empaqueta por ti (autoPackage)',
|
|
357
|
+
'scan.warning.not-packaged-manual': 'aún sin empaquetar — autoPackage está desactivado, ejecuta `serverless package` antes de registrar',
|
|
337
358
|
'scan.warning.ts-config': 'config en TypeScript — nombre, región y puertos se resuelven al empaquetar',
|
|
338
359
|
'scan.warning.unreadable-config': 'no se pudo leer {file}',
|
|
339
360
|
'scan.warning.invalid-json': 'serverless.json no es un JSON válido',
|
|
@@ -349,6 +370,9 @@ const MESSAGES = {
|
|
|
349
370
|
'start.logs': '📝 Registros: {path}',
|
|
350
371
|
'start.running': '✅ El servicio está en marcha',
|
|
351
372
|
'start.failed': '❌ El servicio no arrancó. Revisa los registros: {path}',
|
|
373
|
+
'start.waiting': '⏳ Esperando a que el orquestador responda (hasta {seconds}s)...',
|
|
374
|
+
'start.waitTimeout': '❌ El orquestador no respondió en {seconds}s',
|
|
375
|
+
'start.logTail': '--- últimas líneas del registro ---',
|
|
352
376
|
'start.notBuilt': '❌ Orquestador no encontrado o sin compilar.',
|
|
353
377
|
'start.notBuiltDev': 'Si estás desarrollando LSS, ejecuta:',
|
|
354
378
|
'start.notBuiltBug': 'Si lo instalaste con npm, por favor repórtalo como un bug.',
|
|
@@ -363,6 +387,8 @@ const MESSAGES = {
|
|
|
363
387
|
'status.engine': ' Self Engine: {url}',
|
|
364
388
|
'status.dynamoProxy': ' Proxy de DynamoDB: {url}',
|
|
365
389
|
'status.logs': ' Registros: {path}',
|
|
390
|
+
'status.portOwnedByOther': '🔶 El puerto {port} lo ocupa el orquestador de {root}',
|
|
391
|
+
'status.portAnsweringHere': '🔶 El puerto {port} responde por este proyecto, pero no hay archivo PID registrado aquí (¿arrancó desde otra terminal?)',
|
|
366
392
|
'logs.missing': '⚠️ No hay archivo de registro en {path}',
|
|
367
393
|
'logs.from': '📝 Registros de: {path}',
|
|
368
394
|
|
|
@@ -447,6 +473,7 @@ const MESSAGES = {
|
|
|
447
473
|
'help.cmd.help': 'Muestra esta ayuda',
|
|
448
474
|
'help.opt.config': 'Carga la configuración de este archivo (tiene precedencia sobre la búsqueda en cwd/home). Aplica a start/stop/status/logs, así una instancia aislada se puede direccionar sin entrar a su carpeta.',
|
|
449
475
|
'help.opt.dynamoProxy': 'Habilita el proxy de DynamoDB en el puerto 8000 (para el comando start)',
|
|
476
|
+
'help.opt.wait': 'En start, bloquea hasta que el orquestador responda GET /api/health (30s por defecto) y sale con código distinto de cero — mostrando el final del registro — si no responde. Es lo que necesita una cadena secuencial para no ejecutar el paso siguiente contra un stack que no arrancó.',
|
|
450
477
|
'help.opt.yes': 'Salta la confirmación interactiva de seed:clear (úsalo solo en CI)',
|
|
451
478
|
'help.env.dashboardPort': 'Puerto del orquestador (sobrescribe serverPort)',
|
|
452
479
|
'help.env.enginePort': 'Puerto del self engine (sobrescribe selfEngine.port)',
|
|
@@ -41,7 +41,7 @@ export function s3Error(code, message, status) {
|
|
|
41
41
|
// here (this error is only reachable when no fallback is configured).
|
|
42
42
|
export function notImplemented(service, operation) {
|
|
43
43
|
return new AwsError('NotImplemented', `${service}.${operation} is not implemented by the LSS self engine — ` +
|
|
44
|
-
'see docs/SELF_ENGINE.md#coverage, or set selfEngine.fallbackEndpoint to forward it to
|
|
44
|
+
'see docs/SELF_ENGINE.md#coverage, or set selfEngine.fallbackEndpoint to forward it to another AWS-compatible endpoint', { status: 400 });
|
|
45
45
|
}
|
|
46
46
|
// Operation-level gap inside a service the engine DOES serve: the fallback
|
|
47
47
|
// proxy never forwards these (and it would read the wrong state anyway — the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../../src/server/engine/http/errors.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,2EAA2E;AAC3E,6EAA6E;AAC7E,2EAA2E;AAC3E,yEAAyE;AAIzE,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,IAAI,CAAS;IACb,MAAM,CAAS;IACf,KAAK,CAAgB;IAC9B,wEAAwE;IACxE,uEAAuE;IAC9D,QAAQ,CAAU;IAC3B,sEAAsE;IACtE,mCAAmC;IAC1B,KAAK,CAA2B;IAEzC,YACE,IAAY,EACZ,OAAe,EACf,OAAwG;QAExG,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,GAAG,CAAC;QACrC,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,QAAQ,CAAC;QACxC,IAAI,CAAC,QAAQ,GAAG,OAAO,EAAE,QAAQ,CAAC;QAClC,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,SAAS,GAAG,kCAAkC,CAAC;AAErD,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,OAAe,EAAE,MAAM,GAAG,GAAG;IACrE,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,OAAO,WAAW,CAAC,qBAAqB,EAAE,OAAO,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,OAAe,EAAE,MAAM,GAAG,GAAG;IAClE,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,OAAe,EAAE,MAAc;IACnE,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,6EAA6E;AAC7E,8EAA8E;AAC9E,sEAAsE;AACtE,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,SAAiB;IAC/D,OAAO,IAAI,QAAQ,CACjB,gBAAgB,EAChB,GAAG,OAAO,IAAI,SAAS,+CAA+C;QACpE,
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../../src/server/engine/http/errors.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,2EAA2E;AAC3E,6EAA6E;AAC7E,2EAA2E;AAC3E,yEAAyE;AAIzE,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,IAAI,CAAS;IACb,MAAM,CAAS;IACf,KAAK,CAAgB;IAC9B,wEAAwE;IACxE,uEAAuE;IAC9D,QAAQ,CAAU;IAC3B,sEAAsE;IACtE,mCAAmC;IAC1B,KAAK,CAA2B;IAEzC,YACE,IAAY,EACZ,OAAe,EACf,OAAwG;QAExG,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,GAAG,CAAC;QACrC,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,QAAQ,CAAC;QACxC,IAAI,CAAC,QAAQ,GAAG,OAAO,EAAE,QAAQ,CAAC;QAClC,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,SAAS,GAAG,kCAAkC,CAAC;AAErD,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,OAAe,EAAE,MAAM,GAAG,GAAG;IACrE,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,OAAO,WAAW,CAAC,qBAAqB,EAAE,OAAO,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,OAAe,EAAE,MAAM,GAAG,GAAG;IAClE,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,OAAe,EAAE,MAAc;IACnE,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,6EAA6E;AAC7E,8EAA8E;AAC9E,sEAAsE;AACtE,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,SAAiB;IAC/D,OAAO,IAAI,QAAQ,CACjB,gBAAgB,EAChB,GAAG,OAAO,IAAI,SAAS,+CAA+C;QACpE,uHAAuH,EACzH,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAC;AACJ,CAAC;AAED,2EAA2E;AAC3E,6EAA6E;AAC7E,yEAAyE;AACzE,6CAA6C;AAC7C,MAAM,UAAU,uBAAuB,CAAC,OAAe,EAAE,SAAiB;IACxE,OAAO,IAAI,QAAQ,CACjB,gBAAgB,EAChB,GAAG,OAAO,IAAI,SAAS,iFAAiF;QACtG,0GAA0G;QAC1G,OAAO,OAAO,mDAAmD,EACnE,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/server/routes/config.ts"],"names":[],"mappings":"AAUA,QAAA,MAAM,MAAM,4CAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/server/routes/config.ts"],"names":[],"mappings":"AAUA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA4NxB,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,CAAC"}
|
|
@@ -83,6 +83,12 @@ router.get('/', (_req, res) => {
|
|
|
83
83
|
// lss.config.json in the project root when none is loaded) and hot-reload the
|
|
84
84
|
// in-memory config. The human reviews and commits the file — LSS never
|
|
85
85
|
// touches git. Boot-materialized keys come back in restartRequired.
|
|
86
|
+
//
|
|
87
|
+
// `packageEnv` — global and per-service — is patched one VARIABLE at a time (a
|
|
88
|
+
// string sets it, null removes it) rather than replaced, because this router
|
|
89
|
+
// only ever hands out `packageEnvKeys`: a caller that never received the values
|
|
90
|
+
// cannot resend them, so a replace would delete every variable it could not
|
|
91
|
+
// see. See mergeEnvRecord() in config-manager.ts.
|
|
86
92
|
router.put('/', (req, res) => {
|
|
87
93
|
const cm = ConfigManager.getInstance();
|
|
88
94
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/server/routes/config.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/server/routes/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lambdas.d.ts","sourceRoot":"","sources":["../../../src/server/routes/lambdas.ts"],"names":[],"mappings":"AAOA,QAAA,MAAM,MAAM,4CAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"lambdas.d.ts","sourceRoot":"","sources":["../../../src/server/routes/lambdas.ts"],"names":[],"mappings":"AAOA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAqKxB,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,CAAC"}
|
|
@@ -52,6 +52,12 @@ router.get('/activity', (req, res) => {
|
|
|
52
52
|
});
|
|
53
53
|
// One row per registered service: a worker is a whole OS process, so this is
|
|
54
54
|
// the unit that actually costs memory — not the function count.
|
|
55
|
+
//
|
|
56
|
+
// `loadedFunctions` is the other half of the question, and the one the
|
|
57
|
+
// service row cannot answer: a worker is one process serving many functions,
|
|
58
|
+
// each loaded on ITS first invocation. "billing-service is warm" does not say
|
|
59
|
+
// whether that is one handler or sixty, nor WHICH — and which is what an
|
|
60
|
+
// operator debugging a silent lambda is actually looking for.
|
|
55
61
|
const workers = FunctionRegistry.getInstance().listServices().map(service => {
|
|
56
62
|
const info = runtimeManager.getRuntimeInfo(service.name);
|
|
57
63
|
return {
|
|
@@ -64,6 +70,7 @@ router.get('/activity', (req, res) => {
|
|
|
64
70
|
invocations: info.invocations,
|
|
65
71
|
errors: info.errors,
|
|
66
72
|
functions: service.functions.length,
|
|
73
|
+
loadedFunctions: info.loadedFunctions ?? [],
|
|
67
74
|
executionMode: info.resolvedMode,
|
|
68
75
|
};
|
|
69
76
|
});
|
|
@@ -78,6 +85,11 @@ router.get('/activity', (req, res) => {
|
|
|
78
85
|
maxWarmWorkers: cm.getLambdaMaxWarmWorkers(),
|
|
79
86
|
lazy: cm.isLambdaRuntimeLazy(),
|
|
80
87
|
idleTimeoutMs: cm.getLambdaIdleTimeoutMs(),
|
|
88
|
+
// Handlers resident across every live worker, and how many exist in
|
|
89
|
+
// total. The gap between them is the point of lazy loading: 3 of 1024
|
|
90
|
+
// means the stack is paying for three.
|
|
91
|
+
loadedFunctions: workers.reduce((sum, w) => sum + w.loadedFunctions.length, 0),
|
|
92
|
+
registeredFunctions: workers.reduce((sum, w) => sum + w.functions, 0),
|
|
81
93
|
},
|
|
82
94
|
host: {
|
|
83
95
|
// Resident set of the orchestrator process — with in-process emulation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lambdas.js","sourceRoot":"","sources":["../../../src/server/routes/lambdas.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"lambdas.js","sourceRoot":"","sources":["../../../src/server/routes/lambdas.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../../src/server/routes/services.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAQhE,QAAA,MAAM,MAAM,4CAAW,CAAC;AAIxB,QAAA,MAAM,cAAc,gBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../../src/server/routes/services.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAQhE,QAAA,MAAM,MAAM,4CAAW,CAAC;AAIxB,QAAA,MAAM,cAAc,gBAAuB,CAAC;AAgmB5C,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -121,19 +121,28 @@ router.get('/', async (_req, res) => {
|
|
|
121
121
|
router.get('/scan', async (_req, res) => {
|
|
122
122
|
try {
|
|
123
123
|
await ensureCacheInit();
|
|
124
|
-
const
|
|
124
|
+
const registeredServices = await cache.listServices();
|
|
125
|
+
const byRoot = new Map(registeredServices.map(s => [path.resolve(s.root), s]));
|
|
125
126
|
const cm = ConfigManager.getInstance();
|
|
126
127
|
const projectRoot = cm.getProjectRoot();
|
|
127
128
|
// Overlay the config on the yml hints: `serviceRuntime` ports win (same
|
|
128
129
|
// precedence registration applies), and the effective package command is
|
|
129
130
|
// what onboarding shows/edits (a `servicePackaging` entry, else global).
|
|
130
|
-
const services = scanForServices(projectRoot,
|
|
131
|
+
const services = scanForServices(projectRoot, [...byRoot.keys()], {
|
|
132
|
+
isIgnored: dir => cm.isScanIgnored(dir),
|
|
133
|
+
autoPackage: cm.isAutoPackage(),
|
|
134
|
+
}).map(svc => {
|
|
131
135
|
const runtime = cm.getRuntimeConfigForService(svc.root);
|
|
136
|
+
// For a service already registered, the packaged state has settled what
|
|
137
|
+
// the yml scrape could only guess — prefer it.
|
|
138
|
+
const cached = byRoot.get(path.resolve(svc.root));
|
|
132
139
|
return {
|
|
133
140
|
...svc,
|
|
134
141
|
apiPort: runtime.apiPort ?? svc.apiPort,
|
|
135
142
|
invokePort: runtime.invokePort ?? svc.invokePort,
|
|
136
143
|
packageCommand: cm.getPackageConfigForService(svc.root).command,
|
|
144
|
+
hasFunctions: cached ? (cached.functions?.length ?? 0) > 0 : svc.hasFunctions,
|
|
145
|
+
routeCount: cached?.routes?.length,
|
|
137
146
|
};
|
|
138
147
|
});
|
|
139
148
|
return res.json({ projectRoot, services });
|
|
@@ -332,14 +341,18 @@ router.post('/package', async (req, res) => {
|
|
|
332
341
|
return;
|
|
333
342
|
const pkg = ConfigManager.getInstance().getPackageConfigForService(dir);
|
|
334
343
|
const displayCmd = [pkg.command, ...pkg.args].join(' ');
|
|
335
|
-
console.log(`📦 Packaging ${dir} ('${displayCmd}')`);
|
|
344
|
+
console.log(`📦 Packaging ${dir} ('${displayCmd}' in ${pkg.cwd})`);
|
|
336
345
|
const startedAt = Date.now();
|
|
337
346
|
try {
|
|
338
347
|
const result = await runServerlessPackage({
|
|
339
348
|
command: pkg.command,
|
|
340
349
|
args: pkg.args,
|
|
341
350
|
env: pkg.env,
|
|
342
|
-
|
|
351
|
+
// `packageCwd` may point the command at a directory above the service
|
|
352
|
+
// (a root-level script packaging a resources-only stack); it is fenced to
|
|
353
|
+
// the project root by ConfigManager, the same fence resolveServiceDir
|
|
354
|
+
// applies to the request's own path.
|
|
355
|
+
cwd: pkg.cwd,
|
|
343
356
|
timeoutMs: pkg.timeoutMs,
|
|
344
357
|
});
|
|
345
358
|
return res.json({ success: true, exitCode: result.exitCode, durationMs: Date.now() - startedAt, output: outputTail(result.stdout, result.stderr) });
|