mnfst-publish 0.1.9 → 0.1.10

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.
@@ -301,7 +301,15 @@ export function collectFiles(root, outputDir) {
301
301
  // .manifestignore applies ON TOP of gitignore, so a versioned file can still be
302
302
  // kept out of the published bundle.
303
303
  const publishIgnored = loadPublishIgnore(root);
304
- return rels.filter((r) => !isExcludedPath(r) && !publishIgnored(r));
304
+ return rels
305
+ .filter((r) => !isExcludedPath(r) && !publishIgnored(r))
306
+ // `git ls-files -c` reports paths from the index, not the working tree — a file
307
+ // committed once (e.g. an old build's <locale>/docs/** output) then deleted on
308
+ // disk without `git rm` still shows up here. Ship what's actually there; a
309
+ // stale tracked-but-missing path would otherwise crash buildZip with ENOENT
310
+ // (seen with mnfst-publish --no-render after a re-render dropped locale
311
+ // variants under an excluded route prefix).
312
+ .filter((r) => existsSync(join(root, r)));
305
313
  }
306
314
 
307
315
  // --- Upload + publish status ------------------------------------------------
@@ -380,6 +388,13 @@ export async function pollPublishStatus(statusUrl, opts = {}) {
380
388
  if (json && json.status === 'pending' && now() - started >= pendingGraceMs) {
381
389
  return { state: 'pending', body: json };
382
390
  }
391
+ // An HTTP error body that skips the {status:'error'} tag entirely (a plain
392
+ // {error, message} shape, same as an upload-time rejection) is still a
393
+ // settled failure, not a blip — UNLESS it's 429 (rate limited) or a 5xx,
394
+ // both of which are expected to be transient and worth retrying.
395
+ if (json && json.error && !json.status && status >= 400 && status !== 429 && status < 500) {
396
+ return { state: 'error', body: json };
397
+ }
383
398
  // Anything else (ingesting, pending inside the grace, 429, 5xx, a blip) —
384
399
  // keep waiting.
385
400
 
@@ -399,7 +414,8 @@ function settledPayload(res) {
399
414
  if (res.state === 'done') return res.body;
400
415
  if (res.state === 'error') {
401
416
  const b = res.body || {};
402
- throw new Error(`publish failed${b.error ? ` (${b.error})` : ''}: ${b.message || 'the server rejected the upload.'}`);
417
+ const retrySafe = b.error === 'retry_upload' ? ' Re-running the same command is safe and cheap nothing was double-charged or double-shipped.' : '';
418
+ throw new Error(`publish failed${b.error ? ` (${b.error})` : ''}: ${b.message || 'the server rejected the upload.'}${retrySafe}`);
403
419
  }
404
420
  if (res.state === 'unknown') {
405
421
  throw new Error('this publish link expired before the upload finished. Run the publish again.');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mnfst-publish",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "One-command managed publishing for Manifest projects — render, zip, upload, live URL.",
5
5
  "type": "module",
6
6
  "bin": {