local-serverless-stack 1.0.0 → 1.1.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/CHANGELOG.md +125 -3
- package/README.md +92 -38
- package/bin/cli.js +218 -28
- package/bin/i18n.js +57 -3
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/namespaces/services.d.ts +46 -0
- package/dist/client/namespaces/services.d.ts.map +1 -1
- package/dist/client/namespaces/services.js +1 -0
- package/dist/client/namespaces/services.js.map +1 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +17 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/server/engine/backends/self-backend.d.ts +26 -1
- package/dist/server/engine/backends/self-backend.d.ts.map +1 -1
- package/dist/server/engine/backends/self-backend.js +104 -11
- package/dist/server/engine/backends/self-backend.js.map +1 -1
- package/dist/server/engine/emulators/dynamodb/expressions/parser.d.ts.map +1 -1
- package/dist/server/engine/emulators/dynamodb/expressions/parser.js +12 -1
- package/dist/server/engine/emulators/dynamodb/expressions/parser.js.map +1 -1
- package/dist/server/engine/emulators/dynamodb/expressions/reserved-words.d.ts +3 -0
- package/dist/server/engine/emulators/dynamodb/expressions/reserved-words.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/reserved-words.js +78 -0
- package/dist/server/engine/emulators/dynamodb/expressions/reserved-words.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/index.d.ts +11 -0
- package/dist/server/engine/emulators/dynamodb/index.d.ts.map +1 -1
- package/dist/server/engine/emulators/dynamodb/index.js +101 -7
- package/dist/server/engine/emulators/dynamodb/index.js.map +1 -1
- package/dist/server/engine/emulators/dynamodb/query.d.ts +1 -0
- package/dist/server/engine/emulators/dynamodb/query.d.ts.map +1 -1
- package/dist/server/engine/emulators/dynamodb/query.js +34 -6
- package/dist/server/engine/emulators/dynamodb/query.js.map +1 -1
- package/dist/server/engine/emulators/s3/index.d.ts +10 -0
- package/dist/server/engine/emulators/s3/index.d.ts.map +1 -1
- package/dist/server/engine/emulators/s3/index.js +369 -25
- package/dist/server/engine/emulators/s3/index.js.map +1 -1
- package/dist/server/engine/emulators/sqs/index.d.ts +2 -0
- package/dist/server/engine/emulators/sqs/index.d.ts.map +1 -1
- package/dist/server/engine/emulators/sqs/index.js +70 -7
- package/dist/server/engine/emulators/sqs/index.js.map +1 -1
- package/dist/server/engine/emulators/sqs/queue.d.ts +2 -1
- package/dist/server/engine/emulators/sqs/queue.d.ts.map +1 -1
- package/dist/server/engine/emulators/sqs/queue.js +68 -35
- package/dist/server/engine/emulators/sqs/queue.js.map +1 -1
- package/dist/server/engine/emulators/ssm/index.d.ts +31 -0
- package/dist/server/engine/emulators/ssm/index.d.ts.map +1 -0
- package/dist/server/engine/emulators/ssm/index.js +670 -0
- package/dist/server/engine/emulators/ssm/index.js.map +1 -0
- package/dist/server/engine/http/errors.d.ts +1 -0
- package/dist/server/engine/http/errors.d.ts.map +1 -1
- package/dist/server/engine/http/errors.js +13 -5
- package/dist/server/engine/http/errors.js.map +1 -1
- package/dist/server/engine/http/is-aws-request.d.ts.map +1 -1
- package/dist/server/engine/http/is-aws-request.js +13 -3
- package/dist/server/engine/http/is-aws-request.js.map +1 -1
- package/dist/server/engine/http/protocols/aws-json.d.ts +1 -0
- package/dist/server/engine/http/protocols/aws-json.d.ts.map +1 -1
- package/dist/server/engine/http/protocols/aws-json.js +13 -0
- package/dist/server/engine/http/protocols/aws-json.js.map +1 -1
- package/dist/server/engine/http/reset.d.ts +4 -0
- package/dist/server/engine/http/reset.d.ts.map +1 -0
- package/dist/server/engine/http/reset.js +17 -0
- package/dist/server/engine/http/reset.js.map +1 -0
- package/dist/server/engine/http/router.d.ts +1 -0
- package/dist/server/engine/http/router.d.ts.map +1 -1
- package/dist/server/engine/http/router.js +185 -34
- package/dist/server/engine/http/router.js.map +1 -1
- package/dist/server/engine/types.d.ts +2 -1
- package/dist/server/engine/types.d.ts.map +1 -1
- package/dist/server/routes/apis.d.ts.map +1 -1
- package/dist/server/routes/apis.js +6 -0
- package/dist/server/routes/apis.js.map +1 -1
- package/dist/server/routes/config.d.ts.map +1 -1
- package/dist/server/routes/config.js +25 -1
- 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 +66 -5
- package/dist/server/routes/services.js.map +1 -1
- package/dist/server/runtime/runtime-worker.js +40 -3
- package/dist/server/runtime/runtime-worker.js.map +1 -1
- package/dist/server/services/api-gateway-events.d.ts +14 -0
- package/dist/server/services/api-gateway-events.d.ts.map +1 -1
- package/dist/server/services/api-gateway-events.js +114 -8
- package/dist/server/services/api-gateway-events.js.map +1 -1
- package/dist/server/services/artifact-staleness.d.ts +20 -0
- package/dist/server/services/artifact-staleness.d.ts.map +1 -0
- package/dist/server/services/artifact-staleness.js +115 -0
- package/dist/server/services/artifact-staleness.js.map +1 -0
- package/dist/server/services/authorizer-service.d.ts +34 -5
- package/dist/server/services/authorizer-service.d.ts.map +1 -1
- package/dist/server/services/authorizer-service.js +0 -0
- package/dist/server/services/authorizer-service.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/cfn-intrinsics.d.ts +63 -0
- package/dist/server/services/cfn-intrinsics.d.ts.map +1 -0
- package/dist/server/services/cfn-intrinsics.js +403 -0
- package/dist/server/services/cfn-intrinsics.js.map +1 -0
- package/dist/server/services/cfn-physical-values.d.ts +51 -0
- package/dist/server/services/cfn-physical-values.d.ts.map +1 -0
- package/dist/server/services/cfn-physical-values.js +186 -0
- package/dist/server/services/cfn-physical-values.js.map +1 -0
- package/dist/server/services/cloudformation-parser.d.ts +26 -3
- package/dist/server/services/cloudformation-parser.d.ts.map +1 -1
- package/dist/server/services/cloudformation-parser.js +79 -7
- package/dist/server/services/cloudformation-parser.js.map +1 -1
- package/dist/server/services/config-manager.d.ts +49 -2
- package/dist/server/services/config-manager.d.ts.map +1 -1
- package/dist/server/services/config-manager.js +206 -24
- package/dist/server/services/config-manager.js.map +1 -1
- package/dist/server/services/gateway-manager.d.ts.map +1 -1
- package/dist/server/services/gateway-manager.js +52 -20
- package/dist/server/services/gateway-manager.js.map +1 -1
- package/dist/server/services/lambda-runtime-manager.d.ts +2 -0
- package/dist/server/services/lambda-runtime-manager.d.ts.map +1 -1
- package/dist/server/services/lambda-runtime-manager.js +49 -15
- package/dist/server/services/lambda-runtime-manager.js.map +1 -1
- package/dist/server/services/raw-api-assembler.d.ts +1 -1
- package/dist/server/services/raw-api-assembler.d.ts.map +1 -1
- package/dist/server/services/raw-api-assembler.js +18 -8
- package/dist/server/services/raw-api-assembler.js.map +1 -1
- package/dist/server/services/resource-provisioner.d.ts +31 -1
- package/dist/server/services/resource-provisioner.d.ts.map +1 -1
- package/dist/server/services/resource-provisioner.js +257 -25
- 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/serverless-state-parser.d.ts +45 -2
- package/dist/server/services/serverless-state-parser.d.ts.map +1 -1
- package/dist/server/services/serverless-state-parser.js +217 -29
- package/dist/server/services/serverless-state-parser.js.map +1 -1
- package/dist/server/services/service-graph.d.ts +76 -0
- package/dist/server/services/service-graph.d.ts.map +1 -0
- package/dist/server/services/service-graph.js +914 -0
- package/dist/server/services/service-graph.js.map +1 -0
- package/dist/server/services/service-registrar.d.ts +17 -1
- package/dist/server/services/service-registrar.d.ts.map +1 -1
- package/dist/server/services/service-registrar.js +190 -66
- 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/server/services/source-watcher.d.ts +1 -0
- package/dist/server/services/source-watcher.d.ts.map +1 -1
- package/dist/server/services/source-watcher.js +19 -1
- package/dist/server/services/source-watcher.js.map +1 -1
- package/dist/server/services/worker-runtime.d.ts +82 -0
- package/dist/server/services/worker-runtime.d.ts.map +1 -0
- package/dist/server/services/worker-runtime.js +303 -0
- package/dist/server/services/worker-runtime.js.map +1 -0
- package/dist/ui/assets/ApisPage-BkW-QZ0X.js +1 -0
- package/dist/ui/assets/BucketDetailPage-CJwTQJh7.js +1 -0
- package/dist/ui/assets/BucketsPage-B1xPVhZC.js +1 -0
- package/dist/ui/assets/DynamoPage-DvbpwZDc.js +1 -0
- package/dist/ui/assets/DynamoTablePage-xn3Lq3so.js +3 -0
- package/dist/ui/assets/LambdaDetailPage-BhUyO77H.js +4 -0
- package/dist/ui/assets/LambdasPage-CUF_4rOH.js +1 -0
- package/dist/ui/assets/OnboardingPage-U49THUzu.js +1 -0
- package/dist/ui/assets/OpenSearchCollectionPage-BJTVNCq4.js +1 -0
- package/dist/ui/assets/OpenSearchPage-4s-egkB9.js +1 -0
- package/dist/ui/assets/OverviewPage-DJeJQktG.js +1 -0
- package/dist/ui/assets/{OverviewPage-C1pBJ8aP.css → OverviewPage-DjQETmb_.css} +1 -1
- package/dist/ui/assets/QueueDetailPage-DWsy5Yt8.js +1 -0
- package/dist/ui/assets/QueuesPage-BZJSqman.js +1 -0
- package/dist/ui/assets/SecretsPage-YC9ua54G.js +1 -0
- package/dist/ui/assets/ServiceDetailPage-Cum5frP4.js +2 -0
- package/dist/ui/assets/ServicesPage-IpaPDuqx.js +2 -0
- package/dist/ui/assets/SettingsPage-BiCRU8O6.js +1 -0
- package/dist/ui/assets/index-BDlrAJhi.css +1 -0
- package/dist/ui/assets/index-BouKSS43.js +38 -0
- package/dist/ui/assets/resourceIcons-DZs28nbs.js +1 -0
- package/dist/ui/index.html +5 -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/ServicesPage-2JuiIiRr.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/dist/ui/assets/resourceIcons-baecADXA.js +0 -1
|
@@ -22,7 +22,7 @@ const IGNORED_DIRS = new Set([
|
|
|
22
22
|
// Beyond this depth a hit is more likely a fixture than a service; the scan
|
|
23
23
|
// stays fast on monorepos either way.
|
|
24
24
|
const MAX_DEPTH = 6;
|
|
25
|
-
export function scanForServices(rootDir, registeredRoots) {
|
|
25
|
+
export function scanForServices(rootDir, registeredRoots, options = {}) {
|
|
26
26
|
const registered = new Set([...registeredRoots].map(root => path.resolve(root)));
|
|
27
27
|
const found = [];
|
|
28
28
|
walk(path.resolve(rootDir), 0);
|
|
@@ -38,7 +38,11 @@ export function scanForServices(rootDir, registeredRoots) {
|
|
|
38
38
|
}
|
|
39
39
|
const configFile = CONFIG_FILES.find(name => entries.some(e => e.isFile() && e.name === name));
|
|
40
40
|
if (configFile) {
|
|
41
|
-
|
|
41
|
+
// An ignored stack is still a leaf: it is a service, just not one this
|
|
42
|
+
// project registers locally, so descending into it would only surface
|
|
43
|
+
// its fixtures.
|
|
44
|
+
if (!options.isIgnored?.(dir))
|
|
45
|
+
found.push(inspect(dir, configFile));
|
|
42
46
|
// A service root is a leaf: nested serverless configs under one service
|
|
43
47
|
// are fixtures/templates, not independently registrable services.
|
|
44
48
|
return;
|
|
@@ -63,10 +67,15 @@ export function scanForServices(rootDir, registeredRoots) {
|
|
|
63
67
|
});
|
|
64
68
|
}
|
|
65
69
|
if (!packaged) {
|
|
66
|
-
warnings.push(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
warnings.push(options.autoPackage
|
|
71
|
+
? {
|
|
72
|
+
code: 'not-packaged',
|
|
73
|
+
message: 'not packaged yet — registration will package it (autoPackage)',
|
|
74
|
+
}
|
|
75
|
+
: {
|
|
76
|
+
code: 'not-packaged-manual',
|
|
77
|
+
message: 'not packaged yet — autoPackage is off, so run `serverless package` before registering',
|
|
78
|
+
});
|
|
70
79
|
}
|
|
71
80
|
return {
|
|
72
81
|
name: hints.name ?? path.basename(dir),
|
|
@@ -79,6 +88,7 @@ export function scanForServices(rootDir, registeredRoots) {
|
|
|
79
88
|
region: hints.region,
|
|
80
89
|
apiPort: hints.apiPort,
|
|
81
90
|
invokePort: hints.invokePort,
|
|
91
|
+
hasFunctions: hints.hasFunctions,
|
|
82
92
|
warnings,
|
|
83
93
|
};
|
|
84
94
|
}
|
|
@@ -139,6 +149,8 @@ function readHints(configPath, warnings) {
|
|
|
139
149
|
region: typeof parsed.provider?.region === 'string' ? parsed.provider.region : undefined,
|
|
140
150
|
apiPort: asPort(parsed.custom?.lss?.apiPort),
|
|
141
151
|
invokePort: asPort(parsed.custom?.lss?.invokePort),
|
|
152
|
+
// JSON leaves nothing to guess: the key is there with entries, or it is not.
|
|
153
|
+
hasFunctions: Object.keys((parsed.functions ?? {})).length > 0,
|
|
142
154
|
};
|
|
143
155
|
}
|
|
144
156
|
catch {
|
|
@@ -146,7 +158,7 @@ function readHints(configPath, warnings) {
|
|
|
146
158
|
return {};
|
|
147
159
|
}
|
|
148
160
|
}
|
|
149
|
-
const hints = {};
|
|
161
|
+
const hints = { hasFunctions: scrapeHasFunctions(raw) };
|
|
150
162
|
for (const line of raw.split('\n')) {
|
|
151
163
|
let match = /^service:\s*['"]?([\w-]+)['"]?\s*$/.exec(line);
|
|
152
164
|
if (match && !hints.name)
|
|
@@ -165,6 +177,40 @@ function readHints(configPath, warnings) {
|
|
|
165
177
|
}
|
|
166
178
|
return hints;
|
|
167
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* Does this serverless.yml declare any function?
|
|
182
|
+
*
|
|
183
|
+
* no `functions:` key at all → false (a resources-only stack)
|
|
184
|
+
* `functions:` + an indented key → true
|
|
185
|
+
* `functions: ${file(./fns.yml)}` → undefined — the value is resolved at
|
|
186
|
+
* packaging time, and claiming "no
|
|
187
|
+
* functions" for a service that has 23 is
|
|
188
|
+
* the failure this hint must never cause.
|
|
189
|
+
*
|
|
190
|
+
* Line-oriented like the rest of readHints: this informs a form field, and the
|
|
191
|
+
* packaged state is what registration actually reads.
|
|
192
|
+
*/
|
|
193
|
+
function scrapeHasFunctions(raw) {
|
|
194
|
+
const lines = raw.split('\n');
|
|
195
|
+
const index = lines.findIndex(line => /^functions:/.test(line));
|
|
196
|
+
if (index === -1)
|
|
197
|
+
return false;
|
|
198
|
+
const inline = lines[index].slice('functions:'.length).trim();
|
|
199
|
+
// Anything on the same line is a reference or an inline map — neither is a
|
|
200
|
+
// count this scrape can trust. `functions: {}` is the one honest exception.
|
|
201
|
+
if (inline)
|
|
202
|
+
return inline === '{}' ? false : undefined;
|
|
203
|
+
for (const line of lines.slice(index + 1)) {
|
|
204
|
+
if (!line.trim() || /^\s*#/.test(line))
|
|
205
|
+
continue;
|
|
206
|
+
// Dedented back to column 0: the block ended without an entry.
|
|
207
|
+
if (!/^\s/.test(line))
|
|
208
|
+
return false;
|
|
209
|
+
if (/^\s+[^\s#-][^:]*:/.test(line))
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
168
214
|
function asPort(value) {
|
|
169
215
|
return typeof value === 'number' && Number.isInteger(value) && value >= 1 && value <= 65535
|
|
170
216
|
? value
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-scanner.js","sourceRoot":"","sources":["../../../src/server/services/service-scanner.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,8EAA8E;AAC9E,gFAAgF;AAChF,6BAA6B;AAC7B,EAAE;AACF,uEAAuE;AACvE,+EAA+E;AAC/E,2EAA2E;AAC3E,+EAA+E;AAC/E,uCAAuC;AAEvC,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"service-scanner.js","sourceRoot":"","sources":["../../../src/server/services/service-scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,7 @@ export declare class SourceWatcher {
|
|
|
15
15
|
static getInstance(): SourceWatcher;
|
|
16
16
|
setHandlers(handlers: ReloadHandlers): void;
|
|
17
17
|
watch(serviceName: string, root: string): void;
|
|
18
|
+
private ownStatePaths;
|
|
18
19
|
unwatch(serviceName: string): void;
|
|
19
20
|
unwatchAll(): void;
|
|
20
21
|
getStatus(serviceName: string): WatchStatus;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-watcher.d.ts","sourceRoot":"","sources":["../../../src/server/services/source-watcher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"source-watcher.d.ts","sourceRoot":"","sources":["../../../src/server/services/source-watcher.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAeD,MAAM,WAAW,cAAc;IAE7B,eAAe,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAExD,YAAY,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD;AAMD,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAgB;IACvC,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,QAAQ,CAAC,CAAiB;IAElC,MAAM,CAAC,WAAW,IAAI,aAAa;IAOnC,WAAW,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAe3C,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IA4C9C,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAQlC,UAAU,IAAI,IAAI;IAMlB,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW;IAI3C,OAAO,CAAC,QAAQ;YAoBF,MAAM;CAiBrB"}
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
// need a re-package + re-registration, which the caller wires in.
|
|
5
5
|
import fs from 'fs';
|
|
6
6
|
import path from 'path';
|
|
7
|
+
import { ConfigManager } from './config-manager.js';
|
|
8
|
+
import { ignoredSubpaths, isIgnoredSubpath } from './worker-runtime.js';
|
|
7
9
|
const DEBOUNCE_MS = 500;
|
|
8
10
|
const IGNORED_SEGMENTS = new Set(['node_modules', '.serverless', '.esbuild', '.build', '.git', 'dist', '.lss']);
|
|
9
11
|
const FULL_RELOAD_FILES = new Set(['serverless.yml', 'serverless.yaml', 'serverless.json', 'package.json']);
|
|
@@ -34,6 +36,7 @@ export class SourceWatcher {
|
|
|
34
36
|
watch(serviceName, root) {
|
|
35
37
|
this.unwatch(serviceName);
|
|
36
38
|
const watchers = [];
|
|
39
|
+
const ignored = this.ownStatePaths(root);
|
|
37
40
|
const add = (dir, recursive, prefix) => {
|
|
38
41
|
const watcher = fs.watch(dir, { recursive }, (_event, filename) => {
|
|
39
42
|
const name = filename ? String(filename) : '';
|
|
@@ -48,12 +51,13 @@ export class SourceWatcher {
|
|
|
48
51
|
try {
|
|
49
52
|
add(root, false, '');
|
|
50
53
|
for (const entry of fs.readdirSync(root, { withFileTypes: true })) {
|
|
51
|
-
if (!entry.isDirectory() || IGNORED_SEGMENTS.has(entry.name))
|
|
54
|
+
if (!entry.isDirectory() || IGNORED_SEGMENTS.has(entry.name) || ignored.includes(entry.name))
|
|
52
55
|
continue;
|
|
53
56
|
add(path.join(root, entry.name), true, entry.name);
|
|
54
57
|
}
|
|
55
58
|
this.watched.set(serviceName, {
|
|
56
59
|
root,
|
|
60
|
+
ignored,
|
|
57
61
|
watchers,
|
|
58
62
|
pendingFullReload: false,
|
|
59
63
|
status: { watching: true },
|
|
@@ -66,6 +70,18 @@ export class SourceWatcher {
|
|
|
66
70
|
console.warn(`⚠️ Could not watch ${root}: ${err instanceof Error ? err.message : err}`);
|
|
67
71
|
}
|
|
68
72
|
}
|
|
73
|
+
// Directories LSS itself writes to while serving: the configured stateDir
|
|
74
|
+
// (which also holds the CLI's orchestrator.pid / orchestrator.log whenever a
|
|
75
|
+
// stateDir is set) and the engine's data dir (snapshots + WAL, written on
|
|
76
|
+
// every mutation). Placed inside a service — `"stateDir": ".lss-state"` in a
|
|
77
|
+
// single-service repo is the natural spelling — each write fired a reload,
|
|
78
|
+
// the reload's own activity wrote again, and the runtime restarted forever.
|
|
79
|
+
// Only paths inside the watched root matter; the default locations live
|
|
80
|
+
// under ~/.lss and the OS temp dir and are dropped by ignoredSubpaths().
|
|
81
|
+
ownStatePaths(root) {
|
|
82
|
+
const config = ConfigManager.getInstance();
|
|
83
|
+
return ignoredSubpaths(root, [config.getStateDir(), config.getSelfEngineConfig().dataDir]);
|
|
84
|
+
}
|
|
69
85
|
unwatch(serviceName) {
|
|
70
86
|
const watched = this.watched.get(serviceName);
|
|
71
87
|
if (!watched)
|
|
@@ -91,6 +107,8 @@ export class SourceWatcher {
|
|
|
91
107
|
const segments = filename.split(path.sep);
|
|
92
108
|
if (segments.some(s => IGNORED_SEGMENTS.has(s)))
|
|
93
109
|
return;
|
|
110
|
+
if (isIgnoredSubpath(filename, watched.ignored))
|
|
111
|
+
return;
|
|
94
112
|
if (FULL_RELOAD_FILES.has(path.basename(filename)) && segments.length === 1) {
|
|
95
113
|
watched.pendingFullReload = true;
|
|
96
114
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-watcher.js","sourceRoot":"","sources":["../../../src/server/services/source-watcher.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,0EAA0E;AAC1E,6EAA6E;AAC7E,kEAAkE;AAElE,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"source-watcher.js","sourceRoot":"","sources":["../../../src/server/services/source-watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export interface WorkerEnvOptions {
|
|
2
|
+
region: string;
|
|
3
|
+
engineEndpoint: string;
|
|
4
|
+
serviceRoot: string;
|
|
5
|
+
serviceEnv?: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The environment a forked runtime worker starts with.
|
|
9
|
+
*
|
|
10
|
+
* Every SDK client a handler creates without an explicit endpoint must land on
|
|
11
|
+
* the engine, not on AWS: `AWS_ENDPOINT_URL` is the variable AWS SDK v3 (and
|
|
12
|
+
* the CLI, boto3, SDK v2 >= 2.1580) reads for that — `AWS_ENDPOINT`, which
|
|
13
|
+
* many templates set, is only a convention that code has to read by hand.
|
|
14
|
+
* Credentials are the engine's dummy pair and the region is the service's.
|
|
15
|
+
*
|
|
16
|
+
* What the orchestrator inherited is the BASE, not the authority: a
|
|
17
|
+
* service-specific `AWS_ENDPOINT_URL_<SERVICE>` exported in the operator's
|
|
18
|
+
* shell would outrank the generic endpoint inside the SDK, so those are dropped
|
|
19
|
+
* too. A template or override that sets any of these explicitly still wins —
|
|
20
|
+
* `serviceEnv` here at fork, function env per invocation in the worker.
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildWorkerEnv(parentEnv: NodeJS.ProcessEnv, options: WorkerEnvOptions): NodeJS.ProcessEnv;
|
|
23
|
+
/**
|
|
24
|
+
* The env one invocation runs with. Precedence, lowest first: the template's
|
|
25
|
+
* function environment (provider + function level, already merged by the
|
|
26
|
+
* packager), then `serviceRuntime.<svc>.env`, then
|
|
27
|
+
* `serviceRuntime.<svc>.functions.<fn>.env` — the override closest to the
|
|
28
|
+
* function wins, the way a function-level `environment:` beats the provider's.
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveInvocationEnv(templateEnv: Record<string, string> | undefined, serviceEnv: Record<string, string> | undefined, functionEnv: Record<string, string> | undefined): Record<string, string>;
|
|
31
|
+
/**
|
|
32
|
+
* Every `node_modules` directory the service would resolve through, nearest
|
|
33
|
+
* first — its own, then each ancestor's (a workspace monorepo hoists most
|
|
34
|
+
* dependencies to the repo root, so the service's own dir is often partial or
|
|
35
|
+
* absent).
|
|
36
|
+
*/
|
|
37
|
+
export declare function ancestorNodeModules(serviceRoot: string): string[];
|
|
38
|
+
/**
|
|
39
|
+
* Make bare specifiers resolve from an artifact extracted OUTSIDE the service.
|
|
40
|
+
*
|
|
41
|
+
* The extraction lives under ~/.lss, so a bundle that keeps a package external
|
|
42
|
+
* (`import pg from 'pg'`) has no node_modules anywhere above it. CommonJS gets
|
|
43
|
+
* by on NODE_PATH; ESM does not — the ESM resolver ignores NODE_PATH entirely
|
|
44
|
+
* and only walks the importing file's parent directories. So the walk is given
|
|
45
|
+
* something to find: `<extractDir>/node_modules` links to the nearest
|
|
46
|
+
* node_modules of the service, and `<extractDir>/../node_modules` (the
|
|
47
|
+
* per-service directory that holds the content-addressed extractions) to the
|
|
48
|
+
* next one up — which covers the service's own dependencies plus a monorepo's
|
|
49
|
+
* hoisted root. Node resolves a package to its realpath, so the package's own
|
|
50
|
+
* imports then resolve from inside the service tree as usual.
|
|
51
|
+
*
|
|
52
|
+
* An artifact that ships its own node_modules (non-bundled packaging) is
|
|
53
|
+
* self-contained and left untouched. A link already pointing at the right
|
|
54
|
+
* place is kept; one pointing elsewhere (the service moved) is replaced.
|
|
55
|
+
* Linking is best effort: a filesystem that refuses links (some Windows setups)
|
|
56
|
+
* costs only the ESM externals, so it warns instead of failing the boot.
|
|
57
|
+
*
|
|
58
|
+
* Returns the links that now exist, as `[link, target]` pairs.
|
|
59
|
+
*/
|
|
60
|
+
export declare function linkArtifactNodeModules(extractDir: string, serviceRoot: string): Array<[string, string]>;
|
|
61
|
+
/** Null when `value` is an acceptable execArgv list, else the error message. */
|
|
62
|
+
export declare function execArgvError(key: string, value: unknown): string | null;
|
|
63
|
+
/**
|
|
64
|
+
* A warning when the functions declare a Node runtime (`nodejs20.x`) whose
|
|
65
|
+
* major differs from the Node the workers run on — handlers are executed by
|
|
66
|
+
* the orchestrator's own Node, so a template targeting 18 that leans on an API
|
|
67
|
+
* only 22 has (or the reverse) would pass locally and fail deployed. Null when
|
|
68
|
+
* every declared Node runtime matches, or none is a Node runtime at all.
|
|
69
|
+
*/
|
|
70
|
+
export declare function runtimeMismatchWarning(serviceName: string, runtimes: Array<string | undefined>, nodeVersion: string): string | null;
|
|
71
|
+
/**
|
|
72
|
+
* The paths among `candidates` that sit strictly INSIDE `root`, returned
|
|
73
|
+
* relative to it (platform separators) — the form the watcher's event
|
|
74
|
+
* filenames arrive in. Candidates outside the root, or equal to it, are
|
|
75
|
+
* dropped: ignoring the root itself would silently disable the watch. Both
|
|
76
|
+
* sides are realpath-resolved when they exist, so a symlinked checkout still
|
|
77
|
+
* matches.
|
|
78
|
+
*/
|
|
79
|
+
export declare function ignoredSubpaths(root: string, candidates: Array<string | undefined>): string[];
|
|
80
|
+
/** True when `filename` (relative to the watched root) is, or is under, one of `ignored`. */
|
|
81
|
+
export declare function isIgnoredSubpath(filename: string, ignored: string[]): boolean;
|
|
82
|
+
//# sourceMappingURL=worker-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-runtime.d.ts","sourceRoot":"","sources":["../../../src/server/services/worker-runtime.ts"],"names":[],"mappings":"AAqCA,MAAM,WAAW,gBAAgB;IAE/B,MAAM,EAAE,MAAM,CAAC;IAEf,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IAGpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,CAAC,UAAU,EAC5B,OAAO,EAAE,gBAAgB,GACxB,MAAM,CAAC,UAAU,CAoBnB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC/C,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC9C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAC9C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAExB;AAcD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAUjE;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAmCxG;AAyDD,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAoBxE;AAMD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,EACnC,WAAW,EAAE,MAAM,GAClB,MAAM,GAAG,IAAI,CAWf;AAcD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,EAAE,CAU7F;AAED,6FAA6F;AAC7F,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAE7E"}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
// Pure helpers behind the Lambda runtime worker's process setup: the env a
|
|
2
|
+
// forked worker starts with, the per-invocation env merge, the node_modules
|
|
3
|
+
// links that let an extracted artifact resolve bare ESM specifiers, the
|
|
4
|
+
// execArgv fence for the config API, the `runtime` vs Node major check, and
|
|
5
|
+
// the paths the source watcher must never react to.
|
|
6
|
+
//
|
|
7
|
+
// Split out of LambdaRuntimeManager / SourceWatcher (both integration-only:
|
|
8
|
+
// they fork processes and drive fs.watch) so every rule here is unit-tested.
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Worker environment
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Credential and profile variables the ORCHESTRATOR may carry from the
|
|
15
|
+
// operator's shell. A forked worker must never inherit them: a handler with
|
|
16
|
+
// the developer's real session token, pointed at an endpoint it did not
|
|
17
|
+
// expect, is how local code ends up writing to a real account. The AWS SDK
|
|
18
|
+
// credential chain reads env credentials first, then the profile — so the
|
|
19
|
+
// session token (which would be paired with the dummy key below and rejected,
|
|
20
|
+
// or worse, accepted) and the profile selectors all go.
|
|
21
|
+
const INHERITED_AWS_VARS_TO_DROP = [
|
|
22
|
+
'AWS_SESSION_TOKEN',
|
|
23
|
+
'AWS_SECURITY_TOKEN',
|
|
24
|
+
'AWS_PROFILE',
|
|
25
|
+
'AWS_DEFAULT_PROFILE',
|
|
26
|
+
'AWS_ROLE_ARN',
|
|
27
|
+
'AWS_ROLE_SESSION_NAME',
|
|
28
|
+
'AWS_WEB_IDENTITY_TOKEN_FILE',
|
|
29
|
+
'AWS_CREDENTIAL_EXPIRATION',
|
|
30
|
+
'AWS_CONTAINER_CREDENTIALS_RELATIVE_URI',
|
|
31
|
+
'AWS_CONTAINER_CREDENTIALS_FULL_URI',
|
|
32
|
+
'AWS_CONTAINER_AUTHORIZATION_TOKEN',
|
|
33
|
+
];
|
|
34
|
+
/**
|
|
35
|
+
* The environment a forked runtime worker starts with.
|
|
36
|
+
*
|
|
37
|
+
* Every SDK client a handler creates without an explicit endpoint must land on
|
|
38
|
+
* the engine, not on AWS: `AWS_ENDPOINT_URL` is the variable AWS SDK v3 (and
|
|
39
|
+
* the CLI, boto3, SDK v2 >= 2.1580) reads for that — `AWS_ENDPOINT`, which
|
|
40
|
+
* many templates set, is only a convention that code has to read by hand.
|
|
41
|
+
* Credentials are the engine's dummy pair and the region is the service's.
|
|
42
|
+
*
|
|
43
|
+
* What the orchestrator inherited is the BASE, not the authority: a
|
|
44
|
+
* service-specific `AWS_ENDPOINT_URL_<SERVICE>` exported in the operator's
|
|
45
|
+
* shell would outrank the generic endpoint inside the SDK, so those are dropped
|
|
46
|
+
* too. A template or override that sets any of these explicitly still wins —
|
|
47
|
+
* `serviceEnv` here at fork, function env per invocation in the worker.
|
|
48
|
+
*/
|
|
49
|
+
export function buildWorkerEnv(parentEnv, options) {
|
|
50
|
+
const env = { ...parentEnv };
|
|
51
|
+
for (const key of INHERITED_AWS_VARS_TO_DROP)
|
|
52
|
+
delete env[key];
|
|
53
|
+
for (const key of Object.keys(env)) {
|
|
54
|
+
if (key.startsWith('AWS_ENDPOINT_URL_'))
|
|
55
|
+
delete env[key];
|
|
56
|
+
}
|
|
57
|
+
Object.assign(env, {
|
|
58
|
+
AWS_ENDPOINT_URL: options.engineEndpoint,
|
|
59
|
+
AWS_ACCESS_KEY_ID: 'test',
|
|
60
|
+
AWS_SECRET_ACCESS_KEY: 'test',
|
|
61
|
+
AWS_REGION: options.region,
|
|
62
|
+
AWS_DEFAULT_REGION: options.region,
|
|
63
|
+
// Bundled artifacts with externalized deps still resolve against the
|
|
64
|
+
// service's own node_modules — for CommonJS. ESM ignores NODE_PATH; see
|
|
65
|
+
// linkArtifactNodeModules() for that half.
|
|
66
|
+
NODE_PATH: [path.join(options.serviceRoot, 'node_modules'), parentEnv.NODE_PATH || '']
|
|
67
|
+
.filter(Boolean)
|
|
68
|
+
.join(path.delimiter),
|
|
69
|
+
});
|
|
70
|
+
return { ...env, ...(options.serviceEnv ?? {}) };
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The env one invocation runs with. Precedence, lowest first: the template's
|
|
74
|
+
* function environment (provider + function level, already merged by the
|
|
75
|
+
* packager), then `serviceRuntime.<svc>.env`, then
|
|
76
|
+
* `serviceRuntime.<svc>.functions.<fn>.env` — the override closest to the
|
|
77
|
+
* function wins, the way a function-level `environment:` beats the provider's.
|
|
78
|
+
*/
|
|
79
|
+
export function resolveInvocationEnv(templateEnv, serviceEnv, functionEnv) {
|
|
80
|
+
return { ...(templateEnv ?? {}), ...(serviceEnv ?? {}), ...(functionEnv ?? {}) };
|
|
81
|
+
}
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// Artifact node_modules
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
function isDirectory(target) {
|
|
86
|
+
try {
|
|
87
|
+
return fs.statSync(target).isDirectory();
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Every `node_modules` directory the service would resolve through, nearest
|
|
95
|
+
* first — its own, then each ancestor's (a workspace monorepo hoists most
|
|
96
|
+
* dependencies to the repo root, so the service's own dir is often partial or
|
|
97
|
+
* absent).
|
|
98
|
+
*/
|
|
99
|
+
export function ancestorNodeModules(serviceRoot) {
|
|
100
|
+
const found = [];
|
|
101
|
+
let dir = path.resolve(serviceRoot);
|
|
102
|
+
for (;;) {
|
|
103
|
+
const candidate = path.join(dir, 'node_modules');
|
|
104
|
+
if (isDirectory(candidate))
|
|
105
|
+
found.push(candidate);
|
|
106
|
+
const parent = path.dirname(dir);
|
|
107
|
+
if (parent === dir)
|
|
108
|
+
return found;
|
|
109
|
+
dir = parent;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Make bare specifiers resolve from an artifact extracted OUTSIDE the service.
|
|
114
|
+
*
|
|
115
|
+
* The extraction lives under ~/.lss, so a bundle that keeps a package external
|
|
116
|
+
* (`import pg from 'pg'`) has no node_modules anywhere above it. CommonJS gets
|
|
117
|
+
* by on NODE_PATH; ESM does not — the ESM resolver ignores NODE_PATH entirely
|
|
118
|
+
* and only walks the importing file's parent directories. So the walk is given
|
|
119
|
+
* something to find: `<extractDir>/node_modules` links to the nearest
|
|
120
|
+
* node_modules of the service, and `<extractDir>/../node_modules` (the
|
|
121
|
+
* per-service directory that holds the content-addressed extractions) to the
|
|
122
|
+
* next one up — which covers the service's own dependencies plus a monorepo's
|
|
123
|
+
* hoisted root. Node resolves a package to its realpath, so the package's own
|
|
124
|
+
* imports then resolve from inside the service tree as usual.
|
|
125
|
+
*
|
|
126
|
+
* An artifact that ships its own node_modules (non-bundled packaging) is
|
|
127
|
+
* self-contained and left untouched. A link already pointing at the right
|
|
128
|
+
* place is kept; one pointing elsewhere (the service moved) is replaced.
|
|
129
|
+
* Linking is best effort: a filesystem that refuses links (some Windows setups)
|
|
130
|
+
* costs only the ESM externals, so it warns instead of failing the boot.
|
|
131
|
+
*
|
|
132
|
+
* Returns the links that now exist, as `[link, target]` pairs.
|
|
133
|
+
*/
|
|
134
|
+
export function linkArtifactNodeModules(extractDir, serviceRoot) {
|
|
135
|
+
const own = path.join(extractDir, 'node_modules');
|
|
136
|
+
const ownStat = lstatOrNull(own);
|
|
137
|
+
if (ownStat && !ownStat.isSymbolicLink())
|
|
138
|
+
return [];
|
|
139
|
+
const targets = ancestorNodeModules(serviceRoot);
|
|
140
|
+
const slots = [extractDir, path.dirname(extractDir)];
|
|
141
|
+
const links = [];
|
|
142
|
+
slots.forEach((slot, index) => {
|
|
143
|
+
const target = targets[index];
|
|
144
|
+
if (!target)
|
|
145
|
+
return;
|
|
146
|
+
const link = path.join(slot, 'node_modules');
|
|
147
|
+
try {
|
|
148
|
+
const existing = lstatOrNull(link);
|
|
149
|
+
if (existing) {
|
|
150
|
+
// Anything that is not one of our links is someone else's directory.
|
|
151
|
+
if (!existing.isSymbolicLink())
|
|
152
|
+
return;
|
|
153
|
+
if (fs.readlinkSync(link) === target) {
|
|
154
|
+
links.push([link, target]);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
fs.unlinkSync(link);
|
|
158
|
+
}
|
|
159
|
+
// 'junction' makes the call succeed on Windows without the symlink
|
|
160
|
+
// privilege; it is ignored everywhere else.
|
|
161
|
+
fs.symlinkSync(target, link, 'junction');
|
|
162
|
+
links.push([link, target]);
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
console.warn(`⚠️ Could not link ${link} -> ${target}: ${err instanceof Error ? err.message : String(err)} ` +
|
|
166
|
+
'(ESM imports of external packages from the artifact will not resolve)');
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
return links;
|
|
170
|
+
}
|
|
171
|
+
function lstatOrNull(target) {
|
|
172
|
+
try {
|
|
173
|
+
return fs.lstatSync(target);
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
// execArgv fence
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
// Node flags a worker may be forked with when the value arrives through
|
|
183
|
+
// PUT /api/config. That endpoint is unauthenticated and execArgv reaches
|
|
184
|
+
// fork() verbatim, so an open list would be code execution one flag away
|
|
185
|
+
// (`--import data:…`, `--require /tmp/x.js`, `--loader`, `--eval`). An
|
|
186
|
+
// allowlist rather than a blocklist, because node grows new code-loading flags
|
|
187
|
+
// and a blocklist silently goes stale. The set is what a developer actually
|
|
188
|
+
// reaches for: a debugger, source maps, heap/stack sizing, diagnostics.
|
|
189
|
+
//
|
|
190
|
+
// Like every other fence in config-manager.ts this guards the API only — a
|
|
191
|
+
// hand-edited lss.config.json is the operator's own shell and is read as is.
|
|
192
|
+
const EXEC_ARGV_BARE_FLAGS = new Set([
|
|
193
|
+
'--enable-source-maps',
|
|
194
|
+
'--trace-warnings',
|
|
195
|
+
'--trace-deprecation',
|
|
196
|
+
'--trace-uncaught',
|
|
197
|
+
'--no-warnings',
|
|
198
|
+
'--no-deprecation',
|
|
199
|
+
'--expose-gc',
|
|
200
|
+
'--experimental-strip-types',
|
|
201
|
+
'--no-experimental-strip-types',
|
|
202
|
+
'--experimental-transform-types',
|
|
203
|
+
'--experimental-vm-modules',
|
|
204
|
+
'--experimental-require-module',
|
|
205
|
+
'--inspect',
|
|
206
|
+
'--inspect-brk',
|
|
207
|
+
'--inspect-wait',
|
|
208
|
+
]);
|
|
209
|
+
const EXEC_ARGV_NUMERIC_FLAGS = new Set([
|
|
210
|
+
'--max-old-space-size',
|
|
211
|
+
'--max-semi-space-size',
|
|
212
|
+
'--stack-size',
|
|
213
|
+
'--stack-trace-limit',
|
|
214
|
+
]);
|
|
215
|
+
const INSPECT_FLAGS = new Set(['--inspect', '--inspect-brk', '--inspect-wait', '--inspect-port']);
|
|
216
|
+
const UNHANDLED_REJECTION_MODES = new Set(['throw', 'strict', 'warn', 'none', 'warn-with-error-code']);
|
|
217
|
+
// A debugger is remote code execution for whoever can reach its port, so the
|
|
218
|
+
// inspector may only bind the loopback: `--inspect=9230`,
|
|
219
|
+
// `--inspect=127.0.0.1:9230`, `--inspect=localhost:9230`, `--inspect=[::1]:9230`.
|
|
220
|
+
const LOOPBACK_INSPECT_VALUE = /^(?:(?:127\.0\.0\.1|localhost|\[::1\]):)?\d{1,5}$/;
|
|
221
|
+
/** Null when `value` is an acceptable execArgv list, else the error message. */
|
|
222
|
+
export function execArgvError(key, value) {
|
|
223
|
+
if (!Array.isArray(value) || !value.every(v => typeof v === 'string')) {
|
|
224
|
+
return `"${key}" must be an array of strings`;
|
|
225
|
+
}
|
|
226
|
+
for (const [index, flag] of value.entries()) {
|
|
227
|
+
const eq = flag.indexOf('=');
|
|
228
|
+
const name = eq === -1 ? flag : flag.slice(0, eq);
|
|
229
|
+
const arg = eq === -1 ? undefined : flag.slice(eq + 1);
|
|
230
|
+
const ok = arg === undefined
|
|
231
|
+
? EXEC_ARGV_BARE_FLAGS.has(name)
|
|
232
|
+
: (INSPECT_FLAGS.has(name) && LOOPBACK_INSPECT_VALUE.test(arg))
|
|
233
|
+
|| (EXEC_ARGV_NUMERIC_FLAGS.has(name) && /^\d+$/.test(arg))
|
|
234
|
+
|| (name === '--unhandled-rejections' && UNHANDLED_REJECTION_MODES.has(arg));
|
|
235
|
+
if (!ok) {
|
|
236
|
+
return `"${key}[${index}]": "${flag}" is not an allowed worker flag — through the config API execArgv accepts ` +
|
|
237
|
+
'only debugger (loopback), source-map, memory/stack sizing and diagnostic flags; ' +
|
|
238
|
+
'set anything else by editing lss.config.json';
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
// ---------------------------------------------------------------------------
|
|
244
|
+
// runtime vs Node major
|
|
245
|
+
// ---------------------------------------------------------------------------
|
|
246
|
+
/**
|
|
247
|
+
* A warning when the functions declare a Node runtime (`nodejs20.x`) whose
|
|
248
|
+
* major differs from the Node the workers run on — handlers are executed by
|
|
249
|
+
* the orchestrator's own Node, so a template targeting 18 that leans on an API
|
|
250
|
+
* only 22 has (or the reverse) would pass locally and fail deployed. Null when
|
|
251
|
+
* every declared Node runtime matches, or none is a Node runtime at all.
|
|
252
|
+
*/
|
|
253
|
+
export function runtimeMismatchWarning(serviceName, runtimes, nodeVersion) {
|
|
254
|
+
const workerMajor = Number(nodeVersion.replace(/^v/, '').split('.')[0]);
|
|
255
|
+
const declared = new Set();
|
|
256
|
+
for (const runtime of runtimes) {
|
|
257
|
+
const match = /^nodejs(\d+)\.x$/.exec(runtime ?? '');
|
|
258
|
+
if (match)
|
|
259
|
+
declared.add(Number(match[1]));
|
|
260
|
+
}
|
|
261
|
+
const mismatched = [...declared].filter(major => major !== workerMajor).sort((a, b) => a - b);
|
|
262
|
+
if (mismatched.length === 0)
|
|
263
|
+
return null;
|
|
264
|
+
return `⚠️ "${serviceName}" declares ${mismatched.map(m => `nodejs${m}.x`).join(', ')} but its Lambda workers ` +
|
|
265
|
+
`run on Node ${workerMajor} (the orchestrator's) — behaviour that differs between the two majors will not show up locally`;
|
|
266
|
+
}
|
|
267
|
+
// ---------------------------------------------------------------------------
|
|
268
|
+
// Watcher exclusions
|
|
269
|
+
// ---------------------------------------------------------------------------
|
|
270
|
+
function realpathOrSelf(target) {
|
|
271
|
+
try {
|
|
272
|
+
return fs.realpathSync(target);
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
return target;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* The paths among `candidates` that sit strictly INSIDE `root`, returned
|
|
280
|
+
* relative to it (platform separators) — the form the watcher's event
|
|
281
|
+
* filenames arrive in. Candidates outside the root, or equal to it, are
|
|
282
|
+
* dropped: ignoring the root itself would silently disable the watch. Both
|
|
283
|
+
* sides are realpath-resolved when they exist, so a symlinked checkout still
|
|
284
|
+
* matches.
|
|
285
|
+
*/
|
|
286
|
+
export function ignoredSubpaths(root, candidates) {
|
|
287
|
+
const realRoot = realpathOrSelf(path.resolve(root));
|
|
288
|
+
const result = new Set();
|
|
289
|
+
for (const candidate of candidates) {
|
|
290
|
+
if (!candidate)
|
|
291
|
+
continue;
|
|
292
|
+
const relative = path.relative(realRoot, realpathOrSelf(path.resolve(candidate)));
|
|
293
|
+
if (!relative || relative.startsWith('..') || path.isAbsolute(relative))
|
|
294
|
+
continue;
|
|
295
|
+
result.add(relative);
|
|
296
|
+
}
|
|
297
|
+
return [...result];
|
|
298
|
+
}
|
|
299
|
+
/** True when `filename` (relative to the watched root) is, or is under, one of `ignored`. */
|
|
300
|
+
export function isIgnoredSubpath(filename, ignored) {
|
|
301
|
+
return ignored.some(rel => filename === rel || filename.startsWith(rel + path.sep));
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=worker-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-runtime.js","sourceRoot":"","sources":["../../../src/server/services/worker-runtime.ts"],"names":[],"mappings":"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"}
|