@valbuild/server 0.60.16 → 0.60.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.
@@ -32,9 +32,9 @@ export declare abstract class ValServer implements IValServer {
32
32
  patch?: string;
33
33
  schema?: string;
34
34
  source?: string;
35
- }, cookies: ValCookies<VAL_SESSION_COOKIE>): Promise<ValServerJsonResult<ApiTreeResponse>>;
36
- postValidate(rawBody: unknown, cookies: ValCookies<VAL_SESSION_COOKIE>): Promise<ValServerJsonResult<ApiPostValidationResponse | ApiPostValidationErrorResponse>>;
37
- postCommit(rawBody: unknown, cookies: ValCookies<VAL_SESSION_COOKIE>): Promise<ValServerJsonResult<ApiCommitResponse, ApiPostValidationErrorResponse>>;
35
+ }, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerJsonResult<ApiTreeResponse>>;
36
+ postValidate(rawBody: unknown, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerJsonResult<ApiPostValidationResponse | ApiPostValidationErrorResponse>>;
37
+ postCommit(rawBody: unknown, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerJsonResult<ApiCommitResponse, ApiPostValidationErrorResponse>>;
38
38
  private applyAllPatchesThenValidate;
39
39
  private revalidateImageAndFileValidation;
40
40
  protected sortPatchIds(patchesByModule: Record<ModuleId, {
@@ -69,7 +69,7 @@ export declare abstract class ValServer implements IValServer {
69
69
  } | ValServerError>;
70
70
  abstract getFiles(filePath: string, query: {
71
71
  sha256?: string;
72
- }, cookies: ValCookies<VAL_SESSION_COOKIE>): Promise<ValServerResult<never, ReadableStream<Uint8Array>>>;
72
+ }, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerResult<never, ReadableStream<Uint8Array>> | ValServerRedirectResult<VAL_ENABLE_COOKIE_NAME>>;
73
73
  abstract session(cookies: ValCookies<VAL_SESSION_COOKIE>): Promise<ValServerJsonResult<ValSession>>;
74
74
  abstract authorize(query: {
75
75
  redirect_to?: string;
@@ -129,7 +129,7 @@ export interface IValServer {
129
129
  patch?: string;
130
130
  schema?: string;
131
131
  source?: string;
132
- }, cookies: ValCookies<VAL_SESSION_COOKIE>): Promise<ValServerJsonResult<ApiTreeResponse>>;
132
+ }, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerJsonResult<ApiTreeResponse>>;
133
133
  getPatches(query: {
134
134
  id?: string[];
135
135
  }, cookies: ValCookies<VAL_SESSION_COOKIE>): Promise<ValServerJsonResult<ApiGetPatchResponse>>;
@@ -137,11 +137,11 @@ export interface IValServer {
137
137
  deletePatches(query: {
138
138
  id?: string[];
139
139
  }, cookies: ValCookies<VAL_SESSION_COOKIE>): Promise<ValServerJsonResult<ApiDeletePatchResponse>>;
140
- postValidate(body: unknown, cookies: ValCookies<VAL_SESSION_COOKIE>): Promise<ValServerJsonResult<ApiPostValidationResponse | ApiPostValidationErrorResponse>>;
141
- postCommit(body: unknown, cookies: ValCookies<VAL_SESSION_COOKIE>): Promise<ValServerJsonResult<ApiCommitResponse, ApiPostValidationErrorResponse>>;
140
+ postValidate(body: unknown, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerJsonResult<ApiPostValidationResponse | ApiPostValidationErrorResponse>>;
141
+ postCommit(body: unknown, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerJsonResult<ApiCommitResponse, ApiPostValidationErrorResponse>>;
142
142
  getFiles(filePath: string, query: {
143
143
  sha256?: string;
144
- }, cookies: ValCookies<VAL_SESSION_COOKIE>): Promise<ValServerResult<never, ReadableStream<Uint8Array>>>;
144
+ }, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerResult<never, ReadableStream<Uint8Array>> | ValServerRedirectResult<VAL_ENABLE_COOKIE_NAME>>;
145
145
  }
146
146
  export declare function guessMimeTypeFromPath(filePath: string): string | null;
147
147
  export declare function isCachedPatchFileOp(op: Operation): op is {
@@ -152,3 +152,7 @@ export declare function isCachedPatchFileOp(op: Operation): op is {
152
152
  sha256: string;
153
153
  };
154
154
  };
155
+ export type RequestHeaders = {
156
+ host?: string | null;
157
+ "x-forwarded-proto"?: string | null;
158
+ };
@@ -1032,12 +1032,12 @@ export const IS_DEV = false;
1032
1032
  }
1033
1033
  if (modulePath.startsWith("react/jsx-runtime")) {
1034
1034
  return {
1035
- value: "export const jsx = () => { throw Error(`Cannot use 'jsx' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } ); export const jsxs = () => { throw Error(`Cannot use 'jsxs' in this type of file`) };"
1035
+ value: "export const jsx = () => { throw Error(`Cannot use 'jsx' in this type of file`) }; export const Fragment = () => { throw Error(`Cannot use 'Fragment' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } ); export const jsxs = () => { throw Error(`Cannot use 'jsxs' in this type of file`) };"
1036
1036
  };
1037
1037
  }
1038
1038
  if (modulePath.startsWith("react")) {
1039
1039
  return {
1040
- value: "export const useTransition = () => { throw Error(`Cannot use 'useTransition' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } )"
1040
+ value: "export const createContext = () => new Proxy({}, { get() { return () => { throw new Error(`Cannot use 'createContext' in this file`) } } } ); export const useTransition = () => { throw Error(`Cannot use 'useTransition' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } )"
1041
1041
  };
1042
1042
  }
1043
1043
  if (modulePath.includes("/ValNextProvider")) {
@@ -1045,6 +1045,11 @@ export const IS_DEV = false;
1045
1045
  value: "export const ValNextProvider = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValNextProvider' in this file`) } } } )"
1046
1046
  };
1047
1047
  }
1048
+ if (modulePath.includes("/ValContext")) {
1049
+ return {
1050
+ value: "export const useValEvents = () => { throw Error(`Cannot use 'useValEvents' in this type of file`) }; export const ValContext = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValContext' in this file`) } } } ) export const ValEvents = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValEvents' in this file`) } } } )"
1051
+ };
1052
+ }
1048
1053
  if (modulePath.includes("/ValImage")) {
1049
1054
  return {
1050
1055
  value: "export const ValImage = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValImage' in this file`) } } } )"
@@ -1110,6 +1115,11 @@ export const IS_DEV = false;
1110
1115
  value: requestedName
1111
1116
  };
1112
1117
  }
1118
+ if (requestedName.includes("/ValContext")) {
1119
+ return {
1120
+ value: requestedName
1121
+ };
1122
+ }
1113
1123
  if (requestedName.includes("/ValImage")) {
1114
1124
  return {
1115
1125
  value: requestedName
@@ -1419,7 +1429,7 @@ class ValServer {
1419
1429
  }
1420
1430
  async getTree(treePath,
1421
1431
  // TODO: use the params: patch, schema, source now we return everything, every time
1422
- query, cookies) {
1432
+ query, cookies, requestHeaders) {
1423
1433
  const ensureRes = await this.ensureRemoteFSInitialized("getTree", cookies);
1424
1434
  if (fp.result.isErr(ensureRes)) {
1425
1435
  return ensureRes.error;
@@ -1445,7 +1455,7 @@ class ValServer {
1445
1455
  fileUpdates = res.value.fileUpdates;
1446
1456
  }
1447
1457
  const possiblyPatchedContent = await Promise.all(moduleIds.map(async moduleId => {
1448
- return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies);
1458
+ return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies, requestHeaders);
1449
1459
  }));
1450
1460
  const modules = Object.fromEntries(possiblyPatchedContent.map(serializedModuleContent => {
1451
1461
  const module = {
@@ -1464,19 +1474,19 @@ class ValServer {
1464
1474
  json: apiTreeResponse
1465
1475
  };
1466
1476
  }
1467
- async postValidate(rawBody, cookies) {
1477
+ async postValidate(rawBody, cookies, requestHeaders) {
1468
1478
  const ensureRes = await this.ensureRemoteFSInitialized("postValidate", cookies);
1469
1479
  if (fp.result.isErr(ensureRes)) {
1470
1480
  return ensureRes.error;
1471
1481
  }
1472
- return this.validateThenMaybeCommit(rawBody, false, cookies);
1482
+ return this.validateThenMaybeCommit(rawBody, false, cookies, requestHeaders);
1473
1483
  }
1474
- async postCommit(rawBody, cookies) {
1484
+ async postCommit(rawBody, cookies, requestHeaders) {
1475
1485
  const ensureRes = await this.ensureRemoteFSInitialized("postCommit", cookies);
1476
1486
  if (fp.result.isErr(ensureRes)) {
1477
1487
  return ensureRes.error;
1478
1488
  }
1479
- const res = await this.validateThenMaybeCommit(rawBody, true, cookies);
1489
+ const res = await this.validateThenMaybeCommit(rawBody, true, cookies, requestHeaders);
1480
1490
  if (res.status === 200) {
1481
1491
  if (res.json.validationErrors) {
1482
1492
  return {
@@ -1499,7 +1509,7 @@ class ValServer {
1499
1509
 
1500
1510
  /* */
1501
1511
 
1502
- async applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies) {
1512
+ async applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies, requestHeaders) {
1503
1513
  const serializedModuleContent = await this.getModule(moduleId);
1504
1514
  const schema = serializedModuleContent.schema;
1505
1515
  const maybeSource = serializedModuleContent.source;
@@ -1543,7 +1553,7 @@ class ValServer {
1543
1553
  }
1544
1554
  const validationErrors = core.deserializeSchema(schema).validate(moduleId, source);
1545
1555
  if (validationErrors) {
1546
- const revalidated = await this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies);
1556
+ const revalidated = await this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders);
1547
1557
  return {
1548
1558
  path: moduleId,
1549
1559
  schema,
@@ -1566,7 +1576,7 @@ class ValServer {
1566
1576
  // The reason is that validate will be called inside QuickJS (in the future, hopefully),
1567
1577
  // which does not have access to the filesystem, at least not at the time of writing this comment.
1568
1578
  // If you are reading this, and we still are not using QuickJS to validate, this assumption might be wrong.
1569
- async revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies) {
1579
+ async revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders) {
1570
1580
  const revalidatedValidationErrors = {};
1571
1581
  for (const pathStr in validationErrors) {
1572
1582
  const errorSourcePath = pathStr;
@@ -1588,7 +1598,7 @@ class ValServer {
1588
1598
  if (updatedFileMetadata) {
1589
1599
  const fileRes = await this.getFiles(fileRef, {
1590
1600
  sha256: updatedFileMetadata.sha256
1591
- }, cookies);
1601
+ }, cookies, requestHeaders);
1592
1602
  if (fileRes.status === 200 && fileRes.body) {
1593
1603
  const res = new Response(fileRes.body);
1594
1604
  fileBuffer = Buffer.from(await res.arrayBuffer());
@@ -1724,7 +1734,7 @@ class ValServer {
1724
1734
  });
1725
1735
  }
1726
1736
  }
1727
- async validateThenMaybeCommit(rawBody, commit, cookies) {
1737
+ async validateThenMaybeCommit(rawBody, commit, cookies, requestHeaders) {
1728
1738
  const filterPatchesByModuleIdRes = z.z.object({
1729
1739
  patches: z.z.record(z.z.array(z.z.string())).optional()
1730
1740
  }).safeParse(rawBody);
@@ -1752,7 +1762,7 @@ class ValServer {
1752
1762
  const moduleId = moduleIdStr;
1753
1763
  const serializedModuleContent = await this.applyAllPatchesThenValidate(moduleId, filterPatchesByModuleIdRes.data.patches ||
1754
1764
  // TODO: refine to ModuleId and PatchId when parsing
1755
- patchIdsByModuleId, patchesById, fileUpdates, true, cookies);
1765
+ patchIdsByModuleId, patchesById, fileUpdates, true, cookies, requestHeaders);
1756
1766
  if (serializedModuleContent.errors) {
1757
1767
  validationErrorsByModuleId[moduleId] = serializedModuleContent;
1758
1768
  }
@@ -2970,7 +2980,7 @@ class ProxyValServer extends ValServer {
2970
2980
  }
2971
2981
  });
2972
2982
  }
2973
- async getFiles(filePath, query, cookies) {
2983
+ async getFiles(filePath, query, cookies, reqHeaders) {
2974
2984
  return withAuth(this.options.valSecret, cookies, "getFiles", async data => {
2975
2985
  const url = new URL(`/v1/files/${this.options.remote}${filePath}`, this.options.valContentUrl);
2976
2986
  if (typeof query.sha256 === "string") {
@@ -3002,41 +3012,19 @@ class ProxyValServer extends ValServer {
3002
3012
  };
3003
3013
  }
3004
3014
  } else {
3005
- const fileExists = this.remoteFS.fileExists(path__namespace["default"].join(this.cwd, filePath));
3006
- let buffer;
3007
- if (fileExists) {
3008
- buffer = await this.readStaticBinaryFile(path__namespace["default"].join(this.cwd, filePath));
3009
- }
3010
- if (!buffer) {
3015
+ if (!(reqHeaders.host && reqHeaders["x-forwarded-proto"])) {
3011
3016
  return {
3012
- status: 404,
3017
+ status: 500,
3013
3018
  json: {
3014
- message: "File not found"
3019
+ message: "Missing host or x-forwarded-proto header"
3015
3020
  }
3016
3021
  };
3017
3022
  }
3018
- const mimeType = guessMimeTypeFromPath(filePath) || "application/octet-stream";
3019
- if (query.sha256) {
3020
- const sha256 = getSha256(mimeType, buffer);
3021
- if (sha256 === query.sha256) {
3022
- return {
3023
- status: 200,
3024
- headers: {
3025
- "Content-Type": mimeType,
3026
- "Content-Length": buffer.byteLength.toString(),
3027
- "Cache-Control": "public, max-age=31536000, immutable"
3028
- },
3029
- body: bufferToReadableStream(buffer)
3030
- };
3031
- }
3032
- }
3023
+ const host = `${reqHeaders["x-forwarded-proto"]}://${reqHeaders["host"]}`;
3024
+ const fileUrl = filePath.slice("/public".length);
3033
3025
  return {
3034
- status: 200,
3035
- headers: {
3036
- "Content-Type": mimeType,
3037
- "Content-Length": buffer.byteLength.toString()
3038
- },
3039
- body: bufferToReadableStream(buffer)
3026
+ status: 302,
3027
+ redirectTo: new URL(fileUrl, host).toString()
3040
3028
  };
3041
3029
  }
3042
3030
  });
@@ -3359,8 +3347,10 @@ function createValApiRouter(route, valServerPromise, convert) {
3359
3347
  return async req => {
3360
3348
  var _req$method;
3361
3349
  const valServer = await valServerPromise;
3362
- req.headers.get("content-type");
3363
- req.headers.get("Cookie");
3350
+ const requestHeaders = {
3351
+ host: req.headers.get("host"),
3352
+ "x-forwarded-proto": req.headers.get("x-forwarded-proto")
3353
+ };
3364
3354
  const url = new URL(req.url);
3365
3355
  if (!url.pathname.startsWith(route)) {
3366
3356
  const error = {
@@ -3423,16 +3413,16 @@ function createValApiRouter(route, valServerPromise, convert) {
3423
3413
  }));
3424
3414
  } else if (method === "POST" && path === "/commit") {
3425
3415
  const body = await req.json();
3426
- return convert(await valServer.postCommit(body, getCookies(req, [VAL_SESSION_COOKIE])));
3416
+ return convert(await valServer.postCommit(body, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
3427
3417
  } else if (method === "POST" && path === "/validate") {
3428
3418
  const body = await req.json();
3429
- return convert(await valServer.postValidate(body, getCookies(req, [VAL_SESSION_COOKIE])));
3419
+ return convert(await valServer.postValidate(body, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
3430
3420
  } else if (method === "GET" && path.startsWith(TREE_PATH_PREFIX)) {
3431
3421
  return withTreePath(path, TREE_PATH_PREFIX)(async treePath => convert(await valServer.getTree(treePath, {
3432
3422
  patch: url.searchParams.get("patch") || undefined,
3433
3423
  schema: url.searchParams.get("schema") || undefined,
3434
3424
  source: url.searchParams.get("source") || undefined
3435
- }, getCookies(req, [VAL_SESSION_COOKIE]))));
3425
+ }, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders)));
3436
3426
  } else if (method === "GET" && path.startsWith(PATCHES_PATH_PREFIX)) {
3437
3427
  return withTreePath(path, PATCHES_PATH_PREFIX)(async () => convert(await valServer.getPatches({
3438
3428
  id: url.searchParams.getAll("id")
@@ -3448,7 +3438,7 @@ function createValApiRouter(route, valServerPromise, convert) {
3448
3438
  const treePath = path.slice(FILES_PATH_PREFIX.length);
3449
3439
  return convert(await valServer.getFiles(treePath, {
3450
3440
  sha256: url.searchParams.get("sha256") || undefined
3451
- }, getCookies(req, [VAL_SESSION_COOKIE])));
3441
+ }, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
3452
3442
  } else {
3453
3443
  return convert({
3454
3444
  status: 404,
@@ -1032,12 +1032,12 @@ export const IS_DEV = false;
1032
1032
  }
1033
1033
  if (modulePath.startsWith("react/jsx-runtime")) {
1034
1034
  return {
1035
- value: "export const jsx = () => { throw Error(`Cannot use 'jsx' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } ); export const jsxs = () => { throw Error(`Cannot use 'jsxs' in this type of file`) };"
1035
+ value: "export const jsx = () => { throw Error(`Cannot use 'jsx' in this type of file`) }; export const Fragment = () => { throw Error(`Cannot use 'Fragment' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } ); export const jsxs = () => { throw Error(`Cannot use 'jsxs' in this type of file`) };"
1036
1036
  };
1037
1037
  }
1038
1038
  if (modulePath.startsWith("react")) {
1039
1039
  return {
1040
- value: "export const useTransition = () => { throw Error(`Cannot use 'useTransition' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } )"
1040
+ value: "export const createContext = () => new Proxy({}, { get() { return () => { throw new Error(`Cannot use 'createContext' in this file`) } } } ); export const useTransition = () => { throw Error(`Cannot use 'useTransition' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } )"
1041
1041
  };
1042
1042
  }
1043
1043
  if (modulePath.includes("/ValNextProvider")) {
@@ -1045,6 +1045,11 @@ export const IS_DEV = false;
1045
1045
  value: "export const ValNextProvider = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValNextProvider' in this file`) } } } )"
1046
1046
  };
1047
1047
  }
1048
+ if (modulePath.includes("/ValContext")) {
1049
+ return {
1050
+ value: "export const useValEvents = () => { throw Error(`Cannot use 'useValEvents' in this type of file`) }; export const ValContext = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValContext' in this file`) } } } ) export const ValEvents = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValEvents' in this file`) } } } )"
1051
+ };
1052
+ }
1048
1053
  if (modulePath.includes("/ValImage")) {
1049
1054
  return {
1050
1055
  value: "export const ValImage = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValImage' in this file`) } } } )"
@@ -1110,6 +1115,11 @@ export const IS_DEV = false;
1110
1115
  value: requestedName
1111
1116
  };
1112
1117
  }
1118
+ if (requestedName.includes("/ValContext")) {
1119
+ return {
1120
+ value: requestedName
1121
+ };
1122
+ }
1113
1123
  if (requestedName.includes("/ValImage")) {
1114
1124
  return {
1115
1125
  value: requestedName
@@ -1419,7 +1429,7 @@ class ValServer {
1419
1429
  }
1420
1430
  async getTree(treePath,
1421
1431
  // TODO: use the params: patch, schema, source now we return everything, every time
1422
- query, cookies) {
1432
+ query, cookies, requestHeaders) {
1423
1433
  const ensureRes = await this.ensureRemoteFSInitialized("getTree", cookies);
1424
1434
  if (fp.result.isErr(ensureRes)) {
1425
1435
  return ensureRes.error;
@@ -1445,7 +1455,7 @@ class ValServer {
1445
1455
  fileUpdates = res.value.fileUpdates;
1446
1456
  }
1447
1457
  const possiblyPatchedContent = await Promise.all(moduleIds.map(async moduleId => {
1448
- return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies);
1458
+ return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies, requestHeaders);
1449
1459
  }));
1450
1460
  const modules = Object.fromEntries(possiblyPatchedContent.map(serializedModuleContent => {
1451
1461
  const module = {
@@ -1464,19 +1474,19 @@ class ValServer {
1464
1474
  json: apiTreeResponse
1465
1475
  };
1466
1476
  }
1467
- async postValidate(rawBody, cookies) {
1477
+ async postValidate(rawBody, cookies, requestHeaders) {
1468
1478
  const ensureRes = await this.ensureRemoteFSInitialized("postValidate", cookies);
1469
1479
  if (fp.result.isErr(ensureRes)) {
1470
1480
  return ensureRes.error;
1471
1481
  }
1472
- return this.validateThenMaybeCommit(rawBody, false, cookies);
1482
+ return this.validateThenMaybeCommit(rawBody, false, cookies, requestHeaders);
1473
1483
  }
1474
- async postCommit(rawBody, cookies) {
1484
+ async postCommit(rawBody, cookies, requestHeaders) {
1475
1485
  const ensureRes = await this.ensureRemoteFSInitialized("postCommit", cookies);
1476
1486
  if (fp.result.isErr(ensureRes)) {
1477
1487
  return ensureRes.error;
1478
1488
  }
1479
- const res = await this.validateThenMaybeCommit(rawBody, true, cookies);
1489
+ const res = await this.validateThenMaybeCommit(rawBody, true, cookies, requestHeaders);
1480
1490
  if (res.status === 200) {
1481
1491
  if (res.json.validationErrors) {
1482
1492
  return {
@@ -1499,7 +1509,7 @@ class ValServer {
1499
1509
 
1500
1510
  /* */
1501
1511
 
1502
- async applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies) {
1512
+ async applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies, requestHeaders) {
1503
1513
  const serializedModuleContent = await this.getModule(moduleId);
1504
1514
  const schema = serializedModuleContent.schema;
1505
1515
  const maybeSource = serializedModuleContent.source;
@@ -1543,7 +1553,7 @@ class ValServer {
1543
1553
  }
1544
1554
  const validationErrors = core.deserializeSchema(schema).validate(moduleId, source);
1545
1555
  if (validationErrors) {
1546
- const revalidated = await this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies);
1556
+ const revalidated = await this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders);
1547
1557
  return {
1548
1558
  path: moduleId,
1549
1559
  schema,
@@ -1566,7 +1576,7 @@ class ValServer {
1566
1576
  // The reason is that validate will be called inside QuickJS (in the future, hopefully),
1567
1577
  // which does not have access to the filesystem, at least not at the time of writing this comment.
1568
1578
  // If you are reading this, and we still are not using QuickJS to validate, this assumption might be wrong.
1569
- async revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies) {
1579
+ async revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders) {
1570
1580
  const revalidatedValidationErrors = {};
1571
1581
  for (const pathStr in validationErrors) {
1572
1582
  const errorSourcePath = pathStr;
@@ -1588,7 +1598,7 @@ class ValServer {
1588
1598
  if (updatedFileMetadata) {
1589
1599
  const fileRes = await this.getFiles(fileRef, {
1590
1600
  sha256: updatedFileMetadata.sha256
1591
- }, cookies);
1601
+ }, cookies, requestHeaders);
1592
1602
  if (fileRes.status === 200 && fileRes.body) {
1593
1603
  const res = new Response(fileRes.body);
1594
1604
  fileBuffer = Buffer.from(await res.arrayBuffer());
@@ -1724,7 +1734,7 @@ class ValServer {
1724
1734
  });
1725
1735
  }
1726
1736
  }
1727
- async validateThenMaybeCommit(rawBody, commit, cookies) {
1737
+ async validateThenMaybeCommit(rawBody, commit, cookies, requestHeaders) {
1728
1738
  const filterPatchesByModuleIdRes = z.z.object({
1729
1739
  patches: z.z.record(z.z.array(z.z.string())).optional()
1730
1740
  }).safeParse(rawBody);
@@ -1752,7 +1762,7 @@ class ValServer {
1752
1762
  const moduleId = moduleIdStr;
1753
1763
  const serializedModuleContent = await this.applyAllPatchesThenValidate(moduleId, filterPatchesByModuleIdRes.data.patches ||
1754
1764
  // TODO: refine to ModuleId and PatchId when parsing
1755
- patchIdsByModuleId, patchesById, fileUpdates, true, cookies);
1765
+ patchIdsByModuleId, patchesById, fileUpdates, true, cookies, requestHeaders);
1756
1766
  if (serializedModuleContent.errors) {
1757
1767
  validationErrorsByModuleId[moduleId] = serializedModuleContent;
1758
1768
  }
@@ -2970,7 +2980,7 @@ class ProxyValServer extends ValServer {
2970
2980
  }
2971
2981
  });
2972
2982
  }
2973
- async getFiles(filePath, query, cookies) {
2983
+ async getFiles(filePath, query, cookies, reqHeaders) {
2974
2984
  return withAuth(this.options.valSecret, cookies, "getFiles", async data => {
2975
2985
  const url = new URL(`/v1/files/${this.options.remote}${filePath}`, this.options.valContentUrl);
2976
2986
  if (typeof query.sha256 === "string") {
@@ -3002,41 +3012,19 @@ class ProxyValServer extends ValServer {
3002
3012
  };
3003
3013
  }
3004
3014
  } else {
3005
- const fileExists = this.remoteFS.fileExists(path__namespace["default"].join(this.cwd, filePath));
3006
- let buffer;
3007
- if (fileExists) {
3008
- buffer = await this.readStaticBinaryFile(path__namespace["default"].join(this.cwd, filePath));
3009
- }
3010
- if (!buffer) {
3015
+ if (!(reqHeaders.host && reqHeaders["x-forwarded-proto"])) {
3011
3016
  return {
3012
- status: 404,
3017
+ status: 500,
3013
3018
  json: {
3014
- message: "File not found"
3019
+ message: "Missing host or x-forwarded-proto header"
3015
3020
  }
3016
3021
  };
3017
3022
  }
3018
- const mimeType = guessMimeTypeFromPath(filePath) || "application/octet-stream";
3019
- if (query.sha256) {
3020
- const sha256 = getSha256(mimeType, buffer);
3021
- if (sha256 === query.sha256) {
3022
- return {
3023
- status: 200,
3024
- headers: {
3025
- "Content-Type": mimeType,
3026
- "Content-Length": buffer.byteLength.toString(),
3027
- "Cache-Control": "public, max-age=31536000, immutable"
3028
- },
3029
- body: bufferToReadableStream(buffer)
3030
- };
3031
- }
3032
- }
3023
+ const host = `${reqHeaders["x-forwarded-proto"]}://${reqHeaders["host"]}`;
3024
+ const fileUrl = filePath.slice("/public".length);
3033
3025
  return {
3034
- status: 200,
3035
- headers: {
3036
- "Content-Type": mimeType,
3037
- "Content-Length": buffer.byteLength.toString()
3038
- },
3039
- body: bufferToReadableStream(buffer)
3026
+ status: 302,
3027
+ redirectTo: new URL(fileUrl, host).toString()
3040
3028
  };
3041
3029
  }
3042
3030
  });
@@ -3359,8 +3347,10 @@ function createValApiRouter(route, valServerPromise, convert) {
3359
3347
  return async req => {
3360
3348
  var _req$method;
3361
3349
  const valServer = await valServerPromise;
3362
- req.headers.get("content-type");
3363
- req.headers.get("Cookie");
3350
+ const requestHeaders = {
3351
+ host: req.headers.get("host"),
3352
+ "x-forwarded-proto": req.headers.get("x-forwarded-proto")
3353
+ };
3364
3354
  const url = new URL(req.url);
3365
3355
  if (!url.pathname.startsWith(route)) {
3366
3356
  const error = {
@@ -3423,16 +3413,16 @@ function createValApiRouter(route, valServerPromise, convert) {
3423
3413
  }));
3424
3414
  } else if (method === "POST" && path === "/commit") {
3425
3415
  const body = await req.json();
3426
- return convert(await valServer.postCommit(body, getCookies(req, [VAL_SESSION_COOKIE])));
3416
+ return convert(await valServer.postCommit(body, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
3427
3417
  } else if (method === "POST" && path === "/validate") {
3428
3418
  const body = await req.json();
3429
- return convert(await valServer.postValidate(body, getCookies(req, [VAL_SESSION_COOKIE])));
3419
+ return convert(await valServer.postValidate(body, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
3430
3420
  } else if (method === "GET" && path.startsWith(TREE_PATH_PREFIX)) {
3431
3421
  return withTreePath(path, TREE_PATH_PREFIX)(async treePath => convert(await valServer.getTree(treePath, {
3432
3422
  patch: url.searchParams.get("patch") || undefined,
3433
3423
  schema: url.searchParams.get("schema") || undefined,
3434
3424
  source: url.searchParams.get("source") || undefined
3435
- }, getCookies(req, [VAL_SESSION_COOKIE]))));
3425
+ }, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders)));
3436
3426
  } else if (method === "GET" && path.startsWith(PATCHES_PATH_PREFIX)) {
3437
3427
  return withTreePath(path, PATCHES_PATH_PREFIX)(async () => convert(await valServer.getPatches({
3438
3428
  id: url.searchParams.getAll("id")
@@ -3448,7 +3438,7 @@ function createValApiRouter(route, valServerPromise, convert) {
3448
3438
  const treePath = path.slice(FILES_PATH_PREFIX.length);
3449
3439
  return convert(await valServer.getFiles(treePath, {
3450
3440
  sha256: url.searchParams.get("sha256") || undefined
3451
- }, getCookies(req, [VAL_SESSION_COOKIE])));
3441
+ }, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
3452
3442
  } else {
3453
3443
  return convert({
3454
3444
  status: 404,
@@ -1001,12 +1001,12 @@ export const IS_DEV = false;
1001
1001
  }
1002
1002
  if (modulePath.startsWith("react/jsx-runtime")) {
1003
1003
  return {
1004
- value: "export const jsx = () => { throw Error(`Cannot use 'jsx' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } ); export const jsxs = () => { throw Error(`Cannot use 'jsxs' in this type of file`) };"
1004
+ value: "export const jsx = () => { throw Error(`Cannot use 'jsx' in this type of file`) }; export const Fragment = () => { throw Error(`Cannot use 'Fragment' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } ); export const jsxs = () => { throw Error(`Cannot use 'jsxs' in this type of file`) };"
1005
1005
  };
1006
1006
  }
1007
1007
  if (modulePath.startsWith("react")) {
1008
1008
  return {
1009
- value: "export const useTransition = () => { throw Error(`Cannot use 'useTransition' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } )"
1009
+ value: "export const createContext = () => new Proxy({}, { get() { return () => { throw new Error(`Cannot use 'createContext' in this file`) } } } ); export const useTransition = () => { throw Error(`Cannot use 'useTransition' in this type of file`) }; export default new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'react' in this file`) } } } )"
1010
1010
  };
1011
1011
  }
1012
1012
  if (modulePath.includes("/ValNextProvider")) {
@@ -1014,6 +1014,11 @@ export const IS_DEV = false;
1014
1014
  value: "export const ValNextProvider = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValNextProvider' in this file`) } } } )"
1015
1015
  };
1016
1016
  }
1017
+ if (modulePath.includes("/ValContext")) {
1018
+ return {
1019
+ value: "export const useValEvents = () => { throw Error(`Cannot use 'useValEvents' in this type of file`) }; export const ValContext = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValContext' in this file`) } } } ) export const ValEvents = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValEvents' in this file`) } } } )"
1020
+ };
1021
+ }
1017
1022
  if (modulePath.includes("/ValImage")) {
1018
1023
  return {
1019
1024
  value: "export const ValImage = new Proxy({}, { get() { return () => { throw new Error(`Cannot import 'ValImage' in this file`) } } } )"
@@ -1079,6 +1084,11 @@ export const IS_DEV = false;
1079
1084
  value: requestedName
1080
1085
  };
1081
1086
  }
1087
+ if (requestedName.includes("/ValContext")) {
1088
+ return {
1089
+ value: requestedName
1090
+ };
1091
+ }
1082
1092
  if (requestedName.includes("/ValImage")) {
1083
1093
  return {
1084
1094
  value: requestedName
@@ -1388,7 +1398,7 @@ class ValServer {
1388
1398
  }
1389
1399
  async getTree(treePath,
1390
1400
  // TODO: use the params: patch, schema, source now we return everything, every time
1391
- query, cookies) {
1401
+ query, cookies, requestHeaders) {
1392
1402
  const ensureRes = await this.ensureRemoteFSInitialized("getTree", cookies);
1393
1403
  if (result.isErr(ensureRes)) {
1394
1404
  return ensureRes.error;
@@ -1414,7 +1424,7 @@ class ValServer {
1414
1424
  fileUpdates = res.value.fileUpdates;
1415
1425
  }
1416
1426
  const possiblyPatchedContent = await Promise.all(moduleIds.map(async moduleId => {
1417
- return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies);
1427
+ return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies, requestHeaders);
1418
1428
  }));
1419
1429
  const modules = Object.fromEntries(possiblyPatchedContent.map(serializedModuleContent => {
1420
1430
  const module = {
@@ -1433,19 +1443,19 @@ class ValServer {
1433
1443
  json: apiTreeResponse
1434
1444
  };
1435
1445
  }
1436
- async postValidate(rawBody, cookies) {
1446
+ async postValidate(rawBody, cookies, requestHeaders) {
1437
1447
  const ensureRes = await this.ensureRemoteFSInitialized("postValidate", cookies);
1438
1448
  if (result.isErr(ensureRes)) {
1439
1449
  return ensureRes.error;
1440
1450
  }
1441
- return this.validateThenMaybeCommit(rawBody, false, cookies);
1451
+ return this.validateThenMaybeCommit(rawBody, false, cookies, requestHeaders);
1442
1452
  }
1443
- async postCommit(rawBody, cookies) {
1453
+ async postCommit(rawBody, cookies, requestHeaders) {
1444
1454
  const ensureRes = await this.ensureRemoteFSInitialized("postCommit", cookies);
1445
1455
  if (result.isErr(ensureRes)) {
1446
1456
  return ensureRes.error;
1447
1457
  }
1448
- const res = await this.validateThenMaybeCommit(rawBody, true, cookies);
1458
+ const res = await this.validateThenMaybeCommit(rawBody, true, cookies, requestHeaders);
1449
1459
  if (res.status === 200) {
1450
1460
  if (res.json.validationErrors) {
1451
1461
  return {
@@ -1468,7 +1478,7 @@ class ValServer {
1468
1478
 
1469
1479
  /* */
1470
1480
 
1471
- async applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies) {
1481
+ async applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, applyPatches, cookies, requestHeaders) {
1472
1482
  const serializedModuleContent = await this.getModule(moduleId);
1473
1483
  const schema = serializedModuleContent.schema;
1474
1484
  const maybeSource = serializedModuleContent.source;
@@ -1512,7 +1522,7 @@ class ValServer {
1512
1522
  }
1513
1523
  const validationErrors = deserializeSchema(schema).validate(moduleId, source);
1514
1524
  if (validationErrors) {
1515
- const revalidated = await this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies);
1525
+ const revalidated = await this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders);
1516
1526
  return {
1517
1527
  path: moduleId,
1518
1528
  schema,
@@ -1535,7 +1545,7 @@ class ValServer {
1535
1545
  // The reason is that validate will be called inside QuickJS (in the future, hopefully),
1536
1546
  // which does not have access to the filesystem, at least not at the time of writing this comment.
1537
1547
  // If you are reading this, and we still are not using QuickJS to validate, this assumption might be wrong.
1538
- async revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies) {
1548
+ async revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders) {
1539
1549
  const revalidatedValidationErrors = {};
1540
1550
  for (const pathStr in validationErrors) {
1541
1551
  const errorSourcePath = pathStr;
@@ -1557,7 +1567,7 @@ class ValServer {
1557
1567
  if (updatedFileMetadata) {
1558
1568
  const fileRes = await this.getFiles(fileRef, {
1559
1569
  sha256: updatedFileMetadata.sha256
1560
- }, cookies);
1570
+ }, cookies, requestHeaders);
1561
1571
  if (fileRes.status === 200 && fileRes.body) {
1562
1572
  const res = new Response(fileRes.body);
1563
1573
  fileBuffer = Buffer.from(await res.arrayBuffer());
@@ -1693,7 +1703,7 @@ class ValServer {
1693
1703
  });
1694
1704
  }
1695
1705
  }
1696
- async validateThenMaybeCommit(rawBody, commit, cookies) {
1706
+ async validateThenMaybeCommit(rawBody, commit, cookies, requestHeaders) {
1697
1707
  const filterPatchesByModuleIdRes = z$1.object({
1698
1708
  patches: z$1.record(z$1.array(z$1.string())).optional()
1699
1709
  }).safeParse(rawBody);
@@ -1721,7 +1731,7 @@ class ValServer {
1721
1731
  const moduleId = moduleIdStr;
1722
1732
  const serializedModuleContent = await this.applyAllPatchesThenValidate(moduleId, filterPatchesByModuleIdRes.data.patches ||
1723
1733
  // TODO: refine to ModuleId and PatchId when parsing
1724
- patchIdsByModuleId, patchesById, fileUpdates, true, cookies);
1734
+ patchIdsByModuleId, patchesById, fileUpdates, true, cookies, requestHeaders);
1725
1735
  if (serializedModuleContent.errors) {
1726
1736
  validationErrorsByModuleId[moduleId] = serializedModuleContent;
1727
1737
  }
@@ -2939,7 +2949,7 @@ class ProxyValServer extends ValServer {
2939
2949
  }
2940
2950
  });
2941
2951
  }
2942
- async getFiles(filePath, query, cookies) {
2952
+ async getFiles(filePath, query, cookies, reqHeaders) {
2943
2953
  return withAuth(this.options.valSecret, cookies, "getFiles", async data => {
2944
2954
  const url = new URL(`/v1/files/${this.options.remote}${filePath}`, this.options.valContentUrl);
2945
2955
  if (typeof query.sha256 === "string") {
@@ -2971,41 +2981,19 @@ class ProxyValServer extends ValServer {
2971
2981
  };
2972
2982
  }
2973
2983
  } else {
2974
- const fileExists = this.remoteFS.fileExists(path__default.join(this.cwd, filePath));
2975
- let buffer;
2976
- if (fileExists) {
2977
- buffer = await this.readStaticBinaryFile(path__default.join(this.cwd, filePath));
2978
- }
2979
- if (!buffer) {
2984
+ if (!(reqHeaders.host && reqHeaders["x-forwarded-proto"])) {
2980
2985
  return {
2981
- status: 404,
2986
+ status: 500,
2982
2987
  json: {
2983
- message: "File not found"
2988
+ message: "Missing host or x-forwarded-proto header"
2984
2989
  }
2985
2990
  };
2986
2991
  }
2987
- const mimeType = guessMimeTypeFromPath(filePath) || "application/octet-stream";
2988
- if (query.sha256) {
2989
- const sha256 = getSha256(mimeType, buffer);
2990
- if (sha256 === query.sha256) {
2991
- return {
2992
- status: 200,
2993
- headers: {
2994
- "Content-Type": mimeType,
2995
- "Content-Length": buffer.byteLength.toString(),
2996
- "Cache-Control": "public, max-age=31536000, immutable"
2997
- },
2998
- body: bufferToReadableStream(buffer)
2999
- };
3000
- }
3001
- }
2992
+ const host = `${reqHeaders["x-forwarded-proto"]}://${reqHeaders["host"]}`;
2993
+ const fileUrl = filePath.slice("/public".length);
3002
2994
  return {
3003
- status: 200,
3004
- headers: {
3005
- "Content-Type": mimeType,
3006
- "Content-Length": buffer.byteLength.toString()
3007
- },
3008
- body: bufferToReadableStream(buffer)
2995
+ status: 302,
2996
+ redirectTo: new URL(fileUrl, host).toString()
3009
2997
  };
3010
2998
  }
3011
2999
  });
@@ -3328,8 +3316,10 @@ function createValApiRouter(route, valServerPromise, convert) {
3328
3316
  return async req => {
3329
3317
  var _req$method;
3330
3318
  const valServer = await valServerPromise;
3331
- req.headers.get("content-type");
3332
- req.headers.get("Cookie");
3319
+ const requestHeaders = {
3320
+ host: req.headers.get("host"),
3321
+ "x-forwarded-proto": req.headers.get("x-forwarded-proto")
3322
+ };
3333
3323
  const url = new URL(req.url);
3334
3324
  if (!url.pathname.startsWith(route)) {
3335
3325
  const error = {
@@ -3392,16 +3382,16 @@ function createValApiRouter(route, valServerPromise, convert) {
3392
3382
  }));
3393
3383
  } else if (method === "POST" && path === "/commit") {
3394
3384
  const body = await req.json();
3395
- return convert(await valServer.postCommit(body, getCookies(req, [VAL_SESSION_COOKIE])));
3385
+ return convert(await valServer.postCommit(body, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
3396
3386
  } else if (method === "POST" && path === "/validate") {
3397
3387
  const body = await req.json();
3398
- return convert(await valServer.postValidate(body, getCookies(req, [VAL_SESSION_COOKIE])));
3388
+ return convert(await valServer.postValidate(body, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
3399
3389
  } else if (method === "GET" && path.startsWith(TREE_PATH_PREFIX)) {
3400
3390
  return withTreePath(path, TREE_PATH_PREFIX)(async treePath => convert(await valServer.getTree(treePath, {
3401
3391
  patch: url.searchParams.get("patch") || undefined,
3402
3392
  schema: url.searchParams.get("schema") || undefined,
3403
3393
  source: url.searchParams.get("source") || undefined
3404
- }, getCookies(req, [VAL_SESSION_COOKIE]))));
3394
+ }, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders)));
3405
3395
  } else if (method === "GET" && path.startsWith(PATCHES_PATH_PREFIX)) {
3406
3396
  return withTreePath(path, PATCHES_PATH_PREFIX)(async () => convert(await valServer.getPatches({
3407
3397
  id: url.searchParams.getAll("id")
@@ -3417,7 +3407,7 @@ function createValApiRouter(route, valServerPromise, convert) {
3417
3407
  const treePath = path.slice(FILES_PATH_PREFIX.length);
3418
3408
  return convert(await valServer.getFiles(treePath, {
3419
3409
  sha256: url.searchParams.get("sha256") || undefined
3420
- }, getCookies(req, [VAL_SESSION_COOKIE])));
3410
+ }, getCookies(req, [VAL_SESSION_COOKIE]), requestHeaders));
3421
3411
  } else {
3422
3412
  return convert({
3423
3413
  status: 404,
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "./package.json": "./package.json"
13
13
  },
14
14
  "types": "dist/valbuild-server.cjs.d.ts",
15
- "version": "0.60.16",
15
+ "version": "0.60.18",
16
16
  "scripts": {
17
17
  "typecheck": "tsc --noEmit",
18
18
  "test": "jest",
@@ -24,9 +24,9 @@
24
24
  "concurrently": "^7.6.0"
25
25
  },
26
26
  "dependencies": {
27
- "@valbuild/core": "~0.60.16",
28
- "@valbuild/shared": "~0.60.16",
29
- "@valbuild/ui": "~0.60.16",
27
+ "@valbuild/core": "~0.60.18",
28
+ "@valbuild/shared": "~0.60.18",
29
+ "@valbuild/ui": "~0.60.18",
30
30
  "express": "^4.18.2",
31
31
  "image-size": "^1.0.2",
32
32
  "minimatch": "^3.0.4",