@lark-apaas/fullstack-cli 1.1.59-alpha.20260722071909 → 1.1.59-alpha.20260722165429
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/dist/index.js +281 -69
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8261,6 +8261,57 @@ function classTransformerStorageResolver(projectRoot) {
|
|
|
8261
8261
|
}
|
|
8262
8262
|
};
|
|
8263
8263
|
}
|
|
8264
|
+
function projectUsesNestjsDevtools(projectRoot) {
|
|
8265
|
+
const distRoot = path25.join(projectRoot, "dist");
|
|
8266
|
+
if (!fs29.existsSync(distRoot)) return false;
|
|
8267
|
+
const pending = [distRoot];
|
|
8268
|
+
while (pending.length > 0) {
|
|
8269
|
+
const current = pending.pop();
|
|
8270
|
+
if (!current) continue;
|
|
8271
|
+
for (const entry of fs29.readdirSync(current, { withFileTypes: true })) {
|
|
8272
|
+
const entryPath = path25.join(current, entry.name);
|
|
8273
|
+
if (entry.isDirectory()) {
|
|
8274
|
+
pending.push(entryPath);
|
|
8275
|
+
} else if (entry.isFile() && /\.[cm]?js$/.test(entry.name)) {
|
|
8276
|
+
const source = fs29.readFileSync(entryPath, "utf8");
|
|
8277
|
+
if (source.includes("@lark-apaas/fullstack-nestjs-core") && /\bDevTools(?:V2)?Module\b/.test(source)) {
|
|
8278
|
+
return true;
|
|
8279
|
+
}
|
|
8280
|
+
}
|
|
8281
|
+
}
|
|
8282
|
+
}
|
|
8283
|
+
return false;
|
|
8284
|
+
}
|
|
8285
|
+
function previewNestjsRuntimeEntryPlugin(projectRoot) {
|
|
8286
|
+
const projectRequire = createRequire3(path25.join(projectRoot, "package.json"));
|
|
8287
|
+
let runtimeEntry;
|
|
8288
|
+
if (!projectUsesNestjsDevtools(projectRoot)) {
|
|
8289
|
+
try {
|
|
8290
|
+
runtimeEntry = projectRequire.resolve(
|
|
8291
|
+
"@lark-apaas/fullstack-nestjs-core/runtime"
|
|
8292
|
+
);
|
|
8293
|
+
} catch {
|
|
8294
|
+
runtimeEntry = void 0;
|
|
8295
|
+
}
|
|
8296
|
+
}
|
|
8297
|
+
let runtimeEntryUsed = false;
|
|
8298
|
+
return {
|
|
8299
|
+
used: () => runtimeEntryUsed,
|
|
8300
|
+
plugin: {
|
|
8301
|
+
name: "preview-nestjs-runtime-entry",
|
|
8302
|
+
setup(esbuild) {
|
|
8303
|
+
esbuild.onResolve(
|
|
8304
|
+
{ filter: /^@lark-apaas\/fullstack-nestjs-core$/ },
|
|
8305
|
+
() => {
|
|
8306
|
+
if (!runtimeEntry) return void 0;
|
|
8307
|
+
runtimeEntryUsed = true;
|
|
8308
|
+
return { path: runtimeEntry };
|
|
8309
|
+
}
|
|
8310
|
+
);
|
|
8311
|
+
}
|
|
8312
|
+
}
|
|
8313
|
+
};
|
|
8314
|
+
}
|
|
8264
8315
|
function optionalDependencyStubPlugin() {
|
|
8265
8316
|
const stubbedDependencies = /* @__PURE__ */ new Set();
|
|
8266
8317
|
const escapedNames = OPTIONAL_DEPENDENCY_STUBS.map(
|
|
@@ -8523,6 +8574,7 @@ async function buildPreviewServerArtifact(options) {
|
|
|
8523
8574
|
);
|
|
8524
8575
|
fs29.writeFileSync(bootstrapPath, generateBootstrap(entryPath, plugins));
|
|
8525
8576
|
const optionalDependencies = optionalDependencyStubPlugin();
|
|
8577
|
+
const nestjsRuntimeEntry = previewNestjsRuntimeEntryPlugin(projectRoot);
|
|
8526
8578
|
const buildOptions = {
|
|
8527
8579
|
absWorkingDir: projectRoot,
|
|
8528
8580
|
entryPoints: [bootstrapPath],
|
|
@@ -8538,6 +8590,7 @@ async function buildPreviewServerArtifact(options) {
|
|
|
8538
8590
|
metafile: true,
|
|
8539
8591
|
logLevel: "silent",
|
|
8540
8592
|
plugins: [
|
|
8593
|
+
nestjsRuntimeEntry.plugin,
|
|
8541
8594
|
classTransformerStorageResolver(projectRoot),
|
|
8542
8595
|
optionalDependencies.plugin
|
|
8543
8596
|
]
|
|
@@ -8574,6 +8627,7 @@ async function buildPreviewServerArtifact(options) {
|
|
|
8574
8627
|
closureStatus,
|
|
8575
8628
|
closureRisks,
|
|
8576
8629
|
stubbedOptionalDependencies,
|
|
8630
|
+
nestjsRuntimeEntryUsed: nestjsRuntimeEntry.used(),
|
|
8577
8631
|
runtimeProbeStatus: "not-run",
|
|
8578
8632
|
consumable: false,
|
|
8579
8633
|
elapsedMs: Date.now() - startedAt
|
|
@@ -8623,7 +8677,7 @@ async function buildPreviewServerArtifact(options) {
|
|
|
8623
8677
|
}
|
|
8624
8678
|
|
|
8625
8679
|
// src/commands/preview-artifact/producer.ts
|
|
8626
|
-
import * as
|
|
8680
|
+
import * as crypto3 from "crypto";
|
|
8627
8681
|
import * as fs34 from "fs";
|
|
8628
8682
|
import * as path30 from "path";
|
|
8629
8683
|
import { spawnSync as spawnSync8 } from "child_process";
|
|
@@ -8929,6 +8983,10 @@ function rejectSymlinks(root) {
|
|
|
8929
8983
|
}
|
|
8930
8984
|
}
|
|
8931
8985
|
}
|
|
8986
|
+
function inspectClientArchive(archivePath) {
|
|
8987
|
+
archiveEntries(archivePath);
|
|
8988
|
+
rejectArchivedSymlinks(archivePath);
|
|
8989
|
+
}
|
|
8932
8990
|
function isPathInside(parent, candidate) {
|
|
8933
8991
|
const relative5 = path27.relative(parent, candidate);
|
|
8934
8992
|
return relative5 !== "" && relative5 !== ".." && !relative5.startsWith(`..${path27.sep}`) && !path27.isAbsolute(relative5);
|
|
@@ -9004,8 +9062,7 @@ function extractClientArchive(archivePath, destination) {
|
|
|
9004
9062
|
if (fs31.existsSync(destination)) {
|
|
9005
9063
|
throw new Error("client archive destination must not already exist");
|
|
9006
9064
|
}
|
|
9007
|
-
|
|
9008
|
-
rejectArchivedSymlinks(archivePath);
|
|
9065
|
+
inspectClientArchive(archivePath);
|
|
9009
9066
|
fs31.mkdirSync(destination, { recursive: true });
|
|
9010
9067
|
try {
|
|
9011
9068
|
const extraction = spawnSync7(
|
|
@@ -9024,6 +9081,40 @@ function extractClientArchive(archivePath, destination) {
|
|
|
9024
9081
|
throw error;
|
|
9025
9082
|
}
|
|
9026
9083
|
}
|
|
9084
|
+
async function extractInspectedClientArchive(archivePath, destination) {
|
|
9085
|
+
if (fs31.existsSync(destination)) {
|
|
9086
|
+
throw new Error("client archive destination must not already exist");
|
|
9087
|
+
}
|
|
9088
|
+
fs31.mkdirSync(destination, { recursive: true });
|
|
9089
|
+
try {
|
|
9090
|
+
await new Promise((resolve9, reject) => {
|
|
9091
|
+
const extraction = spawn2(
|
|
9092
|
+
"unzip",
|
|
9093
|
+
["-q", archivePath, "-d", destination],
|
|
9094
|
+
{ stdio: ["ignore", "ignore", "pipe"] }
|
|
9095
|
+
);
|
|
9096
|
+
let stderr = "";
|
|
9097
|
+
extraction.stderr?.setEncoding("utf8");
|
|
9098
|
+
extraction.stderr?.on("data", (chunk) => {
|
|
9099
|
+
stderr = `${stderr}${String(chunk)}`.slice(-8 * 1024);
|
|
9100
|
+
});
|
|
9101
|
+
extraction.once("error", reject);
|
|
9102
|
+
extraction.once("close", (code) => {
|
|
9103
|
+
if (code === 0) resolve9();
|
|
9104
|
+
else
|
|
9105
|
+
reject(
|
|
9106
|
+
new Error(
|
|
9107
|
+
`client archive extraction failed: ${stderr.trim() || `exit ${code ?? "unknown"}`}`
|
|
9108
|
+
)
|
|
9109
|
+
);
|
|
9110
|
+
});
|
|
9111
|
+
});
|
|
9112
|
+
rejectSymlinks(destination);
|
|
9113
|
+
} catch (error) {
|
|
9114
|
+
fs31.rmSync(destination, { recursive: true, force: true });
|
|
9115
|
+
throw error;
|
|
9116
|
+
}
|
|
9117
|
+
}
|
|
9027
9118
|
async function fetchUntil(url, timeoutAt) {
|
|
9028
9119
|
while (Date.now() < timeoutAt) {
|
|
9029
9120
|
try {
|
|
@@ -9200,6 +9291,7 @@ function previewArtifactRuntimeEnvironment(environment) {
|
|
|
9200
9291
|
}
|
|
9201
9292
|
|
|
9202
9293
|
// src/commands/preview-artifact/store.ts
|
|
9294
|
+
import * as crypto2 from "crypto";
|
|
9203
9295
|
import * as fs33 from "fs";
|
|
9204
9296
|
import * as path29 from "path";
|
|
9205
9297
|
var GENERATION_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
@@ -9261,7 +9353,7 @@ function validateRegularDirectory(directoryPath, label) {
|
|
|
9261
9353
|
];
|
|
9262
9354
|
}
|
|
9263
9355
|
}
|
|
9264
|
-
function validateGeneration(generationDir, runtime) {
|
|
9356
|
+
function validateGeneration(generationDir, runtime, verifyPayloads = true) {
|
|
9265
9357
|
const reasons = validateRegularDirectory(
|
|
9266
9358
|
generationDir,
|
|
9267
9359
|
"generation directory"
|
|
@@ -9301,19 +9393,29 @@ function validateGeneration(generationDir, runtime) {
|
|
|
9301
9393
|
if (!/^[a-f0-9]{64}$/.test(manifest.buildEnvironmentSha256)) {
|
|
9302
9394
|
reasons.push("build environment identity is invalid");
|
|
9303
9395
|
}
|
|
9304
|
-
const
|
|
9305
|
-
|
|
9306
|
-
|
|
9307
|
-
|
|
9308
|
-
|
|
9396
|
+
for (const [label, identity, expectedPath] of [
|
|
9397
|
+
["server", manifest.files?.server, "server.bundle.cjs"],
|
|
9398
|
+
["client", manifest.files?.client, "client.zip"]
|
|
9399
|
+
]) {
|
|
9400
|
+
if (!identity || identity.path !== expectedPath || !Number.isSafeInteger(identity.bytes) || identity.bytes < 0 || !/^[a-f0-9]{64}$/.test(identity.sha256)) {
|
|
9401
|
+
reasons.push(`${label} file identity is invalid`);
|
|
9309
9402
|
}
|
|
9310
|
-
|
|
9311
|
-
|
|
9403
|
+
}
|
|
9404
|
+
if (verifyPayloads && manifest.files?.server && manifest.files?.client) {
|
|
9405
|
+
const serverPath = path29.join(generationDir, "server.bundle.cjs");
|
|
9406
|
+
const clientPath = path29.join(generationDir, "client.zip");
|
|
9407
|
+
try {
|
|
9408
|
+
if (sha256File(serverPath) !== manifest.files.server.sha256) {
|
|
9409
|
+
reasons.push("server.bundle.cjs hash does not match manifest");
|
|
9410
|
+
}
|
|
9411
|
+
if (sha256File(clientPath) !== manifest.files.client.sha256) {
|
|
9412
|
+
reasons.push("client.zip hash does not match manifest");
|
|
9413
|
+
}
|
|
9414
|
+
} catch (error) {
|
|
9415
|
+
reasons.push(
|
|
9416
|
+
`generation files are unavailable: ${error instanceof Error ? error.message : String(error)}`
|
|
9417
|
+
);
|
|
9312
9418
|
}
|
|
9313
|
-
} catch (error) {
|
|
9314
|
-
reasons.push(
|
|
9315
|
-
`generation files are unavailable: ${error instanceof Error ? error.message : String(error)}`
|
|
9316
|
-
);
|
|
9317
9419
|
}
|
|
9318
9420
|
if (probe.serverSha256 !== manifest.files.server.sha256 || probe.clientSha256 !== manifest.files.client.sha256) {
|
|
9319
9421
|
reasons.push("probe file identity does not match manifest");
|
|
@@ -9374,7 +9476,7 @@ function publishPreviewArtifactGeneration(options) {
|
|
|
9374
9476
|
};
|
|
9375
9477
|
}
|
|
9376
9478
|
}
|
|
9377
|
-
function
|
|
9479
|
+
function resolveCurrentPreviewArtifactMetadata(options) {
|
|
9378
9480
|
const storeRoot = path29.resolve(options.storeRoot);
|
|
9379
9481
|
let pointer;
|
|
9380
9482
|
try {
|
|
@@ -9402,11 +9504,15 @@ function resolveCurrentPreviewArtifact(options) {
|
|
|
9402
9504
|
"generations",
|
|
9403
9505
|
pointer.generationId
|
|
9404
9506
|
);
|
|
9405
|
-
const validation = validateGeneration(
|
|
9406
|
-
|
|
9407
|
-
|
|
9408
|
-
|
|
9409
|
-
|
|
9507
|
+
const validation = validateGeneration(
|
|
9508
|
+
generationDir,
|
|
9509
|
+
{
|
|
9510
|
+
nodeMajor,
|
|
9511
|
+
platform: options.platform,
|
|
9512
|
+
arch: options.arch
|
|
9513
|
+
},
|
|
9514
|
+
false
|
|
9515
|
+
);
|
|
9410
9516
|
if (!validation.manifest || validation.reasons.length > 0) {
|
|
9411
9517
|
return { resolved: false, reasons: validation.reasons };
|
|
9412
9518
|
}
|
|
@@ -9429,11 +9535,85 @@ function resolveCurrentPreviewArtifact(options) {
|
|
|
9429
9535
|
manifest: validation.manifest
|
|
9430
9536
|
};
|
|
9431
9537
|
}
|
|
9538
|
+
async function materializeVerifiedPreviewArtifactFile(options) {
|
|
9539
|
+
const source = path29.resolve(options.source);
|
|
9540
|
+
const destination = path29.resolve(options.destination);
|
|
9541
|
+
const temporary = `${destination}.${process.pid}.${Date.now()}.tmp`;
|
|
9542
|
+
fs33.mkdirSync(path29.dirname(destination), { recursive: true });
|
|
9543
|
+
if (fs33.existsSync(destination)) {
|
|
9544
|
+
throw new Error(
|
|
9545
|
+
`materialization destination already exists: ${destination}`
|
|
9546
|
+
);
|
|
9547
|
+
}
|
|
9548
|
+
const noFollow = fs33.constants.O_NOFOLLOW ?? 0;
|
|
9549
|
+
let sourceHandle;
|
|
9550
|
+
let destinationHandle;
|
|
9551
|
+
try {
|
|
9552
|
+
sourceHandle = await fs33.promises.open(
|
|
9553
|
+
source,
|
|
9554
|
+
fs33.constants.O_RDONLY | noFollow
|
|
9555
|
+
);
|
|
9556
|
+
const sourceStat = await sourceHandle.stat();
|
|
9557
|
+
if (!sourceStat.isFile()) {
|
|
9558
|
+
throw new Error(`${options.identity.path} is not a regular file`);
|
|
9559
|
+
}
|
|
9560
|
+
destinationHandle = await fs33.promises.open(
|
|
9561
|
+
temporary,
|
|
9562
|
+
fs33.constants.O_WRONLY | fs33.constants.O_CREAT | fs33.constants.O_EXCL,
|
|
9563
|
+
384
|
|
9564
|
+
);
|
|
9565
|
+
const hash = crypto2.createHash("sha256");
|
|
9566
|
+
const buffer = Buffer.allocUnsafe(256 * 1024);
|
|
9567
|
+
let totalBytes = 0;
|
|
9568
|
+
for (; ; ) {
|
|
9569
|
+
const { bytesRead } = await sourceHandle.read(
|
|
9570
|
+
buffer,
|
|
9571
|
+
0,
|
|
9572
|
+
buffer.length,
|
|
9573
|
+
null
|
|
9574
|
+
);
|
|
9575
|
+
if (bytesRead === 0) break;
|
|
9576
|
+
hash.update(buffer.subarray(0, bytesRead));
|
|
9577
|
+
let written = 0;
|
|
9578
|
+
while (written < bytesRead) {
|
|
9579
|
+
const result = await destinationHandle.write(
|
|
9580
|
+
buffer,
|
|
9581
|
+
written,
|
|
9582
|
+
bytesRead - written,
|
|
9583
|
+
null
|
|
9584
|
+
);
|
|
9585
|
+
if (result.bytesWritten <= 0) {
|
|
9586
|
+
throw new Error(
|
|
9587
|
+
`${options.identity.path} materialization short write`
|
|
9588
|
+
);
|
|
9589
|
+
}
|
|
9590
|
+
written += result.bytesWritten;
|
|
9591
|
+
}
|
|
9592
|
+
totalBytes += bytesRead;
|
|
9593
|
+
}
|
|
9594
|
+
const sha256 = hash.digest("hex");
|
|
9595
|
+
if (sha256 !== options.identity.sha256) {
|
|
9596
|
+
throw new Error(`${options.identity.path} hash does not match manifest`);
|
|
9597
|
+
}
|
|
9598
|
+
if (totalBytes !== options.identity.bytes) {
|
|
9599
|
+
throw new Error(`${options.identity.path} bytes do not match manifest`);
|
|
9600
|
+
}
|
|
9601
|
+
await destinationHandle.sync();
|
|
9602
|
+
await destinationHandle.close();
|
|
9603
|
+
destinationHandle = void 0;
|
|
9604
|
+
await fs33.promises.rename(temporary, destination);
|
|
9605
|
+
return { bytes: totalBytes, sha256 };
|
|
9606
|
+
} finally {
|
|
9607
|
+
await destinationHandle?.close().catch(() => void 0);
|
|
9608
|
+
await sourceHandle?.close().catch(() => void 0);
|
|
9609
|
+
await fs33.promises.rm(temporary, { force: true }).catch(() => void 0);
|
|
9610
|
+
}
|
|
9611
|
+
}
|
|
9432
9612
|
|
|
9433
9613
|
// src/commands/preview-artifact/producer.ts
|
|
9434
9614
|
function defaultGenerationId() {
|
|
9435
9615
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:.TZ]/g, "");
|
|
9436
|
-
return `${timestamp}-${
|
|
9616
|
+
return `${timestamp}-${crypto3.randomBytes(5).toString("hex")}`;
|
|
9437
9617
|
}
|
|
9438
9618
|
function defaultPreviewBundleBuildCommands(projectRootInput) {
|
|
9439
9619
|
const projectRoot = path30.resolve(projectRootInput);
|
|
@@ -9957,7 +10137,7 @@ async function startPreviewArtifactRuntime(options) {
|
|
|
9957
10137
|
const resolved = measure(
|
|
9958
10138
|
timings,
|
|
9959
10139
|
"metadata_validate",
|
|
9960
|
-
() =>
|
|
10140
|
+
() => resolveCurrentPreviewArtifactMetadata({
|
|
9961
10141
|
storeRoot: options.storeRoot,
|
|
9962
10142
|
nodeVersion: process.version,
|
|
9963
10143
|
platform: process.platform,
|
|
@@ -9993,53 +10173,85 @@ async function startPreviewArtifactRuntime(options) {
|
|
|
9993
10173
|
);
|
|
9994
10174
|
const runtimeBundle = path32.join(runtimeDir, "server.bundle.cjs");
|
|
9995
10175
|
const serverSource = path32.join(resolved.generationDir, "server.bundle.cjs");
|
|
9996
|
-
|
|
9997
|
-
|
|
9998
|
-
"server_materialize",
|
|
9999
|
-
() => fs36.copyFileSync(serverSource, runtimeBundle),
|
|
10000
|
-
{ bytes: resolved.manifest.files.server.bytes }
|
|
10001
|
-
);
|
|
10176
|
+
const clientArchive = path32.join(runtimeDir, "client.zip");
|
|
10177
|
+
const clientSource = path32.join(resolved.generationDir, "client.zip");
|
|
10002
10178
|
const clientRoot = path32.join(runtimeDir, "dist", "client");
|
|
10003
|
-
|
|
10004
|
-
|
|
10005
|
-
|
|
10006
|
-
|
|
10007
|
-
|
|
10008
|
-
|
|
10009
|
-
|
|
10010
|
-
|
|
10011
|
-
|
|
10012
|
-
|
|
10013
|
-
|
|
10014
|
-
|
|
10015
|
-
|
|
10016
|
-
|
|
10017
|
-
|
|
10018
|
-
|
|
10019
|
-
|
|
10020
|
-
|
|
10021
|
-
|
|
10022
|
-
|
|
10023
|
-
|
|
10024
|
-
|
|
10025
|
-
|
|
10026
|
-
|
|
10027
|
-
|
|
10028
|
-
|
|
10029
|
-
|
|
10030
|
-
|
|
10031
|
-
|
|
10032
|
-
|
|
10033
|
-
|
|
10034
|
-
|
|
10035
|
-
|
|
10036
|
-
|
|
10037
|
-
|
|
10038
|
-
|
|
10039
|
-
)
|
|
10040
|
-
|
|
10041
|
-
|
|
10042
|
-
|
|
10179
|
+
const backendReady = (async () => {
|
|
10180
|
+
await measureAsync(
|
|
10181
|
+
timings,
|
|
10182
|
+
"server_materialize",
|
|
10183
|
+
() => materializeVerifiedPreviewArtifactFile({
|
|
10184
|
+
source: serverSource,
|
|
10185
|
+
destination: runtimeBundle,
|
|
10186
|
+
identity: resolved.manifest.files.server
|
|
10187
|
+
}),
|
|
10188
|
+
{ bytes: resolved.manifest.files.server.bytes }
|
|
10189
|
+
);
|
|
10190
|
+
const cachedServerPort2 = options.cachedServerPort === 0 ? await reservePort2() : options.cachedServerPort;
|
|
10191
|
+
cachedRuntime = spawn3(process.execPath, [runtimeBundle], {
|
|
10192
|
+
cwd: runtimeDir,
|
|
10193
|
+
detached: true,
|
|
10194
|
+
stdio: "ignore",
|
|
10195
|
+
env: {
|
|
10196
|
+
...process.env,
|
|
10197
|
+
...previewArtifactRuntimeEnvironment(options.environment),
|
|
10198
|
+
SERVER_PORT: String(cachedServerPort2)
|
|
10199
|
+
}
|
|
10200
|
+
});
|
|
10201
|
+
const cachedOrigin = `http://127.0.0.1:${cachedServerPort2}`;
|
|
10202
|
+
await measureAsync(
|
|
10203
|
+
timings,
|
|
10204
|
+
"backend_spawn_to_business_ready",
|
|
10205
|
+
() => waitForCachedRuntime(
|
|
10206
|
+
cachedOrigin,
|
|
10207
|
+
options.appBasePath,
|
|
10208
|
+
options.businessApiPath,
|
|
10209
|
+
options.startupTimeoutMs ?? 3e4,
|
|
10210
|
+
cachedRuntime
|
|
10211
|
+
)
|
|
10212
|
+
);
|
|
10213
|
+
return cachedServerPort2;
|
|
10214
|
+
})();
|
|
10215
|
+
const assetsReady = (async () => {
|
|
10216
|
+
await measureAsync(
|
|
10217
|
+
timings,
|
|
10218
|
+
"client_materialize",
|
|
10219
|
+
() => materializeVerifiedPreviewArtifactFile({
|
|
10220
|
+
source: clientSource,
|
|
10221
|
+
destination: clientArchive,
|
|
10222
|
+
identity: resolved.manifest.files.client
|
|
10223
|
+
}),
|
|
10224
|
+
{ bytes: resolved.manifest.files.client.bytes }
|
|
10225
|
+
);
|
|
10226
|
+
measure(
|
|
10227
|
+
timings,
|
|
10228
|
+
"client_archive_inspect",
|
|
10229
|
+
() => inspectClientArchive(clientArchive)
|
|
10230
|
+
);
|
|
10231
|
+
await measureAsync(
|
|
10232
|
+
timings,
|
|
10233
|
+
"client_extract",
|
|
10234
|
+
() => extractInspectedClientArchive(clientArchive, clientRoot)
|
|
10235
|
+
);
|
|
10236
|
+
const cachedAssetFiles2 = measure(
|
|
10237
|
+
timings,
|
|
10238
|
+
"asset_index",
|
|
10239
|
+
() => collectCachedAssetFiles(clientRoot, options.appBasePath)
|
|
10240
|
+
);
|
|
10241
|
+
timings[timings.length - 1].fileCount = new Set(
|
|
10242
|
+
cachedAssetFiles2.values()
|
|
10243
|
+
).size;
|
|
10244
|
+
fs36.rmSync(clientArchive, { force: true });
|
|
10245
|
+
return cachedAssetFiles2;
|
|
10246
|
+
})();
|
|
10247
|
+
const [backendResult, assetsResult] = await Promise.allSettled([
|
|
10248
|
+
backendReady,
|
|
10249
|
+
assetsReady
|
|
10250
|
+
]);
|
|
10251
|
+
if (assetsResult.status === "rejected") throw assetsResult.reason;
|
|
10252
|
+
if (backendResult.status === "rejected") throw backendResult.reason;
|
|
10253
|
+
const cachedServerPort = backendResult.value;
|
|
10254
|
+
const cachedAssetFiles = assetsResult.value;
|
|
10043
10255
|
switcher = createPreviewArtifactSwitcher({
|
|
10044
10256
|
listenHost: options.listenHost,
|
|
10045
10257
|
listenPort: options.listenPort,
|