@lark-apaas/fullstack-cli 1.1.64-alpha.20260901065806 → 1.1.64-alpha.20260901133248

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/index.ts
2
- import fs30 from "fs";
3
- import path26 from "path";
2
+ import fs29 from "fs";
3
+ import path25 from "path";
4
4
  import { fileURLToPath as fileURLToPath5 } from "url";
5
5
  import { config as dotenvConfig } from "dotenv";
6
6
 
@@ -8260,1436 +8260,21 @@ async function preUploadStatic(options) {
8260
8260
  }
8261
8261
  }
8262
8262
 
8263
- // src/commands/build/server-startup-bundle.handler.ts
8264
- import fs29 from "fs";
8265
- import http from "http";
8266
- import net from "net";
8267
- import os3 from "os";
8268
- import path25 from "path";
8269
- import { builtinModules, createRequire as createRequire3 } from "module";
8270
- import { spawn as spawn2 } from "child_process";
8271
- import { createHash, randomUUID } from "crypto";
8272
- import { build } from "esbuild";
8273
- import { parse } from "acorn";
8274
- import { ancestor as walkAncestor, simple as walkSimple } from "acorn-walk";
8275
- var OPTIONAL_NEST_DEPENDENCIES = [
8276
- "@nestjs/microservices",
8277
- "@nestjs/microservices/microservices-module",
8278
- "@nestjs/websockets/socket-module",
8279
- "@node-rs/xxhash",
8280
- "fsevents"
8281
- ];
8282
- var BUILTINS = /* @__PURE__ */ new Set([
8283
- ...builtinModules,
8284
- ...builtinModules.map((name) => `node:${name}`)
8285
- ]);
8286
- var BUILDER_POLICY_VERSION = 5;
8287
- var RUNTIME_ASSET_READ_METHODS = /* @__PURE__ */ new Set([
8288
- "access",
8289
- "accessSync",
8290
- "createReadStream",
8291
- "open",
8292
- "openSync",
8293
- "readFile",
8294
- "readFileSync",
8295
- "stat",
8296
- "statSync"
8297
- ]);
8298
- var SOURCE_HASH_IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([
8299
- ".git",
8300
- ".miaoda-cache",
8301
- ".turbo",
8302
- "coverage",
8303
- "dist",
8304
- "logs",
8305
- "node_modules"
8306
- ]);
8307
- var AUDITED_FRAMEWORK_DYNAMIC_LOADER_HASHES = {
8308
- "/@nestjs/common/utils/load-package.util.js": [
8309
- "8fc26b273fe5499285e25355b4368fe8e1527ae217ede53144219c17cf1aa721"
8310
- ],
8311
- "/@nestjs/core/helpers/optional-require.js": [
8312
- "c8a109dab1b2461e866fe04b8be5988ccc199a2239c730abc05fc28c0f85d7f2"
8313
- ],
8314
- "/@nestjs/core/helpers/load-adapter.js": [
8315
- "7970867a441f356a2e257a12e43dbb8022b58631b3076f298058abb46270009a"
8316
- ],
8317
- "/express/lib/view.js": [
8318
- "ec627880c1b43aee5887164ac2e9c58f01e4ee8086e23a829eddf1af3858c021"
8319
- ],
8320
- "/require-in-the-middle/index.js": [
8321
- "721b78e7afebc91a75ecc8b8d9a166775ef03fd8f96e7cbcad1b46f8b4e74a07"
8322
- ],
8323
- "/@opentelemetry/instrumentation/build/src/platform/node/instrumentation.js": ["098033348a2d1750e5722457fa56ccbe51c7df1aafe58f960ec20566a9a8b310"],
8324
- "/@lark-apaas/nestjs-capability/dist/index.cjs": [
8325
- "9a6aea944995f46adf9733daaf13ec6cd0d46decab044e2548e0f0b1ba54cde2"
8326
- ],
8327
- "/@lark-apaas/fullstack-nestjs-core/dist/index.cjs": [
8328
- "76fd8e2b4eaf762346e22919b229d81bc6c3848f1e7968e8e63e9493ca6127d9"
8329
- ],
8330
- "/pino/lib/transport.js": [
8331
- "c4857be63a0392312c9010fc222e7216fee0c216ef8dbcf133c61158528ab091"
8332
- ],
8333
- "/hbs/lib/hbs.js": [
8334
- "fdab192a37993e8643e5ce27698fc7e1138b0033e487270f77fd865fa00feab0"
8335
- ],
8336
- "/handlebars/lib/index.js": [
8337
- "76f96bd806c6b48987dd811de149be3d8c296eb440f9c91a3b8cad9fb2f9030a"
8338
- ]
8339
- };
8340
- var AUDITED_RUNTIME_FS_READER_HASHES = {
8341
- "/@grpc/grpc-js/build/src/tls-helpers.js": [
8342
- "9c3b00e23fca5e7996212778f151301eb202337da931f384fb1b60eb9d13f6c4"
8343
- ],
8344
- "/@grpc/proto-loader/build/src/util.js": [
8345
- "72101d764f31ece6d3c22cc6674c32ab3fb1f4975756d9ee4e39f3b155fb6f03"
8346
- ],
8347
- "/@lark-apaas/fullstack-nestjs-core/dist/index.cjs": [
8348
- "76fd8e2b4eaf762346e22919b229d81bc6c3848f1e7968e8e63e9493ca6127d9"
8349
- ],
8350
- "/@lark-apaas/nestjs-capability/dist/index.cjs": [
8351
- "9a6aea944995f46adf9733daaf13ec6cd0d46decab044e2548e0f0b1ba54cde2"
8352
- ],
8353
- "/@nestjs/config/dist/config.module.js": [
8354
- "6d907e32437d1c922d5dcd17e3a0daf052d7d95a56adfc2972965e47cca31ff4"
8355
- ],
8356
- "/@nestjs/config/dist/config.service.js": [
8357
- "a6febcebd600bf8468ffa15e736266407404b5c281f2b1ddcec466245e889a72"
8358
- ],
8359
- "/dotenv/lib/main.js": [
8360
- "0d55d84f7ae79c6752b9b6ffd6f083c32a72d1d6ca2e3606f9161ffa441c3f52"
8361
- ],
8362
- "/express/lib/view.js": [
8363
- "ec627880c1b43aee5887164ac2e9c58f01e4ee8086e23a829eddf1af3858c021"
8364
- ],
8365
- "/send/index.js": [
8366
- "614d9bdd1944cc51663785b0e74c245296830f014a6f8c6c48cdc6a26b56c01e"
8367
- ],
8368
- "/@opentelemetry/otlp-exporter-base/build/esm/configuration/otlp-node-http-env-configuration.js": ["d4397f98b3cea799130dd26fee05ce2f27811e5643244e9d59264d218ac9f364"],
8369
- "/@opentelemetry/otlp-grpc-exporter-base/build/src/configuration/otlp-grpc-env-configuration.js": ["901d2348bf46babe99c7b13cf1aea5bf76f44e5ab45c6f5f1aefbed525938696"],
8370
- "/@opentelemetry/resources/build/src/detectors/platform/node/machine-id/getMachineId-bsd.js": [
8371
- "e4cef35e2b61c3471154414de9b9b3dc21b0778e8e728c56ae0f1cdf2558b8ed",
8372
- "e56af724ce673fe33e83aec425822f5211cd368afcba0d04be41f47da728115f"
8373
- ],
8374
- "/@opentelemetry/resources/build/src/detectors/platform/node/machine-id/getMachineId-linux.js": [
8375
- "d62c5a539558002a63a05093f4f3a0820a35ebf95d51966725fb92110beefc95",
8376
- "631b352f8994ff3cccf365473127b1dfa97f95bb0d0c70e3ce1137c744b92830"
8377
- ],
8378
- "/@protobufjs/fetch/index.js": [
8379
- "5e8c1d65ee1857327528c5b3fc807c3647324f3097a6cb9358f9e2c328c143fe"
8380
- ],
8381
- "/axios/dist/node/axios.cjs": [
8382
- "241146620c67551291fef242d9ab9fd9b28f1e0e14ae311e7db759d36942b574"
8383
- ],
8384
- "/chokidar/index.js": [
8385
- "18ce2effe87d6379aa1d3756e5694c57c72cf97804056d688499a2bffcec66fd"
8386
- ],
8387
- "/chokidar/lib/fsevents-handler.js": [
8388
- "c2e15baebf066bf8531cbf82a324631a40b218d073274429edb50b4bdbbb0265"
8389
- ],
8390
- "/chokidar/lib/nodefs-handler.js": [
8391
- "60be035e7ea64858a0144230d5073b18a69f3b0eefba62a9b032c6d2f179d807"
8392
- ],
8393
- "/form-data/lib/form_data.js": [
8394
- "c63c99e10e2c3f46fa990787d7dc4a4f65ea90211c422e19626fecb3d767c41d"
8395
- ],
8396
- "/handlebars/lib/index.js": [
8397
- "76f96bd806c6b48987dd811de149be3d8c296eb440f9c91a3b8cad9fb2f9030a"
8398
- ],
8399
- "/hbs/lib/hbs.js": [
8400
- "fdab192a37993e8643e5ce27698fc7e1138b0033e487270f77fd865fa00feab0"
8401
- ],
8402
- "/mime/mime.js": [
8403
- "a121a0b9e780e9ae349a26227a0d25c33ebac2d52a85aae5affa84ba0f53f16c"
8404
- ],
8405
- "/mkdirp/index.js": [
8406
- "df33312136061eee26701a34ca4f9be043b9675d359a115503dc2df909106432"
8407
- ],
8408
- "/postgres/cjs/src/index.js": [
8409
- "d8fea1a5311c47e65004646bc81f57305ac64d48f99004a5b3ca27bcfc6babf8"
8410
- ],
8411
- "/protobufjs/src/root.js": [
8412
- "1f610f79137dff45ce2ec4e0f742ae43f26b296f2518f4ba41e0a497af5ad624"
8413
- ],
8414
- "/sonic-boom/index.js": [
8415
- "cd3f77b5b75366df3f0a9c27dc18c4f8c47478a7cc982a2bbdc70bfded3c1221"
8416
- ],
8417
- "/undici/lib/mock/snapshot-recorder.js": [
8418
- "9bf63c8b207b6f6e7fe4400b32d8322cfc185735d6ecfbd87a2691a8fba82922"
8419
- ]
8420
- };
8421
- var probeIdentities = /* @__PURE__ */ new WeakMap();
8422
- function sha256(contents) {
8423
- return createHash("sha256").update(contents).digest("hex");
8424
- }
8425
- function isInside(root, candidate) {
8426
- const relative = path25.relative(root, candidate);
8427
- return relative === "" || !relative.startsWith("..") && !path25.isAbsolute(relative);
8428
- }
8429
- function assertNoSymlinkComponents(root, candidate, message) {
8430
- const relative = path25.relative(root, candidate);
8431
- if (!isInside(root, candidate))
8432
- throw new Error(`${message}: path escaped root`);
8433
- let current = root;
8434
- for (const segment of relative.split(path25.sep).filter(Boolean)) {
8435
- current = path25.join(current, segment);
8436
- if (fs29.existsSync(current) && fs29.lstatSync(current).isSymbolicLink()) {
8437
- throw new Error(message);
8438
- }
8439
- }
8440
- }
8441
- function walkFiles(root, directory, output) {
8442
- if (!fs29.existsSync(directory)) return;
8443
- for (const entry of fs29.readdirSync(directory, { withFileTypes: true })) {
8444
- if (SOURCE_HASH_IGNORED_DIRECTORIES.has(entry.name)) continue;
8445
- const candidate = path25.join(directory, entry.name);
8446
- if (entry.isSymbolicLink()) {
8447
- throw new Error(
8448
- `source symlink is unsupported: ${path25.relative(root, candidate)}`
8449
- );
8450
- }
8451
- if (entry.isDirectory()) walkFiles(root, candidate, output);
8452
- else if (entry.isFile()) output.push(candidate);
8453
- }
8454
- }
8455
- function workspaceSourceSha256(projectRoot) {
8456
- const files = [];
8457
- walkFiles(projectRoot, projectRoot, files);
8458
- const hash = createHash("sha256");
8459
- for (const file of files.sort()) {
8460
- hash.update(path25.relative(projectRoot, file).split(path25.sep).join("/"));
8461
- hash.update("\0");
8462
- hash.update(fs29.readFileSync(file));
8463
- hash.update("\0");
8464
- }
8465
- return hash.digest("hex");
8466
- }
8467
- function workspaceLockfileSha256(projectRoot) {
8468
- const names = ["package-lock.json", "yarn.lock", "pnpm-lock.yaml"];
8469
- const hash = createHash("sha256");
8470
- let found = false;
8471
- for (const name of names) {
8472
- const file = path25.join(projectRoot, name);
8473
- if (!fs29.existsSync(file)) continue;
8474
- found = true;
8475
- hash.update(name);
8476
- hash.update("\0");
8477
- hash.update(fs29.readFileSync(file));
8478
- hash.update("\0");
8479
- }
8480
- return found ? hash.digest("hex") : sha256("");
8481
- }
8482
- function resolveEntry(projectRoot, requested) {
8483
- const entry = path25.resolve(projectRoot, requested);
8484
- if (!isInside(projectRoot, entry))
8485
- throw new Error("compiled entry escaped project root");
8486
- if (!fs29.existsSync(entry))
8487
- throw new Error(`compiled entry is not a file: ${entry}`);
8488
- if (fs29.lstatSync(entry).isSymbolicLink()) {
8489
- throw new Error("compiled entry symlink is unsupported");
8490
- }
8491
- const realEntry = fs29.realpathSync(entry);
8492
- if (!isInside(projectRoot, realEntry))
8493
- throw new Error("compiled entry escaped project root");
8494
- if (!fs29.statSync(realEntry).isFile())
8495
- throw new Error(`compiled entry is not a file: ${entry}`);
8496
- return realEntry;
8497
- }
8498
- function optionalNestDependencyStubs() {
8499
- const escaped = OPTIONAL_NEST_DEPENDENCIES.map(
8500
- (name) => name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
8501
- );
8502
- const filter = new RegExp(`^(?:${escaped.join("|")})$`);
8503
- return {
8504
- name: "miaoda-optional-nest-dependency-stubs",
8505
- setup(esbuild) {
8506
- esbuild.onResolve({ filter }, (args) => ({
8507
- path: args.path,
8508
- namespace: "miaoda-optional-nest-dependency"
8509
- }));
8510
- esbuild.onLoad(
8511
- { filter: /.*/, namespace: "miaoda-optional-nest-dependency" },
8512
- (args) => ({
8513
- contents: `const error = new Error(${JSON.stringify(
8514
- `Optional dependency is unavailable in startup bundle: ${args.path}`
8515
- )}); error.code = 'MODULE_NOT_FOUND'; throw error;`,
8516
- loader: "js"
8517
- })
8518
- );
8519
- }
8520
- };
8521
- }
8522
- function neutralizeDynamicLoads(code) {
8523
- const replacements = [];
8524
- const ast = parse(code, {
8525
- ecmaVersion: "latest",
8526
- sourceType: "module",
8527
- allowHashBang: true,
8528
- allowReturnOutsideFunction: true
8529
- });
8530
- const isCreateRequireReference = (node) => {
8531
- if (!node || typeof node !== "object") return false;
8532
- const candidate = node;
8533
- if (candidate.type === "Identifier")
8534
- return candidate.name === "createRequire";
8535
- if (candidate.type === "MemberExpression") {
8536
- return candidate.property?.type === "Identifier" && candidate.property.name === "createRequire" || candidate.property?.type === "Literal" && candidate.property.value === "createRequire";
8537
- }
8538
- if (candidate.type === "SequenceExpression") {
8539
- return candidate.expressions?.some(isCreateRequireReference) ?? false;
8540
- }
8541
- return false;
8542
- };
8543
- walkSimple(ast, {
8544
- CallExpression(node) {
8545
- const isCreateRequire = isCreateRequireReference(node.callee);
8546
- const isRequire = node.callee.type === "Identifier" && (node.callee.name === "require" || node.callee.name === "__require") || node.callee.type === "MemberExpression" && node.callee.object.type === "Identifier" && node.callee.object.name === "module" && (node.callee.property.type === "Identifier" && node.callee.property.name === "require" || node.callee.property.type === "Literal" && node.callee.property.value === "require");
8547
- const isRequireResolve = node.callee.type === "MemberExpression" && node.callee.object.type === "Identifier" && (node.callee.object.name === "require" || node.callee.object.name === "__require") && node.callee.property.type === "Identifier" && node.callee.property.name === "resolve";
8548
- if (isCreateRequire) {
8549
- replacements.push({
8550
- start: node.start,
8551
- end: node.end,
8552
- kind: "create-require"
8553
- });
8554
- } else if ((isRequire || isRequireResolve) && (node.arguments[0]?.type !== "Literal" || typeof node.arguments[0].value !== "string")) {
8555
- replacements.push({
8556
- start: node.start,
8557
- end: node.end,
8558
- kind: "dynamic-load"
8559
- });
8560
- }
8561
- },
8562
- ImportExpression(node) {
8563
- if (node.source.type !== "Literal" || typeof node.source.value !== "string") {
8564
- replacements.push({
8565
- start: node.start,
8566
- end: node.end,
8567
- kind: "dynamic-load"
8568
- });
8569
- }
8570
- },
8571
- MemberExpression(node) {
8572
- if (node.object.type !== "Identifier" || node.object.name !== "require" && node.object.name !== "__require") {
8573
- return;
8574
- }
8575
- const property = memberPropertyName(node.property);
8576
- if (property === "cache") {
8577
- replacements.push({
8578
- start: node.start,
8579
- end: node.end,
8580
- kind: "require-cache"
8581
- });
8582
- } else if (property === "main") {
8583
- replacements.push({
8584
- start: node.start,
8585
- end: node.end,
8586
- kind: "require-main"
8587
- });
8588
- } else if (property === "extensions") {
8589
- replacements.push({
8590
- start: node.start,
8591
- end: node.end,
8592
- kind: "require-extensions"
8593
- });
8594
- }
8595
- }
8596
- });
8597
- const unavailable = '(()=>{const error=new Error("dynamic dependency unavailable in startup bundle");error.code="MODULE_NOT_FOUND";throw error})()';
8598
- const disabledCreateRequire = '(()=>{const disabled=()=>{const error=new Error("dynamic dependency unavailable in startup bundle");error.code="MODULE_NOT_FOUND";throw error};disabled.resolve=disabled;return disabled})()';
8599
- let output = code;
8600
- for (const replacement of replacements.sort(
8601
- (left, right) => right.start - left.start
8602
- )) {
8603
- const value = replacement.kind === "create-require" ? disabledCreateRequire : replacement.kind === "dynamic-load" ? unavailable : replacement.kind === "require-main" ? "undefined" : "Object.create(null)";
8604
- output = `${output.slice(0, replacement.start)}${value}${output.slice(
8605
- replacement.end
8606
- )}`;
8607
- }
8608
- return output.replace(
8609
- /\bcreateRequire\b/g,
8610
- "__miaoda_disabled_create_require"
8611
- );
8612
- }
8613
- function knownFrameworkDynamicLoaderStubs() {
8614
- return {
8615
- name: "miaoda-known-framework-dynamic-loader-stubs",
8616
- setup(esbuild) {
8617
- esbuild.onLoad({ filter: /\.(?:cjs|js)$/ }, (args) => {
8618
- const normalized = args.path.split(path25.sep).join("/");
8619
- const source = fs29.readFileSync(args.path, "utf8");
8620
- if (!normalized.includes("/node_modules/") || !Object.entries(AUDITED_FRAMEWORK_DYNAMIC_LOADER_HASHES).some(
8621
- ([suffix, hashes]) => normalized.endsWith(suffix) && hashes.includes(sha256(source))
8622
- )) {
8623
- return void 0;
8624
- }
8625
- return {
8626
- contents: neutralizeDynamicLoads(source),
8627
- loader: "js",
8628
- resolveDir: path25.dirname(args.path)
8629
- };
8630
- });
8631
- }
8632
- };
8633
- }
8634
- function classTransformerStorageResolver(projectRoot) {
8635
- const projectRequire = createRequire3(path25.join(projectRoot, "package.json"));
8636
- return {
8637
- name: "miaoda-class-transformer-storage-resolver",
8638
- setup(esbuild) {
8639
- esbuild.onResolve({ filter: /^class-transformer\/storage$/ }, () => {
8640
- try {
8641
- return {
8642
- path: projectRequire.resolve("class-transformer/cjs/storage.js")
8643
- };
8644
- } catch {
8645
- return void 0;
8646
- }
8647
- });
8648
- }
8649
- };
8650
- }
8651
- function resolveProjectPackage(projectRoot, specifier) {
8652
- return createRequire3(path25.join(projectRoot, "package.json")).resolve(
8653
- specifier
8654
- );
8655
- }
8656
- function fullstackNestRuntimeResolver(projectRoot) {
8657
- return {
8658
- name: "miaoda-fullstack-nest-runtime-resolver",
8659
- setup(esbuild) {
8660
- esbuild.onResolve(
8661
- { filter: /^@lark-apaas\/fullstack-nestjs-core$/ },
8662
- () => {
8663
- try {
8664
- return {
8665
- path: resolveProjectPackage(
8666
- projectRoot,
8667
- "@lark-apaas/fullstack-nestjs-core/runtime"
8668
- )
8669
- };
8670
- } catch {
8671
- try {
8672
- return {
8673
- path: resolveProjectPackage(
8674
- projectRoot,
8675
- "@lark-apaas/fullstack-nestjs-core"
8676
- )
8677
- };
8678
- } catch (error) {
8679
- return {
8680
- errors: [
8681
- {
8682
- text: `@lark-apaas/fullstack-nestjs-core cannot be resolved from project: ${error instanceof Error ? error.message : String(error)}`
8683
- }
8684
- ]
8685
- };
8686
- }
8687
- }
8688
- }
8689
- );
8690
- }
8691
- };
8692
- }
8693
- function legacyFullstackNestOpenApiStub(projectRoot) {
8694
- let runtimeOnlyEntryAvailable = false;
8695
- try {
8696
- resolveProjectPackage(
8697
- projectRoot,
8698
- "@lark-apaas/fullstack-nestjs-core/runtime"
8699
- );
8700
- runtimeOnlyEntryAvailable = true;
8701
- } catch {
8702
- }
8703
- return {
8704
- name: "miaoda-legacy-nest-openapi-stub",
8705
- setup(esbuild) {
8706
- if (runtimeOnlyEntryAvailable) return;
8707
- esbuild.onResolve(
8708
- { filter: /^@lark-apaas\/nestjs-openapi-devtools$/ },
8709
- () => ({
8710
- path: "@lark-apaas/nestjs-openapi-devtools",
8711
- namespace: "miaoda-legacy-nest-openapi-stub"
8712
- })
8713
- );
8714
- esbuild.onLoad(
8715
- { filter: /.*/, namespace: "miaoda-legacy-nest-openapi-stub" },
8716
- () => ({
8717
- contents: "class DisabledOpenApiModule { static async mount() {} }\nmodule.exports = { DevToolsModule: DisabledOpenApiModule, DevToolsV2Module: DisabledOpenApiModule };",
8718
- loader: "js"
8719
- })
8720
- );
8721
- }
8722
- };
8723
- }
8724
- function findDynamicModuleLoads(code) {
8725
- const warnings = [];
8726
- const ast = parse(code, { ecmaVersion: "latest", sourceType: "script" });
8727
- walkSimple(ast, {
8728
- Identifier(node) {
8729
- if (node.name === "createRequire") {
8730
- warnings.push("node createRequire remains in bundle");
8731
- }
8732
- },
8733
- MemberExpression(node) {
8734
- if (node.computed && node.property.type === "Literal" && node.property.value === "createRequire") {
8735
- warnings.push("node createRequire remains in bundle");
8736
- }
8737
- },
8738
- CallExpression(node) {
8739
- const args = node.arguments;
8740
- const isRequire = node.callee.type === "Identifier" && (node.callee.name === "require" || node.callee.name === "__require") || node.callee.type === "MemberExpression" && node.callee.object.type === "Identifier" && node.callee.object.name === "module" && (node.callee.property.type === "Identifier" && node.callee.property.name === "require" || node.callee.property.type === "Literal" && node.callee.property.value === "require");
8741
- const isRequireResolve = node.callee.type === "MemberExpression" && node.callee.object.type === "Identifier" && (node.callee.object.name === "require" || node.callee.object.name === "__require") && node.callee.property.type === "Identifier" && node.callee.property.name === "resolve";
8742
- if (isRequire && args[0]?.type !== "Literal") {
8743
- warnings.push("dynamic require remains in bundle");
8744
- } else if (isRequireResolve && args[0]?.type === "Literal" && typeof args[0].value === "string" && !BUILTINS.has(args[0].value)) {
8745
- warnings.push(`require.resolve remains in bundle: ${args[0].value}`);
8746
- } else if (isRequireResolve && (args[0]?.type !== "Literal" || typeof args[0].value !== "string")) {
8747
- warnings.push("dynamic require.resolve remains in bundle");
8748
- }
8749
- },
8750
- ImportExpression(node) {
8751
- if (node.source.type !== "Literal" || typeof node.source.value !== "string") {
8752
- warnings.push("dynamic import remains in bundle");
8753
- }
8754
- }
8755
- });
8756
- walkAncestor(ast, {
8757
- Identifier(node, _state, ancestors) {
8758
- if (node.name !== "require" && node.name !== "__require") return;
8759
- const parent = ancestors.at(-2);
8760
- const grandparent = ancestors.at(-3);
8761
- if (node.name === "__require" && (parent?.type === "FunctionExpression" || parent?.type === "FunctionDeclaration") && parent.id === node) {
8762
- return;
8763
- }
8764
- if (parent?.type === "CallExpression" && parent.callee === node && parent.arguments[0]?.type === "Literal" && typeof parent.arguments[0].value === "string" && BUILTINS.has(parent.arguments[0].value)) {
8765
- return;
8766
- }
8767
- if (parent?.type === "MemberExpression" && parent.object === node && memberPropertyName(parent.property) === "resolve" && grandparent?.type === "CallExpression" && grandparent.callee === parent && grandparent.arguments[0]?.type === "Literal" && typeof grandparent.arguments[0].value === "string" && BUILTINS.has(grandparent.arguments[0].value)) {
8768
- return;
8769
- }
8770
- if (parent?.type === "UnaryExpression" && parent.operator === "typeof") {
8771
- return;
8772
- }
8773
- const member = parent?.type === "MemberExpression" && parent.object === node ? memberPropertyName(parent.property) : void 0;
8774
- warnings.push(
8775
- `${node.name} value escapes static call${member ? ` via ${member}` : ""}`
8776
- );
8777
- },
8778
- MemberExpression(node, _state, ancestors) {
8779
- if (node.object.type !== "Identifier" || node.object.name !== "module" || memberPropertyName(node.property) !== "require") {
8780
- return;
8781
- }
8782
- const parent = ancestors.at(-2);
8783
- if (parent?.type === "CallExpression" && parent.callee === node && parent.arguments[0]?.type === "Literal" && typeof parent.arguments[0].value === "string" && BUILTINS.has(parent.arguments[0].value)) {
8784
- return;
8785
- }
8786
- warnings.push("module.require value escapes static call");
8787
- }
8788
- });
8789
- return [...new Set(warnings)];
8790
- }
8791
- function memberPropertyName(node) {
8792
- if (!node || typeof node !== "object") return void 0;
8793
- const candidate = node;
8794
- if (candidate.type === "Identifier") return candidate.name;
8795
- if (candidate.type === "Literal" && typeof candidate.value === "string") {
8796
- return candidate.value;
8797
- }
8798
- if (candidate.type === "MemberExpression") {
8799
- return memberPropertyName(candidate.property);
8800
- }
8801
- return void 0;
8802
- }
8803
- function expressionContainsNodeModulesPath(node) {
8804
- const fragments = [];
8805
- const visit = (value) => {
8806
- if (!value || typeof value !== "object") return;
8807
- if (Array.isArray(value)) {
8808
- for (const item of value) visit(item);
8809
- return;
8810
- }
8811
- const candidate = value;
8812
- if (candidate.type === "Literal" && typeof candidate.value === "string") {
8813
- fragments.push(candidate.value);
8814
- return;
8815
- }
8816
- if (candidate.type === "TemplateElement") {
8817
- const templateValue = candidate.value;
8818
- const text = templateValue?.cooked ?? templateValue?.raw;
8819
- if (typeof text === "string") fragments.push(text);
8820
- return;
8821
- }
8822
- for (const [key, child] of Object.entries(candidate)) {
8823
- if (key === "start" || key === "end" || key === "loc") continue;
8824
- visit(child);
8825
- }
8826
- };
8827
- visit(node);
8828
- return /(?:^|[\\/])node_modules(?:[\\/]|$)/.test(
8829
- fragments.join("/").replace(/\\\\/g, "/")
8830
- );
8831
- }
8832
- function expressionContainsIdentifier(node, name) {
8833
- if (!node || typeof node !== "object") return false;
8834
- if (Array.isArray(node)) {
8835
- return node.some((item) => expressionContainsIdentifier(item, name));
8836
- }
8837
- const candidate = node;
8838
- if (candidate.type === "Identifier" && candidate.name === name) return true;
8839
- return Object.entries(candidate).some(
8840
- ([key, child]) => key !== "start" && key !== "end" && key !== "loc" && expressionContainsIdentifier(child, name)
8841
- );
8842
- }
8843
- function findNodeModulesRuntimeAssetReads(code, origin, rejectEveryRead) {
8844
- const warnings = [];
8845
- const ast = parse(code, {
8846
- ecmaVersion: "latest",
8847
- sourceType: "module",
8848
- allowHashBang: true,
8849
- allowReturnOutsideFunction: true
8850
- });
8851
- walkSimple(ast, {
8852
- CallExpression(node) {
8853
- const method = memberPropertyName(node.callee);
8854
- if (method && RUNTIME_ASSET_READ_METHODS.has(method) && rejectEveryRead) {
8855
- warnings.push(`dependency runtime fs read in input: ${origin}`);
8856
- } else if (method && RUNTIME_ASSET_READ_METHODS.has(method) && expressionContainsNodeModulesPath(node.arguments[0])) {
8857
- warnings.push(`node_modules runtime asset read in input: ${origin}`);
8858
- } else if (method && RUNTIME_ASSET_READ_METHODS.has(method) && expressionContainsIdentifier(node.arguments[0], "__dirname")) {
8859
- warnings.push(`__dirname runtime asset read in input: ${origin}`);
8860
- }
8861
- }
8862
- });
8863
- return warnings;
8864
- }
8865
- function findUnsafeApplicationModuleLoads(projectRoot, applicationRoot, inputFiles) {
8866
- const realApplicationRoot = fs29.realpathSync(applicationRoot);
8867
- const warnings = [];
8868
- for (const input of inputFiles) {
8869
- const candidate = path25.isAbsolute(input) ? input : path25.resolve(projectRoot, input);
8870
- if (!fs29.existsSync(candidate)) continue;
8871
- const realInput = fs29.realpathSync(candidate);
8872
- if (!/\.(?:cjs|mjs|js)$/.test(realInput)) continue;
8873
- const source = fs29.readFileSync(realInput, "utf8");
8874
- const isDependencyInput = realInput.split(path25.sep).includes("node_modules");
8875
- const normalizedInput = realInput.split(path25.sep).join("/");
8876
- const auditedRuntimeFsReader = isDependencyInput && Object.entries(AUDITED_RUNTIME_FS_READER_HASHES).some(
8877
- ([suffix, hashes]) => normalizedInput.endsWith(suffix) && hashes.includes(sha256(source))
8878
- );
8879
- const origin = path25.relative(projectRoot, realInput).split(path25.sep).join("/");
8880
- warnings.push(
8881
- ...findNodeModulesRuntimeAssetReads(
8882
- source,
8883
- origin,
8884
- isDependencyInput && !auditedRuntimeFsReader
8885
- )
8886
- );
8887
- if (!isInside(realApplicationRoot, realInput) || isDependencyInput) {
8888
- continue;
8889
- }
8890
- const ast = parse(source, {
8891
- ecmaVersion: "latest",
8892
- sourceType: "module",
8893
- allowHashBang: true,
8894
- allowReturnOutsideFunction: true
8895
- });
8896
- walkSimple(ast, {
8897
- CallExpression(node) {
8898
- const isRequire = node.callee.type === "Identifier" && (node.callee.name === "require" || node.callee.name === "__require") || node.callee.type === "MemberExpression" && node.callee.object.type === "Identifier" && node.callee.object.name === "module" && (node.callee.property.type === "Identifier" && node.callee.property.name === "require" || node.callee.property.type === "Literal" && node.callee.property.value === "require");
8899
- const isRequireResolve = node.callee.type === "MemberExpression" && node.callee.object.type === "Identifier" && (node.callee.object.name === "require" || node.callee.object.name === "__require") && node.callee.property.type === "Identifier" && node.callee.property.name === "resolve";
8900
- if (isRequire && node.arguments[0]?.type !== "Literal") {
8901
- warnings.push(`dynamic require in application input: ${origin}`);
8902
- }
8903
- if (isRequireResolve && (node.arguments[0]?.type !== "Literal" || typeof node.arguments[0].value !== "string")) {
8904
- warnings.push(
8905
- `dynamic require.resolve in application input: ${origin}`
8906
- );
8907
- }
8908
- },
8909
- ImportExpression(node) {
8910
- if (node.source.type !== "Literal" || typeof node.source.value !== "string") {
8911
- warnings.push(`dynamic import in application input: ${origin}`);
8912
- }
8913
- }
8914
- });
8915
- }
8916
- return [...new Set(warnings)].sort();
8917
- }
8918
- function reservePort() {
8919
- return new Promise((resolve2, reject) => {
8920
- const server = net.createServer();
8921
- server.once("error", reject);
8922
- server.listen(0, "127.0.0.1", () => {
8923
- const address = server.address();
8924
- if (!address || typeof address === "string") {
8925
- server.close(
8926
- () => reject(new Error("isolated probe failed to reserve a port"))
8927
- );
8928
- return;
8929
- }
8930
- server.close((error) => error ? reject(error) : resolve2(address.port));
8931
- });
8932
- });
8933
- }
8934
- function waitForExit(child) {
8935
- if (child.exitCode !== null || child.signalCode !== null)
8936
- return Promise.resolve();
8937
- return new Promise((resolve2) => child.once("exit", () => resolve2()));
8938
- }
8939
- function readLinuxProcessIdentity(pid) {
8940
- if (process.platform !== "linux") return void 0;
8941
- try {
8942
- const stat = fs29.readFileSync(`/proc/${pid}/stat`, "utf8");
8943
- const commandEnd = stat.lastIndexOf(")");
8944
- if (commandEnd < 0) return void 0;
8945
- const fields = stat.slice(commandEnd + 1).trim().split(/\s+/);
8946
- return /^\d+$/.test(fields[19] || "") && /^\d+$/.test(fields[2] || "") ? { processStartTicks: fields[19], processGroupId: Number(fields[2]) } : void 0;
8947
- } catch {
8948
- return void 0;
8949
- }
8950
- }
8951
- function registerProbe(child) {
8952
- if (!child.pid) throw new Error("isolated process pid unavailable");
8953
- const identity = readLinuxProcessIdentity(child.pid);
8954
- if (process.platform === "linux" && !identity) {
8955
- child.kill("SIGKILL");
8956
- throw new Error("isolated process birth identity unavailable");
8957
- }
8958
- probeIdentities.set(child, {
8959
- pid: child.pid,
8960
- processStartTicks: identity?.processStartTicks
8961
- });
8962
- }
8963
- function probeGroupRunning(child) {
8964
- const registered = probeIdentities.get(child);
8965
- if (!registered) return false;
8966
- if (process.platform === "linux") {
8967
- const current = readLinuxProcessIdentity(registered.pid);
8968
- if (current) {
8969
- if (current.processStartTicks !== registered.processStartTicks || current.processGroupId !== registered.pid) {
8970
- return false;
8971
- }
8972
- } else {
8973
- try {
8974
- process.kill(registered.pid, 0);
8975
- return false;
8976
- } catch (error) {
8977
- if (error.code !== "ESRCH") return false;
8978
- }
8979
- }
8980
- }
8981
- try {
8982
- process.kill(-registered.pid, 0);
8983
- return true;
8984
- } catch (error) {
8985
- return error.code === "EPERM";
8986
- }
8987
- }
8988
- async function waitForProbeGroup(child, timeoutMs) {
8989
- const deadline = Date.now() + timeoutMs;
8990
- while (probeGroupRunning(child) && Date.now() < deadline) {
8991
- await new Promise((resolve2) => setTimeout(resolve2, 25));
8992
- }
8993
- return !probeGroupRunning(child);
8994
- }
8995
- async function stopProbe(child) {
8996
- const registered = probeIdentities.get(child);
8997
- if (!registered) return;
8998
- if (probeGroupRunning(child)) {
8999
- try {
9000
- process.kill(-registered.pid, "SIGTERM");
9001
- } catch {
9002
- }
9003
- }
9004
- if (!await waitForProbeGroup(child, 500)) {
9005
- if (probeGroupRunning(child)) {
9006
- try {
9007
- process.kill(-registered.pid, "SIGKILL");
9008
- } catch {
9009
- }
9010
- }
9011
- if (!await waitForProbeGroup(child, 500)) {
9012
- throw new Error(
9013
- `isolated probe process group did not exit: ${registered.pid}`
9014
- );
9015
- }
9016
- }
9017
- await waitForExit(child);
9018
- }
9019
- function resolveNestTsconfig(projectRoot) {
9020
- const nestConfigFile = path25.join(projectRoot, "nest-cli.json");
9021
- let configured;
9022
- if (fs29.existsSync(nestConfigFile)) {
9023
- const nestConfig = JSON.parse(fs29.readFileSync(nestConfigFile, "utf8"));
9024
- configured = nestConfig.compilerOptions?.tsConfigPath;
9025
- if (configured !== void 0 && typeof configured !== "string") {
9026
- throw new Error("nest-cli.json compilerOptions.tsConfigPath is invalid");
9027
- }
9028
- }
9029
- const candidates = typeof configured === "string" ? [configured] : ["tsconfig.build.json", "tsconfig.node.json", "tsconfig.json"];
9030
- const selected = candidates.map((candidate) => path25.resolve(projectRoot, candidate)).find((candidate) => fs29.existsSync(candidate));
9031
- if (!selected) {
9032
- throw new Error(`Nest TypeScript config missing: ${candidates.join(", ")}`);
9033
- }
9034
- if (!isInside(projectRoot, selected))
9035
- throw new Error("Nest TypeScript config escaped project root");
9036
- if (fs29.lstatSync(selected).isSymbolicLink())
9037
- throw new Error("Nest TypeScript config symlink is unsupported");
9038
- const realConfig = fs29.realpathSync(selected);
9039
- if (!isInside(projectRoot, realConfig) || !fs29.statSync(realConfig).isFile()) {
9040
- throw new Error("Nest TypeScript config escaped project root");
9041
- }
9042
- return realConfig;
9043
- }
9044
- function resolveLocalTsconfigReference(projectRoot, fromFile, requested) {
9045
- if (!path25.isAbsolute(requested) && !requested.startsWith(".")) {
9046
- return void 0;
9047
- }
9048
- const base = path25.isAbsolute(requested) ? requested : path25.resolve(path25.dirname(fromFile), requested);
9049
- const candidate = [
9050
- base,
9051
- `${base}.json`,
9052
- path25.join(base, "tsconfig.json")
9053
- ].find((file) => fs29.existsSync(file));
9054
- if (!candidate) return void 0;
9055
- const realCandidate = fs29.realpathSync(candidate);
9056
- if (!isInside(projectRoot, realCandidate)) {
9057
- throw new Error("local TypeScript config escaped project root");
9058
- }
9059
- return realCandidate;
9060
- }
9061
- function sourceInputRecords(projectRoot, inputFiles) {
9062
- const records = /* @__PURE__ */ new Map();
9063
- for (const inputFile of inputFiles) {
9064
- if (!fs29.existsSync(inputFile)) continue;
9065
- if (fs29.lstatSync(inputFile).isSymbolicLink()) {
9066
- throw new Error(
9067
- `source input symlink is unsupported: ${path25.relative(projectRoot, inputFile)}`
9068
- );
9069
- }
9070
- const realFile = fs29.realpathSync(inputFile);
9071
- if (!isInside(projectRoot, realFile) || !fs29.statSync(realFile).isFile()) {
9072
- throw new Error("source input escaped project root");
9073
- }
9074
- const relative = path25.relative(projectRoot, realFile).split(path25.sep).join("/");
9075
- const contents = fs29.readFileSync(realFile);
9076
- records.set(relative, {
9077
- path: relative,
9078
- sha256: sha256(contents),
9079
- size: contents.length
9080
- });
9081
- }
9082
- return [...records.values()].sort(
9083
- (left, right) => left.path.localeCompare(right.path)
9084
- );
9085
- }
9086
- function nestCompilationSourceInputs(projectRoot, sourceConfig) {
9087
- const projectRequire = createRequire3(path25.join(projectRoot, "package.json"));
9088
- const typescript = projectRequire(
9089
- "typescript"
9090
- );
9091
- const configFiles = /* @__PURE__ */ new Set();
9092
- const visitConfig = (configFile) => {
9093
- const realConfig = fs29.realpathSync(configFile);
9094
- if (configFiles.has(realConfig)) return;
9095
- if (!isInside(projectRoot, realConfig)) return;
9096
- configFiles.add(realConfig);
9097
- const loaded2 = typescript.readConfigFile(
9098
- realConfig,
9099
- typescript.sys.readFile
9100
- );
9101
- if (loaded2.error) {
9102
- throw new Error(`TypeScript config cannot be read: ${realConfig}`);
9103
- }
9104
- const extended = Array.isArray(loaded2.config?.extends) ? loaded2.config.extends : loaded2.config?.extends ? [loaded2.config.extends] : [];
9105
- for (const requested of extended) {
9106
- if (typeof requested !== "string") continue;
9107
- const local = resolveLocalTsconfigReference(
9108
- projectRoot,
9109
- realConfig,
9110
- requested
9111
- );
9112
- if (local) visitConfig(local);
9113
- }
9114
- for (const reference of loaded2.config?.references ?? []) {
9115
- if (typeof reference?.path !== "string") continue;
9116
- const local = resolveLocalTsconfigReference(
9117
- projectRoot,
9118
- realConfig,
9119
- reference.path
9120
- );
9121
- if (local) visitConfig(local);
9122
- }
9123
- };
9124
- visitConfig(sourceConfig);
9125
- const loaded = typescript.readConfigFile(
9126
- sourceConfig,
9127
- typescript.sys.readFile
9128
- );
9129
- if (loaded.error) {
9130
- throw new Error(`TypeScript config cannot be read: ${sourceConfig}`);
9131
- }
9132
- const parsed = typescript.parseJsonConfigFileContent(
9133
- loaded.config,
9134
- typescript.sys,
9135
- path25.dirname(sourceConfig),
9136
- { noEmit: true, incremental: false, composite: false },
9137
- sourceConfig
9138
- );
9139
- if (parsed.errors.length > 0) {
9140
- throw new Error("TypeScript config contains errors");
9141
- }
9142
- const program = typescript.createProgram({
9143
- rootNames: parsed.fileNames,
9144
- options: parsed.options,
9145
- projectReferences: parsed.projectReferences
9146
- });
9147
- const inputs = new Set(configFiles);
9148
- for (const sourceFile of program.getSourceFiles()) {
9149
- if (!fs29.existsSync(sourceFile.fileName)) continue;
9150
- const realFile = fs29.realpathSync(sourceFile.fileName);
9151
- const relative = path25.relative(projectRoot, realFile);
9152
- if (isInside(projectRoot, realFile) && !relative.split(path25.sep).includes("node_modules")) {
9153
- inputs.add(realFile);
9154
- }
9155
- }
9156
- for (const name of ["package.json", "nest-cli.json"]) {
9157
- const file = path25.join(projectRoot, name);
9158
- if (fs29.existsSync(file)) inputs.add(file);
9159
- }
9160
- return sourceInputRecords(projectRoot, inputs);
9161
- }
9162
- function sourceIdentitySha256(workspaceTreeSha256, sourceInputs) {
9163
- return sha256(JSON.stringify({ sourceInputs, workspaceTreeSha256 }));
9164
- }
9165
- function resolveNestCli(projectRoot) {
9166
- const projectRequire = createRequire3(path25.join(projectRoot, "package.json"));
9167
- try {
9168
- return projectRequire.resolve("@nestjs/cli/bin/nest.js");
9169
- } catch (directError) {
9170
- try {
9171
- const packageFile = projectRequire.resolve("@nestjs/cli/package.json");
9172
- const packageJson = JSON.parse(fs29.readFileSync(packageFile, "utf8"));
9173
- const relativeBin = typeof packageJson.bin === "string" ? packageJson.bin : packageJson.bin?.nest;
9174
- if (!relativeBin) throw new Error("@nestjs/cli has no nest binary");
9175
- const cliFile = path25.resolve(path25.dirname(packageFile), relativeBin);
9176
- if (!fs29.statSync(cliFile).isFile())
9177
- throw new Error("@nestjs/cli nest binary is not a file");
9178
- return cliFile;
9179
- } catch (packageError) {
9180
- throw new Error(
9181
- `project @nestjs/cli is unavailable: ${packageError instanceof Error ? packageError.message : String(packageError)}; direct=${directError instanceof Error ? directError.message : String(directError)}`
9182
- );
9183
- }
9184
- }
9185
- }
9186
- function collectChildOutput(child, stream) {
9187
- let output = "";
9188
- child[stream]?.setEncoding("utf8");
9189
- child[stream]?.on("data", (chunk) => {
9190
- output = `${output}${String(chunk)}`.slice(-64 * 1024);
9191
- });
9192
- return () => output;
9193
- }
9194
- async function waitForCommand(child, timeoutMs, description) {
9195
- let timer;
9196
- try {
9197
- return await new Promise((resolve2, reject) => {
9198
- let settled = false;
9199
- const finish = (callback) => {
9200
- if (settled) return;
9201
- settled = true;
9202
- if (timer) clearTimeout(timer);
9203
- callback();
9204
- };
9205
- child.once("error", (error) => finish(() => reject(error)));
9206
- child.once(
9207
- "exit",
9208
- (code, signal) => finish(
9209
- () => signal ? reject(new Error(`${description} exited by ${signal}`)) : resolve2(code ?? 1)
9210
- )
9211
- );
9212
- timer = setTimeout(
9213
- () => finish(() => reject(new Error(`${description} timeout`))),
9214
- timeoutMs
9215
- );
9216
- });
9217
- } finally {
9218
- if (timer) clearTimeout(timer);
9219
- }
9220
- }
9221
- async function compileNestSource(projectRoot, stagingRoot, timeoutMs, sourceConfig) {
9222
- const cliFile = resolveNestCli(projectRoot);
9223
- const compileRoot = path25.join(stagingRoot, ".compiled");
9224
- const outputRoot = path25.join(compileRoot, "output");
9225
- fs29.mkdirSync(outputRoot, { recursive: true });
9226
- const isolatedConfig = path25.join(compileRoot, "tsconfig.json");
9227
- fs29.writeFileSync(
9228
- isolatedConfig,
9229
- `${JSON.stringify(
9230
- {
9231
- extends: sourceConfig,
9232
- compilerOptions: {
9233
- outDir: outputRoot,
9234
- incremental: false,
9235
- composite: false,
9236
- declaration: false,
9237
- declarationMap: false,
9238
- sourceMap: false,
9239
- inlineSourceMap: false
9240
- }
9241
- },
9242
- null,
9243
- 2
9244
- )}
9245
- `,
9246
- { mode: 384 }
9247
- );
9248
- const child = spawn2(
9249
- process.execPath,
9250
- [cliFile, "build", "--path", path25.relative(projectRoot, isolatedConfig)],
9251
- {
9252
- cwd: projectRoot,
9253
- detached: true,
9254
- stdio: ["ignore", "pipe", "pipe"],
9255
- env: { ...process.env, NODE_ENV: "production" }
9256
- }
9257
- );
9258
- registerProbe(child);
9259
- const stdout = collectChildOutput(child, "stdout");
9260
- const stderr = collectChildOutput(child, "stderr");
9261
- try {
9262
- const code = await waitForCommand(
9263
- child,
9264
- timeoutMs,
9265
- "isolated Nest compilation"
9266
- );
9267
- if (code !== 0) {
9268
- throw new Error(
9269
- `isolated Nest compilation failed with exit ${code}: ${stderr().trim() || stdout().trim()}`
9270
- );
9271
- }
9272
- } finally {
9273
- await stopProbe(child);
9274
- }
9275
- const candidates = [
9276
- path25.join(outputRoot, "server", "main.js"),
9277
- path25.join(outputRoot, "main.js")
9278
- ].filter((candidate) => fs29.existsSync(candidate));
9279
- if (candidates.length !== 1) {
9280
- throw new Error(
9281
- candidates.length === 0 ? "isolated Nest compiled entry missing; checked server/main.js and main.js" : "isolated Nest compiled entry is ambiguous"
9282
- );
9283
- }
9284
- const entry = fs29.realpathSync(candidates[0]);
9285
- if (!isInside(fs29.realpathSync(outputRoot), entry) || !fs29.statSync(entry).isFile()) {
9286
- throw new Error("isolated Nest compiled entry escaped output root");
9287
- }
9288
- return {
9289
- entry,
9290
- applicationRoot: outputRoot,
9291
- manifestEntry: `.isolated/${path25.relative(outputRoot, entry).split(path25.sep).join("/")}`
9292
- };
9293
- }
9294
- async function isolatedProbe(bundleFile, timeoutMs) {
9295
- const probeRoot = fs29.mkdtempSync(
9296
- path25.join(os3.tmpdir(), "miaoda-server-bundle-probe-")
9297
- );
9298
- const probeBundle = path25.join(probeRoot, "server.bundle.cjs");
9299
- fs29.copyFileSync(bundleFile, probeBundle);
9300
- const port = await reservePort();
9301
- const configuredBasePath = process.env.CLIENT_BASE_PATH;
9302
- const basePath = configuredBasePath?.startsWith("/") && !configuredBasePath.startsWith("//") ? configuredBasePath.replace(/\/+$/, "") : "";
9303
- const readinessPath = `${basePath}/__innerapi__/capability/list`;
9304
- const startedAt = Date.now();
9305
- const child = spawn2(process.execPath, [probeBundle], {
9306
- cwd: probeRoot,
9307
- detached: true,
9308
- stdio: ["ignore", "pipe", "pipe"],
9309
- env: {
9310
- ...process.env,
9311
- NODE_PATH: "",
9312
- NODE_ENV: "development",
9313
- SERVER_HOST: "127.0.0.1",
9314
- SERVER_PORT: String(port),
9315
- MIAODA_SERVER_CACHE_PROBE: "true",
9316
- DEPRECATED_SKIP_INIT_DB_CONNECTION: process.env.DEPRECATED_SKIP_INIT_DB_CONNECTION ?? "true",
9317
- FORCE_AUTHN_INNERAPI_DOMAIN: process.env.FORCE_AUTHN_INNERAPI_DOMAIN ?? "http://127.0.0.1",
9318
- FORCE_AUTHN_ACCESS_KEY: process.env.FORCE_AUTHN_ACCESS_KEY ?? "server-startup-probe",
9319
- FORCE_AUTHN_ACCESS_SECRET: process.env.FORCE_AUTHN_ACCESS_SECRET ?? "server-startup-probe"
9320
- }
9321
- });
9322
- registerProbe(child);
9323
- let stdout = "";
9324
- let stderr = "";
9325
- child.stdout?.setEncoding("utf8");
9326
- child.stdout?.on("data", (chunk) => {
9327
- stdout = `${stdout}${String(chunk)}`.slice(-64 * 1024);
9328
- });
9329
- child.stderr?.setEncoding("utf8");
9330
- child.stderr?.on("data", (chunk) => {
9331
- stderr += String(chunk);
9332
- });
9333
- try {
9334
- await new Promise((resolve2, reject) => {
9335
- const deadline = Date.now() + timeoutMs;
9336
- const timeoutError = () => new Error(
9337
- `isolated bundle readiness timeout${`${stderr}
9338
- ${stdout}`.trim() ? `: ${`${stderr}
9339
- ${stdout}`.trim()}` : ""}`
9340
- );
9341
- let settled = false;
9342
- let retryTimer;
9343
- const finish = (error) => {
9344
- if (settled) return;
9345
- settled = true;
9346
- if (retryTimer) clearTimeout(retryTimer);
9347
- if (error) reject(error);
9348
- else resolve2();
9349
- };
9350
- const retry = () => {
9351
- if (settled) return;
9352
- const remaining = deadline - Date.now();
9353
- if (remaining <= 0) {
9354
- finish(timeoutError());
9355
- return;
9356
- }
9357
- retryTimer = setTimeout(attempt, Math.min(25, remaining));
9358
- };
9359
- const attempt = () => {
9360
- if (settled) return;
9361
- if (child.exitCode !== null || child.signalCode !== null) {
9362
- finish(
9363
- new Error(
9364
- `isolated bundle exited before readiness: ${stderr.trim()}`
9365
- )
9366
- );
9367
- return;
9368
- }
9369
- const remaining = deadline - Date.now();
9370
- if (remaining <= 0) {
9371
- finish(timeoutError());
9372
- return;
9373
- }
9374
- let attemptSettled = false;
9375
- const request = http.get(
9376
- { host: "127.0.0.1", port, path: readinessPath },
9377
- (response) => {
9378
- if (attemptSettled || settled) {
9379
- response.destroy();
9380
- return;
9381
- }
9382
- attemptSettled = true;
9383
- response.resume();
9384
- if ((response.statusCode ?? 500) < 500) finish();
9385
- else retry();
9386
- }
9387
- );
9388
- request.setTimeout(remaining, () => {
9389
- request.destroy(new Error("isolated bundle readiness timeout"));
9390
- });
9391
- request.once("error", (error) => {
9392
- if (attemptSettled || settled) return;
9393
- attemptSettled = true;
9394
- if (Date.now() >= deadline || error.message === "isolated bundle readiness timeout") {
9395
- finish(timeoutError());
9396
- } else {
9397
- retry();
9398
- }
9399
- });
9400
- };
9401
- attempt();
9402
- });
9403
- if (fs29.existsSync(path25.join(probeRoot, "node_modules"))) {
9404
- throw new Error("isolated probe unexpectedly contained node_modules");
9405
- }
9406
- return Date.now() - startedAt;
9407
- } finally {
9408
- await stopProbe(child);
9409
- fs29.rmSync(probeRoot, { recursive: true, force: true });
9410
- }
9411
- }
9412
- function atomicWriteJson(file, value) {
9413
- fs29.mkdirSync(path25.dirname(file), { recursive: true });
9414
- const temporary = `${file}.${process.pid}.${randomUUID()}.tmp`;
9415
- fs29.writeFileSync(temporary, `${JSON.stringify(value, null, 2)}
9416
- `, {
9417
- mode: 384
9418
- });
9419
- fs29.renameSync(temporary, file);
9420
- }
9421
- function snapshotCurrentPointer(file) {
9422
- if (!fs29.existsSync(file)) return void 0;
9423
- if (fs29.lstatSync(file).isSymbolicLink()) {
9424
- throw new Error("current pointer symlink is unsupported");
9425
- }
9426
- const stats = fs29.statSync(file);
9427
- if (!stats.isFile()) throw new Error("current pointer is not a file");
9428
- return { file, dev: stats.dev, ino: stats.ino };
9429
- }
9430
- function invalidateCurrentPointerIfUnchanged(identity) {
9431
- if (!identity || !fs29.existsSync(identity.file)) return;
9432
- const stats = fs29.lstatSync(identity.file);
9433
- if (stats.isSymbolicLink() || !stats.isFile() || stats.dev !== identity.dev || stats.ino !== identity.ino) {
9434
- return;
9435
- }
9436
- fs29.unlinkSync(identity.file);
9437
- }
9438
- function stableJson(value) {
9439
- if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
9440
- if (value && typeof value === "object") {
9441
- return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => `${JSON.stringify(key)}:${stableJson(item)}`).join(",")}}`;
9442
- }
9443
- return JSON.stringify(value);
9444
- }
9445
- function assertExistingGenerationEquivalent(generationRoot, generationsRoot, expectedBundle, expectedManifest) {
9446
- const mismatch = () => new Error("immutable generation already exists with different content");
9447
- if (fs29.lstatSync(generationRoot).isSymbolicLink()) throw mismatch();
9448
- const realGenerationRoot = fs29.realpathSync(generationRoot);
9449
- if (!isInside(generationsRoot, realGenerationRoot) || !fs29.statSync(realGenerationRoot).isDirectory()) {
9450
- throw mismatch();
9451
- }
9452
- const bundleFile = path25.join(realGenerationRoot, "server.bundle.cjs");
9453
- const manifestFile = path25.join(realGenerationRoot, "manifest.json");
9454
- if (fs29.lstatSync(bundleFile).isSymbolicLink() || fs29.lstatSync(manifestFile).isSymbolicLink() || !fs29.statSync(bundleFile).isFile() || !fs29.statSync(manifestFile).isFile()) {
9455
- throw mismatch();
9456
- }
9457
- const existingBundle = fs29.readFileSync(bundleFile);
9458
- const existingManifest = JSON.parse(
9459
- fs29.readFileSync(manifestFile, "utf8")
9460
- );
9461
- const existingStartupMs = existingManifest?.isolatedProbe?.startupMs;
9462
- if (sha256(existingBundle) !== sha256(expectedBundle) || !Number.isFinite(existingStartupMs) || existingStartupMs < 0) {
9463
- throw mismatch();
9464
- }
9465
- const expectedWithExistingProbeTime = {
9466
- ...expectedManifest,
9467
- isolatedProbe: {
9468
- ...expectedManifest.isolatedProbe,
9469
- startupMs: existingStartupMs
9470
- }
9471
- };
9472
- if (stableJson(existingManifest) !== stableJson(expectedWithExistingProbeTime))
9473
- throw mismatch();
9474
- }
9475
- async function buildServerStartupBundle(options) {
9476
- const startedAt = Date.now();
9477
- let stagingRoot;
9478
- let currentPointerIdentity;
9479
- try {
9480
- const projectRoot = fs29.realpathSync(path25.resolve(options.projectRoot));
9481
- const cacheRoot = path25.resolve(
9482
- projectRoot,
9483
- options.cacheRoot ?? ".miaoda-cache/server"
9484
- );
9485
- if (!isInside(projectRoot, cacheRoot))
9486
- throw new Error("cache root escaped project root");
9487
- assertNoSymlinkComponents(
9488
- projectRoot,
9489
- cacheRoot,
9490
- "cache path symlink is unsupported"
9491
- );
9492
- currentPointerIdentity = snapshotCurrentPointer(
9493
- path25.join(cacheRoot, "current.json")
9494
- );
9495
- const timeoutMs = options.probeTimeoutMs ?? 1e4;
9496
- if (!Number.isFinite(timeoutMs) || timeoutMs <= 0)
9497
- throw new Error("probe timeout must be positive");
9498
- const compileTimeoutMs = options.compileTimeoutMs ?? 12e4;
9499
- if (!Number.isFinite(compileTimeoutMs) || compileTimeoutMs <= 0)
9500
- throw new Error("compile timeout must be positive");
9501
- const explicitEntry = options.entry ? resolveEntry(projectRoot, options.entry) : void 0;
9502
- const sourceConfig = explicitEntry ? void 0 : resolveNestTsconfig(projectRoot);
9503
- const readSourceInputs = () => explicitEntry ? sourceInputRecords(
9504
- projectRoot,
9505
- [
9506
- explicitEntry,
9507
- path25.join(projectRoot, "package.json"),
9508
- path25.join(projectRoot, "nest-cli.json")
9509
- ].filter((file) => fs29.existsSync(file))
9510
- ) : nestCompilationSourceInputs(projectRoot, sourceConfig);
9511
- const sourceInputs = readSourceInputs();
9512
- const readSourceIdentity = () => sourceIdentitySha256(
9513
- workspaceSourceSha256(projectRoot),
9514
- readSourceInputs()
9515
- );
9516
- const sourceSha256 = sourceIdentitySha256(
9517
- workspaceSourceSha256(projectRoot),
9518
- sourceInputs
9519
- );
9520
- const generationsRoot = path25.join(cacheRoot, "generations");
9521
- fs29.mkdirSync(generationsRoot, { recursive: true });
9522
- assertNoSymlinkComponents(
9523
- projectRoot,
9524
- generationsRoot,
9525
- "cache path symlink is unsupported"
9526
- );
9527
- stagingRoot = fs29.mkdtempSync(path25.join(generationsRoot, ".staging-"));
9528
- let compiled;
9529
- if (explicitEntry) {
9530
- compiled = {
9531
- entry: explicitEntry,
9532
- applicationRoot: projectRoot,
9533
- manifestEntry: path25.relative(projectRoot, explicitEntry).split(path25.sep).join("/")
9534
- };
9535
- } else {
9536
- compiled = await compileNestSource(
9537
- projectRoot,
9538
- stagingRoot,
9539
- compileTimeoutMs,
9540
- sourceConfig
9541
- );
9542
- }
9543
- const entry = compiled.entry;
9544
- if (readSourceIdentity() !== sourceSha256) {
9545
- throw new Error("source changed during isolated Nest compilation");
9546
- }
9547
- const stagingBundle = path25.join(stagingRoot, "server.bundle.cjs");
9548
- const buildResult2 = await build({
9549
- absWorkingDir: projectRoot,
9550
- entryPoints: [entry],
9551
- outfile: stagingBundle,
9552
- bundle: true,
9553
- platform: "node",
9554
- format: "cjs",
9555
- target: `node${process.versions.node.split(".")[0]}`,
9556
- metafile: true,
9557
- logLevel: "silent",
9558
- sourcemap: false,
9559
- plugins: [
9560
- knownFrameworkDynamicLoaderStubs(),
9561
- optionalNestDependencyStubs(),
9562
- fullstackNestRuntimeResolver(projectRoot),
9563
- legacyFullstackNestOpenApiStub(projectRoot),
9564
- classTransformerStorageResolver(projectRoot)
9565
- ]
9566
- });
9567
- const output = buildResult2.metafile.outputs[stagingBundle] ?? Object.values(buildResult2.metafile.outputs)[0];
9568
- const unsafeApplicationLoads = findUnsafeApplicationModuleLoads(
9569
- projectRoot,
9570
- compiled.applicationRoot,
9571
- Object.keys(buildResult2.metafile.inputs)
9572
- );
9573
- if (unsafeApplicationLoads.length > 0) {
9574
- throw new Error(unsafeApplicationLoads.join("; "));
9575
- }
9576
- const externalImports = (output?.imports ?? []).filter((item) => item.external && !BUILTINS.has(item.path)).map((item) => item.path).sort();
9577
- if (externalImports.length > 0) {
9578
- throw new Error(
9579
- `bundle contains external imports: ${externalImports.join(", ")}`
9580
- );
9581
- }
9582
- const bundle = fs29.readFileSync(stagingBundle);
9583
- const dynamicLoads = findDynamicModuleLoads(bundle.toString("utf8"));
9584
- if (dynamicLoads.length > 0) throw new Error(dynamicLoads.join("; "));
9585
- const startupMs = await isolatedProbe(stagingBundle, timeoutMs);
9586
- if (readSourceIdentity() !== sourceSha256) {
9587
- throw new Error("source changed while building startup bundle");
9588
- }
9589
- const lockfileSha256 = workspaceLockfileSha256(projectRoot);
9590
- const bundleSha256 = sha256(bundle);
9591
- const nodeMajor = Number(process.versions.node.split(".")[0]);
9592
- const generationId = sha256(
9593
- [
9594
- BUILDER_POLICY_VERSION,
9595
- sourceSha256,
9596
- lockfileSha256,
9597
- bundleSha256,
9598
- nodeMajor,
9599
- process.platform,
9600
- process.arch
9601
- ].join("\0")
9602
- );
9603
- const manifest = {
9604
- schemaVersion: 1,
9605
- builderPolicyVersion: BUILDER_POLICY_VERSION,
9606
- generationId,
9607
- entry: compiled.manifestEntry,
9608
- sourceSha256,
9609
- sourceInputs,
9610
- lockfileSha256,
9611
- bundleSha256,
9612
- nodeMajor,
9613
- platform: process.platform,
9614
- arch: process.arch,
9615
- externalImports: [],
9616
- runtimeAssets: [],
9617
- isolatedProbe: {
9618
- success: true,
9619
- nodeModulesPresent: false,
9620
- startupMs
9621
- }
9622
- };
9623
- fs29.rmSync(path25.join(stagingRoot, ".compiled"), {
9624
- recursive: true,
9625
- force: true
9626
- });
9627
- atomicWriteJson(path25.join(stagingRoot, "manifest.json"), manifest);
9628
- const generationRoot = path25.join(generationsRoot, generationId);
9629
- if (fs29.existsSync(generationRoot)) {
9630
- assertExistingGenerationEquivalent(
9631
- generationRoot,
9632
- generationsRoot,
9633
- bundle,
9634
- manifest
9635
- );
9636
- fs29.rmSync(stagingRoot, { recursive: true, force: true });
9637
- } else {
9638
- fs29.renameSync(stagingRoot, generationRoot);
9639
- }
9640
- stagingRoot = void 0;
9641
- atomicWriteJson(path25.join(cacheRoot, "current.json"), {
9642
- schemaVersion: 1,
9643
- generationId
9644
- });
9645
- return {
9646
- built: true,
9647
- generationId,
9648
- bundleFile: path25.join(generationRoot, "server.bundle.cjs"),
9649
- manifestFile: path25.join(generationRoot, "manifest.json"),
9650
- reasons: [],
9651
- elapsedMs: Date.now() - startedAt
9652
- };
9653
- } catch (error) {
9654
- if (stagingRoot) fs29.rmSync(stagingRoot, { recursive: true, force: true });
9655
- invalidateCurrentPointerIfUnchanged(currentPointerIdentity);
9656
- return {
9657
- built: false,
9658
- reasons: [error instanceof Error ? error.message : String(error)],
9659
- elapsedMs: Date.now() - startedAt
9660
- };
9661
- }
9662
- }
9663
-
9664
8263
  // src/commands/build/index.ts
9665
8264
  var getTokenCommand = {
9666
8265
  name: "get-token",
9667
8266
  description: "Get artifact upload credential (STI token)",
9668
8267
  register(program) {
9669
- program.command(this.name).description(this.description).requiredOption("--app-id <id>", "Application ID").requiredOption("--scene <scene>", "Build scene (pipeline, static)").option("--commit-id <id>", "Git commit ID (required for pipeline scene)").action(
9670
- async (options) => {
9671
- await getToken(options);
9672
- }
9673
- );
8268
+ program.command(this.name).description(this.description).requiredOption("--app-id <id>", "Application ID").requiredOption("--scene <scene>", "Build scene (pipeline, static)").option("--commit-id <id>", "Git commit ID (required for pipeline scene)").action(async (options) => {
8269
+ await getToken(options);
8270
+ });
9674
8271
  }
9675
8272
  };
9676
8273
  var uploadStaticCommand = {
9677
8274
  name: "upload-static",
9678
8275
  description: "Upload shared/static files to TOS",
9679
8276
  register(program) {
9680
- program.command(this.name).description(this.description).requiredOption("--app-id <id>", "Application ID").option(
9681
- "--static-dir <dir>",
9682
- "Static files directory",
9683
- UPLOAD_STATIC_DEFAULTS.staticDir
9684
- ).option(
9685
- "--tosutil-path <path>",
9686
- "Path to tosutil binary",
9687
- UPLOAD_STATIC_DEFAULTS.tosutilPath
9688
- ).option(
9689
- "--endpoint <endpoint>",
9690
- "TOS endpoint",
9691
- UPLOAD_STATIC_DEFAULTS.endpoint
9692
- ).option("--region <region>", "TOS region", UPLOAD_STATIC_DEFAULTS.region).action(async (options) => {
8277
+ program.command(this.name).description(this.description).requiredOption("--app-id <id>", "Application ID").option("--static-dir <dir>", "Static files directory", UPLOAD_STATIC_DEFAULTS.staticDir).option("--tosutil-path <path>", "Path to tosutil binary", UPLOAD_STATIC_DEFAULTS.tosutilPath).option("--endpoint <endpoint>", "TOS endpoint", UPLOAD_STATIC_DEFAULTS.endpoint).option("--region <region>", "TOS region", UPLOAD_STATIC_DEFAULTS.region).action(async (options) => {
9693
8278
  await uploadStatic(options);
9694
8279
  });
9695
8280
  }
@@ -9703,42 +8288,10 @@ var preUploadStaticCommand = {
9703
8288
  });
9704
8289
  }
9705
8290
  };
9706
- var serverStartupBundleCommand = {
9707
- name: "server-startup-bundle",
9708
- description: "Build and isolate-probe a node_modules-free NestJS startup bundle",
9709
- register(program) {
9710
- program.command(this.name).description(this.description).option("--project-root <dir>", "Application project root", process.cwd()).option(
9711
- "--entry <file>",
9712
- "Advanced: bundle an existing compiled entry instead of isolated Nest compilation"
9713
- ).option(
9714
- "--cache-root <dir>",
9715
- "Server startup cache root",
9716
- ".miaoda-cache/server"
9717
- ).option(
9718
- "--probe-timeout-ms <ms>",
9719
- "Isolated availability probe timeout in milliseconds",
9720
- "10000"
9721
- ).action(
9722
- async (options) => {
9723
- const result = await buildServerStartupBundle({
9724
- ...options,
9725
- probeTimeoutMs: Number(options.probeTimeoutMs)
9726
- });
9727
- console.log(JSON.stringify(result));
9728
- if (!result.built) process.exitCode = 2;
9729
- }
9730
- );
9731
- }
9732
- };
9733
8291
  var buildCommandGroup = {
9734
8292
  name: "build",
9735
8293
  description: "Build related commands",
9736
- commands: [
9737
- getTokenCommand,
9738
- uploadStaticCommand,
9739
- preUploadStaticCommand,
9740
- serverStartupBundleCommand
9741
- ]
8294
+ commands: [getTokenCommand, uploadStaticCommand, preUploadStaticCommand]
9742
8295
  };
9743
8296
 
9744
8297
  // src/commands/index.ts
@@ -9756,13 +8309,13 @@ var commands = [
9756
8309
 
9757
8310
  // src/index.ts
9758
8311
  for (const filename of [".env.local", ".env"]) {
9759
- const envPath = path26.join(process.cwd(), filename);
9760
- if (fs30.existsSync(envPath)) {
8312
+ const envPath = path25.join(process.cwd(), filename);
8313
+ if (fs29.existsSync(envPath)) {
9761
8314
  dotenvConfig({ path: envPath });
9762
8315
  }
9763
8316
  }
9764
- var __dirname = path26.dirname(fileURLToPath5(import.meta.url));
9765
- var pkg = JSON.parse(fs30.readFileSync(path26.join(__dirname, "../package.json"), "utf-8"));
8317
+ var __dirname = path25.dirname(fileURLToPath5(import.meta.url));
8318
+ var pkg = JSON.parse(fs29.readFileSync(path25.join(__dirname, "../package.json"), "utf-8"));
9766
8319
  var cli = new FullstackCLI(pkg.version);
9767
8320
  cli.useAll(commands);
9768
8321
  cli.run();