@valbuild/server 0.88.0 → 0.89.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.
@@ -1849,6 +1849,52 @@ class ValOps {
1849
1849
  message: `Key '${key}' does not exist in ${sourcePath}.`
1850
1850
  };
1851
1851
  };
1852
+ const checkRouteIsValid = async (route, includePattern, excludePattern) => {
1853
+ // Find all router modules (record schemas with router property)
1854
+ const routerModules = [];
1855
+ for (const [moduleFilePath, schema] of Object.entries(schemas)) {
1856
+ const serializedSchema = schema["executeSerialize"]();
1857
+ if (serializedSchema.type === "record" && serializedSchema.router) {
1858
+ const source = sources[moduleFilePath];
1859
+ if (source && typeof source === "object") {
1860
+ routerModules.push({
1861
+ path: moduleFilePath,
1862
+ routes: Object.keys(source)
1863
+ });
1864
+ }
1865
+ }
1866
+ }
1867
+ if (routerModules.length === 0) {
1868
+ return {
1869
+ error: true,
1870
+ message: `No router modules found. Route validation requires at least one s.record().router() module.`
1871
+ };
1872
+ }
1873
+
1874
+ // Check if route exists in any router module
1875
+ const allRoutes = routerModules.flatMap(m => m.routes);
1876
+ const routeExists = allRoutes.includes(route);
1877
+ if (!routeExists) {
1878
+ // Filter routes by include/exclude patterns for suggestions
1879
+ const validRoutes = internal.filterRoutesByPatterns(allRoutes, includePattern, excludePattern);
1880
+ return {
1881
+ error: true,
1882
+ message: `Route '${route}' does not exist in any router module. Available routes: ${validRoutes.slice(0, 10).join(", ")}${validRoutes.length > 10 ? "..." : ""}`
1883
+ };
1884
+ }
1885
+
1886
+ // Validate against include/exclude patterns
1887
+ const patternValidation = internal.validateRoutePatterns(route, includePattern, excludePattern);
1888
+ if (!patternValidation.valid) {
1889
+ return {
1890
+ error: true,
1891
+ message: patternValidation.message
1892
+ };
1893
+ }
1894
+ return {
1895
+ error: false
1896
+ };
1897
+ };
1852
1898
  const errors = {};
1853
1899
  const files = {};
1854
1900
  const remoteFiles = {};
@@ -1893,7 +1939,7 @@ class ValOps {
1893
1939
  };
1894
1940
  if (validationErrors) {
1895
1941
  for (const validationError of validationErrors) {
1896
- var _validationError$fixe, _validationError$fixe2, _validationError$fixe3;
1942
+ var _validationError$fixe, _validationError$fixe2, _validationError$fixe3, _validationError$fixe4;
1897
1943
  if (isOnlyFileCheckValidationError(validationError)) {
1898
1944
  if (files[sourcePath]) {
1899
1945
  throw new Error("Cannot have multiple files with same path. Path: " + sourcePath + "; Module: " + path);
@@ -1944,6 +1990,38 @@ class ValOps {
1944
1990
  }
1945
1991
  }
1946
1992
  }
1993
+ } else if ((_validationError$fixe4 = validationError.fixes) !== null && _validationError$fixe4 !== void 0 && _validationError$fixe4.includes("router:check-route")) {
1994
+ const TYPE_ERROR_MESSAGE = `This is most likely a Val version mismatch or Val bug.`;
1995
+ if (!validationError.value) {
1996
+ addError({
1997
+ message: `Could not find a value for route at ${sourcePath}. ${TYPE_ERROR_MESSAGE}`,
1998
+ typeError: true
1999
+ });
2000
+ } else {
2001
+ if (typeof validationError.value !== "object") {
2002
+ addError({
2003
+ message: `Expected route validation error to have a 'value' property of type 'object'. Found: ${typeof validationError.value}. ${TYPE_ERROR_MESSAGE}`,
2004
+ typeError: true
2005
+ });
2006
+ } else {
2007
+ const route = "route" in validationError.value && validationError.value.route;
2008
+ const includePattern = "include" in validationError.value && validationError.value.include;
2009
+ const excludePattern = "exclude" in validationError.value && validationError.value.exclude;
2010
+ if (typeof route !== "string") {
2011
+ addError({
2012
+ message: `Expected route validation error 'value' to have property 'route' of type 'string'. Found: ${typeof route}. ${TYPE_ERROR_MESSAGE}`,
2013
+ typeError: true
2014
+ });
2015
+ } else {
2016
+ const res = await checkRouteIsValid(route, includePattern && typeof includePattern === "object" && "source" in includePattern && "flags" in includePattern ? includePattern : undefined, excludePattern && typeof excludePattern === "object" && "source" in excludePattern && "flags" in excludePattern ? excludePattern : undefined);
2017
+ if (res.error) {
2018
+ addError({
2019
+ message: res.message
2020
+ });
2021
+ }
2022
+ }
2023
+ }
2024
+ }
1947
2025
  } else {
1948
2026
  addError(validationError);
1949
2027
  }
@@ -2279,8 +2357,8 @@ class ValOps {
2279
2357
  // #region abstract ops
2280
2358
  }
2281
2359
  function isOnlyFileCheckValidationError(validationError) {
2282
- var _validationError$fixe4;
2283
- if ((_validationError$fixe4 = validationError.fixes) !== null && _validationError$fixe4 !== void 0 && _validationError$fixe4.every(f => f === "file:check-metadata" || f === "image:check-metadata")) {
2360
+ var _validationError$fixe5;
2361
+ if ((_validationError$fixe5 = validationError.fixes) !== null && _validationError$fixe5 !== void 0 && _validationError$fixe5.every(f => f === "file:check-metadata" || f === "image:check-metadata")) {
2284
2362
  return true;
2285
2363
  }
2286
2364
  return false;
@@ -4523,7 +4601,7 @@ function hasRemoteFileSchema(schema) {
4523
4601
  }
4524
4602
  }
4525
4603
  return false;
4526
- } else if (schema.type === "boolean" || schema.type === "number" || schema.type === "string" || schema.type === "literal" || schema.type === "date" || schema.type === "keyOf") {
4604
+ } else if (schema.type === "boolean" || schema.type === "number" || schema.type === "string" || schema.type === "literal" || schema.type === "date" || schema.type === "keyOf" || schema.type === "route") {
4527
4605
  return false;
4528
4606
  } else {
4529
4607
  const exhaustiveCheck = schema;
@@ -1849,6 +1849,52 @@ class ValOps {
1849
1849
  message: `Key '${key}' does not exist in ${sourcePath}.`
1850
1850
  };
1851
1851
  };
1852
+ const checkRouteIsValid = async (route, includePattern, excludePattern) => {
1853
+ // Find all router modules (record schemas with router property)
1854
+ const routerModules = [];
1855
+ for (const [moduleFilePath, schema] of Object.entries(schemas)) {
1856
+ const serializedSchema = schema["executeSerialize"]();
1857
+ if (serializedSchema.type === "record" && serializedSchema.router) {
1858
+ const source = sources[moduleFilePath];
1859
+ if (source && typeof source === "object") {
1860
+ routerModules.push({
1861
+ path: moduleFilePath,
1862
+ routes: Object.keys(source)
1863
+ });
1864
+ }
1865
+ }
1866
+ }
1867
+ if (routerModules.length === 0) {
1868
+ return {
1869
+ error: true,
1870
+ message: `No router modules found. Route validation requires at least one s.record().router() module.`
1871
+ };
1872
+ }
1873
+
1874
+ // Check if route exists in any router module
1875
+ const allRoutes = routerModules.flatMap(m => m.routes);
1876
+ const routeExists = allRoutes.includes(route);
1877
+ if (!routeExists) {
1878
+ // Filter routes by include/exclude patterns for suggestions
1879
+ const validRoutes = internal.filterRoutesByPatterns(allRoutes, includePattern, excludePattern);
1880
+ return {
1881
+ error: true,
1882
+ message: `Route '${route}' does not exist in any router module. Available routes: ${validRoutes.slice(0, 10).join(", ")}${validRoutes.length > 10 ? "..." : ""}`
1883
+ };
1884
+ }
1885
+
1886
+ // Validate against include/exclude patterns
1887
+ const patternValidation = internal.validateRoutePatterns(route, includePattern, excludePattern);
1888
+ if (!patternValidation.valid) {
1889
+ return {
1890
+ error: true,
1891
+ message: patternValidation.message
1892
+ };
1893
+ }
1894
+ return {
1895
+ error: false
1896
+ };
1897
+ };
1852
1898
  const errors = {};
1853
1899
  const files = {};
1854
1900
  const remoteFiles = {};
@@ -1893,7 +1939,7 @@ class ValOps {
1893
1939
  };
1894
1940
  if (validationErrors) {
1895
1941
  for (const validationError of validationErrors) {
1896
- var _validationError$fixe, _validationError$fixe2, _validationError$fixe3;
1942
+ var _validationError$fixe, _validationError$fixe2, _validationError$fixe3, _validationError$fixe4;
1897
1943
  if (isOnlyFileCheckValidationError(validationError)) {
1898
1944
  if (files[sourcePath]) {
1899
1945
  throw new Error("Cannot have multiple files with same path. Path: " + sourcePath + "; Module: " + path);
@@ -1944,6 +1990,38 @@ class ValOps {
1944
1990
  }
1945
1991
  }
1946
1992
  }
1993
+ } else if ((_validationError$fixe4 = validationError.fixes) !== null && _validationError$fixe4 !== void 0 && _validationError$fixe4.includes("router:check-route")) {
1994
+ const TYPE_ERROR_MESSAGE = `This is most likely a Val version mismatch or Val bug.`;
1995
+ if (!validationError.value) {
1996
+ addError({
1997
+ message: `Could not find a value for route at ${sourcePath}. ${TYPE_ERROR_MESSAGE}`,
1998
+ typeError: true
1999
+ });
2000
+ } else {
2001
+ if (typeof validationError.value !== "object") {
2002
+ addError({
2003
+ message: `Expected route validation error to have a 'value' property of type 'object'. Found: ${typeof validationError.value}. ${TYPE_ERROR_MESSAGE}`,
2004
+ typeError: true
2005
+ });
2006
+ } else {
2007
+ const route = "route" in validationError.value && validationError.value.route;
2008
+ const includePattern = "include" in validationError.value && validationError.value.include;
2009
+ const excludePattern = "exclude" in validationError.value && validationError.value.exclude;
2010
+ if (typeof route !== "string") {
2011
+ addError({
2012
+ message: `Expected route validation error 'value' to have property 'route' of type 'string'. Found: ${typeof route}. ${TYPE_ERROR_MESSAGE}`,
2013
+ typeError: true
2014
+ });
2015
+ } else {
2016
+ const res = await checkRouteIsValid(route, includePattern && typeof includePattern === "object" && "source" in includePattern && "flags" in includePattern ? includePattern : undefined, excludePattern && typeof excludePattern === "object" && "source" in excludePattern && "flags" in excludePattern ? excludePattern : undefined);
2017
+ if (res.error) {
2018
+ addError({
2019
+ message: res.message
2020
+ });
2021
+ }
2022
+ }
2023
+ }
2024
+ }
1947
2025
  } else {
1948
2026
  addError(validationError);
1949
2027
  }
@@ -2279,8 +2357,8 @@ class ValOps {
2279
2357
  // #region abstract ops
2280
2358
  }
2281
2359
  function isOnlyFileCheckValidationError(validationError) {
2282
- var _validationError$fixe4;
2283
- if ((_validationError$fixe4 = validationError.fixes) !== null && _validationError$fixe4 !== void 0 && _validationError$fixe4.every(f => f === "file:check-metadata" || f === "image:check-metadata")) {
2360
+ var _validationError$fixe5;
2361
+ if ((_validationError$fixe5 = validationError.fixes) !== null && _validationError$fixe5 !== void 0 && _validationError$fixe5.every(f => f === "file:check-metadata" || f === "image:check-metadata")) {
2284
2362
  return true;
2285
2363
  }
2286
2364
  return false;
@@ -4523,7 +4601,7 @@ function hasRemoteFileSchema(schema) {
4523
4601
  }
4524
4602
  }
4525
4603
  return false;
4526
- } else if (schema.type === "boolean" || schema.type === "number" || schema.type === "string" || schema.type === "literal" || schema.type === "date" || schema.type === "keyOf") {
4604
+ } else if (schema.type === "boolean" || schema.type === "number" || schema.type === "string" || schema.type === "literal" || schema.type === "date" || schema.type === "keyOf" || schema.type === "route") {
4527
4605
  return false;
4528
4606
  } else {
4529
4607
  const exhaustiveCheck = schema;
@@ -8,7 +8,7 @@ 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 { Patch, ParentRef, VAL_ENABLE_COOKIE_NAME, VAL_STATE_COOKIE, VAL_SESSION_COOKIE, Api } from '@valbuild/shared/internal';
11
+ import { filterRoutesByPatterns, validateRoutePatterns, 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';
@@ -1818,6 +1818,52 @@ class ValOps {
1818
1818
  message: `Key '${key}' does not exist in ${sourcePath}.`
1819
1819
  };
1820
1820
  };
1821
+ const checkRouteIsValid = async (route, includePattern, excludePattern) => {
1822
+ // Find all router modules (record schemas with router property)
1823
+ const routerModules = [];
1824
+ for (const [moduleFilePath, schema] of Object.entries(schemas)) {
1825
+ const serializedSchema = schema["executeSerialize"]();
1826
+ if (serializedSchema.type === "record" && serializedSchema.router) {
1827
+ const source = sources[moduleFilePath];
1828
+ if (source && typeof source === "object") {
1829
+ routerModules.push({
1830
+ path: moduleFilePath,
1831
+ routes: Object.keys(source)
1832
+ });
1833
+ }
1834
+ }
1835
+ }
1836
+ if (routerModules.length === 0) {
1837
+ return {
1838
+ error: true,
1839
+ message: `No router modules found. Route validation requires at least one s.record().router() module.`
1840
+ };
1841
+ }
1842
+
1843
+ // Check if route exists in any router module
1844
+ const allRoutes = routerModules.flatMap(m => m.routes);
1845
+ const routeExists = allRoutes.includes(route);
1846
+ if (!routeExists) {
1847
+ // Filter routes by include/exclude patterns for suggestions
1848
+ const validRoutes = filterRoutesByPatterns(allRoutes, includePattern, excludePattern);
1849
+ return {
1850
+ error: true,
1851
+ message: `Route '${route}' does not exist in any router module. Available routes: ${validRoutes.slice(0, 10).join(", ")}${validRoutes.length > 10 ? "..." : ""}`
1852
+ };
1853
+ }
1854
+
1855
+ // Validate against include/exclude patterns
1856
+ const patternValidation = validateRoutePatterns(route, includePattern, excludePattern);
1857
+ if (!patternValidation.valid) {
1858
+ return {
1859
+ error: true,
1860
+ message: patternValidation.message
1861
+ };
1862
+ }
1863
+ return {
1864
+ error: false
1865
+ };
1866
+ };
1821
1867
  const errors = {};
1822
1868
  const files = {};
1823
1869
  const remoteFiles = {};
@@ -1862,7 +1908,7 @@ class ValOps {
1862
1908
  };
1863
1909
  if (validationErrors) {
1864
1910
  for (const validationError of validationErrors) {
1865
- var _validationError$fixe, _validationError$fixe2, _validationError$fixe3;
1911
+ var _validationError$fixe, _validationError$fixe2, _validationError$fixe3, _validationError$fixe4;
1866
1912
  if (isOnlyFileCheckValidationError(validationError)) {
1867
1913
  if (files[sourcePath]) {
1868
1914
  throw new Error("Cannot have multiple files with same path. Path: " + sourcePath + "; Module: " + path);
@@ -1913,6 +1959,38 @@ class ValOps {
1913
1959
  }
1914
1960
  }
1915
1961
  }
1962
+ } else if ((_validationError$fixe4 = validationError.fixes) !== null && _validationError$fixe4 !== void 0 && _validationError$fixe4.includes("router:check-route")) {
1963
+ const TYPE_ERROR_MESSAGE = `This is most likely a Val version mismatch or Val bug.`;
1964
+ if (!validationError.value) {
1965
+ addError({
1966
+ message: `Could not find a value for route at ${sourcePath}. ${TYPE_ERROR_MESSAGE}`,
1967
+ typeError: true
1968
+ });
1969
+ } else {
1970
+ if (typeof validationError.value !== "object") {
1971
+ addError({
1972
+ message: `Expected route validation error to have a 'value' property of type 'object'. Found: ${typeof validationError.value}. ${TYPE_ERROR_MESSAGE}`,
1973
+ typeError: true
1974
+ });
1975
+ } else {
1976
+ const route = "route" in validationError.value && validationError.value.route;
1977
+ const includePattern = "include" in validationError.value && validationError.value.include;
1978
+ const excludePattern = "exclude" in validationError.value && validationError.value.exclude;
1979
+ if (typeof route !== "string") {
1980
+ addError({
1981
+ message: `Expected route validation error 'value' to have property 'route' of type 'string'. Found: ${typeof route}. ${TYPE_ERROR_MESSAGE}`,
1982
+ typeError: true
1983
+ });
1984
+ } else {
1985
+ const res = await checkRouteIsValid(route, includePattern && typeof includePattern === "object" && "source" in includePattern && "flags" in includePattern ? includePattern : undefined, excludePattern && typeof excludePattern === "object" && "source" in excludePattern && "flags" in excludePattern ? excludePattern : undefined);
1986
+ if (res.error) {
1987
+ addError({
1988
+ message: res.message
1989
+ });
1990
+ }
1991
+ }
1992
+ }
1993
+ }
1916
1994
  } else {
1917
1995
  addError(validationError);
1918
1996
  }
@@ -2248,8 +2326,8 @@ class ValOps {
2248
2326
  // #region abstract ops
2249
2327
  }
2250
2328
  function isOnlyFileCheckValidationError(validationError) {
2251
- var _validationError$fixe4;
2252
- if ((_validationError$fixe4 = validationError.fixes) !== null && _validationError$fixe4 !== void 0 && _validationError$fixe4.every(f => f === "file:check-metadata" || f === "image:check-metadata")) {
2329
+ var _validationError$fixe5;
2330
+ if ((_validationError$fixe5 = validationError.fixes) !== null && _validationError$fixe5 !== void 0 && _validationError$fixe5.every(f => f === "file:check-metadata" || f === "image:check-metadata")) {
2253
2331
  return true;
2254
2332
  }
2255
2333
  return false;
@@ -4492,7 +4570,7 @@ function hasRemoteFileSchema(schema) {
4492
4570
  }
4493
4571
  }
4494
4572
  return false;
4495
- } else if (schema.type === "boolean" || schema.type === "number" || schema.type === "string" || schema.type === "literal" || schema.type === "date" || schema.type === "keyOf") {
4573
+ } else if (schema.type === "boolean" || schema.type === "number" || schema.type === "string" || schema.type === "literal" || schema.type === "date" || schema.type === "keyOf" || schema.type === "route") {
4496
4574
  return false;
4497
4575
  } else {
4498
4576
  const exhaustiveCheck = schema;
package/package.json CHANGED
@@ -16,7 +16,7 @@
16
16
  "./package.json": "./package.json"
17
17
  },
18
18
  "types": "dist/valbuild-server.cjs.d.ts",
19
- "version": "0.88.0",
19
+ "version": "0.89.0",
20
20
  "scripts": {
21
21
  "typecheck": "tsc --noEmit",
22
22
  "test": "jest",
@@ -27,9 +27,9 @@
27
27
  "@types/jest": "^29.2.5"
28
28
  },
29
29
  "dependencies": {
30
- "@valbuild/core": "~0.88.0",
31
- "@valbuild/shared": "~0.88.0",
32
- "@valbuild/ui": "~0.88.0",
30
+ "@valbuild/core": "~0.89.0",
31
+ "@valbuild/shared": "~0.89.0",
32
+ "@valbuild/ui": "~0.89.0",
33
33
  "chokidar": "^4.0.1",
34
34
  "image-size": "^1.0.2",
35
35
  "minimatch": "^3.0.4",