run402 4.83.0 → 4.84.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/gitvault-surface.json +1 -1
- package/lib/deploy-v2.mjs +30 -68
- package/lib/doctor-source-scan.mjs +2 -547
- package/lib/doctor.mjs +28 -8
- package/lib/sdk-errors.mjs +7 -0
- package/lib/status.mjs +1 -1
- package/lib/up.mjs +27 -10
- package/lib/update-check.mjs +11 -6
- package/lib/update-check.test.mjs +18 -5
- package/package.json +1 -1
- package/sdk/dist/actions.d.ts +16 -3
- package/sdk/dist/actions.d.ts.map +1 -1
- package/sdk/dist/config.d.ts +1 -1
- package/sdk/dist/config.d.ts.map +1 -1
- package/sdk/dist/config.js.map +1 -1
- package/sdk/dist/index.d.ts +2 -0
- package/sdk/dist/index.d.ts.map +1 -1
- package/sdk/dist/index.js +2 -0
- package/sdk/dist/index.js.map +1 -1
- package/sdk/dist/namespaces/deploy.d.ts.map +1 -1
- package/sdk/dist/namespaces/deploy.js +2 -1
- package/sdk/dist/namespaces/deploy.js.map +1 -1
- package/sdk/dist/namespaces/deploy.types.d.ts +6 -0
- package/sdk/dist/namespaces/deploy.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/edge-evidence.d.ts +22 -0
- package/sdk/dist/namespaces/edge-evidence.d.ts.map +1 -0
- package/sdk/dist/namespaces/edge-evidence.js +38 -0
- package/sdk/dist/namespaces/edge-evidence.js.map +1 -0
- package/sdk/dist/namespaces/projects.d.ts.map +1 -1
- package/sdk/dist/namespaces/projects.js +9 -7
- package/sdk/dist/namespaces/projects.js.map +1 -1
- package/sdk/dist/node/actions-node.d.ts.map +1 -1
- package/sdk/dist/node/actions-node.js +71 -57
- package/sdk/dist/node/actions-node.js.map +1 -1
- package/sdk/dist/node/app-scope.d.ts +24 -0
- package/sdk/dist/node/app-scope.d.ts.map +1 -0
- package/sdk/dist/node/app-scope.js +47 -0
- package/sdk/dist/node/app-scope.js.map +1 -0
- package/sdk/dist/node/deploy-manifest.d.ts +6 -0
- package/sdk/dist/node/deploy-manifest.d.ts.map +1 -1
- package/sdk/dist/node/deploy-manifest.js +61 -0
- package/sdk/dist/node/deploy-manifest.js.map +1 -1
- package/sdk/dist/node/index.d.ts +5 -0
- package/sdk/dist/node/index.d.ts.map +1 -1
- package/sdk/dist/node/index.js +5 -0
- package/sdk/dist/node/index.js.map +1 -1
- package/sdk/dist/node/manifest-export.d.ts +5 -0
- package/sdk/dist/node/manifest-export.d.ts.map +1 -0
- package/sdk/dist/node/manifest-export.js +78 -0
- package/sdk/dist/node/manifest-export.js.map +1 -0
- package/sdk/dist/node/preflight.d.ts +65 -0
- package/sdk/dist/node/preflight.d.ts.map +1 -0
- package/sdk/dist/node/preflight.js +23 -0
- package/sdk/dist/node/preflight.js.map +1 -0
- package/sdk/dist/node/source-scan.d.ts +73 -0
- package/sdk/dist/node/source-scan.d.ts.map +1 -0
- package/sdk/dist/node/source-scan.js +552 -0
- package/sdk/dist/node/source-scan.js.map +1 -0
- package/sdk/dist/rest-diagnostics.d.ts +15 -0
- package/sdk/dist/rest-diagnostics.d.ts.map +1 -0
- package/sdk/dist/rest-diagnostics.js +19 -0
- package/sdk/dist/rest-diagnostics.js.map +1 -0
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { serializeDeployManifest, manifestExportUnsupported } from "./manifest-export.js";
|
|
2
|
+
import { describeLocalPreflight } from "./preflight.js";
|
|
3
|
+
import { resolveApplicationScope, materializeTemplates } from "./app-scope.js";
|
|
4
|
+
import { scanDeploymentSources } from "./source-scan.js";
|
|
1
5
|
import { createHash } from "node:crypto";
|
|
2
6
|
import { execFile } from "node:child_process";
|
|
3
7
|
import { lstat, mkdir, mkdtemp, readdir, readFile, rename, rm, writeFile, } from "node:fs/promises";
|
|
@@ -194,15 +198,20 @@ export class NodeActions {
|
|
|
194
198
|
let workspaceDir = source.workspaceDir;
|
|
195
199
|
const manifest = await this.#discoverAndValidateManifest(input, workspaceDir, source.metadata, run);
|
|
196
200
|
workspaceDir = dirname(manifest.manifestPath);
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
201
|
+
const target = !input.verifyOnly ? await resolveDeploymentTarget({
|
|
202
|
+
appRoot: workspaceDir, manifestPath: manifest.manifestPath, projectId: input.projectId,
|
|
203
|
+
manifestProjectId: manifest.manifestProjectId ?? manifest.appSpec?.project.id, name: input.name,
|
|
204
|
+
targetKind: this.#targetKind(), apiBase: this.sdk.apiBase,
|
|
205
|
+
allowUnresolved: run.executionMode === "check" || (run.executionMode === "printSpec" || run.executionMode === "printManifest") || run.dryRun,
|
|
206
|
+
}) : null;
|
|
207
|
+
if (!input.verifyOnly && process.env.RUN402_DEPLOY_SKIP_SCAN !== "1") {
|
|
208
|
+
const scan = scanDeploymentSources(manifest.releaseSpec ?? {}, workspaceDir);
|
|
209
|
+
if (scan.errors.length)
|
|
210
|
+
throw run.error("Source scan blocked this application.", "R402_AUTH_PREFLIGHT_FAILED", scan);
|
|
204
211
|
}
|
|
205
212
|
if (manifest.manifestKind === "app") {
|
|
213
|
+
if (run.executionMode === "printManifest")
|
|
214
|
+
manifestExportUnsupported("app", "app resources and build intent cannot be faithfully represented as a release manifest");
|
|
206
215
|
if (input.verifyOnly) {
|
|
207
216
|
return this.#verifyAppManifestOnly(input, manifest, workspaceDir, run, startedAt);
|
|
208
217
|
}
|
|
@@ -211,22 +220,23 @@ export class NodeActions {
|
|
|
211
220
|
startedAt,
|
|
212
221
|
status: block ? "blocked" : "planned",
|
|
213
222
|
dryRun: run.dryRun || run.executionMode === "check" || run.executionMode === "printSpec",
|
|
214
|
-
projectId:
|
|
223
|
+
projectId: target?.project_id ?? null,
|
|
215
224
|
diagnostics: block?.diagnostics,
|
|
216
225
|
nextActions: block?.nextActions,
|
|
217
226
|
blockedNodeId: block?.nodeId,
|
|
218
227
|
});
|
|
219
228
|
if (run.executionMode === "check" || run.executionMode === "printSpec" || run.dryRun) {
|
|
220
229
|
return run.result({
|
|
221
|
-
project_id:
|
|
230
|
+
project_id: target?.project_id ?? null,
|
|
222
231
|
manifest_path: manifest.manifestPath,
|
|
223
232
|
app_graph: manifest.appGraph,
|
|
224
233
|
app_result: appResult,
|
|
234
|
+
preflight: describeLocalPreflight({ appRoot: workspaceDir, manifestPath: manifest.manifestPath, target: target, authoring: manifest.appSpec?.release, spec: manifest.releaseSpec ?? undefined, buildDeferred: !!manifest.appSpec?.build?.commands?.length, apiBase: this.sdk.apiBase, profile: this.opts.profile }),
|
|
225
235
|
});
|
|
226
236
|
}
|
|
227
237
|
if (block) {
|
|
228
238
|
return run.result({
|
|
229
|
-
project_id:
|
|
239
|
+
project_id: target?.project_id ?? null,
|
|
230
240
|
manifest_path: manifest.manifestPath,
|
|
231
241
|
app_graph: manifest.appGraph,
|
|
232
242
|
app_result: appResult,
|
|
@@ -237,14 +247,16 @@ export class NodeActions {
|
|
|
237
247
|
if (input.verifyOnly) {
|
|
238
248
|
return this.#verifyDeployManifestOnly(input, manifest, workspaceDir, run);
|
|
239
249
|
}
|
|
240
|
-
if (run.executionMode === "check" || run.executionMode === "printSpec") {
|
|
250
|
+
if (run.executionMode === "check" || (run.executionMode === "printSpec" || run.executionMode === "printManifest")) {
|
|
241
251
|
if (!manifest.releaseSpec) {
|
|
242
252
|
throw run.error("Internal error: release manifest did not produce a ReleaseSpec.", "RUN402_ACTION_INTERNAL");
|
|
243
253
|
}
|
|
244
254
|
return run.result({
|
|
245
|
-
project_id:
|
|
255
|
+
project_id: target?.project_id ?? null,
|
|
246
256
|
manifest_path: manifest.manifestPath,
|
|
247
|
-
|
|
257
|
+
preflight: describeLocalPreflight({ appRoot: workspaceDir, manifestPath: manifest.manifestPath, target: target, authoring: manifest.loaded?.manifest, spec: manifest.releaseSpec, apiBase: this.sdk.apiBase, profile: this.opts.profile }),
|
|
258
|
+
...(run.executionMode === "printManifest" ? { manifest: serializeDeployManifest(manifest.loaded, workspaceDir, input.projectId) } : {}),
|
|
259
|
+
...(run.executionMode === "printSpec" ? { spec: { ...manifest.releaseSpec, project: target?.project_id ?? undefined } } : {}),
|
|
248
260
|
});
|
|
249
261
|
}
|
|
250
262
|
if (run.executionMode === "plan") {
|
|
@@ -292,14 +304,14 @@ export class NodeActions {
|
|
|
292
304
|
mutation: run.executionMode !== "plan",
|
|
293
305
|
auto: false,
|
|
294
306
|
details: {
|
|
295
|
-
project_id: resolved.projectId,
|
|
307
|
+
project_id: resolved.projectId === "prj_planned" ? null : resolved.projectId,
|
|
296
308
|
manifest_path: manifest.manifestPath,
|
|
297
309
|
},
|
|
298
310
|
});
|
|
299
311
|
if (run.dryRun) {
|
|
300
312
|
run.setState(deployStep, "planned");
|
|
301
313
|
return run.result({
|
|
302
|
-
project_id: resolved.projectId,
|
|
314
|
+
project_id: resolved.projectId === "prj_planned" ? null : resolved.projectId,
|
|
303
315
|
manifest_path: manifest.manifestPath,
|
|
304
316
|
...(resolved.shouldWriteLink ? { workspace_link_path: resolved.linkPath } : {}),
|
|
305
317
|
});
|
|
@@ -410,7 +422,7 @@ export class NodeActions {
|
|
|
410
422
|
* principal has a display name before the deploy that will be credited to
|
|
411
423
|
* it, then join the project's room under that name. Explicit
|
|
412
424
|
* `identityName` / `RUN402_AGENT_NAME` wins and may rename an already-named
|
|
413
|
-
* principal;
|
|
425
|
+
* agent principal; human and unknown principals are preserved. Otherwise a detected client name is set only when no name
|
|
414
426
|
* exists yet, and reported as `detected`. The detected client is always
|
|
415
427
|
* reported (`detected` + `detection`), even when it was not applied, so an
|
|
416
428
|
* agent whose principal is already named sees why. Best-effort end to
|
|
@@ -421,15 +433,23 @@ export class NodeActions {
|
|
|
421
433
|
if (this.#targetKind() === "core") {
|
|
422
434
|
return { display_name: null, source: "unavailable" };
|
|
423
435
|
}
|
|
436
|
+
const explicitName = input.identityName?.trim() || declaredAgentName() || null;
|
|
437
|
+
const detectedName = detectClientName();
|
|
424
438
|
let current = null;
|
|
439
|
+
let principalId = null;
|
|
440
|
+
let principalType = null;
|
|
425
441
|
try {
|
|
426
442
|
const me = await this.sdk.orgs.whoami();
|
|
443
|
+
principalId = me.principal?.id ?? null;
|
|
444
|
+
principalType = me.principal?.type ?? null;
|
|
427
445
|
// The gateway never seeds display_name from a wallet subject (and
|
|
428
446
|
// nulled the ones it once did), so null here means exactly "unset".
|
|
429
447
|
current = me.principal?.display_name ?? null;
|
|
430
448
|
}
|
|
431
449
|
catch {
|
|
432
|
-
return { display_name: null, source: "unavailable"
|
|
450
|
+
return { display_name: null, source: "unavailable", detected: detectedName,
|
|
451
|
+
principal: { id: null, type: null, display_name: null },
|
|
452
|
+
client: { detected: detectedName, declared_name: explicitName } };
|
|
433
453
|
}
|
|
434
454
|
let displayName = current;
|
|
435
455
|
let source = "existing";
|
|
@@ -437,8 +457,13 @@ export class NodeActions {
|
|
|
437
457
|
// (RUN402_AGENT_NAME), then a specifically detected client. A generic
|
|
438
458
|
// guess is never persisted as a name. Detection always runs so the
|
|
439
459
|
// result can say what was seen even when it was not applied.
|
|
440
|
-
|
|
441
|
-
|
|
460
|
+
if (principalType !== "agent") {
|
|
461
|
+
run.skipStep({ action: "identity.name.set", description: "Preserve authenticated human or unknown principal identity; client detection does not rename it.", mutation: false, auto: true, details: { principal_type: principalType } });
|
|
462
|
+
return { display_name: current, source: "existing",
|
|
463
|
+
principal: { id: principalId, type: principalType, display_name: current },
|
|
464
|
+
client: { detected: detectedName, declared_name: explicitName },
|
|
465
|
+
detected: detectedName, detection: { applied: false, reason: "principal_identity_preserved" } };
|
|
466
|
+
}
|
|
442
467
|
const detectionReport = (applied) => {
|
|
443
468
|
const reason = applied
|
|
444
469
|
? "applied"
|
|
@@ -447,7 +472,9 @@ export class NodeActions {
|
|
|
447
472
|
: explicitName
|
|
448
473
|
? "explicit_name_wins"
|
|
449
474
|
: "name_already_set";
|
|
450
|
-
return { detected: detectedName, detection: { applied, reason }
|
|
475
|
+
return { detected: detectedName, detection: { applied, reason },
|
|
476
|
+
principal: { id: principalId, type: principalType, display_name: displayName },
|
|
477
|
+
client: { detected: detectedName, declared_name: explicitName } };
|
|
451
478
|
};
|
|
452
479
|
if (!displayName || (explicitName && explicitName !== displayName)) {
|
|
453
480
|
const desired = explicitName ?? detectedName;
|
|
@@ -693,9 +720,7 @@ export class NodeActions {
|
|
|
693
720
|
// output-dir field to narrow by), so the pre-build check is skipped
|
|
694
721
|
// then and the post-build normalization performs it instead.
|
|
695
722
|
const buildProducesFiles = (appSpec.build?.commands ?? []).length > 0;
|
|
696
|
-
|
|
697
|
-
await this.#assertAppReleaseFileReferences(appSpec, manifestPath, run);
|
|
698
|
-
}
|
|
723
|
+
const checkedRelease = !buildProducesFiles ? await this.#assertAppReleaseFileReferences(appSpec, manifestPath, run) : undefined;
|
|
699
724
|
run.setState(step, "succeeded", {
|
|
700
725
|
manifest_kind: "app",
|
|
701
726
|
manifest_path: manifestPath,
|
|
@@ -707,16 +732,17 @@ export class NodeActions {
|
|
|
707
732
|
manifestKind: "app",
|
|
708
733
|
manifestProjectId: appSpec.project.id,
|
|
709
734
|
manifestPath,
|
|
710
|
-
releaseSpec: null,
|
|
735
|
+
releaseSpec: checkedRelease ?? null,
|
|
711
736
|
appGraph,
|
|
712
737
|
appSpec,
|
|
713
738
|
source,
|
|
714
739
|
};
|
|
715
740
|
}
|
|
716
741
|
}
|
|
717
|
-
const loaded = await loadDeployManifest(manifestPath, {
|
|
742
|
+
const loaded = await this.#normalizeWithTypedFileErrors(() => loadDeployManifest(manifestPath, {
|
|
718
743
|
defaultProject: "prj_up_preflight_placeholder",
|
|
719
|
-
|
|
744
|
+
validateFiles: true,
|
|
745
|
+
}), run);
|
|
720
746
|
if (!hasDeployableContent(loaded.spec)) {
|
|
721
747
|
throw run.error("Deploy manifest contains no deployable sections.", "MANIFEST_EMPTY", { manifest_path: manifestPath });
|
|
722
748
|
}
|
|
@@ -724,13 +750,14 @@ export class NodeActions {
|
|
|
724
750
|
run.setState(step, "succeeded", {
|
|
725
751
|
manifest_kind: "release",
|
|
726
752
|
manifest_path: manifestPath,
|
|
727
|
-
project_id: loaded.spec.project,
|
|
753
|
+
project_id: loaded.spec.project === "prj_up_preflight_placeholder" ? null : loaded.spec.project,
|
|
728
754
|
idempotency_key: loaded.idempotencyKey ?? null,
|
|
729
755
|
});
|
|
730
756
|
return {
|
|
731
757
|
manifestKind: "release",
|
|
732
758
|
manifestPath,
|
|
733
759
|
releaseSpec: loaded.spec,
|
|
760
|
+
loaded,
|
|
734
761
|
idempotencyKey: loaded.idempotencyKey,
|
|
735
762
|
manifestProjectId: loaded.spec.project === "prj_up_preflight_placeholder"
|
|
736
763
|
? undefined
|
|
@@ -807,6 +834,11 @@ export class NodeActions {
|
|
|
807
834
|
async #assertManifestFileReferences(spec, manifestPath, run) {
|
|
808
835
|
try {
|
|
809
836
|
await assertLocalFileReferencesExist(spec, { manifestPath });
|
|
837
|
+
if (process.env.RUN402_DEPLOY_SKIP_SCAN !== "1") {
|
|
838
|
+
const scan = scanDeploymentSources(spec, dirname(manifestPath));
|
|
839
|
+
if (scan.errors.length)
|
|
840
|
+
throw run.error("Source scan blocked this application. Fix the reported findings, or explicitly override with RUN402_DEPLOY_SKIP_SCAN=1.", "R402_AUTH_PREFLIGHT_FAILED", scan);
|
|
841
|
+
}
|
|
810
842
|
}
|
|
811
843
|
catch (err) {
|
|
812
844
|
throw this.#retypeManifestFileError(err, run);
|
|
@@ -854,6 +886,8 @@ export class NodeActions {
|
|
|
854
886
|
try {
|
|
855
887
|
normalized = await normalizeDeployManifest(releaseInput, {
|
|
856
888
|
project: "prj_up_preflight_placeholder",
|
|
889
|
+
validateFiles: true,
|
|
890
|
+
manifestPath,
|
|
857
891
|
baseDir: dirname(manifestPath),
|
|
858
892
|
});
|
|
859
893
|
}
|
|
@@ -864,6 +898,7 @@ export class NodeActions {
|
|
|
864
898
|
return;
|
|
865
899
|
}
|
|
866
900
|
await this.#assertManifestFileReferences(normalized.spec, manifestPath, run);
|
|
901
|
+
return normalized.spec;
|
|
867
902
|
}
|
|
868
903
|
#planAppUpResult(input, manifest, run, opts) {
|
|
869
904
|
if (!manifest.appGraph) {
|
|
@@ -1007,7 +1042,7 @@ export class NodeActions {
|
|
|
1007
1042
|
})),
|
|
1008
1043
|
};
|
|
1009
1044
|
}
|
|
1010
|
-
if (run.executionMode !== "check" && run.executionMode !== "printSpec" && !run.dryRun) {
|
|
1045
|
+
if (run.executionMode !== "check" && run.executionMode !== "printSpec" && run.executionMode !== "printManifest" && !run.dryRun) {
|
|
1011
1046
|
const spendBlock = spendApprovalBlock(input, run);
|
|
1012
1047
|
if (spendBlock)
|
|
1013
1048
|
return spendBlock;
|
|
@@ -1033,7 +1068,7 @@ export class NodeActions {
|
|
|
1033
1068
|
blockedNodeId: block.nodeId,
|
|
1034
1069
|
});
|
|
1035
1070
|
return run.result({
|
|
1036
|
-
project_id: input.projectId ??
|
|
1071
|
+
project_id: input.projectId ?? null,
|
|
1037
1072
|
manifest_path: manifest.manifestPath,
|
|
1038
1073
|
app_graph: manifest.appGraph,
|
|
1039
1074
|
app_result: blocked,
|
|
@@ -1061,7 +1096,7 @@ export class NodeActions {
|
|
|
1061
1096
|
blockedNodeId: "project.ensure",
|
|
1062
1097
|
});
|
|
1063
1098
|
return run.result({
|
|
1064
|
-
project_id: input.projectId ??
|
|
1099
|
+
project_id: input.projectId ?? null,
|
|
1065
1100
|
manifest_path: manifest.manifestPath,
|
|
1066
1101
|
app_graph: manifest.appGraph,
|
|
1067
1102
|
app_result: blocked,
|
|
@@ -1981,7 +2016,7 @@ export class NodeActions {
|
|
|
1981
2016
|
description: "Write workspace project link",
|
|
1982
2017
|
mutation: true,
|
|
1983
2018
|
auto: true,
|
|
1984
|
-
details: { path, project_id: link.project_id, name: link.name ?? null },
|
|
2019
|
+
details: { path, project_id: run.dryRun && link.project_id === "prj_planned" ? null : link.project_id, name: link.name ?? null },
|
|
1985
2020
|
});
|
|
1986
2021
|
await run.approve(step, ["workspace.link.write"], `Write ${shortPath(path)}.`);
|
|
1987
2022
|
if (run.dryRun) {
|
|
@@ -2117,7 +2152,7 @@ class ActionRun {
|
|
|
2117
2152
|
return {
|
|
2118
2153
|
action: this.input.type,
|
|
2119
2154
|
mode: this.executionMode,
|
|
2120
|
-
dry_run: this.dryRun || this.executionMode === "check" || this.executionMode === "printSpec" || this.executionMode === "plan",
|
|
2155
|
+
dry_run: this.dryRun || this.executionMode === "check" || (this.executionMode === "printSpec" || this.executionMode === "printManifest") || this.executionMode === "plan",
|
|
2121
2156
|
target: this.target,
|
|
2122
2157
|
steps: this.steps,
|
|
2123
2158
|
result,
|
|
@@ -2175,20 +2210,6 @@ function appPublicOrigin(input, spec) {
|
|
|
2175
2210
|
return null;
|
|
2176
2211
|
return `https://${subdomain}.run402.com`;
|
|
2177
2212
|
}
|
|
2178
|
-
function materializeTemplates(value, values) {
|
|
2179
|
-
if (typeof value === "string") {
|
|
2180
|
-
return value.replace(/\$\{([^}]+)\}/g, (_match, key) => values[key] ?? "");
|
|
2181
|
-
}
|
|
2182
|
-
if (Array.isArray(value))
|
|
2183
|
-
return value.map((item) => materializeTemplates(item, values));
|
|
2184
|
-
if (value && typeof value === "object") {
|
|
2185
|
-
return Object.fromEntries(Object.entries(value).map(([key, nested]) => [
|
|
2186
|
-
key,
|
|
2187
|
-
materializeTemplates(nested, values),
|
|
2188
|
-
]));
|
|
2189
|
-
}
|
|
2190
|
-
return value;
|
|
2191
|
-
}
|
|
2192
2213
|
function appMailboxSlug(logicalName, spec) {
|
|
2193
2214
|
return spec.slug ?? logicalName.replace(/_/g, "-");
|
|
2194
2215
|
}
|
|
@@ -2310,6 +2331,9 @@ async function classifyAppVerifyAttempt(input) {
|
|
|
2310
2331
|
if (input.attempt.status === input.check.expect.status) {
|
|
2311
2332
|
return { kind: "success" };
|
|
2312
2333
|
}
|
|
2334
|
+
if ((input.attempt.status === 400 || input.attempt.status === 429) && input.attempt.edgeCode === null && !input.attempt.edgeHeader) {
|
|
2335
|
+
return { kind: "failed" };
|
|
2336
|
+
}
|
|
2313
2337
|
const host = hostnameFromUrl(input.url);
|
|
2314
2338
|
const freshness = host ? freshnessForHost(input.context, host) : { fresh: false, ageSeconds: null };
|
|
2315
2339
|
if (freshness.fresh &&
|
|
@@ -2604,17 +2628,7 @@ function appBuildBlock(input, manifest) {
|
|
|
2604
2628
|
return null;
|
|
2605
2629
|
}
|
|
2606
2630
|
async function findManifest(workspaceDir) {
|
|
2607
|
-
|
|
2608
|
-
const path = join(workspaceDir, candidate);
|
|
2609
|
-
try {
|
|
2610
|
-
await lstat(path);
|
|
2611
|
-
return path;
|
|
2612
|
-
}
|
|
2613
|
-
catch {
|
|
2614
|
-
// try next candidate
|
|
2615
|
-
}
|
|
2616
|
-
}
|
|
2617
|
-
return null;
|
|
2631
|
+
return (await resolveApplicationScope({ dir: workspaceDir })).manifest_path;
|
|
2618
2632
|
}
|
|
2619
2633
|
const NEARBY_MANIFEST_SCAN_LIMIT = 200;
|
|
2620
2634
|
/**
|