@valbuild/server 0.60.23 → 0.60.24

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.
@@ -2,7 +2,7 @@
2
2
  import { Service } from "./Service.js";
3
3
  import { result } from "@valbuild/core/fp";
4
4
  import { Patch } from "./patch/validation.js";
5
- import { ApiGetPatchResponse, ApiPostPatchResponse, ModuleId, PatchId, ApiDeletePatchResponse } from "@valbuild/core";
5
+ import { ApiGetPatchResponse, ApiPostPatchResponse, ModuleId, PatchId, ApiDeletePatchResponse, FileMetadata, ImageMetadata } from "@valbuild/core";
6
6
  import { VAL_ENABLE_COOKIE_NAME, VAL_SESSION_COOKIE, VAL_STATE_COOKIE, ValServerError, ValServerJsonResult, ValServerRedirectResult, ValServerResult, ValSession } from "@valbuild/shared/internal";
7
7
  import { ValServer, ValServerCallbacks } from "./ValServer.js";
8
8
  import { SerializedModuleContent } from "./SerializedModuleContent.js";
@@ -32,6 +32,7 @@ export declare class LocalValServer extends ValServer {
32
32
  id?: string[];
33
33
  }): Promise<ValServerJsonResult<ApiDeletePatchResponse>>;
34
34
  postPatches(body: unknown): Promise<ValServerJsonResult<ApiPostPatchResponse>>;
35
+ getMetadata(): Promise<FileMetadata | ImageMetadata | undefined>;
35
36
  getFiles(filePath: string, query: {
36
37
  sha256?: string;
37
38
  }): Promise<ValServerResult<never, ReadableStream<Uint8Array>>>;
@@ -44,7 +45,6 @@ export declare class LocalValServer extends ValServer {
44
45
  private badRequest;
45
46
  protected ensureInitialized(): Promise<result.Result<undefined, ValServerError>>;
46
47
  protected getModule(moduleId: ModuleId, options: {
47
- validate: boolean;
48
48
  source: boolean;
49
49
  schema: boolean;
50
50
  }): Promise<SerializedModuleContent>;
@@ -4,7 +4,7 @@ import { VAL_ENABLE_COOKIE_NAME, VAL_SESSION_COOKIE, VAL_STATE_COOKIE, ValCookie
4
4
  import { result } from "@valbuild/core/fp";
5
5
  import { Operation } from "@valbuild/core/patch";
6
6
  import { Patch } from "./patch/validation.js";
7
- import { ModuleId, PatchId } from "@valbuild/core";
7
+ import { ModuleId, PatchId, FileMetadata, ImageMetadata } from "@valbuild/core";
8
8
  import { SerializedModuleContent } from "./SerializedModuleContent.js";
9
9
  export type ValServerOptions = {
10
10
  valEnableRedirectUrl?: string;
@@ -29,11 +29,11 @@ export declare abstract class ValServer implements IValServer {
29
29
  patch?: string;
30
30
  schema?: string;
31
31
  source?: string;
32
- validate?: string;
33
32
  }, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerJsonResult<ApiTreeResponse>>;
34
33
  postValidate(rawBody: unknown, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerJsonResult<ApiPostValidationResponse | ApiPostValidationErrorResponse>>;
35
34
  postCommit(rawBody: unknown, cookies: ValCookies<VAL_SESSION_COOKIE>, requestHeaders: RequestHeaders): Promise<ValServerJsonResult<ApiCommitResponse, ApiPostValidationErrorResponse>>;
36
35
  private applyAllPatchesThenValidate;
36
+ abstract getMetadata(fileRef: string, sha256?: string): Promise<FileMetadata | ImageMetadata | undefined>;
37
37
  private revalidateImageAndFileValidation;
38
38
  protected abstract getAllModules(treePath: string): Promise<ModuleId[]>;
39
39
  protected sortPatchIds(patchesByModule: Record<ModuleId, {
@@ -58,7 +58,6 @@ export declare abstract class ValServer implements IValServer {
58
58
  * */
59
59
  protected abstract ensureInitialized(errorMessageType: string, cookies: ValCookies<VAL_SESSION_COOKIE>): Promise<result.Result<undefined, ValServerError>>;
60
60
  protected abstract getModule(moduleId: ModuleId, options: {
61
- validate: boolean;
62
61
  source: boolean;
63
62
  schema: boolean;
64
63
  }): Promise<SerializedModuleContent>;
@@ -1457,7 +1457,6 @@ class ValServer {
1457
1457
  return ensureRes.error;
1458
1458
  }
1459
1459
  const applyPatches = query.patch === "true";
1460
- const execValidations = query.validate === "true";
1461
1460
  const includeSource = query.source === "true";
1462
1461
  const includeSchema = query.schema === "true";
1463
1462
  const moduleIds = await debugTiming("getAllModules", () => this.getAllModules(treePath));
@@ -1479,8 +1478,9 @@ class ValServer {
1479
1478
  patchesById = res.value.patchesById;
1480
1479
  fileUpdates = res.value.fileUpdates;
1481
1480
  }
1481
+ const validate = false;
1482
1482
  const possiblyPatchedContent = await debugTiming("applyAllPatchesThenValidate", () => Promise.all(moduleIds.map(async moduleId => {
1483
- return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, applyPatches, execValidations, includeSource, includeSchema);
1483
+ return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, applyPatches, validate, includeSource, includeSchema);
1484
1484
  })));
1485
1485
  const modules = Object.fromEntries(possiblyPatchedContent.map(serializedModuleContent => {
1486
1486
  const module = {
@@ -1535,7 +1535,6 @@ class ValServer {
1535
1535
  /* */
1536
1536
  async applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, applyPatches, validate, includeSource, includeSchema) {
1537
1537
  const serializedModuleContent = await this.getModule(moduleId, {
1538
- validate: validate,
1539
1538
  source: includeSource,
1540
1539
  schema: includeSchema
1541
1540
  });
@@ -1602,7 +1601,6 @@ class ValServer {
1602
1601
  errors: false
1603
1602
  };
1604
1603
  }
1605
-
1606
1604
  // TODO: name this better: we need to check for image and file validation errors
1607
1605
  // since they cannot be handled directly inside the validation function.
1608
1606
  // The reason is that validate will be called inside QuickJS (in the future, hopefully),
@@ -1620,8 +1618,9 @@ class ValServer {
1620
1618
  )) {
1621
1619
  const fileRef = getValidationErrorFileRef(error);
1622
1620
  if (fileRef) {
1621
+ var _fileUpdates$fileRef;
1623
1622
  const filePath = path__namespace["default"].join(this.cwd, fileRef);
1624
- let expectedMetadata;
1623
+ let expectedMetadata = await this.getMetadata(fileRef, (_fileUpdates$fileRef = fileUpdates[fileRef]) === null || _fileUpdates$fileRef === void 0 ? void 0 : _fileUpdates$fileRef.sha256);
1625
1624
 
1626
1625
  // if this is a new file or we have an actual FS, we read the file and get the metadata
1627
1626
  if (!expectedMetadata) {
@@ -1803,7 +1802,7 @@ class ValServer {
1803
1802
  const moduleId = moduleIdStr;
1804
1803
  const serializedModuleContent = await this.applyAllPatchesThenValidate(moduleId, filterPatchesByModuleIdRes.data.patches ||
1805
1804
  // TODO: refine to ModuleId and PatchId when parsing
1806
- patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, true, true, true, true);
1805
+ patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, true, true, true, commit);
1807
1806
  if (serializedModuleContent.errors) {
1808
1807
  validationErrorsByModuleId[moduleId] = serializedModuleContent;
1809
1808
  }
@@ -2168,6 +2167,9 @@ class LocalValServer extends ValServer {
2168
2167
  json: res
2169
2168
  };
2170
2169
  }
2170
+ async getMetadata() {
2171
+ return undefined;
2172
+ }
2171
2173
  async getFiles(filePath, query) {
2172
2174
  if (query.sha256) {
2173
2175
  const fileExists = this.host.fileExists(this.getFilePath(filePath, query.sha256));
@@ -2319,7 +2321,10 @@ class LocalValServer extends ValServer {
2319
2321
  return fp.result.ok(undefined);
2320
2322
  }
2321
2323
  getModule(moduleId, options) {
2322
- return this.options.service.get(moduleId, "", options);
2324
+ return this.options.service.get(moduleId, "", {
2325
+ ...options,
2326
+ validate: false
2327
+ });
2323
2328
  }
2324
2329
  async getAllModules(treePath) {
2325
2330
  const moduleIds = this.host.readDirectory(this.cwd, ["ts", "js"], ["node_modules", ".*"], ["**/*.val.ts", "**/*.val.js"]).filter(file => {
@@ -2836,12 +2841,33 @@ class ProxyValServer extends ValServer {
2836
2841
  }
2837
2842
  });
2838
2843
  }
2844
+ async getMetadata(filePath, sha256) {
2845
+ const url = new URL(`/v1/metadata/${this.options.remote}${filePath}?commit=${this.options.git.commit}${sha256 ? `&sha256=${sha256}` : ""}`, this.options.valContentUrl);
2846
+ const fetchRes = await fetch(url, {
2847
+ headers: {
2848
+ Authorization: `Bearer ${this.options.apiKey}`
2849
+ }
2850
+ });
2851
+ if (fetchRes.status === 200) {
2852
+ const json = await fetchRes.json();
2853
+ if (json.type === "file") {
2854
+ return json;
2855
+ } else if (json.type === "image") {
2856
+ return json;
2857
+ }
2858
+ }
2859
+ return undefined;
2860
+ }
2839
2861
  async getFiles(filePath, query, _cookies, reqHeaders) {
2840
2862
  const url = new URL(`/v1/files/${this.options.remote}${filePath}`, this.options.valContentUrl);
2841
2863
  if (typeof query.sha256 === "string") {
2842
2864
  url.searchParams.append("sha256", query.sha256);
2843
2865
  }
2844
- const fetchRes = await fetch(url);
2866
+ const fetchRes = await fetch(url, {
2867
+ headers: {
2868
+ Authorization: `Bearer ${this.options.apiKey}`
2869
+ }
2870
+ });
2845
2871
  if (fetchRes.status === 200) {
2846
2872
  // TODO: does this stream data?
2847
2873
  if (fetchRes.body) {
@@ -1457,7 +1457,6 @@ class ValServer {
1457
1457
  return ensureRes.error;
1458
1458
  }
1459
1459
  const applyPatches = query.patch === "true";
1460
- const execValidations = query.validate === "true";
1461
1460
  const includeSource = query.source === "true";
1462
1461
  const includeSchema = query.schema === "true";
1463
1462
  const moduleIds = await debugTiming("getAllModules", () => this.getAllModules(treePath));
@@ -1479,8 +1478,9 @@ class ValServer {
1479
1478
  patchesById = res.value.patchesById;
1480
1479
  fileUpdates = res.value.fileUpdates;
1481
1480
  }
1481
+ const validate = false;
1482
1482
  const possiblyPatchedContent = await debugTiming("applyAllPatchesThenValidate", () => Promise.all(moduleIds.map(async moduleId => {
1483
- return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, applyPatches, execValidations, includeSource, includeSchema);
1483
+ return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, applyPatches, validate, includeSource, includeSchema);
1484
1484
  })));
1485
1485
  const modules = Object.fromEntries(possiblyPatchedContent.map(serializedModuleContent => {
1486
1486
  const module = {
@@ -1535,7 +1535,6 @@ class ValServer {
1535
1535
  /* */
1536
1536
  async applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, applyPatches, validate, includeSource, includeSchema) {
1537
1537
  const serializedModuleContent = await this.getModule(moduleId, {
1538
- validate: validate,
1539
1538
  source: includeSource,
1540
1539
  schema: includeSchema
1541
1540
  });
@@ -1602,7 +1601,6 @@ class ValServer {
1602
1601
  errors: false
1603
1602
  };
1604
1603
  }
1605
-
1606
1604
  // TODO: name this better: we need to check for image and file validation errors
1607
1605
  // since they cannot be handled directly inside the validation function.
1608
1606
  // The reason is that validate will be called inside QuickJS (in the future, hopefully),
@@ -1620,8 +1618,9 @@ class ValServer {
1620
1618
  )) {
1621
1619
  const fileRef = getValidationErrorFileRef(error);
1622
1620
  if (fileRef) {
1621
+ var _fileUpdates$fileRef;
1623
1622
  const filePath = path__namespace["default"].join(this.cwd, fileRef);
1624
- let expectedMetadata;
1623
+ let expectedMetadata = await this.getMetadata(fileRef, (_fileUpdates$fileRef = fileUpdates[fileRef]) === null || _fileUpdates$fileRef === void 0 ? void 0 : _fileUpdates$fileRef.sha256);
1625
1624
 
1626
1625
  // if this is a new file or we have an actual FS, we read the file and get the metadata
1627
1626
  if (!expectedMetadata) {
@@ -1803,7 +1802,7 @@ class ValServer {
1803
1802
  const moduleId = moduleIdStr;
1804
1803
  const serializedModuleContent = await this.applyAllPatchesThenValidate(moduleId, filterPatchesByModuleIdRes.data.patches ||
1805
1804
  // TODO: refine to ModuleId and PatchId when parsing
1806
- patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, true, true, true, true);
1805
+ patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, true, true, true, commit);
1807
1806
  if (serializedModuleContent.errors) {
1808
1807
  validationErrorsByModuleId[moduleId] = serializedModuleContent;
1809
1808
  }
@@ -2168,6 +2167,9 @@ class LocalValServer extends ValServer {
2168
2167
  json: res
2169
2168
  };
2170
2169
  }
2170
+ async getMetadata() {
2171
+ return undefined;
2172
+ }
2171
2173
  async getFiles(filePath, query) {
2172
2174
  if (query.sha256) {
2173
2175
  const fileExists = this.host.fileExists(this.getFilePath(filePath, query.sha256));
@@ -2319,7 +2321,10 @@ class LocalValServer extends ValServer {
2319
2321
  return fp.result.ok(undefined);
2320
2322
  }
2321
2323
  getModule(moduleId, options) {
2322
- return this.options.service.get(moduleId, "", options);
2324
+ return this.options.service.get(moduleId, "", {
2325
+ ...options,
2326
+ validate: false
2327
+ });
2323
2328
  }
2324
2329
  async getAllModules(treePath) {
2325
2330
  const moduleIds = this.host.readDirectory(this.cwd, ["ts", "js"], ["node_modules", ".*"], ["**/*.val.ts", "**/*.val.js"]).filter(file => {
@@ -2836,12 +2841,33 @@ class ProxyValServer extends ValServer {
2836
2841
  }
2837
2842
  });
2838
2843
  }
2844
+ async getMetadata(filePath, sha256) {
2845
+ const url = new URL(`/v1/metadata/${this.options.remote}${filePath}?commit=${this.options.git.commit}${sha256 ? `&sha256=${sha256}` : ""}`, this.options.valContentUrl);
2846
+ const fetchRes = await fetch(url, {
2847
+ headers: {
2848
+ Authorization: `Bearer ${this.options.apiKey}`
2849
+ }
2850
+ });
2851
+ if (fetchRes.status === 200) {
2852
+ const json = await fetchRes.json();
2853
+ if (json.type === "file") {
2854
+ return json;
2855
+ } else if (json.type === "image") {
2856
+ return json;
2857
+ }
2858
+ }
2859
+ return undefined;
2860
+ }
2839
2861
  async getFiles(filePath, query, _cookies, reqHeaders) {
2840
2862
  const url = new URL(`/v1/files/${this.options.remote}${filePath}`, this.options.valContentUrl);
2841
2863
  if (typeof query.sha256 === "string") {
2842
2864
  url.searchParams.append("sha256", query.sha256);
2843
2865
  }
2844
- const fetchRes = await fetch(url);
2866
+ const fetchRes = await fetch(url, {
2867
+ headers: {
2868
+ Authorization: `Bearer ${this.options.apiKey}`
2869
+ }
2870
+ });
2845
2871
  if (fetchRes.status === 200) {
2846
2872
  // TODO: does this stream data?
2847
2873
  if (fetchRes.body) {
@@ -1427,7 +1427,6 @@ class ValServer {
1427
1427
  return ensureRes.error;
1428
1428
  }
1429
1429
  const applyPatches = query.patch === "true";
1430
- const execValidations = query.validate === "true";
1431
1430
  const includeSource = query.source === "true";
1432
1431
  const includeSchema = query.schema === "true";
1433
1432
  const moduleIds = await debugTiming("getAllModules", () => this.getAllModules(treePath));
@@ -1449,8 +1448,9 @@ class ValServer {
1449
1448
  patchesById = res.value.patchesById;
1450
1449
  fileUpdates = res.value.fileUpdates;
1451
1450
  }
1451
+ const validate = false;
1452
1452
  const possiblyPatchedContent = await debugTiming("applyAllPatchesThenValidate", () => Promise.all(moduleIds.map(async moduleId => {
1453
- return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, applyPatches, execValidations, includeSource, includeSchema);
1453
+ return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, applyPatches, validate, includeSource, includeSchema);
1454
1454
  })));
1455
1455
  const modules = Object.fromEntries(possiblyPatchedContent.map(serializedModuleContent => {
1456
1456
  const module = {
@@ -1505,7 +1505,6 @@ class ValServer {
1505
1505
  /* */
1506
1506
  async applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, applyPatches, validate, includeSource, includeSchema) {
1507
1507
  const serializedModuleContent = await this.getModule(moduleId, {
1508
- validate: validate,
1509
1508
  source: includeSource,
1510
1509
  schema: includeSchema
1511
1510
  });
@@ -1572,7 +1571,6 @@ class ValServer {
1572
1571
  errors: false
1573
1572
  };
1574
1573
  }
1575
-
1576
1574
  // TODO: name this better: we need to check for image and file validation errors
1577
1575
  // since they cannot be handled directly inside the validation function.
1578
1576
  // The reason is that validate will be called inside QuickJS (in the future, hopefully),
@@ -1590,8 +1588,9 @@ class ValServer {
1590
1588
  )) {
1591
1589
  const fileRef = getValidationErrorFileRef(error);
1592
1590
  if (fileRef) {
1591
+ var _fileUpdates$fileRef;
1593
1592
  const filePath = path__default.join(this.cwd, fileRef);
1594
- let expectedMetadata;
1593
+ let expectedMetadata = await this.getMetadata(fileRef, (_fileUpdates$fileRef = fileUpdates[fileRef]) === null || _fileUpdates$fileRef === void 0 ? void 0 : _fileUpdates$fileRef.sha256);
1595
1594
 
1596
1595
  // if this is a new file or we have an actual FS, we read the file and get the metadata
1597
1596
  if (!expectedMetadata) {
@@ -1773,7 +1772,7 @@ class ValServer {
1773
1772
  const moduleId = moduleIdStr;
1774
1773
  const serializedModuleContent = await this.applyAllPatchesThenValidate(moduleId, filterPatchesByModuleIdRes.data.patches ||
1775
1774
  // TODO: refine to ModuleId and PatchId when parsing
1776
- patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, true, true, true, true);
1775
+ patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, true, true, true, commit);
1777
1776
  if (serializedModuleContent.errors) {
1778
1777
  validationErrorsByModuleId[moduleId] = serializedModuleContent;
1779
1778
  }
@@ -2138,6 +2137,9 @@ class LocalValServer extends ValServer {
2138
2137
  json: res
2139
2138
  };
2140
2139
  }
2140
+ async getMetadata() {
2141
+ return undefined;
2142
+ }
2141
2143
  async getFiles(filePath, query) {
2142
2144
  if (query.sha256) {
2143
2145
  const fileExists = this.host.fileExists(this.getFilePath(filePath, query.sha256));
@@ -2289,7 +2291,10 @@ class LocalValServer extends ValServer {
2289
2291
  return result.ok(undefined);
2290
2292
  }
2291
2293
  getModule(moduleId, options) {
2292
- return this.options.service.get(moduleId, "", options);
2294
+ return this.options.service.get(moduleId, "", {
2295
+ ...options,
2296
+ validate: false
2297
+ });
2293
2298
  }
2294
2299
  async getAllModules(treePath) {
2295
2300
  const moduleIds = this.host.readDirectory(this.cwd, ["ts", "js"], ["node_modules", ".*"], ["**/*.val.ts", "**/*.val.js"]).filter(file => {
@@ -2806,12 +2811,33 @@ class ProxyValServer extends ValServer {
2806
2811
  }
2807
2812
  });
2808
2813
  }
2814
+ async getMetadata(filePath, sha256) {
2815
+ const url = new URL(`/v1/metadata/${this.options.remote}${filePath}?commit=${this.options.git.commit}${sha256 ? `&sha256=${sha256}` : ""}`, this.options.valContentUrl);
2816
+ const fetchRes = await fetch(url, {
2817
+ headers: {
2818
+ Authorization: `Bearer ${this.options.apiKey}`
2819
+ }
2820
+ });
2821
+ if (fetchRes.status === 200) {
2822
+ const json = await fetchRes.json();
2823
+ if (json.type === "file") {
2824
+ return json;
2825
+ } else if (json.type === "image") {
2826
+ return json;
2827
+ }
2828
+ }
2829
+ return undefined;
2830
+ }
2809
2831
  async getFiles(filePath, query, _cookies, reqHeaders) {
2810
2832
  const url = new URL(`/v1/files/${this.options.remote}${filePath}`, this.options.valContentUrl);
2811
2833
  if (typeof query.sha256 === "string") {
2812
2834
  url.searchParams.append("sha256", query.sha256);
2813
2835
  }
2814
- const fetchRes = await fetch(url);
2836
+ const fetchRes = await fetch(url, {
2837
+ headers: {
2838
+ Authorization: `Bearer ${this.options.apiKey}`
2839
+ }
2840
+ });
2815
2841
  if (fetchRes.status === 200) {
2816
2842
  // TODO: does this stream data?
2817
2843
  if (fetchRes.body) {
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.23",
15
+ "version": "0.60.24",
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.23",
28
- "@valbuild/shared": "~0.60.23",
29
- "@valbuild/ui": "~0.60.23",
27
+ "@valbuild/core": "~0.60.24",
28
+ "@valbuild/shared": "~0.60.24",
29
+ "@valbuild/ui": "~0.60.24",
30
30
  "express": "^4.18.2",
31
31
  "image-size": "^1.0.2",
32
32
  "minimatch": "^3.0.4",