@uipath/packager-tool-webapp 1.204.0-preview.254 → 1.205.0-preview.256

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.
@@ -385,13 +385,57 @@ import {
385
385
 
386
386
  // src/webapp-tool.ts
387
387
  import {
388
- Path as Path5,
388
+ Path as Path6,
389
389
  ProjectTool as ProjectTool2,
390
390
  TemporaryStorageService,
391
391
  ToolErrorCodes,
392
392
  ToolResult
393
393
  } from "@uipath/solutionpackager-tool-core";
394
394
 
395
+ // src/utils/bundle-path.ts
396
+ import { Path } from "@uipath/solutionpackager-tool-core";
397
+ function normalizeBundlePath(path) {
398
+ return path.replace(/\\/g, "/");
399
+ }
400
+ function isBundleRelativePath(path) {
401
+ const normalized = normalizeBundlePath(path);
402
+ const segments = normalized.split("/");
403
+ return !normalized.startsWith("/") && !/^[a-zA-Z]:/.test(normalized) && !segments.includes("..") && segments.some((segment) => segment !== "" && segment !== ".");
404
+ }
405
+ async function isCanonicalBundleChild(fileSystem, projectPath, bundlePath) {
406
+ const project = normalizeBundlePath(await fileSystem.realpath(projectPath)).replace(/\/+$/, "") || "/";
407
+ let bundle = project;
408
+ for (const segment of normalizeBundlePath(bundlePath).split("/")) {
409
+ if (!segment || segment === ".")
410
+ continue;
411
+ bundle = normalizeBundlePath(await fileSystem.realpath(Path.join(bundle, segment))).replace(/\/+$/, "") || "/";
412
+ }
413
+ return bundle !== project && bundle.startsWith(project === "/" ? "/" : `${project}/`);
414
+ }
415
+ function isHtmlEntryPointPath(path) {
416
+ return typeof path === "string" && isBundleRelativePath(path) && /\.html?$/i.test(path);
417
+ }
418
+ async function resolveHtmlEntryPoint(fileSystem, folder, declaredPath) {
419
+ if (!isHtmlEntryPointPath(declaredPath))
420
+ return null;
421
+ const segments = normalizeBundlePath(declaredPath).split("/").filter((part) => part !== "" && part !== ".");
422
+ if (!(await fileSystem.stat(Path.join(folder, ...segments)))?.isFile())
423
+ return null;
424
+ const actual = [];
425
+ for (const segment of segments) {
426
+ const entries = await fileSystem.readdir(Path.join(folder, ...actual));
427
+ if (entries.includes(segment)) {
428
+ actual.push(segment);
429
+ continue;
430
+ }
431
+ const matches = entries.filter((entry) => entry.toLowerCase() === segment.toLowerCase());
432
+ if (matches.length !== 1)
433
+ return null;
434
+ actual.push(matches[0]);
435
+ }
436
+ return actual.join("/");
437
+ }
438
+
395
439
  // src/constants.ts
396
440
  var PROJECT_JSON_FILE = "project.json";
397
441
  var DEFAULT_BUNDLE_PATH = "source/dist";
@@ -400,12 +444,23 @@ var CONTENT_APP_FOLDER_NAME = "app";
400
444
  var TARGET_RUNTIME = "Coded";
401
445
  var TARGET_JS_RUNTIME = "JS";
402
446
  var DEFAULT_ENTRY_POINT_TYPE = "api";
447
+ var HTML_ENTRY_POINT_CANDIDATES = [
448
+ "index.html",
449
+ "main.html",
450
+ "app.html"
451
+ ];
403
452
  var ERROR_MESSAGES = {
404
453
  MANIFEST_NOT_FOUND: (file) => `WebApp manifest not found: ${file}. This file is required for WebApp projects.`,
405
454
  PROJECT_JSON_FOUND: "project.json found in WebApp project. The WebApp tool only supports Coded web apps without project.json.",
406
455
  MANIFEST_LOAD_FAILED: (file) => `Failed to load or parse ${file}`,
407
456
  BUNDLE_NOT_FOUND: (path) => `Compiled bundle not found at ${path}. Ensure the project is built before packing.`,
408
457
  BUNDLE_NOT_DIRECTORY: (path) => `Bundle path ${path} exists but is not a directory.`,
458
+ BUNDLE_OUTSIDE_PROJECT: (path) => `Bundle path ${path} resolves to the project root or outside the project. Use a child build output folder inside the project.`,
459
+ BUNDLE_NO_ENTRY_POINT: (path) => `Bundle at ${path} has no HTML entry point (${HTML_ENTRY_POINT_CANDIDATES.join(", ")}). Build the app before packing, or point config.bundlePath in webAppManifest.json at its build output.`,
460
+ MAIN_FILE_INVALID_TYPE: "Invalid webAppManifest.json: config.mainFile must be a string naming an HTML file, or be omitted.",
461
+ MAIN_FILE_NOT_IN_BUNDLE: (path, mainFile) => `${WEBAPP_MANIFEST_FILE_NAME} asks for "${mainFile}" as the app's main file, but the bundle at ${path} does not hold it. Name an HTML file inside the bundle in config.mainFile, or remove it to use the first of ${HTML_ENTRY_POINT_CANDIDATES.join(", ")} the bundle holds.`,
462
+ MAIN_FILE_LOST: (path, mainFile) => `Bundle at ${path} held "${mainFile}" when the pack started, but the copy taken for the package has not. Something changed the folder mid-pack — usually a build or watch process. Stop it and pack again.`,
463
+ BUNDLE_ENTRY_POINT_LOST: (path) => `Bundle at ${path} had an HTML entry point (${HTML_ENTRY_POINT_CANDIDATES.join(", ")}) when the pack started, but the copy taken for the package has none. Something changed the folder mid-pack — usually a build or watch process. Stop it and pack again.`,
409
464
  APP_FOLDER_NOT_FOUND: (path) => `.app folder not found at ${path}. Ensure the project contains a .app folder.`,
410
465
  APP_FOLDER_NOT_DIRECTORY: (path) => `.app path ${path} exists but is not a directory.`,
411
466
  BUILD_NOT_SUPPORTED: "Build execution (isCompiled=false) is not yet supported. Please build the project manually and set isCompiled=true.",
@@ -421,19 +476,19 @@ var ERROR_MESSAGES = {
421
476
  import {
422
477
  NugetConstants,
423
478
  NugetPackager,
424
- Path as Path3,
479
+ Path as Path4,
425
480
  ProjectTypes,
426
481
  TargetFramework
427
482
  } from "@uipath/solutionpackager-tool-core";
428
483
 
429
484
  // src/utils/fs-helpers.ts
430
- import { Path } from "@uipath/solutionpackager-tool-core";
485
+ import { Path as Path2 } from "@uipath/solutionpackager-tool-core";
431
486
  async function copyDirectoryAsync(fileSystem, sourcePath, destinationPath) {
432
487
  await fileSystem.mkdir(destinationPath);
433
488
  const entries = await fileSystem.readdir(sourcePath);
434
489
  for (const entry of entries) {
435
- const sourceEntry = Path.join(sourcePath, entry);
436
- const destEntry = Path.join(destinationPath, entry);
490
+ const sourceEntry = Path2.join(sourcePath, entry);
491
+ const destEntry = Path2.join(destinationPath, entry);
437
492
  const stat = await fileSystem.stat(sourceEntry);
438
493
  if (stat?.isDirectory()) {
439
494
  await copyDirectoryAsync(fileSystem, sourceEntry, destEntry);
@@ -447,9 +502,9 @@ async function copyDirectoryAsync(fileSystem, sourcePath, destinationPath) {
447
502
  }
448
503
 
449
504
  // src/utils/manifest-loader.ts
450
- import { Path as Path2 } from "@uipath/solutionpackager-tool-core";
505
+ import { Path as Path3 } from "@uipath/solutionpackager-tool-core";
451
506
  async function loadWebAppManifest2(fileSystem, projectPath) {
452
- const manifestPath = Path2.join(projectPath, WEBAPP_MANIFEST_FILE_NAME);
507
+ const manifestPath = Path3.join(projectPath, WEBAPP_MANIFEST_FILE_NAME);
453
508
  const exists = await fileSystem.exists(manifestPath);
454
509
  if (!exists) {
455
510
  return null;
@@ -474,7 +529,7 @@ async function ensureWebAppProjectId(fileSystem, projectPath) {
474
529
  const id = crypto.randomUUID();
475
530
  if (manifest) {
476
531
  const updated = { ...manifest, projectId: id };
477
- const manifestPath = Path2.join(projectPath, WEBAPP_MANIFEST_FILE_NAME);
532
+ const manifestPath = Path3.join(projectPath, WEBAPP_MANIFEST_FILE_NAME);
478
533
  await fileSystem.writeFile(manifestPath, `${JSON.stringify(updated, null, 2)}
479
534
  `);
480
535
  }
@@ -496,10 +551,9 @@ class CodedAppStrategy {
496
551
  }
497
552
  const isCompiled = typed.config?.isCompiled ?? true;
498
553
  if (isCompiled) {
499
- const fullBundlePath = Path3.join(projectPath, bundlePath);
500
- const exists = await this.fileSystem.exists(fullBundlePath);
501
- if (!exists) {
502
- const message = ERROR_MESSAGES.BUNDLE_NOT_FOUND(fullBundlePath);
554
+ const fullBundlePath = Path4.join(projectPath, bundlePath);
555
+ const message = await this.describeBundleProblemAsync(fullBundlePath, typed.config?.mainFile);
556
+ if (message) {
503
557
  const warnable = logger;
504
558
  if (warnable?.warn) {
505
559
  warnable.warn(message);
@@ -517,7 +571,11 @@ class CodedAppStrategy {
517
571
  bundlePath = DEFAULT_BUNDLE_PATH;
518
572
  }
519
573
  const isCompiled = manifest.config?.isCompiled ?? true;
520
- const fullBundlePath = Path3.join(projectPath, bundlePath);
574
+ const declaredMainFile = manifest.config?.mainFile;
575
+ const fullBundlePath = Path4.join(projectPath, bundlePath);
576
+ if (isBundleRelativePath(bundlePath) && !await isCanonicalBundleChild(this.fileSystem, projectPath, bundlePath)) {
577
+ throw new Error(ERROR_MESSAGES.BUNDLE_OUTSIDE_PROJECT(bundlePath));
578
+ }
521
579
  if (isCompiled) {
522
580
  logger?.progress("Validating compiled bundle...");
523
581
  const bundleExists = await this.fileSystem.exists(fullBundlePath);
@@ -528,21 +586,25 @@ class CodedAppStrategy {
528
586
  if (!bundleStat?.isDirectory()) {
529
587
  throw new Error(ERROR_MESSAGES.BUNDLE_NOT_DIRECTORY(fullBundlePath));
530
588
  }
589
+ const problem = await this.describeBundleEntryProblemAsync(fullBundlePath, declaredMainFile);
590
+ if (problem) {
591
+ throw new Error(problem);
592
+ }
531
593
  } else {
532
594
  logger?.info("Build mode (isCompiled=false) is not yet implemented in v1.");
533
595
  throw new Error(ERROR_MESSAGES.BUILD_NOT_SUPPORTED);
534
596
  }
535
- const localBuildFolder = Path3.join(outputPath, NugetConstants.OutputFolderName);
536
- const contentFolder = Path3.join(localBuildFolder, NugetConstants.ContentFolderName);
537
- await this.fileSystem.mkdir(contentFolder);
597
+ const localBuildFolder = Path4.join(outputPath, `${NugetConstants.OutputFolderName}-${crypto.randomUUID()}`);
598
+ const contentFolder = Path4.join(localBuildFolder, NugetConstants.ContentFolderName);
538
599
  try {
600
+ await this.fileSystem.mkdir(contentFolder);
539
601
  logger?.progress("Copying bundle to content folder...");
540
602
  await copyDirectoryAsync(this.fileSystem, fullBundlePath, contentFolder);
541
603
  logger?.progress("Preparing metadata files...");
542
- await this.prepareMetadataFiles(localBuildFolder, contentFolder, packageInfo, manifest, projectPath);
604
+ await this.prepareMetadataFiles(localBuildFolder, contentFolder, packageInfo, manifest, projectPath, fullBundlePath);
543
605
  logger?.progress("Creating NuGet package...");
544
606
  const nupkgFileName = `${packageInfo.id}.${packageInfo.version}.nupkg`;
545
- const nupkgPath = Path3.join(outputPath, nupkgFileName);
607
+ const nupkgPath = Path4.join(outputPath, nupkgFileName);
546
608
  const packager = new NugetPackager(this.fileSystem);
547
609
  const result = await packager.packAsync(localBuildFolder, packageInfo, nupkgPath);
548
610
  logger?.info(`Package created successfully: ${result.outputPath}`);
@@ -555,21 +617,13 @@ class CodedAppStrategy {
555
617
  }
556
618
  }
557
619
  }
558
- async prepareMetadataFiles(_localBuildFolder, contentFolder, _packageInfo, _manifest, projectPath) {
559
- let mainFile = "index.html";
560
- const indexHtmlPath = Path3.join(contentFolder, "index.html");
561
- const indexHtmlExists = await this.fileSystem.exists(indexHtmlPath);
562
- if (!indexHtmlExists) {
563
- const possibleEntries = ["index.html", "main.html", "app.html"];
564
- for (const entry of possibleEntries) {
565
- const entryPath = Path3.join(contentFolder, entry);
566
- if (await this.fileSystem.exists(entryPath)) {
567
- mainFile = entry;
568
- break;
569
- }
570
- }
620
+ async prepareMetadataFiles(_localBuildFolder, contentFolder, _packageInfo, manifest, projectPath, sourceBundlePath) {
621
+ const declaredMainFile = manifest.config?.mainFile;
622
+ const mainFile = await this.resolveMainFileAsync(contentFolder, declaredMainFile);
623
+ if (!mainFile) {
624
+ throw new Error(declaredMainFile ? ERROR_MESSAGES.MAIN_FILE_LOST(sourceBundlePath, declaredMainFile) : ERROR_MESSAGES.BUNDLE_ENTRY_POINT_LOST(sourceBundlePath));
571
625
  }
572
- const operatePath = Path3.join(contentFolder, NugetConstants.OperateFileName);
626
+ const operatePath = Path4.join(contentFolder, NugetConstants.OperateFileName);
573
627
  const operateModel = {
574
628
  projectId: await ensureWebAppProjectId(this.fileSystem, projectPath),
575
629
  main: mainFile,
@@ -583,17 +637,13 @@ class CodedAppStrategy {
583
637
  };
584
638
  const operateJson = JSON.stringify(operateModel, null, 2);
585
639
  await this.fileSystem.writeFile(operatePath, operateJson);
586
- const manifestSourcePath = Path3.join(projectPath, WEBAPP_MANIFEST_FILE_NAME);
587
- const manifestDestPath = Path3.join(contentFolder, WEBAPP_MANIFEST_FILE_NAME);
588
- const manifestExists = await this.fileSystem.exists(manifestSourcePath);
589
- if (manifestExists) {
590
- const manifestContent = await this.fileSystem.readFile(manifestSourcePath, "utf-8");
591
- if (manifestContent) {
592
- await this.fileSystem.writeFile(manifestDestPath, manifestContent);
593
- }
594
- }
595
- const uipathJsonSourcePath = Path3.join(projectPath, "uipath.json");
596
- const uipathJsonDestPath = Path3.join(contentFolder, "uipath.json");
640
+ await this.fileSystem.writeFile(Path4.join(contentFolder, WEBAPP_MANIFEST_FILE_NAME), JSON.stringify({
641
+ ...manifest,
642
+ config: { ...manifest.config, mainFile },
643
+ projectId: operateModel.projectId
644
+ }, null, 2));
645
+ const uipathJsonSourcePath = Path4.join(projectPath, "uipath.json");
646
+ const uipathJsonDestPath = Path4.join(contentFolder, "uipath.json");
597
647
  const uipathJsonExists = await this.fileSystem.exists(uipathJsonSourcePath);
598
648
  if (uipathJsonExists) {
599
649
  const uipathJsonContent = await this.fileSystem.readFile(uipathJsonSourcePath, "utf-8");
@@ -601,8 +651,8 @@ class CodedAppStrategy {
601
651
  await this.fileSystem.writeFile(uipathJsonDestPath, uipathJsonContent);
602
652
  }
603
653
  }
604
- const actionSchemaSourcePath = Path3.join(projectPath, "action-schema.json");
605
- const actionSchemaDestPath = Path3.join(contentFolder, "action-schema.json");
654
+ const actionSchemaSourcePath = Path4.join(projectPath, "action-schema.json");
655
+ const actionSchemaDestPath = Path4.join(contentFolder, "action-schema.json");
606
656
  const actionSchemaExists = await this.fileSystem.exists(actionSchemaSourcePath);
607
657
  if (actionSchemaExists) {
608
658
  const actionSchemaContent = await this.fileSystem.readFile(actionSchemaSourcePath, "utf-8");
@@ -610,7 +660,7 @@ class CodedAppStrategy {
610
660
  await this.fileSystem.writeFile(actionSchemaDestPath, actionSchemaContent);
611
661
  }
612
662
  }
613
- const bindingsPath = Path3.join(contentFolder, "bindings.json");
663
+ const bindingsPath = Path4.join(contentFolder, "bindings.json");
614
664
  const bindingsExists = await this.fileSystem.exists(bindingsPath);
615
665
  if (!bindingsExists) {
616
666
  const bindingsJson = JSON.stringify({
@@ -619,12 +669,12 @@ class CodedAppStrategy {
619
669
  }, null, 2);
620
670
  await this.fileSystem.writeFile(bindingsPath, bindingsJson);
621
671
  }
622
- const bindingsV2Path = Path3.join(contentFolder, "bindings_v2.json");
672
+ const bindingsV2Path = Path4.join(contentFolder, "bindings_v2.json");
623
673
  const bindingsCandidatePaths = [
624
- Path3.join(projectPath, "source", "bindings_v2.json"),
625
- Path3.join(projectPath, "source", "bindings.json"),
626
- Path3.join(projectPath, "bindings.json"),
627
- Path3.join(projectPath, "bindings_v2.json")
674
+ Path4.join(projectPath, "source", "bindings_v2.json"),
675
+ Path4.join(projectPath, "source", "bindings.json"),
676
+ Path4.join(projectPath, "bindings.json"),
677
+ Path4.join(projectPath, "bindings_v2.json")
628
678
  ];
629
679
  let bindingsV2Json = null;
630
680
  for (const candidate of bindingsCandidatePaths) {
@@ -644,14 +694,14 @@ class CodedAppStrategy {
644
694
  }, null, 2);
645
695
  }
646
696
  await this.fileSystem.writeFile(bindingsV2Path, bindingsV2Json);
647
- const entryPointsPath = Path3.join(contentFolder, "entry-points.json");
648
- const projectEntryPointsPath = Path3.join(projectPath, "entry-points.json");
697
+ const entryPointsPath = Path4.join(contentFolder, "entry-points.json");
698
+ const projectEntryPointsPath = Path4.join(projectPath, "entry-points.json");
649
699
  let entryPointsContent;
650
700
  const projectEntryPointsExists = await this.fileSystem.exists(projectEntryPointsPath);
651
701
  if (projectEntryPointsExists) {
652
702
  const entryPointsData = await this.fileSystem.readFile(projectEntryPointsPath, "utf-8");
653
703
  if (entryPointsData) {
654
- entryPointsContent = entryPointsData;
704
+ entryPointsContent = this.alignEntryPoint(entryPointsData, mainFile);
655
705
  } else {
656
706
  entryPointsContent = this.createDefaultEntryPoints(mainFile);
657
707
  }
@@ -659,18 +709,68 @@ class CodedAppStrategy {
659
709
  entryPointsContent = this.createDefaultEntryPoints(mainFile);
660
710
  }
661
711
  await this.fileSystem.writeFile(entryPointsPath, entryPointsContent);
662
- const packageDescriptorPath = Path3.join(contentFolder, NugetConstants.PackageDescriptorFileName);
712
+ const packageDescriptorPath = Path4.join(contentFolder, NugetConstants.PackageDescriptorFileName);
663
713
  const packageDescriptor = {
664
714
  $schema: "https://cloud.uipath.com/draft/2024-12/package-descriptor",
665
715
  files: {
666
- [NugetConstants.OperateFileName]: Path3.join(NugetConstants.ContentFolderName, NugetConstants.OperateFileName),
667
- "entry-points.json": Path3.join(NugetConstants.ContentFolderName, "entry-points.json"),
668
- "bindings.json": Path3.join(NugetConstants.ContentFolderName, "bindings_v2.json")
716
+ [NugetConstants.OperateFileName]: Path4.join(NugetConstants.ContentFolderName, NugetConstants.OperateFileName),
717
+ "entry-points.json": Path4.join(NugetConstants.ContentFolderName, "entry-points.json"),
718
+ "bindings.json": Path4.join(NugetConstants.ContentFolderName, "bindings_v2.json")
669
719
  }
670
720
  };
671
721
  const packageDescriptorJson = JSON.stringify(packageDescriptor, null, 2);
672
722
  await this.fileSystem.writeFile(packageDescriptorPath, packageDescriptorJson);
673
723
  }
724
+ async describeBundleProblemAsync(fullBundlePath, declaredMainFile) {
725
+ const bundleStat = await this.fileSystem.stat(fullBundlePath);
726
+ if (!bundleStat) {
727
+ return ERROR_MESSAGES.BUNDLE_NOT_FOUND(fullBundlePath);
728
+ }
729
+ if (!bundleStat.isDirectory()) {
730
+ return ERROR_MESSAGES.BUNDLE_NOT_DIRECTORY(fullBundlePath);
731
+ }
732
+ return this.describeBundleEntryProblemAsync(fullBundlePath, declaredMainFile);
733
+ }
734
+ async describeBundleEntryProblemAsync(fullBundlePath, declaredMainFile) {
735
+ if (declaredMainFile !== undefined && typeof declaredMainFile !== "string") {
736
+ return ERROR_MESSAGES.MAIN_FILE_INVALID_TYPE;
737
+ }
738
+ if (await this.resolveMainFileAsync(fullBundlePath, declaredMainFile)) {
739
+ return null;
740
+ }
741
+ return declaredMainFile !== undefined ? ERROR_MESSAGES.MAIN_FILE_NOT_IN_BUNDLE(fullBundlePath, declaredMainFile) : ERROR_MESSAGES.BUNDLE_NO_ENTRY_POINT(fullBundlePath);
742
+ }
743
+ async resolveMainFileAsync(folder, declaredMainFile) {
744
+ if (declaredMainFile === undefined) {
745
+ return this.findEntryPointAsync(folder);
746
+ }
747
+ return resolveHtmlEntryPoint(this.fileSystem, folder, declaredMainFile);
748
+ }
749
+ async findEntryPointAsync(folder) {
750
+ for (const candidate of HTML_ENTRY_POINT_CANDIDATES) {
751
+ const resolved = await resolveHtmlEntryPoint(this.fileSystem, folder, candidate);
752
+ if (resolved !== null)
753
+ return resolved;
754
+ }
755
+ return null;
756
+ }
757
+ alignEntryPoint(content, mainFile) {
758
+ const document = JSON.parse(content);
759
+ if (typeof document !== "object" || document === null || !("entryPoints" in document) || !Array.isArray(document.entryPoints)) {
760
+ throw new Error("Invalid entry-points.json: expected an entryPoints array.");
761
+ }
762
+ const primary = document.entryPoints[0];
763
+ if (typeof primary !== "object" || primary === null || Array.isArray(primary)) {
764
+ throw new Error("Invalid entry-points.json: expected a primary entry object.");
765
+ }
766
+ return JSON.stringify({
767
+ ...document,
768
+ entryPoints: [
769
+ { ...primary, filePath: mainFile },
770
+ ...document.entryPoints.slice(1)
771
+ ]
772
+ }, null, 2);
773
+ }
674
774
  createDefaultEntryPoints(mainFile) {
675
775
  const uniqueId = this.generateUniqueId();
676
776
  const entryPoints = {
@@ -717,7 +817,7 @@ class CodedAppStrategy {
717
817
  import {
718
818
  NugetConstants as NugetConstants2,
719
819
  NugetPackager as NugetPackager2,
720
- Path as Path4,
820
+ Path as Path5,
721
821
  ProjectTypes as ProjectTypes2,
722
822
  TargetFramework as TargetFramework2
723
823
  } from "@uipath/solutionpackager-tool-core";
@@ -728,7 +828,7 @@ class JsAppsStrategy {
728
828
  }
729
829
  async validateAsync(args) {
730
830
  const { projectPath, logger } = args;
731
- const appFolder = Path4.join(projectPath, APP_FOLDER_NAME);
831
+ const appFolder = Path5.join(projectPath, APP_FOLDER_NAME);
732
832
  const exists = await this.fileSystem.exists(appFolder);
733
833
  if (!exists) {
734
834
  const message = ERROR_MESSAGES.APP_FOLDER_NOT_FOUND(appFolder);
@@ -752,7 +852,7 @@ class JsAppsStrategy {
752
852
  async packageAsync(args) {
753
853
  const { projectPath, manifest, outputPath, packageInfo, logger } = args;
754
854
  logger?.info(`Packaging JS variant: ${packageInfo.id}@${packageInfo.version}`);
755
- const appFolder = Path4.join(projectPath, APP_FOLDER_NAME);
855
+ const appFolder = Path5.join(projectPath, APP_FOLDER_NAME);
756
856
  logger?.progress("Validating .app folder...");
757
857
  const appFolderExists = await this.fileSystem.exists(appFolder);
758
858
  if (!appFolderExists) {
@@ -762,9 +862,9 @@ class JsAppsStrategy {
762
862
  if (!appFolderStat?.isDirectory()) {
763
863
  throw new Error(ERROR_MESSAGES.APP_FOLDER_NOT_DIRECTORY(appFolder));
764
864
  }
765
- const localBuildFolder = Path4.join(outputPath, NugetConstants2.OutputFolderName);
766
- const contentFolder = Path4.join(localBuildFolder, NugetConstants2.ContentFolderName);
767
- const contentAppFolder = Path4.join(contentFolder, CONTENT_APP_FOLDER_NAME);
865
+ const localBuildFolder = Path5.join(outputPath, NugetConstants2.OutputFolderName);
866
+ const contentFolder = Path5.join(localBuildFolder, NugetConstants2.ContentFolderName);
867
+ const contentAppFolder = Path5.join(contentFolder, CONTENT_APP_FOLDER_NAME);
768
868
  await this.fileSystem.mkdir(contentFolder);
769
869
  try {
770
870
  logger?.progress("Copying .app folder into content/app...");
@@ -773,7 +873,7 @@ class JsAppsStrategy {
773
873
  await this.prepareMetadataFiles(contentFolder, contentAppFolder, packageInfo, manifest, projectPath);
774
874
  logger?.progress("Creating NuGet package...");
775
875
  const nupkgFileName = `${packageInfo.id}.${packageInfo.version}.nupkg`;
776
- const nupkgPath = Path4.join(outputPath, nupkgFileName);
876
+ const nupkgPath = Path5.join(outputPath, nupkgFileName);
777
877
  const packager = new NugetPackager2(this.fileSystem);
778
878
  const result = await packager.packAsync(localBuildFolder, packageInfo, nupkgPath);
779
879
  logger?.info(`Package created successfully: ${result.outputPath}`);
@@ -789,7 +889,7 @@ class JsAppsStrategy {
789
889
  async prepareMetadataFiles(contentFolder, _contentAppFolder, _packageInfo, _manifest, projectPath) {
790
890
  const mainFile = "index.html";
791
891
  const mainRelativeToContent = `${CONTENT_APP_FOLDER_NAME}/${mainFile}`;
792
- const operatePath = Path4.join(contentFolder, NugetConstants2.OperateFileName);
892
+ const operatePath = Path5.join(contentFolder, NugetConstants2.OperateFileName);
793
893
  const operateModel = {
794
894
  projectId: await ensureWebAppProjectId(this.fileSystem, projectPath),
795
895
  main: mainRelativeToContent,
@@ -803,8 +903,8 @@ class JsAppsStrategy {
803
903
  };
804
904
  const operateJson = JSON.stringify(operateModel, null, 2);
805
905
  await this.fileSystem.writeFile(operatePath, operateJson);
806
- const manifestSourcePath = Path4.join(projectPath, WEBAPP_MANIFEST_FILE_NAME);
807
- const manifestDestPath = Path4.join(contentFolder, WEBAPP_MANIFEST_FILE_NAME);
906
+ const manifestSourcePath = Path5.join(projectPath, WEBAPP_MANIFEST_FILE_NAME);
907
+ const manifestDestPath = Path5.join(contentFolder, WEBAPP_MANIFEST_FILE_NAME);
808
908
  const manifestExists = await this.fileSystem.exists(manifestSourcePath);
809
909
  if (manifestExists) {
810
910
  const manifestContent = await this.fileSystem.readFile(manifestSourcePath);
@@ -812,8 +912,8 @@ class JsAppsStrategy {
812
912
  await this.fileSystem.writeFile(manifestDestPath, manifestContent);
813
913
  }
814
914
  }
815
- const uipathJsonSourcePath = Path4.join(projectPath, "uipath.json");
816
- const uipathJsonDestPath = Path4.join(contentFolder, "uipath.json");
915
+ const uipathJsonSourcePath = Path5.join(projectPath, "uipath.json");
916
+ const uipathJsonDestPath = Path5.join(contentFolder, "uipath.json");
817
917
  const uipathJsonExists = await this.fileSystem.exists(uipathJsonSourcePath);
818
918
  if (uipathJsonExists) {
819
919
  const uipathJsonContent = await this.fileSystem.readFile(uipathJsonSourcePath);
@@ -821,20 +921,20 @@ class JsAppsStrategy {
821
921
  await this.fileSystem.writeFile(uipathJsonDestPath, uipathJsonContent);
822
922
  }
823
923
  }
824
- const bindingsPath = Path4.join(contentFolder, "bindings.json");
924
+ const bindingsPath = Path5.join(contentFolder, "bindings.json");
825
925
  const bindingsExists = await this.fileSystem.exists(bindingsPath);
826
926
  if (!bindingsExists) {
827
927
  const bindingsJson = JSON.stringify({ version: "1.0", resources: [] }, null, 2);
828
928
  await this.fileSystem.writeFile(bindingsPath, bindingsJson);
829
929
  }
830
- const bindingsV2Path = Path4.join(contentFolder, "bindings_v2.json");
930
+ const bindingsV2Path = Path5.join(contentFolder, "bindings_v2.json");
831
931
  const bindingsV2Exists = await this.fileSystem.exists(bindingsV2Path);
832
932
  if (!bindingsV2Exists) {
833
933
  const bindingsV2Json = JSON.stringify({ version: "2.0", resources: [] }, null, 2);
834
934
  await this.fileSystem.writeFile(bindingsV2Path, bindingsV2Json);
835
935
  }
836
- const entryPointsPath = Path4.join(contentFolder, "entry-points.json");
837
- const projectEntryPointsPath = Path4.join(projectPath, "entry-points.json");
936
+ const entryPointsPath = Path5.join(contentFolder, "entry-points.json");
937
+ const projectEntryPointsPath = Path5.join(projectPath, "entry-points.json");
838
938
  let entryPointsContent;
839
939
  const projectEntryPointsExists = await this.fileSystem.exists(projectEntryPointsPath);
840
940
  if (projectEntryPointsExists) {
@@ -848,12 +948,12 @@ class JsAppsStrategy {
848
948
  entryPointsContent = this.createDefaultEntryPoints(mainRelativeToContent);
849
949
  }
850
950
  await this.fileSystem.writeFile(entryPointsPath, entryPointsContent);
851
- const packageDescriptorPath = Path4.join(contentFolder, NugetConstants2.PackageDescriptorFileName);
951
+ const packageDescriptorPath = Path5.join(contentFolder, NugetConstants2.PackageDescriptorFileName);
852
952
  const packageDescriptor = {
853
953
  files: {
854
- [NugetConstants2.OperateFileName]: Path4.join(NugetConstants2.ContentFolderName, NugetConstants2.OperateFileName),
855
- "entry-points.json": Path4.join(NugetConstants2.ContentFolderName, "entry-points.json"),
856
- "bindings.json": Path4.join(NugetConstants2.ContentFolderName, "bindings_v2.json")
954
+ [NugetConstants2.OperateFileName]: Path5.join(NugetConstants2.ContentFolderName, NugetConstants2.OperateFileName),
955
+ "entry-points.json": Path5.join(NugetConstants2.ContentFolderName, "entry-points.json"),
956
+ "bindings.json": Path5.join(NugetConstants2.ContentFolderName, "bindings_v2.json")
857
957
  }
858
958
  };
859
959
  const packageDescriptorJson = JSON.stringify(packageDescriptor, null, 2);
@@ -983,7 +1083,7 @@ class WebAppTool extends ProjectTool2 {
983
1083
  let manifest;
984
1084
  let strategy;
985
1085
  try {
986
- const prepared = await this.getManifestAndStrategy(options.projectPath);
1086
+ const prepared = await this.getManifestAndStrategy(options.projectPath, options.codedBundle);
987
1087
  manifest = prepared.manifest;
988
1088
  strategy = prepared.strategy;
989
1089
  } catch (error) {
@@ -1013,20 +1113,33 @@ class WebAppTool extends ProjectTool2 {
1013
1113
  await this._temporaryStorage.cleanup();
1014
1114
  } catch {}
1015
1115
  }
1016
- async getManifestAndStrategy(projectPath) {
1017
- const manifestPath = Path5.join(projectPath, WEBAPP_MANIFEST_FILE_NAME);
1116
+ async getManifestAndStrategy(projectPath, codedBundle) {
1117
+ const manifestPath = Path6.join(projectPath, WEBAPP_MANIFEST_FILE_NAME);
1018
1118
  const manifestExists = await this.fileSystem.exists(manifestPath);
1019
- if (!manifestExists) {
1119
+ if (!manifestExists && !codedBundle) {
1020
1120
  throw new Error(ERROR_MESSAGES.MANIFEST_NOT_FOUND(WEBAPP_MANIFEST_FILE_NAME));
1021
1121
  }
1022
- const projectJsonPath = Path5.join(projectPath, PROJECT_JSON_FILE);
1122
+ const projectJsonPath = Path6.join(projectPath, PROJECT_JSON_FILE);
1023
1123
  if (await this.fileSystem.exists(projectJsonPath)) {
1024
1124
  throw new Error(ERROR_MESSAGES.PROJECT_JSON_FOUND);
1025
1125
  }
1026
- const manifest = await loadWebAppManifest2(this.fileSystem, projectPath);
1126
+ let manifest = manifestExists ? await loadWebAppManifest2(this.fileSystem, projectPath) : {
1127
+ type: "Coded" /* Coded */,
1128
+ solutionResourceSubType: "Coded" /* Coded */,
1129
+ config: { isCompiled: true }
1130
+ };
1027
1131
  if (!manifest) {
1028
1132
  throw new Error(ERROR_MESSAGES.MANIFEST_LOAD_FAILED(WEBAPP_MANIFEST_FILE_NAME));
1029
1133
  }
1134
+ if (codedBundle) {
1135
+ if (manifest.type !== "Coded" /* Coded */) {
1136
+ throw new Error("A coded bundle requires a Coded webAppManifest.json.");
1137
+ }
1138
+ manifest = {
1139
+ ...manifest,
1140
+ config: { ...manifest.config, ...codedBundle }
1141
+ };
1142
+ }
1030
1143
  const strategy = VariantStrategyFactory.createStrategy(manifest, this.fileSystem);
1031
1144
  return { manifest, strategy };
1032
1145
  }
@@ -1086,4 +1199,4 @@ export {
1086
1199
  validateActionSchema
1087
1200
  };
1088
1201
 
1089
- //# debugId=E7C8B1E2C5B0339C64756E2164756E21
1202
+ //# debugId=373EDDEBABAD6ECD64756E2164756E21
@@ -1,3 +1,4 @@
1
+ export { isBundleRelativePath, isCanonicalBundleChild, isHtmlEntryPointPath, normalizeBundlePath, resolveHtmlEntryPoint, } from "./utils/bundle-path.js";
1
2
  /**
2
3
  * Constants used throughout the WebApp tool implementation
3
4
  */
@@ -29,6 +30,12 @@ export declare const TARGET_JS_RUNTIME = "JS";
29
30
  * Default entry point type
30
31
  */
31
32
  export declare const DEFAULT_ENTRY_POINT_TYPE = "api";
33
+ /**
34
+ * HTML entry points a packed coded app may boot from, in the order
35
+ * `operate.json`'s `main` is resolved. A bundle with none of them produces an
36
+ * app that cannot start, so pack refuses it rather than shipping it.
37
+ */
38
+ export declare const HTML_ENTRY_POINT_CANDIDATES: readonly ["index.html", "main.html", "app.html"];
32
39
  /**
33
40
  * Error messages
34
41
  */
@@ -38,6 +45,12 @@ export declare const ERROR_MESSAGES: {
38
45
  readonly MANIFEST_LOAD_FAILED: (file: string) => string;
39
46
  readonly BUNDLE_NOT_FOUND: (path: string) => string;
40
47
  readonly BUNDLE_NOT_DIRECTORY: (path: string) => string;
48
+ readonly BUNDLE_OUTSIDE_PROJECT: (path: string) => string;
49
+ readonly BUNDLE_NO_ENTRY_POINT: (path: string) => string;
50
+ readonly MAIN_FILE_INVALID_TYPE: "Invalid webAppManifest.json: config.mainFile must be a string naming an HTML file, or be omitted.";
51
+ readonly MAIN_FILE_NOT_IN_BUNDLE: (path: string, mainFile: string) => string;
52
+ readonly MAIN_FILE_LOST: (path: string, mainFile: string) => string;
53
+ readonly BUNDLE_ENTRY_POINT_LOST: (path: string) => string;
41
54
  readonly APP_FOLDER_NOT_FOUND: (path: string) => string;
42
55
  readonly APP_FOLDER_NOT_DIRECTORY: (path: string) => string;
43
56
  readonly BUILD_NOT_SUPPORTED: "Build execution (isCompiled=false) is not yet supported. Please build the project manually and set isCompiled=true.";