percher 0.5.17 → 0.5.18

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.
@@ -108052,6 +108052,7 @@ function buildTarball(fileBuffers) {
108052
108052
  fileCount: fileBuffers.length,
108053
108053
  topFiles,
108054
108054
  topEntries,
108055
+ topLevelEntries: [...entrySizes.keys()],
108055
108056
  contentHash
108056
108057
  };
108057
108058
  }
@@ -114372,6 +114373,74 @@ function solvePow(nonce, difficulty, maxIterations = 50000000) {
114372
114373
  return null;
114373
114374
  }
114374
114375
 
114376
+ // ../core/dist/bundle-completeness.js
114377
+ var import_cross_spawn2 = __toESM(require_cross_spawn(), 1);
114378
+ var ARTIFACT_DIRS = new Set([
114379
+ "node_modules",
114380
+ ".git",
114381
+ "dist",
114382
+ "build",
114383
+ ".next",
114384
+ ".svelte-kit",
114385
+ "coverage",
114386
+ ".bun",
114387
+ "out",
114388
+ ".turbo",
114389
+ ".cache",
114390
+ ".vercel",
114391
+ ".netlify"
114392
+ ]);
114393
+ var ASSET_DIRS = new Set(["public", "static", "assets"]);
114394
+ var SEVERE_SHRINK_PCT = 60;
114395
+ function gitTrackedFiles(cwd) {
114396
+ try {
114397
+ const res = import_cross_spawn2.default.sync("git", ["ls-files", "-z"], { cwd, encoding: "utf8" });
114398
+ if (res.status !== 0 || typeof res.stdout !== "string")
114399
+ return null;
114400
+ const files = res.stdout.split("\x00").filter(Boolean);
114401
+ return files.length > 0 ? files : null;
114402
+ } catch {
114403
+ return null;
114404
+ }
114405
+ }
114406
+ function checkBundleCompleteness(opts) {
114407
+ const tracked = gitTrackedFiles(opts.cwd);
114408
+ if (!tracked)
114409
+ return null;
114410
+ const packedDirs = new Set(opts.topLevelEntries.filter((e) => e.endsWith("/")).map((e) => e.slice(0, -1)));
114411
+ const trackedDirs = new Set;
114412
+ for (const f of tracked) {
114413
+ const slash = f.indexOf("/");
114414
+ if (slash === -1)
114415
+ continue;
114416
+ const top = f.slice(0, slash);
114417
+ if (!ARTIFACT_DIRS.has(top))
114418
+ trackedDirs.add(top);
114419
+ }
114420
+ const excludedDirs = [...trackedDirs].filter((d) => !packedDirs.has(d)).sort();
114421
+ if (excludedDirs.length === 0)
114422
+ return null;
114423
+ const shrinkPct = Math.round((1 - opts.packedFileCount / tracked.length) * 100);
114424
+ const isStatic = opts.config.app.runtime === "static";
114425
+ const assetExcluded = excludedDirs.some((d) => ASSET_DIRS.has(d));
114426
+ let reason = null;
114427
+ if (assetExcluded)
114428
+ reason = "asset_dir_excluded";
114429
+ else if (isStatic)
114430
+ reason = "static_content_excluded";
114431
+ else if (shrinkPct >= SEVERE_SHRINK_PCT)
114432
+ reason = "severe_shrink";
114433
+ if (!reason)
114434
+ return null;
114435
+ return { excludedDirs, shrinkPct, reason };
114436
+ }
114437
+ function bundleCompletenessMessage(w, config2) {
114438
+ const label = config2.app.framework ? `${config2.app.framework} (${config2.app.runtime})` : config2.app.runtime;
114439
+ const dirs = w.excludedDirs.map((d) => `${d}/`).join(", ");
114440
+ const assetNote = w.reason === "asset_dir_excluded" ? " Those hold static assets — the deployed app will be missing them." : w.reason === "static_content_excluded" ? " A static app serves exactly these files, so the deployed site will be missing content." : "";
114441
+ return `Detected a ${label} app, but the upload is missing ${w.excludedDirs.length} git-tracked ` + `director${w.excludedDirs.length === 1 ? "y" : "ies"} (${dirs}) — the bundle has ~${w.shrinkPct}% ` + `fewer files than your repo tracks.${assetNote} This is almost always an over-broad ` + `.gitignore/.percherignore rule. Those are gitignore-style patterns: a bare \`name\` matches a ` + `\`name/\` directory at ANY depth, so anchor to the repo root with a leading slash (e.g. \`/build\`) ` + `when you mean only the top-level one. If the exclusion is intentional, re-run with --force.`;
114442
+ }
114443
+
114375
114444
  // ../core/dist/event-renderer.js
114376
114445
  function renderDeployEvent(event) {
114377
114446
  if (event.stage === "queue") {
@@ -115387,7 +115456,7 @@ ${bullets}`,
115387
115456
  error: {
115388
115457
  title: "Repository too large",
115389
115458
  explanation: `The project is ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB, which exceeds the 500 MB limit.`,
115390
- suggestion: `Add large files/folders to .gitignore or .percherignore. Biggest: ${formatBiggestEntries(tarball.topEntries)}`
115459
+ suggestion: `Add large files/folders to .gitignore or .percherignore (gitignore-style — anchor with a leading / for top-level only, e.g. /assets). Biggest: ${formatBiggestEntries(tarball.topEntries)}`
115391
115460
  },
115392
115461
  recovery: recoveryAsk({
115393
115462
  prompt: `Repository is ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB, which exceeds the 500 MB upload limit. Add large files/folders to .gitignore or .percherignore (biggest: ${formatBiggestEntries(tarball.topEntries)}) and try again.`,
@@ -115399,7 +115468,33 @@ ${bullets}`,
115399
115468
  };
115400
115469
  }
115401
115470
  if (!input.force && (tarball.fileCount > SUSPICIOUS_FILES || tarball.bytes > SUSPICIOUS_BYTES)) {
115402
- ctx.status(`Warning: ${tarball.fileCount} files, ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB — auto-continuing (MCP mode). Biggest: ${formatBiggestEntries(tarball.topEntries)}. Trim the upload by adding large items to .gitignore or .percherignore.`);
115471
+ ctx.status(`Warning: ${tarball.fileCount} files, ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB — auto-continuing (MCP mode). Biggest: ${formatBiggestEntries(tarball.topEntries)}. Trim the upload by adding large items to .gitignore or .percherignore (gitignore-style patterns — anchor with a leading / for top-level only, e.g. /assets).`);
115472
+ }
115473
+ if (!input.force) {
115474
+ const completeness = checkBundleCompleteness({
115475
+ cwd: ctx.cwd,
115476
+ config: config2,
115477
+ topLevelEntries: tarball.topLevelEntries,
115478
+ packedFileCount: tarball.fileCount
115479
+ });
115480
+ if (completeness) {
115481
+ const message = bundleCompletenessMessage(completeness, config2);
115482
+ const excluded = completeness.excludedDirs.map((d) => `${d}/`).join(", ");
115483
+ return {
115484
+ status: "failed",
115485
+ fileCount: tarball.fileCount,
115486
+ bytes: tarball.bytes,
115487
+ error: {
115488
+ title: "Bundle is missing git-tracked files",
115489
+ explanation: message,
115490
+ suggestion: "Fix the .gitignore/.percherignore pattern that excluded it, or re-run with --force if intentional."
115491
+ },
115492
+ recovery: recoveryAsk({ prompt: message, reasonCode: "unknown" }),
115493
+ summary: `Upload is missing git-tracked dir(s): ${excluded} (~${completeness.shrinkPct}% fewer files than tracked). Re-run with --force if intentional.`,
115494
+ configPath: tomlPathFor2(ctx.cwd),
115495
+ bundle: { fileCount: tarball.fileCount, bytes: tarball.bytes }
115496
+ };
115497
+ }
115403
115498
  }
115404
115499
  emitPreflight(ctx, config2, {
115405
115500
  fileCount: tarball.fileCount,
@@ -116653,10 +116748,10 @@ function updateLocalTomlName(cwd, oldName, newName) {
116653
116748
  import { mkdtempSync, writeFileSync as writeFileSync10 } from "node:fs";
116654
116749
  import { tmpdir } from "node:os";
116655
116750
  import { join as join27 } from "node:path";
116656
- var import_cross_spawn2 = __toESM(require_cross_spawn(), 1);
116751
+ var import_cross_spawn3 = __toESM(require_cross_spawn(), 1);
116657
116752
  function runProcessExit(cmd, args, opts = {}) {
116658
116753
  return new Promise((resolve11, reject) => {
116659
- const child = import_cross_spawn2.default(cmd, args, {
116754
+ const child = import_cross_spawn3.default(cmd, args, {
116660
116755
  cwd: opts.cwd,
116661
116756
  stdio: opts.inherit ? "inherit" : "ignore"
116662
116757
  });
@@ -119504,7 +119599,7 @@ async function renderError(stderr, error48) {
119504
119599
  // package.json
119505
119600
  var package_default = {
119506
119601
  name: "percher",
119507
- version: "0.5.17",
119602
+ version: "0.5.18",
119508
119603
  description: "CLI for the Percher hosting platform — publish apps with one command",
119509
119604
  type: "module",
119510
119605
  bin: {
@@ -119528,9 +119623,9 @@ var package_default = {
119528
119623
  typecheck: "tsc --noEmit"
119529
119624
  },
119530
119625
  dependencies: {
119531
- "@percher/client": "^0.2.16",
119532
- "@percher/core": "^0.4.18",
119533
- "@percher/toml": "^0.1.5",
119626
+ "@percher/client": "^0.2.18",
119627
+ "@percher/core": "^0.4.21",
119628
+ "@percher/toml": "^0.1.7",
119534
119629
  cac: "^7.0.0",
119535
119630
  picocolors: "^1.1.1"
119536
119631
  },
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "percher",
3
- "version": "0.5.17",
3
+ "version": "0.5.18",
4
4
  "description": "CLI for the Percher hosting platform — publish apps with one command",
5
5
  "type": "module",
6
6
  "bin": {
@@ -24,9 +24,9 @@
24
24
  "typecheck": "tsc --noEmit"
25
25
  },
26
26
  "dependencies": {
27
- "@percher/client": "^0.2.16",
28
- "@percher/core": "^0.4.18",
29
- "@percher/toml": "^0.1.5",
27
+ "@percher/client": "^0.2.18",
28
+ "@percher/core": "^0.4.21",
29
+ "@percher/toml": "^0.1.7",
30
30
  "cac": "^7.0.0",
31
31
  "picocolors": "^1.1.1"
32
32
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "percher",
3
- "version": "0.5.17",
3
+ "version": "0.5.18",
4
4
  "description": "CLI for the Percher hosting platform — publish apps with one command",
5
5
  "type": "module",
6
6
  "bin": {
@@ -24,9 +24,9 @@
24
24
  "typecheck": "tsc --noEmit"
25
25
  },
26
26
  "dependencies": {
27
- "@percher/client": "^0.2.16",
28
- "@percher/core": "^0.4.18",
29
- "@percher/toml": "^0.1.5",
27
+ "@percher/client": "^0.2.18",
28
+ "@percher/core": "^0.4.21",
29
+ "@percher/toml": "^0.1.7",
30
30
  "cac": "^7.0.0",
31
31
  "picocolors": "^1.1.1"
32
32
  },