@valbuild/server 0.91.3 → 0.92.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.
package/LICENSE.md ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2025 Fredrik Ekholdt and Blank AS
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,5 +1,3 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
1
  /**
4
2
  * A filesystem that can update and read files.
5
3
  * It does not support creating new files or directories.
@@ -1,5 +1,3 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
1
  import ts from "typescript";
4
2
  import { ValFS } from "./ValFS.js";
5
3
  import { Buffer } from "buffer";
@@ -1,5 +1,3 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
1
  import { ValModules, ValConfig } from "@valbuild/core";
4
2
  import { Api, ServerOf } from "@valbuild/shared/internal";
5
3
  import { z } from "zod";
@@ -41,19 +39,7 @@ declare const IntegratedServerJwtPayload: z.ZodObject<{
41
39
  token: z.ZodString;
42
40
  org: z.ZodString;
43
41
  project: z.ZodString;
44
- }, "strip", z.ZodTypeAny, {
45
- project: string;
46
- sub: string;
47
- token: string;
48
- exp: number;
49
- org: string;
50
- }, {
51
- project: string;
52
- sub: string;
53
- token: string;
54
- exp: number;
55
- org: string;
56
- }>;
42
+ }, z.core.$strip>;
57
43
  export type IntegratedServerJwtPayload = z.infer<typeof IntegratedServerJwtPayload>;
58
44
  export declare const ENABLE_COOKIE_VALUE: {
59
45
  readonly value: "true";
@@ -62,7 +48,7 @@ export declare const ENABLE_COOKIE_VALUE: {
62
48
  readonly sameSite: "lax";
63
49
  };
64
50
  };
65
- export declare function bufferToReadableStream(buffer: Buffer): ReadableStream<any>;
51
+ export declare function bufferToReadableStream(buffer: Buffer): import("node:stream/web").ReadableStream<any>;
66
52
  export declare function getRedirectUrl(query: {
67
53
  redirect_to?: string | undefined;
68
54
  }, overrideHost: string | undefined): string | {
@@ -3,22 +3,8 @@ declare const SettingsSchema: z.ZodObject<{
3
3
  publicProjectId: z.ZodString;
4
4
  remoteFileBuckets: z.ZodArray<z.ZodObject<{
5
5
  bucket: z.ZodString;
6
- }, "strip", z.ZodTypeAny, {
7
- bucket: string;
8
- }, {
9
- bucket: string;
10
- }>, "many">;
11
- }, "strip", z.ZodTypeAny, {
12
- publicProjectId: string;
13
- remoteFileBuckets: {
14
- bucket: string;
15
- }[];
16
- }, {
17
- publicProjectId: string;
18
- remoteFileBuckets: {
19
- bucket: string;
20
- }[];
21
- }>;
6
+ }, z.core.$strip>>;
7
+ }, z.core.$strip>;
22
8
  type Settings = z.infer<typeof SettingsSchema>;
23
9
  export declare function getSettings(projectName: string, auth: {
24
10
  pat: string;
@@ -1,5 +1,3 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
1
  export declare function uploadRemoteFile(contentHost: string, project: string, bucket: string, fileHash: string, fileExt: string, fileBuffer: Buffer, auth: {
4
2
  pat: string;
5
3
  } | {
@@ -1064,9 +1064,7 @@ const MAX_CACHE_SIZE = 100 * 1024 * 1024; // 100 mb
1064
1064
  const MAX_OBJECT_KEY_SIZE = 2 ** 27; // https://stackoverflow.com/questions/13367391/is-there-a-limit-on-length-of-the-key-string-in-js-object
1065
1065
 
1066
1066
  class ValModuleLoader {
1067
- constructor(projectRoot,
1068
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1069
- compilerOptions,
1067
+ constructor(projectRoot, compilerOptions,
1070
1068
  // TODO: remove this?
1071
1069
  sourceFileHandler, host = {
1072
1070
  ...ts__default["default"].sys,
@@ -1280,7 +1278,7 @@ export default new Proxy({}, {
1280
1278
  return {
1281
1279
  value: moduleLoader.getModule(modulePath)
1282
1280
  };
1283
- } catch (e) {
1281
+ } catch {
1284
1282
  return {
1285
1283
  error: Error(`Could not resolve module: '${modulePath}'`)
1286
1284
  };
@@ -1529,7 +1527,7 @@ class ValOps {
1529
1527
  collector.push("[");
1530
1528
  for (let i = 0; i < item.length; i++) {
1531
1529
  this.collectObjectRecursive(item[i], collector);
1532
- i !== item.length - 1 && collector.push(",");
1530
+ if (i !== item.length - 1) collector.push(",");
1533
1531
  }
1534
1532
  collector.push("]");
1535
1533
  } else {
@@ -1538,7 +1536,7 @@ class ValOps {
1538
1536
  keys.forEach((key, i) => {
1539
1537
  collector.push(`"${key}":`);
1540
1538
  this.collectObjectRecursive(item[key], collector);
1541
- i !== keys.length - 1 && collector.push(",");
1539
+ if (i !== keys.length - 1) collector.push(",");
1542
1540
  });
1543
1541
  collector.push("}");
1544
1542
  }
@@ -2495,7 +2493,7 @@ async function uploadRemoteFile(contentHost, project, bucket, fileHash, fileExt,
2495
2493
  ...authHeader,
2496
2494
  "Content-Type": "application/octet-stream"
2497
2495
  },
2498
- body: fileBuffer
2496
+ body: new Uint8Array(fileBuffer)
2499
2497
  });
2500
2498
  if (!res.ok) {
2501
2499
  var _res$headers$get;
@@ -2507,17 +2505,11 @@ async function uploadRemoteFile(contentHost, project, bucket, fileHash, fileExt,
2507
2505
  }
2508
2506
  if ((_res$headers$get = res.headers.get("content-type")) !== null && _res$headers$get !== void 0 && _res$headers$get.includes("application/json")) {
2509
2507
  const json = await res.json();
2510
- if (json.message) {
2511
- return {
2512
- success: false,
2513
- error: `Failed to upload remote file: ${json.message}.`
2514
- };
2515
- } else {
2516
- return {
2517
- success: false,
2518
- error: `Failed to upload remote file: ${JSON.stringify(json)}.`
2519
- };
2520
- }
2508
+ const message = internal.getErrorMessageFromUnknownJson(json, JSON.stringify(json));
2509
+ return {
2510
+ success: false,
2511
+ error: `Failed to upload remote file: ${message}.`
2512
+ };
2521
2513
  }
2522
2514
  return {
2523
2515
  success: false,
@@ -3042,7 +3034,7 @@ class ValOpsFS extends ValOps {
3042
3034
  }]
3043
3035
  };
3044
3036
  }
3045
- const metadataParseRes = this.parseJsonFile(metadataFilePath, zod.z.record(zod.z.union([zod.z.string(), zod.z.number()])));
3037
+ const metadataParseRes = this.parseJsonFile(metadataFilePath, zod.z.record(zod.z.string(), zod.z.union([zod.z.string(), zod.z.number()])));
3046
3038
  if (metadataParseRes.error) {
3047
3039
  return {
3048
3040
  errors: [metadataParseRes.error]
@@ -3416,7 +3408,7 @@ class FSOpsHost {
3416
3408
  fs__default["default"].mkdirSync(path__namespace["default"].dirname(path), {
3417
3409
  recursive: false
3418
3410
  });
3419
- } catch (e) {
3411
+ } catch {
3420
3412
  // ignore
3421
3413
  }
3422
3414
  try {
@@ -3479,7 +3471,7 @@ const MetadataRes = zod.z.object({
3479
3471
  type: zod.z.union([zod.z.literal("file"), zod.z.literal("image")]).nullable()
3480
3472
  });
3481
3473
  const SummaryResponse = zod.z.object({
3482
- commitSummary: zod.z.string().nullable()
3474
+ commitSummary: zod.z.string()
3483
3475
  });
3484
3476
  const GetApplicablePatches = zod.z.object({
3485
3477
  patches: zod.z.array(zod.z.object({
@@ -3566,6 +3558,10 @@ const ProfilesResponse = zod.z.object({
3566
3558
  }).nullable()
3567
3559
  }))
3568
3560
  });
3561
+ const NonceResponse = zod.z.object({
3562
+ nonce: zod.z.string(),
3563
+ url: zod.z.string()
3564
+ });
3569
3565
  class ValOpsHttp extends ValOps {
3570
3566
  constructor(contentUrl, project, commitSha,
3571
3567
  // TODO: CommitSha
@@ -3634,20 +3630,19 @@ class ValOpsHttp extends ValOps {
3634
3630
  }
3635
3631
  };
3636
3632
  }
3633
+ const unknownErrorMessage = `Could not get presigned auth nonce. HTTP error: ${res.status} ${res.statusText}`;
3637
3634
  if ((_res$headers$get = res.headers.get("Content-Type")) !== null && _res$headers$get !== void 0 && _res$headers$get.includes("application/json")) {
3638
3635
  const json = await res.json();
3639
- if (json.message) {
3640
- console.error("Presigned auth nonce error:", json.message);
3641
- return {
3642
- status: "error",
3643
- statusCode: 500,
3644
- error: {
3645
- message: json.message
3646
- }
3647
- };
3648
- }
3636
+ const message = internal.getErrorMessageFromUnknownJson(json, unknownErrorMessage);
3637
+ console.error("Presigned auth nonce error:", message);
3638
+ return {
3639
+ status: "error",
3640
+ statusCode: 500,
3641
+ error: {
3642
+ message
3643
+ }
3644
+ };
3649
3645
  }
3650
- const unknownErrorMessage = `Could not get presigned auth nonce. HTTP error: ${res.status} ${res.statusText}`;
3651
3646
  console.error(unknownErrorMessage);
3652
3647
  return {
3653
3648
  status: "error",
@@ -3707,14 +3702,13 @@ class ValOpsHttp extends ValOps {
3707
3702
  const unknownErrorMessage = `Could not get summary. HTTP error: ${res.status} ${res.statusText}`;
3708
3703
  if ((_res$headers$get2 = res.headers.get("Content-Type")) !== null && _res$headers$get2 !== void 0 && _res$headers$get2.includes("application/json")) {
3709
3704
  const json = await res.json();
3710
- if (json.message) {
3711
- console.error("Summary error:", json.message);
3712
- return {
3713
- error: {
3714
- message: json.message
3715
- }
3716
- };
3717
- }
3705
+ const message = internal.getErrorMessageFromUnknownJson(json, unknownErrorMessage);
3706
+ console.error("Summary error:", message);
3707
+ return {
3708
+ error: {
3709
+ message
3710
+ }
3711
+ };
3718
3712
  }
3719
3713
  console.error(unknownErrorMessage);
3720
3714
  return {
@@ -3823,38 +3817,39 @@ class ValOpsHttp extends ValOps {
3823
3817
  }
3824
3818
  }).then(async res => {
3825
3819
  if (res.ok) {
3826
- const json = await res.json();
3827
- if (typeof json.nonce !== "string" || typeof json.url !== "string") {
3820
+ const json = NonceResponse.safeParse(await res.json());
3821
+ if (!json.success) {
3828
3822
  return {
3829
3823
  status: "error",
3830
3824
  error: {
3831
- message: "Invalid nonce response: " + JSON.stringify(json)
3825
+ message: "Invalid nonce response: " + zodValidationError.fromError(json.error).toString()
3832
3826
  }
3833
3827
  };
3834
3828
  }
3835
- if (!json.url.startsWith("ws://") && !json.url.startsWith("wss://")) {
3829
+ if (!json.data.url.startsWith("ws://") && !json.data.url.startsWith("wss://")) {
3836
3830
  return {
3837
3831
  status: "error",
3838
3832
  error: {
3839
- message: "Invalid websocket url: " + json.url
3833
+ message: "Invalid websocket url: " + json.data.url
3840
3834
  }
3841
3835
  };
3842
3836
  }
3843
3837
  return {
3844
3838
  status: "success",
3845
3839
  data: {
3846
- nonce: json.nonce,
3847
- url: json.url
3840
+ nonce: json.data.nonce,
3841
+ url: json.data.url
3848
3842
  }
3849
3843
  };
3850
3844
  }
3851
3845
  const contentType = res.headers.get("Content-Type") || "";
3852
3846
  if (contentType.startsWith("application/json")) {
3853
3847
  const json = await res.json();
3848
+ const message = internal.getErrorMessageFromUnknownJson(json, "Could not get nonce. Unexpected error (no error message). Status: " + res.status);
3854
3849
  return {
3855
3850
  status: "error",
3856
3851
  error: {
3857
- message: "Could not get nonce." + (json.message || "Unexpected error (no error message). Status: " + res.status)
3852
+ message: "Could not get nonce." + message
3858
3853
  }
3859
3854
  };
3860
3855
  }
@@ -4054,9 +4049,10 @@ class ValOpsHttp extends ValOps {
4054
4049
  }
4055
4050
  if ((_res$headers$get3 = res.headers.get("Content-Type")) !== null && _res$headers$get3 !== void 0 && _res$headers$get3.includes("application/json")) {
4056
4051
  const json = await res.json();
4052
+ const message = internal.getErrorMessageFromUnknownJson(json, "Unknown error");
4057
4053
  return fp.result.err({
4058
4054
  errorType: "other",
4059
- message: json.message || "Unknown error"
4055
+ message
4060
4056
  });
4061
4057
  }
4062
4058
  return fp.result.err({
@@ -4349,15 +4345,24 @@ class ValOpsHttp extends ValOps {
4349
4345
  });
4350
4346
  if (res.ok) {
4351
4347
  const json = await res.json();
4348
+ const parsed = SummaryResponse.safeParse(json);
4349
+ if (parsed.success) {
4350
+ return {
4351
+ commitSummary: parsed.data.commitSummary
4352
+ };
4353
+ }
4352
4354
  return {
4353
- commitSummary: json.commitSummary
4355
+ error: {
4356
+ message: `Could not parse commit summary response. Error: ${zodValidationError.fromError(parsed.error)}`
4357
+ }
4354
4358
  };
4355
4359
  }
4356
4360
  if ((_res$headers$get4 = res.headers.get("Content-Type")) !== null && _res$headers$get4 !== void 0 && _res$headers$get4.includes("application/json")) {
4357
4361
  const json = await res.json();
4362
+ const message = internal.getErrorMessageFromUnknownJson(json, "Unknown error");
4358
4363
  return {
4359
4364
  error: {
4360
- message: json.message
4365
+ message
4361
4366
  }
4362
4367
  };
4363
4368
  }
@@ -4407,8 +4412,10 @@ class ValOpsHttp extends ValOps {
4407
4412
  };
4408
4413
  }
4409
4414
  if ((_res$headers$get5 = res.headers.get("Content-Type")) !== null && _res$headers$get5 !== void 0 && _res$headers$get5.includes("application/json")) {
4410
- const json = await res.json();
4411
- if (json.isNotFastForward) {
4415
+ const json = zod.z.object({
4416
+ isNotFastForward: zod.z.boolean().optional()
4417
+ }).safeParse(await res.json());
4418
+ if (json.success && json.data.isNotFastForward) {
4412
4419
  return {
4413
4420
  isNotFastForward: true,
4414
4421
  error: {
@@ -4416,9 +4423,10 @@ class ValOpsHttp extends ValOps {
4416
4423
  }
4417
4424
  };
4418
4425
  }
4426
+ const message = internal.getErrorMessageFromUnknownJson(json, "Unknown error");
4419
4427
  return {
4420
4428
  error: {
4421
- message: json.message
4429
+ message
4422
4430
  }
4423
4431
  };
4424
4432
  }
@@ -4455,7 +4463,8 @@ class ValOpsHttp extends ValOps {
4455
4463
  }
4456
4464
  if ((_res$headers$get6 = res.headers.get("Content-Type")) !== null && _res$headers$get6 !== void 0 && _res$headers$get6.includes("application/json")) {
4457
4465
  const json = await res.json();
4458
- throw Error(`Could not get profiles (status: ${res.status}): ${"message" in json ? json.message : "Unknown error"}`);
4466
+ const message = internal.getErrorMessageFromUnknownJson(json, "Unknown error");
4467
+ throw Error(`Could not get profiles (status: ${res.status}): ${message}`);
4459
4468
  }
4460
4469
  throw Error(`Could not get profiles. Got status: ${res.status}`);
4461
4470
  }
@@ -4503,7 +4512,7 @@ async function getSettings(projectName, auth) {
4503
4512
  success: true,
4504
4513
  data: parseRes.data
4505
4514
  };
4506
- } catch (err) {
4515
+ } catch {
4507
4516
  return {
4508
4517
  success: false,
4509
4518
  message: `Failed to get project id. Check network connection and try again.`
@@ -5112,20 +5121,42 @@ const ValServer = (valModules, options, callbacks) => {
5112
5121
  headers: getAuthHeaders(data.token, "application/json")
5113
5122
  });
5114
5123
  if (fetchRes.status === 200) {
5115
- return {
5116
- status: fetchRes.status,
5117
- json: {
5118
- mode: "proxy",
5119
- enabled: await callbacks.isEnabled(),
5120
- ...(await fetchRes.json())
5121
- }
5122
- };
5124
+ const json = zod.z.object({
5125
+ member_role: zod.z.union([zod.z.literal("owner"), zod.z.literal("developer"), zod.z.literal("editor")]).optional(),
5126
+ id: zod.z.string(),
5127
+ full_name: zod.z.string().optional(),
5128
+ username: zod.z.string().optional(),
5129
+ avatar_url: zod.z.string().optional()
5130
+ }).safeParse(await fetchRes.json());
5131
+ if (json.success) {
5132
+ return {
5133
+ status: fetchRes.status,
5134
+ json: {
5135
+ mode: "proxy",
5136
+ enabled: await callbacks.isEnabled(),
5137
+ ...json.data
5138
+ }
5139
+ };
5140
+ } else {
5141
+ const message = internal.getErrorMessageFromUnknownJson(json, "Could not parse session response. Unexpected error (no error message). Status: " + fetchRes.status);
5142
+ return {
5143
+ status: 500,
5144
+ json: {
5145
+ message: message,
5146
+ ...json
5147
+ }
5148
+ };
5149
+ }
5123
5150
  } else {
5151
+ const json = zod.z.object({
5152
+ message: zod.z.string()
5153
+ }).safeParse(await fetchRes.json());
5154
+ const message = internal.getErrorMessageFromUnknownJson(json, "Unknown error");
5124
5155
  return {
5125
5156
  status: fetchRes.status,
5126
5157
  json: {
5127
- message: "Failed to authorize",
5128
- ...(await fetchRes.json())
5158
+ message: message,
5159
+ ...json
5129
5160
  }
5130
5161
  };
5131
5162
  }
@@ -5544,7 +5575,7 @@ const ValServer = (valModules, options, callbacks) => {
5544
5575
  return {
5545
5576
  status: 200,
5546
5577
  json: {
5547
- patches,
5578
+ patches: patches,
5548
5579
  baseSha: await serverOps.getBaseSha()
5549
5580
  }
5550
5581
  };
@@ -5872,7 +5903,7 @@ const ValServer = (valModules, options, callbacks) => {
5872
5903
  status: 400,
5873
5904
  json: {
5874
5905
  message: "Invalid body: " + zodValidationError.fromError(bodyRes.error).toString(),
5875
- details: bodyRes.error.errors
5906
+ details: bodyRes.error.issues
5876
5907
  }
5877
5908
  };
5878
5909
  }
@@ -6452,7 +6483,7 @@ async function safeReadGit(cwd) {
6452
6483
  branch: undefined
6453
6484
  };
6454
6485
  }
6455
- } catch (error) {
6486
+ } catch {
6456
6487
  const parentDir = path__namespace.dirname(currentDir);
6457
6488
 
6458
6489
  // We've reached the root directory
@@ -6478,7 +6509,7 @@ async function safeReadGit(cwd) {
6478
6509
  async function readCommit(gitDir, branchName) {
6479
6510
  try {
6480
6511
  return (await fs.promises.readFile(path__namespace.join(gitDir, ".git", "refs", "heads", branchName), "utf-8")).trim();
6481
- } catch (err) {
6512
+ } catch {
6482
6513
  return undefined;
6483
6514
  }
6484
6515
  }
@@ -6668,7 +6699,7 @@ function createValApiRouter(route, valServerPromise, convert) {
6668
6699
  };
6669
6700
  }
6670
6701
  function formatZodErrorString(error) {
6671
- const errors = zodValidationError.fromZodError(error).toString();
6702
+ const errors = zodValidationError.fromError(error).toString();
6672
6703
  return errors.length > 640 ? `${errors.slice(0, 640)}...` : errors;
6673
6704
  }
6674
6705
  function zodErrorResult(error, message) {
@@ -6909,7 +6940,7 @@ async function getFileBufferFromRemote(ref, fileExt, currentFileHash, projectRoo
6909
6940
  await fs__default["default"].promises.unlink(remoteFilePath);
6910
6941
  throw Error(`Cached file hash does not match the expected hash: ${computedFileHash} !== ${currentFileHash}`);
6911
6942
  }
6912
- } catch (err) {
6943
+ } catch {
6913
6944
  try {
6914
6945
  await fs__default["default"].promises.mkdir(remoteFileCacheDir, {
6915
6946
  recursive: true
@@ -1064,9 +1064,7 @@ const MAX_CACHE_SIZE = 100 * 1024 * 1024; // 100 mb
1064
1064
  const MAX_OBJECT_KEY_SIZE = 2 ** 27; // https://stackoverflow.com/questions/13367391/is-there-a-limit-on-length-of-the-key-string-in-js-object
1065
1065
 
1066
1066
  class ValModuleLoader {
1067
- constructor(projectRoot,
1068
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1069
- compilerOptions,
1067
+ constructor(projectRoot, compilerOptions,
1070
1068
  // TODO: remove this?
1071
1069
  sourceFileHandler, host = {
1072
1070
  ...ts__default["default"].sys,
@@ -1280,7 +1278,7 @@ export default new Proxy({}, {
1280
1278
  return {
1281
1279
  value: moduleLoader.getModule(modulePath)
1282
1280
  };
1283
- } catch (e) {
1281
+ } catch {
1284
1282
  return {
1285
1283
  error: Error(`Could not resolve module: '${modulePath}'`)
1286
1284
  };
@@ -1529,7 +1527,7 @@ class ValOps {
1529
1527
  collector.push("[");
1530
1528
  for (let i = 0; i < item.length; i++) {
1531
1529
  this.collectObjectRecursive(item[i], collector);
1532
- i !== item.length - 1 && collector.push(",");
1530
+ if (i !== item.length - 1) collector.push(",");
1533
1531
  }
1534
1532
  collector.push("]");
1535
1533
  } else {
@@ -1538,7 +1536,7 @@ class ValOps {
1538
1536
  keys.forEach((key, i) => {
1539
1537
  collector.push(`"${key}":`);
1540
1538
  this.collectObjectRecursive(item[key], collector);
1541
- i !== keys.length - 1 && collector.push(",");
1539
+ if (i !== keys.length - 1) collector.push(",");
1542
1540
  });
1543
1541
  collector.push("}");
1544
1542
  }
@@ -2495,7 +2493,7 @@ async function uploadRemoteFile(contentHost, project, bucket, fileHash, fileExt,
2495
2493
  ...authHeader,
2496
2494
  "Content-Type": "application/octet-stream"
2497
2495
  },
2498
- body: fileBuffer
2496
+ body: new Uint8Array(fileBuffer)
2499
2497
  });
2500
2498
  if (!res.ok) {
2501
2499
  var _res$headers$get;
@@ -2507,17 +2505,11 @@ async function uploadRemoteFile(contentHost, project, bucket, fileHash, fileExt,
2507
2505
  }
2508
2506
  if ((_res$headers$get = res.headers.get("content-type")) !== null && _res$headers$get !== void 0 && _res$headers$get.includes("application/json")) {
2509
2507
  const json = await res.json();
2510
- if (json.message) {
2511
- return {
2512
- success: false,
2513
- error: `Failed to upload remote file: ${json.message}.`
2514
- };
2515
- } else {
2516
- return {
2517
- success: false,
2518
- error: `Failed to upload remote file: ${JSON.stringify(json)}.`
2519
- };
2520
- }
2508
+ const message = internal.getErrorMessageFromUnknownJson(json, JSON.stringify(json));
2509
+ return {
2510
+ success: false,
2511
+ error: `Failed to upload remote file: ${message}.`
2512
+ };
2521
2513
  }
2522
2514
  return {
2523
2515
  success: false,
@@ -3042,7 +3034,7 @@ class ValOpsFS extends ValOps {
3042
3034
  }]
3043
3035
  };
3044
3036
  }
3045
- const metadataParseRes = this.parseJsonFile(metadataFilePath, zod.z.record(zod.z.union([zod.z.string(), zod.z.number()])));
3037
+ const metadataParseRes = this.parseJsonFile(metadataFilePath, zod.z.record(zod.z.string(), zod.z.union([zod.z.string(), zod.z.number()])));
3046
3038
  if (metadataParseRes.error) {
3047
3039
  return {
3048
3040
  errors: [metadataParseRes.error]
@@ -3416,7 +3408,7 @@ class FSOpsHost {
3416
3408
  fs__default["default"].mkdirSync(path__namespace["default"].dirname(path), {
3417
3409
  recursive: false
3418
3410
  });
3419
- } catch (e) {
3411
+ } catch {
3420
3412
  // ignore
3421
3413
  }
3422
3414
  try {
@@ -3479,7 +3471,7 @@ const MetadataRes = zod.z.object({
3479
3471
  type: zod.z.union([zod.z.literal("file"), zod.z.literal("image")]).nullable()
3480
3472
  });
3481
3473
  const SummaryResponse = zod.z.object({
3482
- commitSummary: zod.z.string().nullable()
3474
+ commitSummary: zod.z.string()
3483
3475
  });
3484
3476
  const GetApplicablePatches = zod.z.object({
3485
3477
  patches: zod.z.array(zod.z.object({
@@ -3566,6 +3558,10 @@ const ProfilesResponse = zod.z.object({
3566
3558
  }).nullable()
3567
3559
  }))
3568
3560
  });
3561
+ const NonceResponse = zod.z.object({
3562
+ nonce: zod.z.string(),
3563
+ url: zod.z.string()
3564
+ });
3569
3565
  class ValOpsHttp extends ValOps {
3570
3566
  constructor(contentUrl, project, commitSha,
3571
3567
  // TODO: CommitSha
@@ -3634,20 +3630,19 @@ class ValOpsHttp extends ValOps {
3634
3630
  }
3635
3631
  };
3636
3632
  }
3633
+ const unknownErrorMessage = `Could not get presigned auth nonce. HTTP error: ${res.status} ${res.statusText}`;
3637
3634
  if ((_res$headers$get = res.headers.get("Content-Type")) !== null && _res$headers$get !== void 0 && _res$headers$get.includes("application/json")) {
3638
3635
  const json = await res.json();
3639
- if (json.message) {
3640
- console.error("Presigned auth nonce error:", json.message);
3641
- return {
3642
- status: "error",
3643
- statusCode: 500,
3644
- error: {
3645
- message: json.message
3646
- }
3647
- };
3648
- }
3636
+ const message = internal.getErrorMessageFromUnknownJson(json, unknownErrorMessage);
3637
+ console.error("Presigned auth nonce error:", message);
3638
+ return {
3639
+ status: "error",
3640
+ statusCode: 500,
3641
+ error: {
3642
+ message
3643
+ }
3644
+ };
3649
3645
  }
3650
- const unknownErrorMessage = `Could not get presigned auth nonce. HTTP error: ${res.status} ${res.statusText}`;
3651
3646
  console.error(unknownErrorMessage);
3652
3647
  return {
3653
3648
  status: "error",
@@ -3707,14 +3702,13 @@ class ValOpsHttp extends ValOps {
3707
3702
  const unknownErrorMessage = `Could not get summary. HTTP error: ${res.status} ${res.statusText}`;
3708
3703
  if ((_res$headers$get2 = res.headers.get("Content-Type")) !== null && _res$headers$get2 !== void 0 && _res$headers$get2.includes("application/json")) {
3709
3704
  const json = await res.json();
3710
- if (json.message) {
3711
- console.error("Summary error:", json.message);
3712
- return {
3713
- error: {
3714
- message: json.message
3715
- }
3716
- };
3717
- }
3705
+ const message = internal.getErrorMessageFromUnknownJson(json, unknownErrorMessage);
3706
+ console.error("Summary error:", message);
3707
+ return {
3708
+ error: {
3709
+ message
3710
+ }
3711
+ };
3718
3712
  }
3719
3713
  console.error(unknownErrorMessage);
3720
3714
  return {
@@ -3823,38 +3817,39 @@ class ValOpsHttp extends ValOps {
3823
3817
  }
3824
3818
  }).then(async res => {
3825
3819
  if (res.ok) {
3826
- const json = await res.json();
3827
- if (typeof json.nonce !== "string" || typeof json.url !== "string") {
3820
+ const json = NonceResponse.safeParse(await res.json());
3821
+ if (!json.success) {
3828
3822
  return {
3829
3823
  status: "error",
3830
3824
  error: {
3831
- message: "Invalid nonce response: " + JSON.stringify(json)
3825
+ message: "Invalid nonce response: " + zodValidationError.fromError(json.error).toString()
3832
3826
  }
3833
3827
  };
3834
3828
  }
3835
- if (!json.url.startsWith("ws://") && !json.url.startsWith("wss://")) {
3829
+ if (!json.data.url.startsWith("ws://") && !json.data.url.startsWith("wss://")) {
3836
3830
  return {
3837
3831
  status: "error",
3838
3832
  error: {
3839
- message: "Invalid websocket url: " + json.url
3833
+ message: "Invalid websocket url: " + json.data.url
3840
3834
  }
3841
3835
  };
3842
3836
  }
3843
3837
  return {
3844
3838
  status: "success",
3845
3839
  data: {
3846
- nonce: json.nonce,
3847
- url: json.url
3840
+ nonce: json.data.nonce,
3841
+ url: json.data.url
3848
3842
  }
3849
3843
  };
3850
3844
  }
3851
3845
  const contentType = res.headers.get("Content-Type") || "";
3852
3846
  if (contentType.startsWith("application/json")) {
3853
3847
  const json = await res.json();
3848
+ const message = internal.getErrorMessageFromUnknownJson(json, "Could not get nonce. Unexpected error (no error message). Status: " + res.status);
3854
3849
  return {
3855
3850
  status: "error",
3856
3851
  error: {
3857
- message: "Could not get nonce." + (json.message || "Unexpected error (no error message). Status: " + res.status)
3852
+ message: "Could not get nonce." + message
3858
3853
  }
3859
3854
  };
3860
3855
  }
@@ -4054,9 +4049,10 @@ class ValOpsHttp extends ValOps {
4054
4049
  }
4055
4050
  if ((_res$headers$get3 = res.headers.get("Content-Type")) !== null && _res$headers$get3 !== void 0 && _res$headers$get3.includes("application/json")) {
4056
4051
  const json = await res.json();
4052
+ const message = internal.getErrorMessageFromUnknownJson(json, "Unknown error");
4057
4053
  return fp.result.err({
4058
4054
  errorType: "other",
4059
- message: json.message || "Unknown error"
4055
+ message
4060
4056
  });
4061
4057
  }
4062
4058
  return fp.result.err({
@@ -4349,15 +4345,24 @@ class ValOpsHttp extends ValOps {
4349
4345
  });
4350
4346
  if (res.ok) {
4351
4347
  const json = await res.json();
4348
+ const parsed = SummaryResponse.safeParse(json);
4349
+ if (parsed.success) {
4350
+ return {
4351
+ commitSummary: parsed.data.commitSummary
4352
+ };
4353
+ }
4352
4354
  return {
4353
- commitSummary: json.commitSummary
4355
+ error: {
4356
+ message: `Could not parse commit summary response. Error: ${zodValidationError.fromError(parsed.error)}`
4357
+ }
4354
4358
  };
4355
4359
  }
4356
4360
  if ((_res$headers$get4 = res.headers.get("Content-Type")) !== null && _res$headers$get4 !== void 0 && _res$headers$get4.includes("application/json")) {
4357
4361
  const json = await res.json();
4362
+ const message = internal.getErrorMessageFromUnknownJson(json, "Unknown error");
4358
4363
  return {
4359
4364
  error: {
4360
- message: json.message
4365
+ message
4361
4366
  }
4362
4367
  };
4363
4368
  }
@@ -4407,8 +4412,10 @@ class ValOpsHttp extends ValOps {
4407
4412
  };
4408
4413
  }
4409
4414
  if ((_res$headers$get5 = res.headers.get("Content-Type")) !== null && _res$headers$get5 !== void 0 && _res$headers$get5.includes("application/json")) {
4410
- const json = await res.json();
4411
- if (json.isNotFastForward) {
4415
+ const json = zod.z.object({
4416
+ isNotFastForward: zod.z.boolean().optional()
4417
+ }).safeParse(await res.json());
4418
+ if (json.success && json.data.isNotFastForward) {
4412
4419
  return {
4413
4420
  isNotFastForward: true,
4414
4421
  error: {
@@ -4416,9 +4423,10 @@ class ValOpsHttp extends ValOps {
4416
4423
  }
4417
4424
  };
4418
4425
  }
4426
+ const message = internal.getErrorMessageFromUnknownJson(json, "Unknown error");
4419
4427
  return {
4420
4428
  error: {
4421
- message: json.message
4429
+ message
4422
4430
  }
4423
4431
  };
4424
4432
  }
@@ -4455,7 +4463,8 @@ class ValOpsHttp extends ValOps {
4455
4463
  }
4456
4464
  if ((_res$headers$get6 = res.headers.get("Content-Type")) !== null && _res$headers$get6 !== void 0 && _res$headers$get6.includes("application/json")) {
4457
4465
  const json = await res.json();
4458
- throw Error(`Could not get profiles (status: ${res.status}): ${"message" in json ? json.message : "Unknown error"}`);
4466
+ const message = internal.getErrorMessageFromUnknownJson(json, "Unknown error");
4467
+ throw Error(`Could not get profiles (status: ${res.status}): ${message}`);
4459
4468
  }
4460
4469
  throw Error(`Could not get profiles. Got status: ${res.status}`);
4461
4470
  }
@@ -4503,7 +4512,7 @@ async function getSettings(projectName, auth) {
4503
4512
  success: true,
4504
4513
  data: parseRes.data
4505
4514
  };
4506
- } catch (err) {
4515
+ } catch {
4507
4516
  return {
4508
4517
  success: false,
4509
4518
  message: `Failed to get project id. Check network connection and try again.`
@@ -5112,20 +5121,42 @@ const ValServer = (valModules, options, callbacks) => {
5112
5121
  headers: getAuthHeaders(data.token, "application/json")
5113
5122
  });
5114
5123
  if (fetchRes.status === 200) {
5115
- return {
5116
- status: fetchRes.status,
5117
- json: {
5118
- mode: "proxy",
5119
- enabled: await callbacks.isEnabled(),
5120
- ...(await fetchRes.json())
5121
- }
5122
- };
5124
+ const json = zod.z.object({
5125
+ member_role: zod.z.union([zod.z.literal("owner"), zod.z.literal("developer"), zod.z.literal("editor")]).optional(),
5126
+ id: zod.z.string(),
5127
+ full_name: zod.z.string().optional(),
5128
+ username: zod.z.string().optional(),
5129
+ avatar_url: zod.z.string().optional()
5130
+ }).safeParse(await fetchRes.json());
5131
+ if (json.success) {
5132
+ return {
5133
+ status: fetchRes.status,
5134
+ json: {
5135
+ mode: "proxy",
5136
+ enabled: await callbacks.isEnabled(),
5137
+ ...json.data
5138
+ }
5139
+ };
5140
+ } else {
5141
+ const message = internal.getErrorMessageFromUnknownJson(json, "Could not parse session response. Unexpected error (no error message). Status: " + fetchRes.status);
5142
+ return {
5143
+ status: 500,
5144
+ json: {
5145
+ message: message,
5146
+ ...json
5147
+ }
5148
+ };
5149
+ }
5123
5150
  } else {
5151
+ const json = zod.z.object({
5152
+ message: zod.z.string()
5153
+ }).safeParse(await fetchRes.json());
5154
+ const message = internal.getErrorMessageFromUnknownJson(json, "Unknown error");
5124
5155
  return {
5125
5156
  status: fetchRes.status,
5126
5157
  json: {
5127
- message: "Failed to authorize",
5128
- ...(await fetchRes.json())
5158
+ message: message,
5159
+ ...json
5129
5160
  }
5130
5161
  };
5131
5162
  }
@@ -5544,7 +5575,7 @@ const ValServer = (valModules, options, callbacks) => {
5544
5575
  return {
5545
5576
  status: 200,
5546
5577
  json: {
5547
- patches,
5578
+ patches: patches,
5548
5579
  baseSha: await serverOps.getBaseSha()
5549
5580
  }
5550
5581
  };
@@ -5872,7 +5903,7 @@ const ValServer = (valModules, options, callbacks) => {
5872
5903
  status: 400,
5873
5904
  json: {
5874
5905
  message: "Invalid body: " + zodValidationError.fromError(bodyRes.error).toString(),
5875
- details: bodyRes.error.errors
5906
+ details: bodyRes.error.issues
5876
5907
  }
5877
5908
  };
5878
5909
  }
@@ -6452,7 +6483,7 @@ async function safeReadGit(cwd) {
6452
6483
  branch: undefined
6453
6484
  };
6454
6485
  }
6455
- } catch (error) {
6486
+ } catch {
6456
6487
  const parentDir = path__namespace.dirname(currentDir);
6457
6488
 
6458
6489
  // We've reached the root directory
@@ -6478,7 +6509,7 @@ async function safeReadGit(cwd) {
6478
6509
  async function readCommit(gitDir, branchName) {
6479
6510
  try {
6480
6511
  return (await fs.promises.readFile(path__namespace.join(gitDir, ".git", "refs", "heads", branchName), "utf-8")).trim();
6481
- } catch (err) {
6512
+ } catch {
6482
6513
  return undefined;
6483
6514
  }
6484
6515
  }
@@ -6668,7 +6699,7 @@ function createValApiRouter(route, valServerPromise, convert) {
6668
6699
  };
6669
6700
  }
6670
6701
  function formatZodErrorString(error) {
6671
- const errors = zodValidationError.fromZodError(error).toString();
6702
+ const errors = zodValidationError.fromError(error).toString();
6672
6703
  return errors.length > 640 ? `${errors.slice(0, 640)}...` : errors;
6673
6704
  }
6674
6705
  function zodErrorResult(error, message) {
@@ -6909,7 +6940,7 @@ async function getFileBufferFromRemote(ref, fileExt, currentFileHash, projectRoo
6909
6940
  await fs__default["default"].promises.unlink(remoteFilePath);
6910
6941
  throw Error(`Cached file hash does not match the expected hash: ${computedFileHash} !== ${currentFileHash}`);
6911
6942
  }
6912
- } catch (err) {
6943
+ } catch {
6913
6944
  try {
6914
6945
  await fs__default["default"].promises.mkdir(remoteFileCacheDir, {
6915
6946
  recursive: true
@@ -8,12 +8,12 @@ import path__default from 'path';
8
8
  import fs, { promises } from 'fs';
9
9
  import { transform } from 'sucrase';
10
10
  import { VAL_CSS_PATH, VAL_APP_ID, VAL_OVERLAY_ID } from '@valbuild/ui';
11
- import { filterRoutesByPatterns, validateRoutePatterns, Patch, ParentRef, VAL_ENABLE_COOKIE_NAME, VAL_STATE_COOKIE, VAL_SESSION_COOKIE, Api } from '@valbuild/shared/internal';
11
+ import { filterRoutesByPatterns, validateRoutePatterns, getErrorMessageFromUnknownJson, Patch, ParentRef, VAL_ENABLE_COOKIE_NAME, VAL_STATE_COOKIE, VAL_SESSION_COOKIE, Api } from '@valbuild/shared/internal';
12
12
  import { createUIRequestHandler } from '@valbuild/ui/server';
13
13
  import crypto$1 from 'crypto';
14
14
  import { z } from 'zod';
15
15
  import sizeOf from 'image-size';
16
- import { fromError, fromZodError } from 'zod-validation-error';
16
+ import { fromError } from 'zod-validation-error';
17
17
  import http from 'http';
18
18
  import https from 'https';
19
19
 
@@ -1033,9 +1033,7 @@ const MAX_CACHE_SIZE = 100 * 1024 * 1024; // 100 mb
1033
1033
  const MAX_OBJECT_KEY_SIZE = 2 ** 27; // https://stackoverflow.com/questions/13367391/is-there-a-limit-on-length-of-the-key-string-in-js-object
1034
1034
 
1035
1035
  class ValModuleLoader {
1036
- constructor(projectRoot,
1037
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1038
- compilerOptions,
1036
+ constructor(projectRoot, compilerOptions,
1039
1037
  // TODO: remove this?
1040
1038
  sourceFileHandler, host = {
1041
1039
  ...ts.sys,
@@ -1249,7 +1247,7 @@ export default new Proxy({}, {
1249
1247
  return {
1250
1248
  value: moduleLoader.getModule(modulePath)
1251
1249
  };
1252
- } catch (e) {
1250
+ } catch {
1253
1251
  return {
1254
1252
  error: Error(`Could not resolve module: '${modulePath}'`)
1255
1253
  };
@@ -1498,7 +1496,7 @@ class ValOps {
1498
1496
  collector.push("[");
1499
1497
  for (let i = 0; i < item.length; i++) {
1500
1498
  this.collectObjectRecursive(item[i], collector);
1501
- i !== item.length - 1 && collector.push(",");
1499
+ if (i !== item.length - 1) collector.push(",");
1502
1500
  }
1503
1501
  collector.push("]");
1504
1502
  } else {
@@ -1507,7 +1505,7 @@ class ValOps {
1507
1505
  keys.forEach((key, i) => {
1508
1506
  collector.push(`"${key}":`);
1509
1507
  this.collectObjectRecursive(item[key], collector);
1510
- i !== keys.length - 1 && collector.push(",");
1508
+ if (i !== keys.length - 1) collector.push(",");
1511
1509
  });
1512
1510
  collector.push("}");
1513
1511
  }
@@ -2464,7 +2462,7 @@ async function uploadRemoteFile(contentHost, project, bucket, fileHash, fileExt,
2464
2462
  ...authHeader,
2465
2463
  "Content-Type": "application/octet-stream"
2466
2464
  },
2467
- body: fileBuffer
2465
+ body: new Uint8Array(fileBuffer)
2468
2466
  });
2469
2467
  if (!res.ok) {
2470
2468
  var _res$headers$get;
@@ -2476,17 +2474,11 @@ async function uploadRemoteFile(contentHost, project, bucket, fileHash, fileExt,
2476
2474
  }
2477
2475
  if ((_res$headers$get = res.headers.get("content-type")) !== null && _res$headers$get !== void 0 && _res$headers$get.includes("application/json")) {
2478
2476
  const json = await res.json();
2479
- if (json.message) {
2480
- return {
2481
- success: false,
2482
- error: `Failed to upload remote file: ${json.message}.`
2483
- };
2484
- } else {
2485
- return {
2486
- success: false,
2487
- error: `Failed to upload remote file: ${JSON.stringify(json)}.`
2488
- };
2489
- }
2477
+ const message = getErrorMessageFromUnknownJson(json, JSON.stringify(json));
2478
+ return {
2479
+ success: false,
2480
+ error: `Failed to upload remote file: ${message}.`
2481
+ };
2490
2482
  }
2491
2483
  return {
2492
2484
  success: false,
@@ -3011,7 +3003,7 @@ class ValOpsFS extends ValOps {
3011
3003
  }]
3012
3004
  };
3013
3005
  }
3014
- const metadataParseRes = this.parseJsonFile(metadataFilePath, z.record(z.union([z.string(), z.number()])));
3006
+ const metadataParseRes = this.parseJsonFile(metadataFilePath, z.record(z.string(), z.union([z.string(), z.number()])));
3015
3007
  if (metadataParseRes.error) {
3016
3008
  return {
3017
3009
  errors: [metadataParseRes.error]
@@ -3385,7 +3377,7 @@ class FSOpsHost {
3385
3377
  fs.mkdirSync(path__default.dirname(path), {
3386
3378
  recursive: false
3387
3379
  });
3388
- } catch (e) {
3380
+ } catch {
3389
3381
  // ignore
3390
3382
  }
3391
3383
  try {
@@ -3448,7 +3440,7 @@ const MetadataRes = z.object({
3448
3440
  type: z.union([z.literal("file"), z.literal("image")]).nullable()
3449
3441
  });
3450
3442
  const SummaryResponse = z.object({
3451
- commitSummary: z.string().nullable()
3443
+ commitSummary: z.string()
3452
3444
  });
3453
3445
  const GetApplicablePatches = z.object({
3454
3446
  patches: z.array(z.object({
@@ -3535,6 +3527,10 @@ const ProfilesResponse = z.object({
3535
3527
  }).nullable()
3536
3528
  }))
3537
3529
  });
3530
+ const NonceResponse = z.object({
3531
+ nonce: z.string(),
3532
+ url: z.string()
3533
+ });
3538
3534
  class ValOpsHttp extends ValOps {
3539
3535
  constructor(contentUrl, project, commitSha,
3540
3536
  // TODO: CommitSha
@@ -3603,20 +3599,19 @@ class ValOpsHttp extends ValOps {
3603
3599
  }
3604
3600
  };
3605
3601
  }
3602
+ const unknownErrorMessage = `Could not get presigned auth nonce. HTTP error: ${res.status} ${res.statusText}`;
3606
3603
  if ((_res$headers$get = res.headers.get("Content-Type")) !== null && _res$headers$get !== void 0 && _res$headers$get.includes("application/json")) {
3607
3604
  const json = await res.json();
3608
- if (json.message) {
3609
- console.error("Presigned auth nonce error:", json.message);
3610
- return {
3611
- status: "error",
3612
- statusCode: 500,
3613
- error: {
3614
- message: json.message
3615
- }
3616
- };
3617
- }
3605
+ const message = getErrorMessageFromUnknownJson(json, unknownErrorMessage);
3606
+ console.error("Presigned auth nonce error:", message);
3607
+ return {
3608
+ status: "error",
3609
+ statusCode: 500,
3610
+ error: {
3611
+ message
3612
+ }
3613
+ };
3618
3614
  }
3619
- const unknownErrorMessage = `Could not get presigned auth nonce. HTTP error: ${res.status} ${res.statusText}`;
3620
3615
  console.error(unknownErrorMessage);
3621
3616
  return {
3622
3617
  status: "error",
@@ -3676,14 +3671,13 @@ class ValOpsHttp extends ValOps {
3676
3671
  const unknownErrorMessage = `Could not get summary. HTTP error: ${res.status} ${res.statusText}`;
3677
3672
  if ((_res$headers$get2 = res.headers.get("Content-Type")) !== null && _res$headers$get2 !== void 0 && _res$headers$get2.includes("application/json")) {
3678
3673
  const json = await res.json();
3679
- if (json.message) {
3680
- console.error("Summary error:", json.message);
3681
- return {
3682
- error: {
3683
- message: json.message
3684
- }
3685
- };
3686
- }
3674
+ const message = getErrorMessageFromUnknownJson(json, unknownErrorMessage);
3675
+ console.error("Summary error:", message);
3676
+ return {
3677
+ error: {
3678
+ message
3679
+ }
3680
+ };
3687
3681
  }
3688
3682
  console.error(unknownErrorMessage);
3689
3683
  return {
@@ -3792,38 +3786,39 @@ class ValOpsHttp extends ValOps {
3792
3786
  }
3793
3787
  }).then(async res => {
3794
3788
  if (res.ok) {
3795
- const json = await res.json();
3796
- if (typeof json.nonce !== "string" || typeof json.url !== "string") {
3789
+ const json = NonceResponse.safeParse(await res.json());
3790
+ if (!json.success) {
3797
3791
  return {
3798
3792
  status: "error",
3799
3793
  error: {
3800
- message: "Invalid nonce response: " + JSON.stringify(json)
3794
+ message: "Invalid nonce response: " + fromError(json.error).toString()
3801
3795
  }
3802
3796
  };
3803
3797
  }
3804
- if (!json.url.startsWith("ws://") && !json.url.startsWith("wss://")) {
3798
+ if (!json.data.url.startsWith("ws://") && !json.data.url.startsWith("wss://")) {
3805
3799
  return {
3806
3800
  status: "error",
3807
3801
  error: {
3808
- message: "Invalid websocket url: " + json.url
3802
+ message: "Invalid websocket url: " + json.data.url
3809
3803
  }
3810
3804
  };
3811
3805
  }
3812
3806
  return {
3813
3807
  status: "success",
3814
3808
  data: {
3815
- nonce: json.nonce,
3816
- url: json.url
3809
+ nonce: json.data.nonce,
3810
+ url: json.data.url
3817
3811
  }
3818
3812
  };
3819
3813
  }
3820
3814
  const contentType = res.headers.get("Content-Type") || "";
3821
3815
  if (contentType.startsWith("application/json")) {
3822
3816
  const json = await res.json();
3817
+ const message = getErrorMessageFromUnknownJson(json, "Could not get nonce. Unexpected error (no error message). Status: " + res.status);
3823
3818
  return {
3824
3819
  status: "error",
3825
3820
  error: {
3826
- message: "Could not get nonce." + (json.message || "Unexpected error (no error message). Status: " + res.status)
3821
+ message: "Could not get nonce." + message
3827
3822
  }
3828
3823
  };
3829
3824
  }
@@ -4023,9 +4018,10 @@ class ValOpsHttp extends ValOps {
4023
4018
  }
4024
4019
  if ((_res$headers$get3 = res.headers.get("Content-Type")) !== null && _res$headers$get3 !== void 0 && _res$headers$get3.includes("application/json")) {
4025
4020
  const json = await res.json();
4021
+ const message = getErrorMessageFromUnknownJson(json, "Unknown error");
4026
4022
  return result.err({
4027
4023
  errorType: "other",
4028
- message: json.message || "Unknown error"
4024
+ message
4029
4025
  });
4030
4026
  }
4031
4027
  return result.err({
@@ -4318,15 +4314,24 @@ class ValOpsHttp extends ValOps {
4318
4314
  });
4319
4315
  if (res.ok) {
4320
4316
  const json = await res.json();
4317
+ const parsed = SummaryResponse.safeParse(json);
4318
+ if (parsed.success) {
4319
+ return {
4320
+ commitSummary: parsed.data.commitSummary
4321
+ };
4322
+ }
4321
4323
  return {
4322
- commitSummary: json.commitSummary
4324
+ error: {
4325
+ message: `Could not parse commit summary response. Error: ${fromError(parsed.error)}`
4326
+ }
4323
4327
  };
4324
4328
  }
4325
4329
  if ((_res$headers$get4 = res.headers.get("Content-Type")) !== null && _res$headers$get4 !== void 0 && _res$headers$get4.includes("application/json")) {
4326
4330
  const json = await res.json();
4331
+ const message = getErrorMessageFromUnknownJson(json, "Unknown error");
4327
4332
  return {
4328
4333
  error: {
4329
- message: json.message
4334
+ message
4330
4335
  }
4331
4336
  };
4332
4337
  }
@@ -4376,8 +4381,10 @@ class ValOpsHttp extends ValOps {
4376
4381
  };
4377
4382
  }
4378
4383
  if ((_res$headers$get5 = res.headers.get("Content-Type")) !== null && _res$headers$get5 !== void 0 && _res$headers$get5.includes("application/json")) {
4379
- const json = await res.json();
4380
- if (json.isNotFastForward) {
4384
+ const json = z.object({
4385
+ isNotFastForward: z.boolean().optional()
4386
+ }).safeParse(await res.json());
4387
+ if (json.success && json.data.isNotFastForward) {
4381
4388
  return {
4382
4389
  isNotFastForward: true,
4383
4390
  error: {
@@ -4385,9 +4392,10 @@ class ValOpsHttp extends ValOps {
4385
4392
  }
4386
4393
  };
4387
4394
  }
4395
+ const message = getErrorMessageFromUnknownJson(json, "Unknown error");
4388
4396
  return {
4389
4397
  error: {
4390
- message: json.message
4398
+ message
4391
4399
  }
4392
4400
  };
4393
4401
  }
@@ -4424,7 +4432,8 @@ class ValOpsHttp extends ValOps {
4424
4432
  }
4425
4433
  if ((_res$headers$get6 = res.headers.get("Content-Type")) !== null && _res$headers$get6 !== void 0 && _res$headers$get6.includes("application/json")) {
4426
4434
  const json = await res.json();
4427
- throw Error(`Could not get profiles (status: ${res.status}): ${"message" in json ? json.message : "Unknown error"}`);
4435
+ const message = getErrorMessageFromUnknownJson(json, "Unknown error");
4436
+ throw Error(`Could not get profiles (status: ${res.status}): ${message}`);
4428
4437
  }
4429
4438
  throw Error(`Could not get profiles. Got status: ${res.status}`);
4430
4439
  }
@@ -4472,7 +4481,7 @@ async function getSettings(projectName, auth) {
4472
4481
  success: true,
4473
4482
  data: parseRes.data
4474
4483
  };
4475
- } catch (err) {
4484
+ } catch {
4476
4485
  return {
4477
4486
  success: false,
4478
4487
  message: `Failed to get project id. Check network connection and try again.`
@@ -5081,20 +5090,42 @@ const ValServer = (valModules, options, callbacks) => {
5081
5090
  headers: getAuthHeaders(data.token, "application/json")
5082
5091
  });
5083
5092
  if (fetchRes.status === 200) {
5084
- return {
5085
- status: fetchRes.status,
5086
- json: {
5087
- mode: "proxy",
5088
- enabled: await callbacks.isEnabled(),
5089
- ...(await fetchRes.json())
5090
- }
5091
- };
5093
+ const json = z.object({
5094
+ member_role: z.union([z.literal("owner"), z.literal("developer"), z.literal("editor")]).optional(),
5095
+ id: z.string(),
5096
+ full_name: z.string().optional(),
5097
+ username: z.string().optional(),
5098
+ avatar_url: z.string().optional()
5099
+ }).safeParse(await fetchRes.json());
5100
+ if (json.success) {
5101
+ return {
5102
+ status: fetchRes.status,
5103
+ json: {
5104
+ mode: "proxy",
5105
+ enabled: await callbacks.isEnabled(),
5106
+ ...json.data
5107
+ }
5108
+ };
5109
+ } else {
5110
+ const message = getErrorMessageFromUnknownJson(json, "Could not parse session response. Unexpected error (no error message). Status: " + fetchRes.status);
5111
+ return {
5112
+ status: 500,
5113
+ json: {
5114
+ message: message,
5115
+ ...json
5116
+ }
5117
+ };
5118
+ }
5092
5119
  } else {
5120
+ const json = z.object({
5121
+ message: z.string()
5122
+ }).safeParse(await fetchRes.json());
5123
+ const message = getErrorMessageFromUnknownJson(json, "Unknown error");
5093
5124
  return {
5094
5125
  status: fetchRes.status,
5095
5126
  json: {
5096
- message: "Failed to authorize",
5097
- ...(await fetchRes.json())
5127
+ message: message,
5128
+ ...json
5098
5129
  }
5099
5130
  };
5100
5131
  }
@@ -5513,7 +5544,7 @@ const ValServer = (valModules, options, callbacks) => {
5513
5544
  return {
5514
5545
  status: 200,
5515
5546
  json: {
5516
- patches,
5547
+ patches: patches,
5517
5548
  baseSha: await serverOps.getBaseSha()
5518
5549
  }
5519
5550
  };
@@ -5841,7 +5872,7 @@ const ValServer = (valModules, options, callbacks) => {
5841
5872
  status: 400,
5842
5873
  json: {
5843
5874
  message: "Invalid body: " + fromError(bodyRes.error).toString(),
5844
- details: bodyRes.error.errors
5875
+ details: bodyRes.error.issues
5845
5876
  }
5846
5877
  };
5847
5878
  }
@@ -6421,7 +6452,7 @@ async function safeReadGit(cwd) {
6421
6452
  branch: undefined
6422
6453
  };
6423
6454
  }
6424
- } catch (error) {
6455
+ } catch {
6425
6456
  const parentDir = path.dirname(currentDir);
6426
6457
 
6427
6458
  // We've reached the root directory
@@ -6447,7 +6478,7 @@ async function safeReadGit(cwd) {
6447
6478
  async function readCommit(gitDir, branchName) {
6448
6479
  try {
6449
6480
  return (await promises.readFile(path.join(gitDir, ".git", "refs", "heads", branchName), "utf-8")).trim();
6450
- } catch (err) {
6481
+ } catch {
6451
6482
  return undefined;
6452
6483
  }
6453
6484
  }
@@ -6637,7 +6668,7 @@ function createValApiRouter(route, valServerPromise, convert) {
6637
6668
  };
6638
6669
  }
6639
6670
  function formatZodErrorString(error) {
6640
- const errors = fromZodError(error).toString();
6671
+ const errors = fromError(error).toString();
6641
6672
  return errors.length > 640 ? `${errors.slice(0, 640)}...` : errors;
6642
6673
  }
6643
6674
  function zodErrorResult(error, message) {
@@ -6878,7 +6909,7 @@ async function getFileBufferFromRemote(ref, fileExt, currentFileHash, projectRoo
6878
6909
  await fs.promises.unlink(remoteFilePath);
6879
6910
  throw Error(`Cached file hash does not match the expected hash: ${computedFileHash} !== ${currentFileHash}`);
6880
6911
  }
6881
- } catch (err) {
6912
+ } catch {
6882
6913
  try {
6883
6914
  await fs.promises.mkdir(remoteFileCacheDir, {
6884
6915
  recursive: true
package/package.json CHANGED
@@ -16,33 +16,33 @@
16
16
  "./package.json": "./package.json"
17
17
  },
18
18
  "types": "dist/valbuild-server.cjs.d.ts",
19
- "version": "0.91.3",
20
- "scripts": {
21
- "typecheck": "tsc --noEmit",
22
- "test": "jest",
23
- "test:watch": "jest --watch"
24
- },
19
+ "version": "0.92.0",
25
20
  "devDependencies": {
26
- "@prettier/sync": "^0.5.2",
27
- "@types/jest": "^29.2.5"
21
+ "@prettier/sync": "^0.6.1",
22
+ "@types/jest": "^30.0.0"
28
23
  },
29
24
  "dependencies": {
30
- "@valbuild/core": "~0.91.3",
31
- "@valbuild/shared": "~0.91.3",
32
- "@valbuild/ui": "~0.91.3",
33
- "chokidar": "^4.0.1",
34
- "image-size": "^1.0.2",
35
- "minimatch": "^3.0.4",
25
+ "chokidar": "^5.0.0",
26
+ "image-size": "^2.0.2",
27
+ "minimatch": "^10.1.1",
36
28
  "quickjs-emscripten": "^0.21.1",
37
- "sucrase": "^3.34.0",
38
- "typescript": "^5.1.3",
39
- "zod": "^3.20.6",
40
- "zod-validation-error": "^3.3.0"
29
+ "sucrase": "^3.35.1",
30
+ "typescript": "^5.9.3",
31
+ "zod": "^4.3.5",
32
+ "zod-validation-error": "^5.0.0",
33
+ "@valbuild/core": "0.92.0",
34
+ "@valbuild/shared": "0.92.0",
35
+ "@valbuild/ui": "0.92.0"
41
36
  },
42
37
  "engines": {
43
38
  "node": ">=18.17.0"
44
39
  },
45
40
  "files": [
46
41
  "dist"
47
- ]
48
- }
42
+ ],
43
+ "scripts": {
44
+ "typecheck": "tsc --noEmit",
45
+ "test": "jest",
46
+ "test:watch": "jest --watch"
47
+ }
48
+ }