@absolutejs/absolute 0.20.0-beta.21 → 0.20.0-beta.22

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.
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  var __require = import.meta.require;
3
3
 
4
- // .angular-partial-tmp-MMVBtX/src/core/streamingSlotRegistrar.ts
4
+ // .angular-partial-tmp-RDcrbx/src/core/streamingSlotRegistrar.ts
5
5
  var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
6
6
  var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
7
7
  var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  var __require = import.meta.require;
3
3
 
4
- // .angular-partial-tmp-MMVBtX/src/core/streamingSlotRegistrar.ts
4
+ // .angular-partial-tmp-RDcrbx/src/core/streamingSlotRegistrar.ts
5
5
  var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
6
6
  var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
7
7
  var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
@@ -48,7 +48,7 @@ var warnMissingStreamingSlotCollector = (primitiveName) => {
48
48
  getWarningController()?.maybeWarn(primitiveName);
49
49
  };
50
50
 
51
- // .angular-partial-tmp-MMVBtX/src/core/streamingSlotRegistry.ts
51
+ // .angular-partial-tmp-RDcrbx/src/core/streamingSlotRegistry.ts
52
52
  var STREAMING_SLOT_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotAsyncLocalStorage");
53
53
  var isObjectRecord2 = (value) => Boolean(value) && typeof value === "object";
54
54
  var isAsyncLocalStorage = (value) => isObjectRecord2(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function";
package/dist/cli/index.js CHANGED
@@ -17706,6 +17706,152 @@ var init_iosConformance = __esm(() => {
17706
17706
  HMR_LINE = new RegExp(String.raw`\[hmr:ios\]\s+([^\n]*?)\s+(applied in|falling back to reload after|failed after)\s+(\d+)ms(?:; server\s+(\d+)ms, client\s+(\d+)ms)?`, "u");
17707
17707
  });
17708
17708
 
17709
+ // src/mobile/iosTestReport.ts
17710
+ import { mkdir as mkdir13, readFile as readFile18, writeFile as writeFile15 } from "fs/promises";
17711
+ import { join as join51 } from "path";
17712
+ var MANUAL_CHECKS, secretPattern, bearerPattern, coordinatePattern, sanitizeIosReportText = (value) => value.replace(bearerPattern, "Bearer [REDACTED]").replace(secretPattern, "$1$2[REDACTED]").replace(coordinatePattern, "$1$2[REDACTED]").replace(/(https?:\/\/[^\s?#]+)[?#][^\s]*/giu, "$1?[REDACTED]"), markdownCell = (value) => sanitizeIosReportText(value).replaceAll("|", "\\|").replaceAll(`
17713
+ `, "<br>"), createAbsoluteIosPartnerReport = (options) => {
17714
+ const { run } = options;
17715
+ const evidence = run.screenshot ? `Simulator screenshot: ${run.screenshot}` : undefined;
17716
+ let hmrResult = "NOT_RUN";
17717
+ if (run.hmr)
17718
+ hmrResult = run.hmr.outcome === "failed" ? "FAIL" : "PASS";
17719
+ const automatedChecks = [
17720
+ {
17721
+ details: `Captured macOS, Xcode, Bun, and AbsoluteJS versions for simulator ${run.udid}.`,
17722
+ id: "AUTO-SETUP-01",
17723
+ result: "PASS"
17724
+ },
17725
+ {
17726
+ details: run.status === "pass" ? `The app was installed, launched, and connected to native HMR in ${run.durationMs}ms.` : `The automated simulator run failed after ${run.durationMs}ms: ${run.error ?? "No error detail was available."}`,
17727
+ ...evidence ? { evidence } : {},
17728
+ id: "AUTO-DEV-01",
17729
+ result: run.status === "pass" ? "PASS" : "FAIL"
17730
+ },
17731
+ {
17732
+ details: run.hmr ? `Observed native HMR ${run.hmr.outcome} in ${run.hmr.durationMs}ms${run.hmr.serverMs === undefined ? "" : ` (server ${run.hmr.serverMs}ms, client ${run.hmr.clientMs}ms)`}.` : "Correlated edit timing was not requested. Rerun with --wait-for-hmr.",
17733
+ id: "AUTO-HMR-01",
17734
+ result: hmrResult
17735
+ },
17736
+ {
17737
+ details: run.screenshot ? "A simulator screenshot was captured. Visually review it before sharing this directory." : "No simulator screenshot was captured.",
17738
+ ...evidence ? { evidence } : {},
17739
+ id: "AUTO-ARTIFACT-01",
17740
+ result: run.screenshot ? "PASS" : "FAIL"
17741
+ }
17742
+ ];
17743
+ const manualChecks = MANUAL_CHECKS.map(([id, details]) => ({
17744
+ details,
17745
+ id,
17746
+ result: "NOT_RUN"
17747
+ }));
17748
+ return {
17749
+ automatedChecks,
17750
+ generatedAt: options.generatedAt ?? new Date().toISOString(),
17751
+ manualChecks,
17752
+ metadata: {
17753
+ absolutejsVersion: options.absolutejsVersion,
17754
+ bunVersion: options.bunVersion,
17755
+ macosVersion: options.macosVersion,
17756
+ provider: "capacitor",
17757
+ xcodeVersion: options.xcodeVersion
17758
+ },
17759
+ overallResult: run.status === "fail" ? "FAIL" : "INCOMPLETE",
17760
+ platform: "ios",
17761
+ reportVersion: 1,
17762
+ run
17763
+ };
17764
+ }, readPackageVersionForIosReport = async (packageJsonPath) => {
17765
+ const manifest = JSON.parse(await readFile18(packageJsonPath, "utf8"));
17766
+ if (typeof manifest !== "object" || manifest === null)
17767
+ return "unknown";
17768
+ const version2 = Reflect.get(manifest, "version");
17769
+ return typeof version2 === "string" ? version2 : "unknown";
17770
+ }, renderAbsoluteIosPartnerReport = (report) => {
17771
+ const table = (checks) => checks.map((check2) => `| ${check2.id} | ${check2.result} | ${markdownCell(check2.details)} | ${markdownCell(check2.evidence ?? "")} |`).join(`
17772
+ `);
17773
+ return `# AbsoluteJS iOS test report
17774
+
17775
+ - Overall result: ${report.overallResult}
17776
+ - Generated: ${report.generatedAt}
17777
+ - AbsoluteJS: ${markdownCell(report.metadata.absolutejsVersion)}
17778
+ - macOS: ${markdownCell(report.metadata.macosVersion)}
17779
+ - Xcode: ${markdownCell(report.metadata.xcodeVersion)}
17780
+ - Bun: ${markdownCell(report.metadata.bunVersion)}
17781
+ - App bundle ID: ${markdownCell(report.run.appId)}
17782
+ - Simulator UDID: ${markdownCell(report.run.udid)}
17783
+ - Automated run: ${report.run.status.toUpperCase()} (${report.run.durationMs}ms)
17784
+
17785
+ ` + `This report is local and is never uploaded by AbsoluteJS. Before sharing its directory, visually inspect screenshots and logs. Never add passwords, signing material, tokens, cookies, private Sync data, or exact coordinates.
17786
+
17787
+ ## Automated checks
17788
+
17789
+ | Test ID | Result | Observed result / timing | Evidence |
17790
+ | --- | --- | --- | --- |
17791
+ ${table(report.automatedChecks)}
17792
+
17793
+ ## Partner checklist
17794
+
17795
+ Replace each \`NOT_RUN\` with \`PASS\`, \`FAIL\`, or \`SKIPPED\` after following \`docs/IOS_MACOS_TESTING.md\`. A failure must name sanitized evidence and state actual versus expected behavior.
17796
+
17797
+ | Test ID | Result | Observed result / timing | Evidence or failure details |
17798
+ | --- | --- | --- | --- |
17799
+ ${table(report.manualChecks)}
17800
+ `;
17801
+ }, writeAbsoluteIosPartnerReport = async (directory, report) => {
17802
+ await mkdir13(directory, { recursive: true });
17803
+ const jsonPath = join51(directory, "report.json");
17804
+ const markdownPath = join51(directory, "report.md");
17805
+ await Promise.all([
17806
+ writeFile15(jsonPath, `${JSON.stringify(report, null, 2)}
17807
+ `),
17808
+ writeFile15(markdownPath, renderAbsoluteIosPartnerReport(report))
17809
+ ]);
17810
+ return { directory, jsonPath, markdownPath };
17811
+ };
17812
+ var init_iosTestReport = __esm(() => {
17813
+ MANUAL_CHECKS = [
17814
+ [
17815
+ "SETUP-01",
17816
+ "Confirm and record all Mac, Xcode, Bun, device, and package versions."
17817
+ ],
17818
+ ["SETUP-02", "Confirm Xcode setup and the required iOS runtime."],
17819
+ ["SETUP-03", "Confirm the runbook package versions are installed."],
17820
+ ["SETUP-04", "Confirm the staging bundle ID and production server origin."],
17821
+ ["SETUP-05", "Confirm generated iOS project signing and Xcode warnings."],
17822
+ ["DEV-01", "Record cold and warm bun dev startup timings."],
17823
+ ["DEV-02", "Complete route traversal, HMR, relaunch, and recovery checks."],
17824
+ ["CAP-01", "Complete automatic device-capability provisioning checks."],
17825
+ ...Array.from({ length: 14 }, (_, index) => [
17826
+ `LOC-${String(index + 1).padStart(2, "0")}`,
17827
+ `Complete foreground-location runbook check LOC-${String(index + 1).padStart(2, "0")} without recording exact coordinates.`
17828
+ ]),
17829
+ [
17830
+ "AUTH-01",
17831
+ "Complete system-browser sign-in, callback, restore, and sign-out checks."
17832
+ ],
17833
+ [
17834
+ "SYNC-01",
17835
+ "Complete online, offline, reconnect, isolation, and conflict checks."
17836
+ ],
17837
+ ["BGSYNC-01", "Complete physical-device background Sync acceptance."],
17838
+ ["REMOTE-01", "Complete remote-Mac acceptance, or mark SKIPPED."],
17839
+ ["BUILD-01", "Pass release doctor and produce a signed IPA."],
17840
+ [
17841
+ "SHIP-01",
17842
+ "Upload, process, assign, install, and launch the TestFlight build."
17843
+ ],
17844
+ ["UPDATE-01", "Prove upload retry reuse and a subsequent web-only update."],
17845
+ [
17846
+ "REPORT-01",
17847
+ "Review this directory for sensitive content and complete every row."
17848
+ ]
17849
+ ];
17850
+ secretPattern = /(authorization|access[_ -]?token|refresh[_ -]?token|socket[_ -]?ticket|password|cookie)(\s*[=:]\s*)([^\s,;]+)/giu;
17851
+ bearerPattern = /bearer\s+[^\s,;]+/giu;
17852
+ coordinatePattern = /\b(latitude|longitude|lat|lng)(\s*[=:]\s*)-?\d+(?:\.\d+)?/giu;
17853
+ });
17854
+
17709
17855
  // src/mobile/releasePublisher.ts
17710
17856
  import { access as access10 } from "fs/promises";
17711
17857
  import { isAbsolute as isAbsolute8, relative as relative26, resolve as resolve40, sep as sep7 } from "path";
@@ -17804,11 +17950,11 @@ var exports_mobile = {};
17804
17950
  __export(exports_mobile, {
17805
17951
  runMobile: () => runMobile
17806
17952
  });
17807
- import { access as access11, mkdir as mkdir13, readFile as readFile18, writeFile as writeFile15 } from "fs/promises";
17808
- import { join as join51, resolve as resolve41 } from "path";
17953
+ import { access as access11, mkdir as mkdir14, readFile as readFile19, writeFile as writeFile16 } from "fs/promises";
17954
+ import { join as join52, resolve as resolve41 } from "path";
17809
17955
  import { createInterface } from "readline/promises";
17810
17956
  var NOT_FOUND3 = -1, isRecord15 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), CAPACITOR_PACKAGES, CAPACITOR_PACKAGE_SPECS, CAPACITOR_SYNC_PACKAGE_SPECS, packageNameFromSpec = (spec) => spec.slice(0, spec.lastIndexOf("@")), directProjectPackages = async (projectRoot) => {
17811
- const manifest = JSON.parse(await readFile18(join51(projectRoot, "package.json"), "utf8"));
17957
+ const manifest = JSON.parse(await readFile19(join52(projectRoot, "package.json"), "utf8"));
17812
17958
  if (!isRecord15(manifest))
17813
17959
  throw new TypeError("Application package.json must contain an object.");
17814
17960
  const names = new Set;
@@ -17821,7 +17967,7 @@ var NOT_FOUND3 = -1, isRecord15 = (value) => typeof value === "object" && value
17821
17967
  return names;
17822
17968
  }, resolvedPackageVersion = async (projectRoot, packageName) => {
17823
17969
  try {
17824
- const manifest = JSON.parse(await readFile18(join51(projectRoot, "node_modules", packageName, "package.json"), "utf8"));
17970
+ const manifest = JSON.parse(await readFile19(join52(projectRoot, "node_modules", packageName, "package.json"), "utf8"));
17825
17971
  return isRecord15(manifest) && typeof manifest.version === "string" ? manifest.version : undefined;
17826
17972
  } catch {
17827
17973
  return;
@@ -17862,7 +18008,7 @@ var NOT_FOUND3 = -1, isRecord15 = (value) => typeof value === "object" && value
17862
18008
  }
17863
18009
  return value;
17864
18010
  }, capacitorExecutable = async (projectRoot) => {
17865
- const executable = join51(projectRoot, "node_modules", ".bin", "cap");
18011
+ const executable = join52(projectRoot, "node_modules", ".bin", "cap");
17866
18012
  try {
17867
18013
  await access11(executable);
17868
18014
  return executable;
@@ -18183,7 +18329,7 @@ Mobile release transport checks failed.`);
18183
18329
  const durationMs = Math.round(performance.now() - startedAt);
18184
18330
  console.log(`Built ${release.metadata.signed ? "signed" : "unsigned"} Android App Bundle in ${getDurationString(durationMs)}.`);
18185
18331
  console.log(`Artifact: ${release.artifactPath}`);
18186
- console.log(`Metadata: ${join51(release.releaseRoot, "release.json")}`);
18332
+ console.log(`Metadata: ${join52(release.releaseRoot, "release.json")}`);
18187
18333
  return release;
18188
18334
  } finally {
18189
18335
  sendTelemetryEvent("mobile:android-release-build", {
@@ -18286,7 +18432,7 @@ Mobile release transport checks failed.`);
18286
18432
  const durationMs = Math.round(performance.now() - startedAt);
18287
18433
  console.log(`Built ${release.metadata.signed ? "signed" : "unsigned"} iOS IPA ${release.metadata.marketingVersion}${release.metadata.buildNumber ? ` (${release.metadata.buildNumber})` : ""} in ${getDurationString(durationMs)}.`);
18288
18434
  console.log(`Artifact: ${release.artifactPath}`);
18289
- console.log(`Metadata: ${join51(release.releaseRoot, "release.json")}`);
18435
+ console.log(`Metadata: ${join52(release.releaseRoot, "release.json")}`);
18290
18436
  return release;
18291
18437
  } finally {
18292
18438
  sendTelemetryEvent("mobile:ios-release-build", {
@@ -18393,7 +18539,7 @@ Mobile release transport checks failed.`);
18393
18539
  checks.push({
18394
18540
  id: "sync.storage-schema",
18395
18541
  label: `Offline schema ${schema.components.map((component2) => `${component2.id}@${component2.version}`).join(", ")}`,
18396
- path: join51(projectRoot, "package.json"),
18542
+ path: join52(projectRoot, "package.json"),
18397
18543
  platform: "host",
18398
18544
  status: "pass"
18399
18545
  });
@@ -18401,7 +18547,7 @@ Mobile release transport checks failed.`);
18401
18547
  checks.push({
18402
18548
  id: "sync.storage-schema",
18403
18549
  label: "Offline schema metadata is invalid",
18404
- path: join51(projectRoot, "package.json"),
18550
+ path: join52(projectRoot, "package.json"),
18405
18551
  platform: "host",
18406
18552
  remediation: error instanceof Error ? error.message : String(error),
18407
18553
  status: "fail"
@@ -18554,12 +18700,12 @@ Emulator setup verification:`);
18554
18700
  timeoutMs
18555
18701
  });
18556
18702
  }, writeAndroidFailureArtifacts = async (options) => {
18557
- await mkdir13(options.artifactRoot, { recursive: true });
18558
- const screenshot = options.session ? await options.session.screenshot(join51(options.artifactRoot, "android-failure.png")).catch(() => {
18703
+ await mkdir14(options.artifactRoot, { recursive: true });
18704
+ const screenshot = options.session ? await options.session.screenshot(join52(options.artifactRoot, "android-failure.png")).catch(() => {
18559
18705
  return;
18560
18706
  }) : undefined;
18561
- const diagnosticPath = join51(options.artifactRoot, "android-failure.json");
18562
- await writeFile15(diagnosticPath, `${JSON.stringify({
18707
+ const diagnosticPath = join52(options.artifactRoot, "android-failure.json");
18708
+ await writeFile16(diagnosticPath, `${JSON.stringify({
18563
18709
  diagnostics: options.session?.diagnostics ?? [],
18564
18710
  error: options.error instanceof Error ? options.error.message : String(options.error),
18565
18711
  platform: "android",
@@ -18735,8 +18881,8 @@ Emulator setup verification:`);
18735
18881
  throw new Error(`${label} failed: ${result.stderr.trim() || result.stdout.trim() || `status ${result.exitCode}`}`);
18736
18882
  return result;
18737
18883
  }, writeIosFailureArtifacts = async (options) => {
18738
- await mkdir13(options.artifactRoot, { recursive: true });
18739
- const screenshot = join51(options.artifactRoot, "ios-failure.png");
18884
+ await mkdir14(options.artifactRoot, { recursive: true });
18885
+ const screenshot = join52(options.artifactRoot, "ios-failure.png");
18740
18886
  const screenshotResult = captureCommand4([
18741
18887
  options.xcrun,
18742
18888
  "simctl",
@@ -18745,8 +18891,8 @@ Emulator setup verification:`);
18745
18891
  "screenshot",
18746
18892
  screenshot
18747
18893
  ]);
18748
- const diagnosticPath = join51(options.artifactRoot, "ios-failure.json");
18749
- await writeFile15(diagnosticPath, `${JSON.stringify({
18894
+ const diagnosticPath = join52(options.artifactRoot, "ios-failure.json");
18895
+ await writeFile16(diagnosticPath, `${JSON.stringify({
18750
18896
  appId: options.appId,
18751
18897
  error: options.error instanceof Error ? options.error.message : String(options.error),
18752
18898
  platform: "ios",
@@ -18760,6 +18906,45 @@ Emulator setup verification:`);
18760
18906
  diagnosticPath,
18761
18907
  screenshot: screenshotResult.exitCode === 0 ? screenshot : undefined
18762
18908
  };
18909
+ }, iosReportRoot = (args, projectRoot) => {
18910
+ const index = args.indexOf("--report");
18911
+ if (index === NOT_FOUND3)
18912
+ return;
18913
+ const candidate = args[index + 1];
18914
+ const explicit = candidate?.startsWith("--") ? undefined : candidate;
18915
+ const timestamp = new Date().toISOString().replaceAll(":", "-");
18916
+ return safeArtifactRoot(projectRoot, explicit ?? `.absolutejs/mobile/test-reports/ios-${timestamp}`);
18917
+ }, iosReportMetadata = async (xcrun) => {
18918
+ const xcodebuildPath = requireCapturedIosCommand([xcrun, "--find", "xcodebuild"], "Xcode version inspection").stdout.trim();
18919
+ const xcodeVersion = requireCapturedIosCommand([xcodebuildPath, "-version"], "Xcode version inspection").stdout.trim();
18920
+ const macosVersion = requireCapturedIosCommand(["/usr/bin/sw_vers", "-productVersion"], "macOS version inspection").stdout.trim();
18921
+ let absolutejsVersion = process.env.ABSOLUTE_VERSION ?? "unknown";
18922
+ for (const candidate of [
18923
+ resolve41(import.meta.dir, "..", "..", "package.json"),
18924
+ resolve41(import.meta.dir, "..", "..", "..", "package.json")
18925
+ ]) {
18926
+ const version2 = await readPackageVersionForIosReport(candidate).catch(() => "unknown");
18927
+ if (version2 === "unknown")
18928
+ continue;
18929
+ absolutejsVersion = version2;
18930
+ break;
18931
+ }
18932
+ return {
18933
+ absolutejsVersion,
18934
+ bunVersion: Bun.version,
18935
+ macosVersion,
18936
+ xcodeVersion
18937
+ };
18938
+ }, writeRequestedIosReport = async (options) => {
18939
+ const reportRoot = iosReportRoot(options.args, options.projectRoot);
18940
+ if (!reportRoot)
18941
+ return;
18942
+ const metadata = await iosReportMetadata(options.xcrun);
18943
+ const paths = await writeAbsoluteIosPartnerReport(reportRoot, createAbsoluteIosPartnerReport({ ...metadata, run: options.run }));
18944
+ const print = options.args.includes("--json") ? console.error : console.log;
18945
+ print(`iOS partner report: ${paths.markdownPath}`);
18946
+ print(`Return this report directory: ${paths.directory}`);
18947
+ return paths;
18763
18948
  }, testIos = async (args) => {
18764
18949
  const { mobile, projectRoot } = await loadMobile(valueAfter(args, "--config"));
18765
18950
  const { https, instance, port } = requireIosTestContext(args, projectRoot);
@@ -18770,7 +18955,8 @@ Emulator setup verification:`);
18770
18955
  const timeoutMs = androidTestTimeout(args);
18771
18956
  const xcrun = await requireIosXcrun();
18772
18957
  const simulator = selectIosSimulator(xcrun, valueAfter(args, "--udid") ?? valueAfter(args, "--serial"));
18773
- const artifactRoot = safeArtifactRoot(projectRoot, valueAfter(args, "--artifacts"));
18958
+ const reportRoot = iosReportRoot(args, projectRoot);
18959
+ const artifactRoot = reportRoot ?? safeArtifactRoot(projectRoot, valueAfter(args, "--artifacts"));
18774
18960
  const startedAt = performance.now();
18775
18961
  try {
18776
18962
  requireCapturedIosCommand([
@@ -18790,8 +18976,8 @@ Emulator setup verification:`);
18790
18976
  mobile.appId
18791
18977
  ], "iOS app launch");
18792
18978
  await waitForIosHmrClient({ https, port, timeoutMs });
18793
- await mkdir13(artifactRoot, { recursive: true });
18794
- const screenshot = join51(artifactRoot, "ios-simulator.png");
18979
+ await mkdir14(artifactRoot, { recursive: true });
18980
+ const screenshot = join52(artifactRoot, "ios-simulator.png");
18795
18981
  requireCapturedIosCommand([xcrun, "simctl", "io", simulator.udid, "screenshot", screenshot], "iOS simulator screenshot");
18796
18982
  const hmrApply = await waitForRequestedIosHmr(args, instance, timeoutMs);
18797
18983
  const report = {
@@ -18814,6 +19000,28 @@ Emulator setup verification:`);
18814
19000
  waitedForHmr: args.includes("--wait-for-hmr")
18815
19001
  });
18816
19002
  printIosTestReport(report, args.includes("--json"));
19003
+ await writeRequestedIosReport({
19004
+ args,
19005
+ projectRoot,
19006
+ run: {
19007
+ appId: report.appId,
19008
+ durationMs: report.durationMs,
19009
+ ...report.hmrApply ? {
19010
+ hmr: {
19011
+ ...report.hmrApply.clientMs === undefined ? {} : { clientMs: report.hmrApply.clientMs },
19012
+ durationMs: report.hmrApply.duration,
19013
+ outcome: report.hmrApply.outcome,
19014
+ ...report.hmrApply.serverMs === undefined ? {} : { serverMs: report.hmrApply.serverMs }
19015
+ }
19016
+ } : {},
19017
+ hmrConnected: report.hmrConnected,
19018
+ port: report.port,
19019
+ screenshot: report.screenshot,
19020
+ status: report.status,
19021
+ udid: report.udid
19022
+ },
19023
+ xcrun
19024
+ });
18817
19025
  return report;
18818
19026
  } catch (error) {
18819
19027
  const durationMs = Math.round(performance.now() - startedAt);
@@ -18832,6 +19040,21 @@ Emulator setup verification:`);
18832
19040
  udid: simulator.udid,
18833
19041
  xcrun
18834
19042
  });
19043
+ await writeRequestedIosReport({
19044
+ args,
19045
+ projectRoot,
19046
+ run: {
19047
+ appId: mobile.appId,
19048
+ durationMs,
19049
+ error: sanitizeIosReportText(error instanceof Error ? error.message : String(error)),
19050
+ hmrConnected: false,
19051
+ port,
19052
+ ...screenshot ? { screenshot } : {},
19053
+ status: "fail",
19054
+ udid: simulator.udid
19055
+ },
19056
+ xcrun
19057
+ });
18835
19058
  throw new Error(`${error instanceof Error ? error.message : String(error)} Failure diagnostics: ${diagnosticPath}${screenshot ? `; screenshot: ${screenshot}` : ""}`, { cause: error });
18836
19059
  }
18837
19060
  }, runMobile = async (args) => {
@@ -18888,7 +19111,7 @@ Emulator setup verification:`);
18888
19111
  await publishIos(args.slice(2));
18889
19112
  return;
18890
19113
  }
18891
- throw new TypeError("Usage: absolute mobile <pair mac <name> <user@host> [--port n] [--workspace path] | remotes [--json] | unpair mac <name> | init [--no-native] [--force] | sync [ios|android] | associations [--outdir dir] [--verify] | doctor [ios|android|release] [--remote name] [--json|--fix [--yes]] | build <android|ios> [server-entry] [--outdir dir] [--web-outdir dir] [--unsigned] | publish android [server-entry] [--registry module] [--channel name] [--play-track track] [--play-status completed|draft|halted|in-progress] [--play-rollout fraction] [--play-name name] [--play-notes language=text] [--play-update-priority 0..5] [--play-hold-review] [--play-cancel-existing-review] [--outdir dir] [--web-outdir dir] [--unsigned] | publish ios [server-entry] [--registry module] [--channel name] [--testflight-group name-or-id] [--testflight-notes locale=text] [--testflight-submit-review] [--outdir dir] [--web-outdir dir] [--unsigned] | test android [--route path] [--wait-for-hmr] [--timeout ms] [--port n] [--serial id] [--artifacts dir] [--json] | test ios [--wait-for-hmr] [--timeout ms] [--port n] [--udid id] [--artifacts dir] [--json]> [--config path]");
19114
+ throw new TypeError("Usage: absolute mobile <pair mac <name> <user@host> [--port n] [--workspace path] | remotes [--json] | unpair mac <name> | init [--no-native] [--force] | sync [ios|android] | associations [--outdir dir] [--verify] | doctor [ios|android|release] [--remote name] [--json|--fix [--yes]] | build <android|ios> [server-entry] [--outdir dir] [--web-outdir dir] [--unsigned] | publish android [server-entry] [--registry module] [--channel name] [--play-track track] [--play-status completed|draft|halted|in-progress] [--play-rollout fraction] [--play-name name] [--play-notes language=text] [--play-update-priority 0..5] [--play-hold-review] [--play-cancel-existing-review] [--outdir dir] [--web-outdir dir] [--unsigned] | publish ios [server-entry] [--registry module] [--channel name] [--testflight-group name-or-id] [--testflight-notes locale=text] [--testflight-submit-review] [--outdir dir] [--web-outdir dir] [--unsigned] | test android [--route path] [--wait-for-hmr] [--timeout ms] [--port n] [--serial id] [--artifacts dir] [--json] | test ios [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--udid id] [--artifacts dir] [--json]> [--config path]");
18892
19115
  };
18893
19116
  var init_mobile = __esm(() => {
18894
19117
  init_dependencies();
@@ -18910,6 +19133,7 @@ var init_mobile = __esm(() => {
18910
19133
  init_iosRelease();
18911
19134
  init_iosSimulatorController();
18912
19135
  init_iosConformance();
19136
+ init_iosTestReport();
18913
19137
  init_releasePublisher();
18914
19138
  init_start();
18915
19139
  init_utils();
@@ -18953,9 +19177,9 @@ var exports_typecheck = {};
18953
19177
  __export(exports_typecheck, {
18954
19178
  typecheck: () => typecheck
18955
19179
  });
18956
- import { resolve as resolve42, join as join52 } from "path";
19180
+ import { resolve as resolve42, join as join53 } from "path";
18957
19181
  import { existsSync as existsSync42, readFileSync as readFileSync40 } from "fs";
18958
- import { mkdir as mkdir14, writeFile as writeFile16 } from "fs/promises";
19182
+ import { mkdir as mkdir15, writeFile as writeFile17 } from "fs/promises";
18959
19183
  var isCommandService3 = (service) => service.kind === "command" || Array.isArray(service.command), resolveConfigPath = (configPath2) => resolve42(configPath2 ?? process.env.ABSOLUTE_CONFIG ?? "absolute.config.ts"), getTypecheckTargets = async (configPath2) => {
18960
19184
  if (!existsSync42(resolveConfigPath(configPath2))) {
18961
19185
  const defaultService = {};
@@ -19062,8 +19286,8 @@ Found ${errorCount} error${suffix}.`;
19062
19286
  console.error("\x1B[31m\u2717\x1B[0m vue-tsc is required for Vue type checking. Install it: bun add -d vue-tsc");
19063
19287
  process.exit(1);
19064
19288
  }
19065
- const vueTsconfigPath = join52(cacheDir, "tsconfig.vue-check.json");
19066
- await writeFile16(vueTsconfigPath, JSON.stringify({
19289
+ const vueTsconfigPath = join53(cacheDir, "tsconfig.vue-check.json");
19290
+ await writeFile17(vueTsconfigPath, JSON.stringify({
19067
19291
  compilerOptions: {
19068
19292
  rootDir: ".."
19069
19293
  },
@@ -19082,7 +19306,7 @@ Found ${errorCount} error${suffix}.`;
19082
19306
  ...base,
19083
19307
  "--incremental",
19084
19308
  "--tsBuildInfoFile",
19085
- join52(cacheDir, "vue-tsc.tsbuildinfo")
19309
+ join53(cacheDir, "vue-tsc.tsbuildinfo")
19086
19310
  ]);
19087
19311
  if (cached.exitCode === 0 || cached.output.length > 0)
19088
19312
  return cached;
@@ -19093,8 +19317,8 @@ Found ${errorCount} error${suffix}.`;
19093
19317
  console.error("\x1B[31m\u2717\x1B[0m @angular/compiler-cli is required for Angular type checking. Install it: bun add -d @angular/compiler-cli");
19094
19318
  process.exit(1);
19095
19319
  }
19096
- const angularTsconfigPath = join52(cacheDir, "tsconfig.angular-check.json");
19097
- await writeFile16(angularTsconfigPath, JSON.stringify({
19320
+ const angularTsconfigPath = join53(cacheDir, "tsconfig.angular-check.json");
19321
+ await writeFile17(angularTsconfigPath, JSON.stringify({
19098
19322
  angularCompilerOptions: {
19099
19323
  strictTemplates: true
19100
19324
  },
@@ -19113,8 +19337,8 @@ Found ${errorCount} error${suffix}.`;
19113
19337
  console.error("\x1B[31m\u2717\x1B[0m typescript is required for type checking. Install it: bun add -d typescript");
19114
19338
  process.exit(1);
19115
19339
  }
19116
- const tscConfigPath = join52(cacheDir, "tsconfig.typecheck.json");
19117
- return writeFile16(tscConfigPath, JSON.stringify({
19340
+ const tscConfigPath = join53(cacheDir, "tsconfig.typecheck.json");
19341
+ return writeFile17(tscConfigPath, JSON.stringify({
19118
19342
  compilerOptions: {
19119
19343
  rootDir: ".."
19120
19344
  },
@@ -19128,7 +19352,7 @@ Found ${errorCount} error${suffix}.`;
19128
19352
  resolve42(tscConfigPath),
19129
19353
  "--incremental",
19130
19354
  "--tsBuildInfoFile",
19131
- join52(cacheDir, "tsc.tsbuildinfo"),
19355
+ join53(cacheDir, "tsc.tsbuildinfo"),
19132
19356
  "--pretty"
19133
19357
  ]));
19134
19358
  }, buildSvelteCheck = async (cacheDir, svelteDir) => {
@@ -19137,8 +19361,8 @@ Found ${errorCount} error${suffix}.`;
19137
19361
  console.error("\x1B[31m\u2717\x1B[0m svelte-check is required for Svelte type checking. Install it: bun add -d svelte-check");
19138
19362
  process.exit(1);
19139
19363
  }
19140
- const svelteTsconfigPath = join52(cacheDir, "tsconfig.svelte-check.json");
19141
- await writeFile16(svelteTsconfigPath, JSON.stringify({
19364
+ const svelteTsconfigPath = join53(cacheDir, "tsconfig.svelte-check.json");
19365
+ await writeFile17(svelteTsconfigPath, JSON.stringify({
19142
19366
  extends: resolve42("tsconfig.json"),
19143
19367
  files: ABSOLUTE_TYPECHECK_FILES,
19144
19368
  include: [`../${svelteDir}/**/*`]
@@ -19167,7 +19391,7 @@ Found ${errorCount} error${suffix}.`;
19167
19391
  ...new Set(targets.map((config) => config.angularDirectory).filter((dir) => typeof dir === "string" && dir.length > 0))
19168
19392
  ];
19169
19393
  const cacheDir = ".absolutejs";
19170
- await mkdir14(cacheDir, { recursive: true });
19394
+ await mkdir15(cacheDir, { recursive: true });
19171
19395
  const checks = [];
19172
19396
  checks.push(hasVue ? buildVueTscCheck(cacheDir) : buildTscCheck(cacheDir));
19173
19397
  for (const svelteDir of hasSvelte ? svelteDirs : []) {
@@ -0,0 +1,57 @@
1
+ export type AbsoluteIosReportResult = 'FAIL' | 'NOT_RUN' | 'PASS' | 'SKIPPED';
2
+ export type AbsoluteIosReportCheck = {
3
+ details: string;
4
+ evidence?: string;
5
+ id: string;
6
+ result: AbsoluteIosReportResult;
7
+ };
8
+ export type AbsoluteIosAutomatedResult = {
9
+ appId: string;
10
+ durationMs: number;
11
+ error?: string;
12
+ hmr?: {
13
+ clientMs?: number;
14
+ durationMs: number;
15
+ outcome: 'applied' | 'failed' | 'reloaded';
16
+ serverMs?: number;
17
+ };
18
+ hmrConnected: boolean;
19
+ port: number;
20
+ screenshot?: string;
21
+ status: 'fail' | 'pass';
22
+ udid: string;
23
+ };
24
+ export type AbsoluteIosPartnerReport = {
25
+ automatedChecks: AbsoluteIosReportCheck[];
26
+ generatedAt: string;
27
+ manualChecks: AbsoluteIosReportCheck[];
28
+ metadata: {
29
+ absolutejsVersion: string;
30
+ bunVersion: string;
31
+ macosVersion: string;
32
+ provider: 'capacitor';
33
+ xcodeVersion: string;
34
+ };
35
+ overallResult: 'FAIL' | 'INCOMPLETE';
36
+ platform: 'ios';
37
+ reportVersion: 1;
38
+ run: AbsoluteIosAutomatedResult;
39
+ };
40
+ type CreateAbsoluteIosPartnerReportOptions = {
41
+ absolutejsVersion: string;
42
+ bunVersion: string;
43
+ generatedAt?: string;
44
+ macosVersion: string;
45
+ run: AbsoluteIosAutomatedResult;
46
+ xcodeVersion: string;
47
+ };
48
+ export declare const sanitizeIosReportText: (value: string) => string;
49
+ export declare const createAbsoluteIosPartnerReport: (options: CreateAbsoluteIosPartnerReportOptions) => AbsoluteIosPartnerReport;
50
+ export declare const readPackageVersionForIosReport: (packageJsonPath: string) => Promise<string>;
51
+ export declare const renderAbsoluteIosPartnerReport: (report: AbsoluteIosPartnerReport) => string;
52
+ export declare const writeAbsoluteIosPartnerReport: (directory: string, report: AbsoluteIosPartnerReport) => Promise<{
53
+ directory: string;
54
+ jsonPath: string;
55
+ markdownPath: string;
56
+ }>;
57
+ export {};
package/package.json CHANGED
@@ -280,12 +280,12 @@
280
280
  "main": "./dist/index.js",
281
281
  "name": "@absolutejs/absolute",
282
282
  "optionalDependencies": {
283
- "@absolutejs/native-darwin-arm64": "0.20.0-beta.21",
284
- "@absolutejs/native-darwin-x64": "0.20.0-beta.21",
285
- "@absolutejs/native-linux-arm64": "0.20.0-beta.21",
286
- "@absolutejs/native-linux-x64": "0.20.0-beta.21",
287
- "@absolutejs/native-windows-arm64": "0.20.0-beta.21",
288
- "@absolutejs/native-windows-x64": "0.20.0-beta.21"
283
+ "@absolutejs/native-darwin-arm64": "0.20.0-beta.22",
284
+ "@absolutejs/native-darwin-x64": "0.20.0-beta.22",
285
+ "@absolutejs/native-linux-arm64": "0.20.0-beta.22",
286
+ "@absolutejs/native-linux-x64": "0.20.0-beta.22",
287
+ "@absolutejs/native-windows-arm64": "0.20.0-beta.22",
288
+ "@absolutejs/native-windows-x64": "0.20.0-beta.22"
289
289
  },
290
290
  "overrides": {
291
291
  "@sinclair/typebox": "0.34.52",
@@ -496,7 +496,7 @@
496
496
  ]
497
497
  }
498
498
  },
499
- "version": "0.20.0-beta.21",
499
+ "version": "0.20.0-beta.22",
500
500
  "workspaces": [
501
501
  "tests/fixtures/*",
502
502
  "tests/fixtures/_packages/*"