vibeview 0.34.0 → 0.36.0

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.
@@ -113,9 +113,10 @@ var NotFoundError = class extends Error {
113
113
  }
114
114
  };
115
115
  var ApiStatusError = class extends Error {
116
- constructor(status, message) {
116
+ constructor(status, message, data = null) {
117
117
  super(message);
118
118
  this.status = status;
119
+ this.data = data;
119
120
  this.name = "ApiStatusError";
120
121
  }
121
122
  };
@@ -129,12 +130,22 @@ function extractDetail(text) {
129
130
  try {
130
131
  const parsed = JSON.parse(text);
131
132
  if (parsed && typeof parsed.detail === "string") return parsed.detail;
132
- if (parsed && parsed.detail && typeof parsed.detail.message === "string")
133
- return parsed.detail.message;
133
+ if (parsed && parsed.detail && typeof parsed.detail.message === "string") {
134
+ const fix = parsed.detail.fix;
135
+ return typeof fix === "string" && fix.trim() ? `${parsed.detail.message} ${fix}` : parsed.detail.message;
136
+ }
134
137
  } catch {
135
138
  }
136
139
  return void 0;
137
140
  }
141
+ function extractDetailObject(text) {
142
+ try {
143
+ const detail = JSON.parse(text)?.detail;
144
+ if (detail && typeof detail === "object" && !Array.isArray(detail)) return detail;
145
+ } catch {
146
+ }
147
+ return null;
148
+ }
138
149
  function httpErrorMessage(status, text) {
139
150
  const body = text.trim();
140
151
  const looksLikeHtml = /^<(!doctype|html|head|body)\b/i.test(body) || /<\/html>\s*$/i.test(body);
@@ -192,7 +203,8 @@ var ApiClient = class {
192
203
  if (resp.status === 404) throw new NotFoundError(`Not found: ${extractDetail(text) ?? path}`);
193
204
  throw new ApiStatusError(
194
205
  resp.status,
195
- extractDetail(text) ?? httpErrorMessage(resp.status, text)
206
+ extractDetail(text) ?? httpErrorMessage(resp.status, text),
207
+ extractDetailObject(text)
196
208
  );
197
209
  }
198
210
  return parseJsonBody(resp);
@@ -273,7 +285,8 @@ var ApiClient = class {
273
285
  if (resp.status === 404) throw new NotFoundError(`Not found: ${extractDetail(text) ?? path}`);
274
286
  throw new ApiStatusError(
275
287
  resp.status,
276
- extractDetail(text) ?? httpErrorMessage(resp.status, text)
288
+ extractDetail(text) ?? httpErrorMessage(resp.status, text),
289
+ extractDetailObject(text)
277
290
  );
278
291
  }
279
292
  return parseJsonBody(resp);
@@ -297,7 +310,8 @@ var ApiClient = class {
297
310
  if (resp.status === 404) throw new NotFoundError(`Not found: ${extractDetail(text) ?? path}`);
298
311
  throw new ApiStatusError(
299
312
  resp.status,
300
- extractDetail(text) ?? httpErrorMessage(resp.status, text)
313
+ extractDetail(text) ?? httpErrorMessage(resp.status, text),
314
+ extractDetailObject(text)
301
315
  );
302
316
  }
303
317
  return parseJsonBody(resp);
@@ -471,7 +485,8 @@ var ApiClient = class {
471
485
  throw new NotFoundError(`Not found: ${extractDetail(text) ?? `/builds/${id}/artifact`}`);
472
486
  throw new ApiStatusError(
473
487
  resp.status,
474
- extractDetail(text) ?? httpErrorMessage(resp.status, text)
488
+ extractDetail(text) ?? httpErrorMessage(resp.status, text),
489
+ extractDetailObject(text)
475
490
  );
476
491
  }
477
492
  const rawFilename = parseContentDispositionFilename(resp.headers.get("content-disposition"));
@@ -891,7 +906,9 @@ async function uploadApp(filePath, options) {
891
906
  deduplicated: result.deduplicated === true,
892
907
  note: options.note?.trim() || null,
893
908
  url: `${baseUrl}/apps/${result.public_id}`,
894
- warnings: result.warnings ?? []
909
+ warnings: result.warnings ?? [],
910
+ compat_status: result.compat_status ?? null,
911
+ findings: result.findings ?? []
895
912
  },
896
913
  null,
897
914
  2
@@ -908,11 +925,36 @@ async function uploadApp(filePath, options) {
908
925
  console.log(chalk.dim(` ${baseUrl}/apps/${result.public_id}
909
926
  `));
910
927
  }
911
- for (const w of result.warnings ?? []) {
912
- console.error(chalk.yellow(`
928
+ const findings = result.findings ?? [];
929
+ if (findings.length) {
930
+ for (const f of findings) console.error(chalk.yellow(`
931
+ \u26A0 ${f.message}`) + `
932
+ ${f.fix}`);
933
+ } else {
934
+ for (const w of result.warnings ?? []) console.error(chalk.yellow(`
913
935
  \u26A0 ${w}`));
914
936
  }
915
937
  } catch (err) {
938
+ if (err instanceof ApiStatusError && err.status === 422 && err.data?.error === "build_refused") {
939
+ const findings = Array.isArray(err.data.findings) ? err.data.findings : [];
940
+ spinner.fail("Build refused: it cannot run on VibeView devices");
941
+ if (options.output === "json") {
942
+ const message2 = typeof err.data.message === "string" ? err.data.message : err.message;
943
+ console.log(JSON.stringify({ error: "build_refused", message: message2, findings }, null, 2));
944
+ } else {
945
+ for (const f of findings.filter((x) => x.severity === "refuse")) {
946
+ console.error(chalk.red(`
947
+ \u2716 ${f.message}`));
948
+ console.error(` ${f.fix}`);
949
+ }
950
+ console.error(
951
+ chalk.dim(
952
+ "\nThink this is a mistake? Email support@vibeview.io with the file name and we'll take a look."
953
+ )
954
+ );
955
+ }
956
+ process.exit(EXIT_TEST_FAIL);
957
+ }
916
958
  const message = err instanceof Error ? err.message : "Upload failed";
917
959
  spinner.fail(message);
918
960
  if (options.output === "json") console.error(chalk.red(`Error: ${message}`));