@rebasepro/server-core 0.0.1-canary.eae7889 → 0.1.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.
Files changed (132) hide show
  1. package/app/frontend/node_modules/esbuild/LICENSE.md +21 -0
  2. package/app/frontend/node_modules/esbuild/README.md +3 -0
  3. package/app/frontend/node_modules/esbuild/bin/esbuild +220 -0
  4. package/app/frontend/node_modules/esbuild/install.js +285 -0
  5. package/app/frontend/node_modules/esbuild/lib/main.d.ts +705 -0
  6. package/app/frontend/node_modules/esbuild/lib/main.js +2239 -0
  7. package/app/frontend/node_modules/esbuild/package.json +46 -0
  8. package/dist/index.es.js +1186 -1673
  9. package/dist/index.es.js.map +1 -1
  10. package/dist/index.umd.js +1185 -1672
  11. package/dist/index.umd.js.map +1 -1
  12. package/dist/server-core/src/api/rest/api-generator.d.ts +15 -3
  13. package/dist/server-core/src/auth/admin-routes.d.ts +5 -0
  14. package/dist/server-core/src/auth/google-oauth.d.ts +36 -3
  15. package/dist/server-core/src/auth/index.d.ts +1 -0
  16. package/dist/server-core/src/cron/cron-scheduler.d.ts +45 -0
  17. package/dist/server-core/src/cron/index.d.ts +1 -1
  18. package/dist/server-core/src/init.d.ts +11 -1
  19. package/dist/types/src/controllers/auth.d.ts +8 -2
  20. package/dist/types/src/controllers/client.d.ts +13 -0
  21. package/dist/types/src/controllers/collection_registry.d.ts +2 -1
  22. package/dist/types/src/controllers/data_driver.d.ts +36 -1
  23. package/dist/types/src/controllers/navigation.d.ts +18 -6
  24. package/dist/types/src/controllers/registry.d.ts +9 -1
  25. package/dist/types/src/controllers/side_entity_controller.d.ts +7 -0
  26. package/dist/types/src/rebase_context.d.ts +17 -0
  27. package/dist/types/src/types/backend_hooks.d.ts +187 -0
  28. package/dist/types/src/types/collections.d.ts +31 -11
  29. package/dist/types/src/types/component_ref.d.ts +47 -0
  30. package/dist/types/src/types/cron.d.ts +1 -1
  31. package/dist/types/src/types/entity_views.d.ts +6 -7
  32. package/dist/types/src/types/formex.d.ts +40 -0
  33. package/dist/types/src/types/index.d.ts +3 -0
  34. package/dist/types/src/types/plugins.d.ts +6 -3
  35. package/dist/types/src/types/properties.d.ts +72 -88
  36. package/dist/types/src/types/slots.d.ts +20 -10
  37. package/dist/types/src/types/translations.d.ts +6 -0
  38. package/examples/firebase/node_modules/esbuild/LICENSE.md +21 -0
  39. package/examples/firebase/node_modules/esbuild/README.md +3 -0
  40. package/examples/firebase/node_modules/esbuild/bin/esbuild +220 -0
  41. package/examples/firebase/node_modules/esbuild/install.js +285 -0
  42. package/examples/firebase/node_modules/esbuild/lib/main.d.ts +705 -0
  43. package/examples/firebase/node_modules/esbuild/lib/main.js +2239 -0
  44. package/examples/firebase/node_modules/esbuild/package.json +46 -0
  45. package/examples/medmot-staging/frontend/node_modules/esbuild/LICENSE.md +21 -0
  46. package/examples/medmot-staging/frontend/node_modules/esbuild/README.md +3 -0
  47. package/examples/medmot-staging/frontend/node_modules/esbuild/bin/esbuild +220 -0
  48. package/examples/medmot-staging/frontend/node_modules/esbuild/install.js +285 -0
  49. package/examples/medmot-staging/frontend/node_modules/esbuild/lib/main.d.ts +705 -0
  50. package/examples/medmot-staging/frontend/node_modules/esbuild/lib/main.js +2239 -0
  51. package/examples/medmot-staging/frontend/node_modules/esbuild/package.json +46 -0
  52. package/examples/sdk-demo/node_modules/esbuild/LICENSE.md +21 -0
  53. package/examples/sdk-demo/node_modules/esbuild/README.md +3 -0
  54. package/examples/sdk-demo/node_modules/esbuild/bin/esbuild +223 -0
  55. package/examples/sdk-demo/node_modules/esbuild/install.js +289 -0
  56. package/examples/sdk-demo/node_modules/esbuild/lib/main.d.ts +716 -0
  57. package/examples/sdk-demo/node_modules/esbuild/lib/main.js +2242 -0
  58. package/examples/sdk-demo/node_modules/esbuild/package.json +49 -0
  59. package/package.json +9 -9
  60. package/packages/client/node_modules/esbuild/LICENSE.md +21 -0
  61. package/packages/client/node_modules/esbuild/README.md +3 -0
  62. package/packages/client/node_modules/esbuild/bin/esbuild +220 -0
  63. package/packages/client/node_modules/esbuild/install.js +285 -0
  64. package/packages/client/node_modules/esbuild/lib/main.d.ts +705 -0
  65. package/packages/client/node_modules/esbuild/lib/main.js +2239 -0
  66. package/packages/client/node_modules/esbuild/package.json +46 -0
  67. package/packages/client-postgresql/node_modules/esbuild/LICENSE.md +21 -0
  68. package/packages/client-postgresql/node_modules/esbuild/README.md +3 -0
  69. package/packages/client-postgresql/node_modules/esbuild/bin/esbuild +220 -0
  70. package/packages/client-postgresql/node_modules/esbuild/install.js +285 -0
  71. package/packages/client-postgresql/node_modules/esbuild/lib/main.d.ts +705 -0
  72. package/packages/client-postgresql/node_modules/esbuild/lib/main.js +2239 -0
  73. package/packages/client-postgresql/node_modules/esbuild/package.json +46 -0
  74. package/packages/common/node_modules/esbuild/LICENSE.md +21 -0
  75. package/packages/common/node_modules/esbuild/README.md +3 -0
  76. package/packages/common/node_modules/esbuild/bin/esbuild +220 -0
  77. package/packages/common/node_modules/esbuild/install.js +285 -0
  78. package/packages/common/node_modules/esbuild/lib/main.d.ts +705 -0
  79. package/packages/common/node_modules/esbuild/lib/main.js +2239 -0
  80. package/packages/common/node_modules/esbuild/package.json +46 -0
  81. package/packages/server-mongodb/node_modules/esbuild/LICENSE.md +21 -0
  82. package/packages/server-mongodb/node_modules/esbuild/README.md +3 -0
  83. package/packages/server-mongodb/node_modules/esbuild/bin/esbuild +220 -0
  84. package/packages/server-mongodb/node_modules/esbuild/install.js +285 -0
  85. package/packages/server-mongodb/node_modules/esbuild/lib/main.d.ts +705 -0
  86. package/packages/server-mongodb/node_modules/esbuild/lib/main.js +2239 -0
  87. package/packages/server-mongodb/node_modules/esbuild/package.json +46 -0
  88. package/packages/server-postgresql/node_modules/esbuild/LICENSE.md +21 -0
  89. package/packages/server-postgresql/node_modules/esbuild/README.md +3 -0
  90. package/packages/server-postgresql/node_modules/esbuild/bin/esbuild +220 -0
  91. package/packages/server-postgresql/node_modules/esbuild/install.js +285 -0
  92. package/packages/server-postgresql/node_modules/esbuild/lib/main.d.ts +705 -0
  93. package/packages/server-postgresql/node_modules/esbuild/lib/main.js +2239 -0
  94. package/packages/server-postgresql/node_modules/esbuild/package.json +46 -0
  95. package/packages/types/node_modules/esbuild/LICENSE.md +21 -0
  96. package/packages/types/node_modules/esbuild/README.md +3 -0
  97. package/packages/types/node_modules/esbuild/bin/esbuild +220 -0
  98. package/packages/types/node_modules/esbuild/install.js +285 -0
  99. package/packages/types/node_modules/esbuild/lib/main.d.ts +705 -0
  100. package/packages/types/node_modules/esbuild/lib/main.js +2239 -0
  101. package/packages/types/node_modules/esbuild/package.json +46 -0
  102. package/packages/utils/node_modules/esbuild/LICENSE.md +21 -0
  103. package/packages/utils/node_modules/esbuild/README.md +3 -0
  104. package/packages/utils/node_modules/esbuild/bin/esbuild +220 -0
  105. package/packages/utils/node_modules/esbuild/install.js +285 -0
  106. package/packages/utils/node_modules/esbuild/lib/main.d.ts +705 -0
  107. package/packages/utils/node_modules/esbuild/lib/main.js +2239 -0
  108. package/packages/utils/node_modules/esbuild/package.json +46 -0
  109. package/src/api/errors.ts +3 -2
  110. package/src/api/rest/api-generator-count.test.ts +113 -0
  111. package/src/api/rest/api-generator.ts +123 -22
  112. package/src/api/server.ts +8 -4
  113. package/src/auth/admin-routes.ts +133 -57
  114. package/src/auth/apple-oauth.ts +8 -18
  115. package/src/auth/google-oauth.ts +192 -22
  116. package/src/auth/index.ts +1 -0
  117. package/src/auth/rate-limiter.ts +9 -5
  118. package/src/auth/routes.ts +25 -5
  119. package/src/collections/loader.ts +3 -3
  120. package/src/cron/cron-scheduler.test.ts +301 -175
  121. package/src/cron/cron-scheduler.ts +220 -57
  122. package/src/cron/index.ts +1 -1
  123. package/src/init.ts +27 -5
  124. package/src/storage/LocalStorageController.ts +37 -13
  125. package/src/storage/S3StorageController.ts +4 -1
  126. package/src/storage/routes.ts +51 -5
  127. package/test/backend-hooks-admin.test.ts +394 -0
  128. package/test/backend-hooks-data.test.ts +408 -0
  129. package/history_diff.log +0 -385
  130. package/scratch.ts +0 -9
  131. package/test-ast.ts +0 -28
  132. package/test_output.txt +0 -1133
package/dist/index.umd.js CHANGED
@@ -1011,13 +1011,14 @@
1011
1011
  }, { buffer: 3, lYpoI2: 11 }] }, {}, [1])(1);
1012
1012
  });
1013
1013
  })(object_hash);
1014
- const snakeCaseRegex = /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g;
1014
+ const tokenizeRegex = /[A-Z]{2,}(?=[A-Z][a-z]|\b)|[A-Z]?[a-z]+|[0-9]+(?:[a-z](?![a-z]))?|[A-Z]/g;
1015
+ const snakeCaseRegex = tokenizeRegex;
1015
1016
  const toSnakeCase = (str) => {
1016
1017
  const regExpMatchArray = str.match(snakeCaseRegex);
1017
1018
  if (!regExpMatchArray) return "";
1018
1019
  return regExpMatchArray.map((x) => x.toLowerCase()).join("_");
1019
1020
  };
1020
- function isObject$b(item) {
1021
+ function isObject$a(item) {
1021
1022
  return !!item && typeof item === "object" && !Array.isArray(item);
1022
1023
  }
1023
1024
  function isPlainObject$3(obj) {
@@ -1028,13 +1029,13 @@
1028
1029
  return proto === Object.prototype;
1029
1030
  }
1030
1031
  function mergeDeep(target, source, ignoreUndefined = false) {
1031
- if (!isObject$b(target)) {
1032
+ if (!isObject$a(target)) {
1032
1033
  return target;
1033
1034
  }
1034
1035
  const output = {
1035
1036
  ...target
1036
1037
  };
1037
- if (!isObject$b(source)) {
1038
+ if (!isObject$a(source)) {
1038
1039
  return output;
1039
1040
  }
1040
1041
  for (const key in source) {
@@ -1075,7 +1076,7 @@
1075
1076
  } else {
1076
1077
  output[key] = sourceValue;
1077
1078
  }
1078
- } else if (isObject$b(sourceValue)) {
1079
+ } else if (isObject$a(sourceValue)) {
1079
1080
  output[key] = sourceValue;
1080
1081
  } else {
1081
1082
  output[key] = sourceValue;
@@ -1712,8 +1713,8 @@
1712
1713
  return jsonLogic;
1713
1714
  });
1714
1715
  })(logic);
1715
- var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;
1716
- var hasOwnProperty$d = Object.prototype.hasOwnProperty;
1716
+ const { getOwnPropertyNames, getOwnPropertySymbols } = Object;
1717
+ const { hasOwnProperty: hasOwnProperty$d } = Object.prototype;
1717
1718
  function combineComparators(comparatorA, comparatorB) {
1718
1719
  return function isEqual(a2, b, state) {
1719
1720
  return comparatorA(a2, b, state) && comparatorB(a2, b, state);
@@ -1724,38 +1725,45 @@
1724
1725
  if (!a2 || !b || typeof a2 !== "object" || typeof b !== "object") {
1725
1726
  return areItemsEqual(a2, b, state);
1726
1727
  }
1727
- var cache2 = state.cache;
1728
- var cachedA = cache2.get(a2);
1729
- var cachedB = cache2.get(b);
1728
+ const { cache } = state;
1729
+ const cachedA = cache.get(a2);
1730
+ const cachedB = cache.get(b);
1730
1731
  if (cachedA && cachedB) {
1731
1732
  return cachedA === b && cachedB === a2;
1732
1733
  }
1733
- cache2.set(a2, b);
1734
- cache2.set(b, a2);
1735
- var result = areItemsEqual(a2, b, state);
1736
- cache2.delete(a2);
1737
- cache2.delete(b);
1734
+ cache.set(a2, b);
1735
+ cache.set(b, a2);
1736
+ const result = areItemsEqual(a2, b, state);
1737
+ cache.delete(a2);
1738
+ cache.delete(b);
1738
1739
  return result;
1739
1740
  };
1740
1741
  }
1741
- function getShortTag(value) {
1742
- return value != null ? value[Symbol.toStringTag] : void 0;
1743
- }
1744
1742
  function getStrictProperties(object) {
1745
1743
  return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));
1746
1744
  }
1747
- var hasOwn$1 = Object.hasOwn || function(object, property) {
1748
- return hasOwnProperty$d.call(object, property);
1749
- };
1750
- function sameValueZeroEqual(a2, b) {
1751
- return a2 === b || !a2 && !b && a2 !== a2 && b !== b;
1745
+ const hasOwn$1 = (
1746
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1747
+ Object.hasOwn || ((object, property) => hasOwnProperty$d.call(object, property))
1748
+ );
1749
+ const PREACT_VNODE = "__v";
1750
+ const PREACT_OWNER = "__o";
1751
+ const REACT_OWNER = "_owner";
1752
+ const { getOwnPropertyDescriptor, keys: keys$5 } = Object;
1753
+ const sameValueEqual = (
1754
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1755
+ Object.is || function sameValueEqual2(a2, b) {
1756
+ return a2 === b ? a2 !== 0 || 1 / a2 === 1 / b : a2 !== a2 && b !== b;
1757
+ }
1758
+ );
1759
+ function strictEqual(a2, b) {
1760
+ return a2 === b;
1761
+ }
1762
+ function areArrayBuffersEqual(a2, b) {
1763
+ return a2.byteLength === b.byteLength && areTypedArraysEqual(new Uint8Array(a2), new Uint8Array(b));
1752
1764
  }
1753
- var PREACT_VNODE = "__v";
1754
- var PREACT_OWNER = "__o";
1755
- var REACT_OWNER = "_owner";
1756
- var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys$5 = Object.keys;
1757
1765
  function areArraysEqual(a2, b, state) {
1758
- var index2 = a2.length;
1766
+ let index2 = a2.length;
1759
1767
  if (b.length !== index2) {
1760
1768
  return false;
1761
1769
  }
@@ -1766,35 +1774,35 @@
1766
1774
  }
1767
1775
  return true;
1768
1776
  }
1777
+ function areDataViewsEqual(a2, b) {
1778
+ return a2.byteLength === b.byteLength && areTypedArraysEqual(new Uint8Array(a2.buffer, a2.byteOffset, a2.byteLength), new Uint8Array(b.buffer, b.byteOffset, b.byteLength));
1779
+ }
1769
1780
  function areDatesEqual(a2, b) {
1770
- return sameValueZeroEqual(a2.getTime(), b.getTime());
1781
+ return sameValueEqual(a2.getTime(), b.getTime());
1771
1782
  }
1772
1783
  function areErrorsEqual(a2, b) {
1773
1784
  return a2.name === b.name && a2.message === b.message && a2.cause === b.cause && a2.stack === b.stack;
1774
1785
  }
1775
- function areFunctionsEqual(a2, b) {
1776
- return a2 === b;
1777
- }
1778
1786
  function areMapsEqual(a2, b, state) {
1779
- var size = a2.size;
1787
+ const size = a2.size;
1780
1788
  if (size !== b.size) {
1781
1789
  return false;
1782
1790
  }
1783
1791
  if (!size) {
1784
1792
  return true;
1785
1793
  }
1786
- var matchedIndices = new Array(size);
1787
- var aIterable = a2.entries();
1788
- var aResult;
1789
- var bResult;
1790
- var index2 = 0;
1794
+ const matchedIndices = new Array(size);
1795
+ const aIterable = a2.entries();
1796
+ let aResult;
1797
+ let bResult;
1798
+ let index2 = 0;
1791
1799
  while (aResult = aIterable.next()) {
1792
1800
  if (aResult.done) {
1793
1801
  break;
1794
1802
  }
1795
- var bIterable = b.entries();
1796
- var hasMatch = false;
1797
- var matchIndex = 0;
1803
+ const bIterable = b.entries();
1804
+ let hasMatch = false;
1805
+ let matchIndex = 0;
1798
1806
  while (bResult = bIterable.next()) {
1799
1807
  if (bResult.done) {
1800
1808
  break;
@@ -1803,8 +1811,8 @@
1803
1811
  matchIndex++;
1804
1812
  continue;
1805
1813
  }
1806
- var aEntry = aResult.value;
1807
- var bEntry = bResult.value;
1814
+ const aEntry = aResult.value;
1815
+ const bEntry = bResult.value;
1808
1816
  if (state.equals(aEntry[0], bEntry[0], index2, matchIndex, a2, b, state) && state.equals(aEntry[1], bEntry[1], aEntry[0], bEntry[0], a2, b, state)) {
1809
1817
  hasMatch = matchedIndices[matchIndex] = true;
1810
1818
  break;
@@ -1818,10 +1826,9 @@
1818
1826
  }
1819
1827
  return true;
1820
1828
  }
1821
- var areNumbersEqual = sameValueZeroEqual;
1822
1829
  function areObjectsEqual(a2, b, state) {
1823
- var properties = keys$5(a2);
1824
- var index2 = properties.length;
1830
+ const properties = keys$5(a2);
1831
+ let index2 = properties.length;
1825
1832
  if (keys$5(b).length !== index2) {
1826
1833
  return false;
1827
1834
  }
@@ -1833,14 +1840,14 @@
1833
1840
  return true;
1834
1841
  }
1835
1842
  function areObjectsEqualStrict(a2, b, state) {
1836
- var properties = getStrictProperties(a2);
1837
- var index2 = properties.length;
1843
+ const properties = getStrictProperties(a2);
1844
+ let index2 = properties.length;
1838
1845
  if (getStrictProperties(b).length !== index2) {
1839
1846
  return false;
1840
1847
  }
1841
- var property;
1842
- var descriptorA;
1843
- var descriptorB;
1848
+ let property;
1849
+ let descriptorA;
1850
+ let descriptorB;
1844
1851
  while (index2-- > 0) {
1845
1852
  property = properties[index2];
1846
1853
  if (!isPropertyEqual(a2, b, state, property)) {
@@ -1855,30 +1862,30 @@
1855
1862
  return true;
1856
1863
  }
1857
1864
  function arePrimitiveWrappersEqual(a2, b) {
1858
- return sameValueZeroEqual(a2.valueOf(), b.valueOf());
1865
+ return sameValueEqual(a2.valueOf(), b.valueOf());
1859
1866
  }
1860
1867
  function areRegExpsEqual(a2, b) {
1861
1868
  return a2.source === b.source && a2.flags === b.flags;
1862
1869
  }
1863
1870
  function areSetsEqual(a2, b, state) {
1864
- var size = a2.size;
1871
+ const size = a2.size;
1865
1872
  if (size !== b.size) {
1866
1873
  return false;
1867
1874
  }
1868
1875
  if (!size) {
1869
1876
  return true;
1870
1877
  }
1871
- var matchedIndices = new Array(size);
1872
- var aIterable = a2.values();
1873
- var aResult;
1874
- var bResult;
1878
+ const matchedIndices = new Array(size);
1879
+ const aIterable = a2.values();
1880
+ let aResult;
1881
+ let bResult;
1875
1882
  while (aResult = aIterable.next()) {
1876
1883
  if (aResult.done) {
1877
1884
  break;
1878
1885
  }
1879
- var bIterable = b.values();
1880
- var hasMatch = false;
1881
- var matchIndex = 0;
1886
+ const bIterable = b.values();
1887
+ let hasMatch = false;
1888
+ let matchIndex = 0;
1882
1889
  while (bResult = bIterable.next()) {
1883
1890
  if (bResult.done) {
1884
1891
  break;
@@ -1896,8 +1903,8 @@
1896
1903
  return true;
1897
1904
  }
1898
1905
  function areTypedArraysEqual(a2, b) {
1899
- var index2 = a2.length;
1900
- if (b.length !== index2) {
1906
+ let index2 = a2.byteLength;
1907
+ if (b.byteLength !== index2 || a2.byteOffset !== b.byteOffset) {
1901
1908
  return false;
1902
1909
  }
1903
1910
  while (index2-- > 0) {
@@ -1916,23 +1923,10 @@
1916
1923
  }
1917
1924
  return hasOwn$1(b, property) && state.equals(a2[property], b[property], property, property, a2, b, state);
1918
1925
  }
1919
- var ARGUMENTS_TAG = "[object Arguments]";
1920
- var BOOLEAN_TAG = "[object Boolean]";
1921
- var DATE_TAG = "[object Date]";
1922
- var ERROR_TAG = "[object Error]";
1923
- var MAP_TAG = "[object Map]";
1924
- var NUMBER_TAG = "[object Number]";
1925
- var OBJECT_TAG = "[object Object]";
1926
- var REG_EXP_TAG = "[object RegExp]";
1927
- var SET_TAG = "[object Set]";
1928
- var STRING_TAG = "[object String]";
1929
- var URL_TAG = "[object URL]";
1930
- var isArray$7 = Array.isArray;
1931
- var isTypedArray$2 = typeof ArrayBuffer === "function" && ArrayBuffer.isView ? ArrayBuffer.isView : null;
1932
- var assign$1 = Object.assign;
1933
- var getTag$4 = Object.prototype.toString.call.bind(Object.prototype.toString);
1934
- function createEqualityComparator(_a2) {
1935
- var areArraysEqual2 = _a2.areArraysEqual, areDatesEqual2 = _a2.areDatesEqual, areErrorsEqual2 = _a2.areErrorsEqual, areFunctionsEqual2 = _a2.areFunctionsEqual, areMapsEqual2 = _a2.areMapsEqual, areNumbersEqual2 = _a2.areNumbersEqual, areObjectsEqual2 = _a2.areObjectsEqual, arePrimitiveWrappersEqual2 = _a2.arePrimitiveWrappersEqual, areRegExpsEqual2 = _a2.areRegExpsEqual, areSetsEqual2 = _a2.areSetsEqual, areTypedArraysEqual2 = _a2.areTypedArraysEqual, areUrlsEqual2 = _a2.areUrlsEqual, unknownTagComparators = _a2.unknownTagComparators;
1926
+ const toString$2 = Object.prototype.toString;
1927
+ function createEqualityComparator(config) {
1928
+ const supportedComparatorMap = createSupportedComparatorMap(config);
1929
+ const { areArraysEqual: areArraysEqual2, areDatesEqual: areDatesEqual2, areFunctionsEqual, areMapsEqual: areMapsEqual2, areNumbersEqual, areObjectsEqual: areObjectsEqual2, areRegExpsEqual: areRegExpsEqual2, areSetsEqual: areSetsEqual2, getUnsupportedCustomComparator } = config;
1936
1930
  return function comparator2(a2, b, state) {
1937
1931
  if (a2 === b) {
1938
1932
  return true;
@@ -1940,32 +1934,29 @@
1940
1934
  if (a2 == null || b == null) {
1941
1935
  return false;
1942
1936
  }
1943
- var type = typeof a2;
1937
+ const type = typeof a2;
1944
1938
  if (type !== typeof b) {
1945
1939
  return false;
1946
1940
  }
1947
1941
  if (type !== "object") {
1948
- if (type === "number") {
1949
- return areNumbersEqual2(a2, b, state);
1942
+ if (type === "number" || type === "bigint") {
1943
+ return areNumbersEqual(a2, b, state);
1950
1944
  }
1951
1945
  if (type === "function") {
1952
- return areFunctionsEqual2(a2, b, state);
1946
+ return areFunctionsEqual(a2, b, state);
1953
1947
  }
1954
1948
  return false;
1955
1949
  }
1956
- var constructor = a2.constructor;
1950
+ const constructor = a2.constructor;
1957
1951
  if (constructor !== b.constructor) {
1958
1952
  return false;
1959
1953
  }
1960
1954
  if (constructor === Object) {
1961
1955
  return areObjectsEqual2(a2, b, state);
1962
1956
  }
1963
- if (isArray$7(a2)) {
1957
+ if (constructor === Array) {
1964
1958
  return areArraysEqual2(a2, b, state);
1965
1959
  }
1966
- if (isTypedArray$2 != null && isTypedArray$2(a2)) {
1967
- return areTypedArraysEqual2(a2, b, state);
1968
- }
1969
1960
  if (constructor === Date) {
1970
1961
  return areDatesEqual2(a2, b, state);
1971
1962
  }
@@ -1978,79 +1969,55 @@
1978
1969
  if (constructor === Set) {
1979
1970
  return areSetsEqual2(a2, b, state);
1980
1971
  }
1981
- var tag2 = getTag$4(a2);
1982
- if (tag2 === DATE_TAG) {
1983
- return areDatesEqual2(a2, b, state);
1984
- }
1985
- if (tag2 === REG_EXP_TAG) {
1986
- return areRegExpsEqual2(a2, b, state);
1987
- }
1988
- if (tag2 === MAP_TAG) {
1989
- return areMapsEqual2(a2, b, state);
1990
- }
1991
- if (tag2 === SET_TAG) {
1992
- return areSetsEqual2(a2, b, state);
1993
- }
1994
- if (tag2 === OBJECT_TAG) {
1995
- return typeof a2.then !== "function" && typeof b.then !== "function" && areObjectsEqual2(a2, b, state);
1996
- }
1997
- if (tag2 === URL_TAG) {
1998
- return areUrlsEqual2(a2, b, state);
1999
- }
2000
- if (tag2 === ERROR_TAG) {
2001
- return areErrorsEqual2(a2, b, state);
1972
+ if (constructor === Promise) {
1973
+ return false;
2002
1974
  }
2003
- if (tag2 === ARGUMENTS_TAG) {
2004
- return areObjectsEqual2(a2, b, state);
1975
+ if (Array.isArray(a2)) {
1976
+ return areArraysEqual2(a2, b, state);
2005
1977
  }
2006
- if (tag2 === BOOLEAN_TAG || tag2 === NUMBER_TAG || tag2 === STRING_TAG) {
2007
- return arePrimitiveWrappersEqual2(a2, b, state);
1978
+ const tag = toString$2.call(a2);
1979
+ const supportedComparator = supportedComparatorMap[tag];
1980
+ if (supportedComparator) {
1981
+ return supportedComparator(a2, b, state);
2008
1982
  }
2009
- if (unknownTagComparators) {
2010
- var unknownTagComparator = unknownTagComparators[tag2];
2011
- if (!unknownTagComparator) {
2012
- var shortTag = getShortTag(a2);
2013
- if (shortTag) {
2014
- unknownTagComparator = unknownTagComparators[shortTag];
2015
- }
2016
- }
2017
- if (unknownTagComparator) {
2018
- return unknownTagComparator(a2, b, state);
2019
- }
1983
+ const unsupportedCustomComparator = getUnsupportedCustomComparator && getUnsupportedCustomComparator(a2, b, state, tag);
1984
+ if (unsupportedCustomComparator) {
1985
+ return unsupportedCustomComparator(a2, b, state);
2020
1986
  }
2021
1987
  return false;
2022
1988
  };
2023
1989
  }
2024
- function createEqualityComparatorConfig(_a2) {
2025
- var circular = _a2.circular, createCustomConfig = _a2.createCustomConfig, strict = _a2.strict;
2026
- var config = {
1990
+ function createEqualityComparatorConfig({ circular, createCustomConfig, strict }) {
1991
+ let config = {
1992
+ areArrayBuffersEqual,
2027
1993
  areArraysEqual: strict ? areObjectsEqualStrict : areArraysEqual,
1994
+ areDataViewsEqual,
2028
1995
  areDatesEqual,
2029
1996
  areErrorsEqual,
2030
- areFunctionsEqual,
1997
+ areFunctionsEqual: strictEqual,
2031
1998
  areMapsEqual: strict ? combineComparators(areMapsEqual, areObjectsEqualStrict) : areMapsEqual,
2032
- areNumbersEqual,
1999
+ areNumbersEqual: sameValueEqual,
2033
2000
  areObjectsEqual: strict ? areObjectsEqualStrict : areObjectsEqual,
2034
2001
  arePrimitiveWrappersEqual,
2035
2002
  areRegExpsEqual,
2036
2003
  areSetsEqual: strict ? combineComparators(areSetsEqual, areObjectsEqualStrict) : areSetsEqual,
2037
- areTypedArraysEqual: strict ? areObjectsEqualStrict : areTypedArraysEqual,
2004
+ areTypedArraysEqual: strict ? combineComparators(areTypedArraysEqual, areObjectsEqualStrict) : areTypedArraysEqual,
2038
2005
  areUrlsEqual,
2039
- unknownTagComparators: void 0
2006
+ getUnsupportedCustomComparator: void 0
2040
2007
  };
2041
2008
  if (createCustomConfig) {
2042
- config = assign$1({}, config, createCustomConfig(config));
2009
+ config = Object.assign({}, config, createCustomConfig(config));
2043
2010
  }
2044
2011
  if (circular) {
2045
- var areArraysEqual$1 = createIsCircular(config.areArraysEqual);
2046
- var areMapsEqual$1 = createIsCircular(config.areMapsEqual);
2047
- var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);
2048
- var areSetsEqual$1 = createIsCircular(config.areSetsEqual);
2049
- config = assign$1({}, config, {
2050
- areArraysEqual: areArraysEqual$1,
2051
- areMapsEqual: areMapsEqual$1,
2052
- areObjectsEqual: areObjectsEqual$1,
2053
- areSetsEqual: areSetsEqual$1
2012
+ const areArraysEqual2 = createIsCircular(config.areArraysEqual);
2013
+ const areMapsEqual2 = createIsCircular(config.areMapsEqual);
2014
+ const areObjectsEqual2 = createIsCircular(config.areObjectsEqual);
2015
+ const areSetsEqual2 = createIsCircular(config.areSetsEqual);
2016
+ config = Object.assign({}, config, {
2017
+ areArraysEqual: areArraysEqual2,
2018
+ areMapsEqual: areMapsEqual2,
2019
+ areObjectsEqual: areObjectsEqual2,
2020
+ areSetsEqual: areSetsEqual2
2054
2021
  });
2055
2022
  }
2056
2023
  return config;
@@ -2060,13 +2027,12 @@
2060
2027
  return compare2(a2, b, state);
2061
2028
  };
2062
2029
  }
2063
- function createIsEqual(_a2) {
2064
- var circular = _a2.circular, comparator2 = _a2.comparator, createState = _a2.createState, equals = _a2.equals, strict = _a2.strict;
2030
+ function createIsEqual({ circular, comparator: comparator2, createState, equals, strict }) {
2065
2031
  if (createState) {
2066
2032
  return function isEqual(a2, b) {
2067
- var _a3 = createState(), _b2 = _a3.cache, cache2 = _b2 === void 0 ? circular ? /* @__PURE__ */ new WeakMap() : void 0 : _b2, meta = _a3.meta;
2033
+ const { cache = circular ? /* @__PURE__ */ new WeakMap() : void 0, meta } = createState();
2068
2034
  return comparator2(a2, b, {
2069
- cache: cache2,
2035
+ cache,
2070
2036
  equals,
2071
2037
  meta,
2072
2038
  strict
@@ -2083,7 +2049,7 @@
2083
2049
  });
2084
2050
  };
2085
2051
  }
2086
- var state = {
2052
+ const state = {
2087
2053
  cache: void 0,
2088
2054
  equals,
2089
2055
  meta: void 0,
@@ -2093,7 +2059,50 @@
2093
2059
  return comparator2(a2, b, state);
2094
2060
  };
2095
2061
  }
2096
- var deepEqual = createCustomEqual();
2062
+ function createSupportedComparatorMap({ areArrayBuffersEqual: areArrayBuffersEqual2, areArraysEqual: areArraysEqual2, areDataViewsEqual: areDataViewsEqual2, areDatesEqual: areDatesEqual2, areErrorsEqual: areErrorsEqual2, areFunctionsEqual, areMapsEqual: areMapsEqual2, areNumbersEqual, areObjectsEqual: areObjectsEqual2, arePrimitiveWrappersEqual: arePrimitiveWrappersEqual2, areRegExpsEqual: areRegExpsEqual2, areSetsEqual: areSetsEqual2, areTypedArraysEqual: areTypedArraysEqual2, areUrlsEqual: areUrlsEqual2 }) {
2063
+ return {
2064
+ "[object Arguments]": areObjectsEqual2,
2065
+ "[object Array]": areArraysEqual2,
2066
+ "[object ArrayBuffer]": areArrayBuffersEqual2,
2067
+ "[object AsyncGeneratorFunction]": areFunctionsEqual,
2068
+ "[object BigInt]": areNumbersEqual,
2069
+ "[object BigInt64Array]": areTypedArraysEqual2,
2070
+ "[object BigUint64Array]": areTypedArraysEqual2,
2071
+ "[object Boolean]": arePrimitiveWrappersEqual2,
2072
+ "[object DataView]": areDataViewsEqual2,
2073
+ "[object Date]": areDatesEqual2,
2074
+ // If an error tag, it should be tested explicitly. Like RegExp, the properties are not
2075
+ // enumerable, and therefore will give false positives if tested like a standard object.
2076
+ "[object Error]": areErrorsEqual2,
2077
+ "[object Float16Array]": areTypedArraysEqual2,
2078
+ "[object Float32Array]": areTypedArraysEqual2,
2079
+ "[object Float64Array]": areTypedArraysEqual2,
2080
+ "[object Function]": areFunctionsEqual,
2081
+ "[object GeneratorFunction]": areFunctionsEqual,
2082
+ "[object Int8Array]": areTypedArraysEqual2,
2083
+ "[object Int16Array]": areTypedArraysEqual2,
2084
+ "[object Int32Array]": areTypedArraysEqual2,
2085
+ "[object Map]": areMapsEqual2,
2086
+ "[object Number]": arePrimitiveWrappersEqual2,
2087
+ "[object Object]": (a2, b, state) => (
2088
+ // The exception for value comparison is custom `Promise`-like class instances. These should
2089
+ // be treated the same as standard `Promise` objects, which means strict equality, and if
2090
+ // it reaches this point then that strict equality comparison has already failed.
2091
+ typeof a2.then !== "function" && typeof b.then !== "function" && areObjectsEqual2(a2, b, state)
2092
+ ),
2093
+ // For RegExp, the properties are not enumerable, and therefore will give false positives if
2094
+ // tested like a standard object.
2095
+ "[object RegExp]": areRegExpsEqual2,
2096
+ "[object Set]": areSetsEqual2,
2097
+ "[object String]": arePrimitiveWrappersEqual2,
2098
+ "[object URL]": areUrlsEqual2,
2099
+ "[object Uint8Array]": areTypedArraysEqual2,
2100
+ "[object Uint8ClampedArray]": areTypedArraysEqual2,
2101
+ "[object Uint16Array]": areTypedArraysEqual2,
2102
+ "[object Uint32Array]": areTypedArraysEqual2
2103
+ };
2104
+ }
2105
+ const deepEqual = createCustomEqual();
2097
2106
  createCustomEqual({ strict: true });
2098
2107
  createCustomEqual({ circular: true });
2099
2108
  createCustomEqual({
@@ -2101,37 +2110,26 @@
2101
2110
  strict: true
2102
2111
  });
2103
2112
  createCustomEqual({
2104
- createInternalComparator: function() {
2105
- return sameValueZeroEqual;
2106
- }
2113
+ createInternalComparator: () => sameValueEqual
2107
2114
  });
2108
2115
  createCustomEqual({
2109
2116
  strict: true,
2110
- createInternalComparator: function() {
2111
- return sameValueZeroEqual;
2112
- }
2117
+ createInternalComparator: () => sameValueEqual
2113
2118
  });
2114
2119
  createCustomEqual({
2115
2120
  circular: true,
2116
- createInternalComparator: function() {
2117
- return sameValueZeroEqual;
2118
- }
2121
+ createInternalComparator: () => sameValueEqual
2119
2122
  });
2120
2123
  createCustomEqual({
2121
2124
  circular: true,
2122
- createInternalComparator: function() {
2123
- return sameValueZeroEqual;
2124
- },
2125
+ createInternalComparator: () => sameValueEqual,
2125
2126
  strict: true
2126
2127
  });
2127
- function createCustomEqual(options2) {
2128
- if (options2 === void 0) {
2129
- options2 = {};
2130
- }
2131
- var _a2 = options2.circular, circular = _a2 === void 0 ? false : _a2, createCustomInternalComparator = options2.createInternalComparator, createState = options2.createState, _b2 = options2.strict, strict = _b2 === void 0 ? false : _b2;
2132
- var config = createEqualityComparatorConfig(options2);
2133
- var comparator2 = createEqualityComparator(config);
2134
- var equals = createCustomInternalComparator ? createCustomInternalComparator(comparator2) : createInternalEqualityComparator(comparator2);
2128
+ function createCustomEqual(options2 = {}) {
2129
+ const { circular = false, createInternalComparator: createCustomInternalComparator, createState, strict = false } = options2;
2130
+ const config = createEqualityComparatorConfig(options2);
2131
+ const comparator2 = createEqualityComparator(config);
2132
+ const equals = createCustomInternalComparator ? createCustomInternalComparator(comparator2) : createInternalEqualityComparator(comparator2);
2135
2133
  return createIsEqual({ circular, comparator: comparator2, createState, equals, strict });
2136
2134
  }
2137
2135
  function listCacheClear$1() {
@@ -2245,7 +2243,7 @@
2245
2243
  var nativeObjectToString$1 = objectProto$j.toString;
2246
2244
  var symToStringTag$1 = Symbol$3 ? Symbol$3.toStringTag : void 0;
2247
2245
  function getRawTag$1(value) {
2248
- var isOwn = hasOwnProperty$c.call(value, symToStringTag$1), tag2 = value[symToStringTag$1];
2246
+ var isOwn = hasOwnProperty$c.call(value, symToStringTag$1), tag = value[symToStringTag$1];
2249
2247
  try {
2250
2248
  value[symToStringTag$1] = void 0;
2251
2249
  var unmasked = true;
@@ -2254,7 +2252,7 @@
2254
2252
  var result = nativeObjectToString$1.call(value);
2255
2253
  if (unmasked) {
2256
2254
  if (isOwn) {
2257
- value[symToStringTag$1] = tag2;
2255
+ value[symToStringTag$1] = tag;
2258
2256
  } else {
2259
2257
  delete value[symToStringTag$1];
2260
2258
  }
@@ -2278,19 +2276,19 @@
2278
2276
  return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString$7(value);
2279
2277
  }
2280
2278
  var _baseGetTag = baseGetTag$4;
2281
- function isObject$a(value) {
2279
+ function isObject$9(value) {
2282
2280
  var type = typeof value;
2283
2281
  return value != null && (type == "object" || type == "function");
2284
2282
  }
2285
- var isObject_1 = isObject$a;
2286
- var baseGetTag$3 = _baseGetTag, isObject$9 = isObject_1;
2283
+ var isObject_1 = isObject$9;
2284
+ var baseGetTag$3 = _baseGetTag, isObject$8 = isObject_1;
2287
2285
  var asyncTag = "[object AsyncFunction]", funcTag$3 = "[object Function]", genTag$2 = "[object GeneratorFunction]", proxyTag = "[object Proxy]";
2288
2286
  function isFunction$3(value) {
2289
- if (!isObject$9(value)) {
2287
+ if (!isObject$8(value)) {
2290
2288
  return false;
2291
2289
  }
2292
- var tag2 = baseGetTag$3(value);
2293
- return tag2 == funcTag$3 || tag2 == genTag$2 || tag2 == asyncTag || tag2 == proxyTag;
2290
+ var tag = baseGetTag$3(value);
2291
+ return tag == funcTag$3 || tag == genTag$2 || tag == asyncTag || tag == proxyTag;
2294
2292
  }
2295
2293
  var isFunction_1 = isFunction$3;
2296
2294
  var root$6 = _root;
@@ -2321,7 +2319,7 @@
2321
2319
  return "";
2322
2320
  }
2323
2321
  var _toSource = toSource$2;
2324
- var isFunction$2 = isFunction_1, isMasked = _isMasked, isObject$8 = isObject_1, toSource$1 = _toSource;
2322
+ var isFunction$2 = isFunction_1, isMasked = _isMasked, isObject$7 = isObject_1, toSource$1 = _toSource;
2325
2323
  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
2326
2324
  var reIsHostCtor = /^\[object .+?Constructor\]$/;
2327
2325
  var funcProto$1 = Function.prototype, objectProto$h = Object.prototype;
@@ -2331,7 +2329,7 @@
2331
2329
  "^" + funcToString$1.call(hasOwnProperty$b).replace(reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$"
2332
2330
  );
2333
2331
  function baseIsNative$1(value) {
2334
- if (!isObject$8(value) || isMasked(value)) {
2332
+ if (!isObject$7(value) || isMasked(value)) {
2335
2333
  return false;
2336
2334
  }
2337
2335
  var pattern = isFunction$2(value) ? reIsNative : reIsHostCtor;
@@ -2573,24 +2571,24 @@
2573
2571
  return result;
2574
2572
  }
2575
2573
  var _baseTimes = baseTimes$2;
2576
- function isObjectLike$e(value) {
2574
+ function isObjectLike$d(value) {
2577
2575
  return value != null && typeof value == "object";
2578
2576
  }
2579
- var isObjectLike_1 = isObjectLike$e;
2580
- var baseGetTag$2 = _baseGetTag, isObjectLike$d = isObjectLike_1;
2577
+ var isObjectLike_1 = isObjectLike$d;
2578
+ var baseGetTag$2 = _baseGetTag, isObjectLike$c = isObjectLike_1;
2581
2579
  var argsTag$3 = "[object Arguments]";
2582
2580
  function baseIsArguments$1(value) {
2583
- return isObjectLike$d(value) && baseGetTag$2(value) == argsTag$3;
2581
+ return isObjectLike$c(value) && baseGetTag$2(value) == argsTag$3;
2584
2582
  }
2585
2583
  var _baseIsArguments = baseIsArguments$1;
2586
- var baseIsArguments = _baseIsArguments, isObjectLike$c = isObjectLike_1;
2584
+ var baseIsArguments = _baseIsArguments, isObjectLike$b = isObjectLike_1;
2587
2585
  var objectProto$d = Object.prototype;
2588
2586
  var hasOwnProperty$7 = objectProto$d.hasOwnProperty;
2589
2587
  var propertyIsEnumerable$2 = objectProto$d.propertyIsEnumerable;
2590
2588
  var isArguments$2 = baseIsArguments(/* @__PURE__ */ function() {
2591
2589
  return arguments;
2592
2590
  }()) ? baseIsArguments : function(value) {
2593
- return isObjectLike$c(value) && hasOwnProperty$7.call(value, "callee") && !propertyIsEnumerable$2.call(value, "callee");
2591
+ return isObjectLike$b(value) && hasOwnProperty$7.call(value, "callee") && !propertyIsEnumerable$2.call(value, "callee");
2594
2592
  };
2595
2593
  var isArguments_1 = isArguments$2;
2596
2594
  var isArray$6 = Array.isArray;
@@ -2625,14 +2623,14 @@
2625
2623
  return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$3;
2626
2624
  }
2627
2625
  var isLength_1 = isLength$3;
2628
- var baseGetTag$1 = _baseGetTag, isLength$2 = isLength_1, isObjectLike$b = isObjectLike_1;
2626
+ var baseGetTag$1 = _baseGetTag, isLength$2 = isLength_1, isObjectLike$a = isObjectLike_1;
2629
2627
  var argsTag$2 = "[object Arguments]", arrayTag$1 = "[object Array]", boolTag$3 = "[object Boolean]", dateTag$2 = "[object Date]", errorTag$1 = "[object Error]", funcTag$2 = "[object Function]", mapTag$4 = "[object Map]", numberTag$3 = "[object Number]", objectTag$3 = "[object Object]", regexpTag$2 = "[object RegExp]", setTag$4 = "[object Set]", stringTag$4 = "[object String]", weakMapTag$2 = "[object WeakMap]";
2630
2628
  var arrayBufferTag$2 = "[object ArrayBuffer]", dataViewTag$3 = "[object DataView]", float32Tag$2 = "[object Float32Array]", float64Tag$2 = "[object Float64Array]", int8Tag$2 = "[object Int8Array]", int16Tag$2 = "[object Int16Array]", int32Tag$2 = "[object Int32Array]", uint8Tag$2 = "[object Uint8Array]", uint8ClampedTag$2 = "[object Uint8ClampedArray]", uint16Tag$2 = "[object Uint16Array]", uint32Tag$2 = "[object Uint32Array]";
2631
2629
  var typedArrayTags = {};
2632
2630
  typedArrayTags[float32Tag$2] = typedArrayTags[float64Tag$2] = typedArrayTags[int8Tag$2] = typedArrayTags[int16Tag$2] = typedArrayTags[int32Tag$2] = typedArrayTags[uint8Tag$2] = typedArrayTags[uint8ClampedTag$2] = typedArrayTags[uint16Tag$2] = typedArrayTags[uint32Tag$2] = true;
2633
2631
  typedArrayTags[argsTag$2] = typedArrayTags[arrayTag$1] = typedArrayTags[arrayBufferTag$2] = typedArrayTags[boolTag$3] = typedArrayTags[dataViewTag$3] = typedArrayTags[dateTag$2] = typedArrayTags[errorTag$1] = typedArrayTags[funcTag$2] = typedArrayTags[mapTag$4] = typedArrayTags[numberTag$3] = typedArrayTags[objectTag$3] = typedArrayTags[regexpTag$2] = typedArrayTags[setTag$4] = typedArrayTags[stringTag$4] = typedArrayTags[weakMapTag$2] = false;
2634
2632
  function baseIsTypedArray$1(value) {
2635
- return isObjectLike$b(value) && isLength$2(value.length) && !!typedArrayTags[baseGetTag$1(value)];
2633
+ return isObjectLike$a(value) && isLength$2(value.length) && !!typedArrayTags[baseGetTag$1(value)];
2636
2634
  }
2637
2635
  var _baseIsTypedArray = baseIsTypedArray$1;
2638
2636
  function baseUnary$3(func) {
@@ -2739,11 +2737,11 @@
2739
2737
  return result;
2740
2738
  }
2741
2739
  var _nativeKeysIn = nativeKeysIn$1;
2742
- var isObject$7 = isObject_1, isPrototype$2 = _isPrototype, nativeKeysIn = _nativeKeysIn;
2740
+ var isObject$6 = isObject_1, isPrototype$2 = _isPrototype, nativeKeysIn = _nativeKeysIn;
2743
2741
  var objectProto$9 = Object.prototype;
2744
2742
  var hasOwnProperty$4 = objectProto$9.hasOwnProperty;
2745
2743
  function baseKeysIn$1(object) {
2746
- if (!isObject$7(object)) {
2744
+ if (!isObject$6(object)) {
2747
2745
  return nativeKeysIn(object);
2748
2746
  }
2749
2747
  var isProto = isPrototype$2(object), result = [];
@@ -2957,9 +2955,9 @@
2957
2955
  var cloneArrayBuffer = _cloneArrayBuffer, cloneDataView = _cloneDataView, cloneRegExp = _cloneRegExp, cloneSymbol = _cloneSymbol, cloneTypedArray = _cloneTypedArray;
2958
2956
  var boolTag$2 = "[object Boolean]", dateTag$1 = "[object Date]", mapTag$2 = "[object Map]", numberTag$2 = "[object Number]", regexpTag$1 = "[object RegExp]", setTag$2 = "[object Set]", stringTag$3 = "[object String]", symbolTag$4 = "[object Symbol]";
2959
2957
  var arrayBufferTag$1 = "[object ArrayBuffer]", dataViewTag$1 = "[object DataView]", float32Tag$1 = "[object Float32Array]", float64Tag$1 = "[object Float64Array]", int8Tag$1 = "[object Int8Array]", int16Tag$1 = "[object Int16Array]", int32Tag$1 = "[object Int32Array]", uint8Tag$1 = "[object Uint8Array]", uint8ClampedTag$1 = "[object Uint8ClampedArray]", uint16Tag$1 = "[object Uint16Array]", uint32Tag$1 = "[object Uint32Array]";
2960
- function initCloneByTag$1(object, tag2, isDeep) {
2958
+ function initCloneByTag$1(object, tag, isDeep) {
2961
2959
  var Ctor = object.constructor;
2962
- switch (tag2) {
2960
+ switch (tag) {
2963
2961
  case arrayBufferTag$1:
2964
2962
  return cloneArrayBuffer(object);
2965
2963
  case boolTag$2:
@@ -2991,13 +2989,13 @@
2991
2989
  }
2992
2990
  }
2993
2991
  var _initCloneByTag = initCloneByTag$1;
2994
- var isObject$6 = isObject_1;
2992
+ var isObject$5 = isObject_1;
2995
2993
  var objectCreate = Object.create;
2996
2994
  var baseCreate$1 = /* @__PURE__ */ function() {
2997
2995
  function object() {
2998
2996
  }
2999
2997
  return function(proto) {
3000
- if (!isObject$6(proto)) {
2998
+ if (!isObject$5(proto)) {
3001
2999
  return {};
3002
3000
  }
3003
3001
  if (objectCreate) {
@@ -3015,27 +3013,27 @@
3015
3013
  return typeof object.constructor == "function" && !isPrototype$1(object) ? baseCreate(getPrototype$1(object)) : {};
3016
3014
  }
3017
3015
  var _initCloneObject = initCloneObject$1;
3018
- var getTag$2 = _getTag, isObjectLike$a = isObjectLike_1;
3016
+ var getTag$2 = _getTag, isObjectLike$9 = isObjectLike_1;
3019
3017
  var mapTag$1 = "[object Map]";
3020
3018
  function baseIsMap$1(value) {
3021
- return isObjectLike$a(value) && getTag$2(value) == mapTag$1;
3019
+ return isObjectLike$9(value) && getTag$2(value) == mapTag$1;
3022
3020
  }
3023
3021
  var _baseIsMap = baseIsMap$1;
3024
3022
  var baseIsMap = _baseIsMap, baseUnary$1 = _baseUnary, nodeUtil$1 = _nodeUtilExports;
3025
3023
  var nodeIsMap = nodeUtil$1 && nodeUtil$1.isMap;
3026
3024
  var isMap$1 = nodeIsMap ? baseUnary$1(nodeIsMap) : baseIsMap;
3027
3025
  var isMap_1 = isMap$1;
3028
- var getTag$1 = _getTag, isObjectLike$9 = isObjectLike_1;
3026
+ var getTag$1 = _getTag, isObjectLike$8 = isObjectLike_1;
3029
3027
  var setTag$1 = "[object Set]";
3030
3028
  function baseIsSet$1(value) {
3031
- return isObjectLike$9(value) && getTag$1(value) == setTag$1;
3029
+ return isObjectLike$8(value) && getTag$1(value) == setTag$1;
3032
3030
  }
3033
3031
  var _baseIsSet = baseIsSet$1;
3034
3032
  var baseIsSet = _baseIsSet, baseUnary = _baseUnary, nodeUtil = _nodeUtilExports;
3035
3033
  var nodeIsSet = nodeUtil && nodeUtil.isSet;
3036
3034
  var isSet$1 = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
3037
3035
  var isSet_1 = isSet$1;
3038
- var Stack = _Stack, arrayEach = _arrayEach, assignValue = _assignValue, baseAssign = _baseAssign, baseAssignIn = _baseAssignIn, cloneBuffer = _cloneBufferExports, copyArray = _copyArray, copySymbols = _copySymbols, copySymbolsIn = _copySymbolsIn, getAllKeys = _getAllKeys, getAllKeysIn = _getAllKeysIn, getTag = _getTag, initCloneArray = _initCloneArray, initCloneByTag = _initCloneByTag, initCloneObject = _initCloneObject, isArray$3 = isArray_1, isBuffer = isBufferExports, isMap = isMap_1, isObject$5 = isObject_1, isSet = isSet_1, keys$1 = keys_1, keysIn = keysIn_1;
3036
+ var Stack = _Stack, arrayEach = _arrayEach, assignValue = _assignValue, baseAssign = _baseAssign, baseAssignIn = _baseAssignIn, cloneBuffer = _cloneBufferExports, copyArray = _copyArray, copySymbols = _copySymbols, copySymbolsIn = _copySymbolsIn, getAllKeys = _getAllKeys, getAllKeysIn = _getAllKeysIn, getTag = _getTag, initCloneArray = _initCloneArray, initCloneByTag = _initCloneByTag, initCloneObject = _initCloneObject, isArray$3 = isArray_1, isBuffer = isBufferExports, isMap = isMap_1, isObject$4 = isObject_1, isSet = isSet_1, keys$1 = keys_1, keysIn = keysIn_1;
3039
3037
  var CLONE_DEEP_FLAG$1 = 1, CLONE_FLAT_FLAG = 2, CLONE_SYMBOLS_FLAG$1 = 4;
3040
3038
  var argsTag$1 = "[object Arguments]", arrayTag = "[object Array]", boolTag$1 = "[object Boolean]", dateTag = "[object Date]", errorTag = "[object Error]", funcTag$1 = "[object Function]", genTag$1 = "[object GeneratorFunction]", mapTag = "[object Map]", numberTag$1 = "[object Number]", objectTag$1 = "[object Object]", regexpTag = "[object RegExp]", setTag = "[object Set]", stringTag$2 = "[object String]", symbolTag$3 = "[object Symbol]", weakMapTag = "[object WeakMap]";
3041
3039
  var arrayBufferTag = "[object ArrayBuffer]", dataViewTag = "[object DataView]", float32Tag = "[object Float32Array]", float64Tag = "[object Float64Array]", int8Tag = "[object Int8Array]", int16Tag = "[object Int16Array]", int32Tag = "[object Int32Array]", uint8Tag = "[object Uint8Array]", uint8ClampedTag = "[object Uint8ClampedArray]", uint16Tag = "[object Uint16Array]", uint32Tag = "[object Uint32Array]";
@@ -3050,7 +3048,7 @@
3050
3048
  if (result !== void 0) {
3051
3049
  return result;
3052
3050
  }
3053
- if (!isObject$5(value)) {
3051
+ if (!isObject$4(value)) {
3054
3052
  return value;
3055
3053
  }
3056
3054
  var isArr = isArray$3(value);
@@ -3060,20 +3058,20 @@
3060
3058
  return copyArray(value, result);
3061
3059
  }
3062
3060
  } else {
3063
- var tag2 = getTag(value), isFunc = tag2 == funcTag$1 || tag2 == genTag$1;
3061
+ var tag = getTag(value), isFunc = tag == funcTag$1 || tag == genTag$1;
3064
3062
  if (isBuffer(value)) {
3065
3063
  return cloneBuffer(value, isDeep);
3066
3064
  }
3067
- if (tag2 == objectTag$1 || tag2 == argsTag$1 || isFunc && !object) {
3065
+ if (tag == objectTag$1 || tag == argsTag$1 || isFunc && !object) {
3068
3066
  result = isFlat || isFunc ? {} : initCloneObject(value);
3069
3067
  if (!isDeep) {
3070
3068
  return isFlat ? copySymbolsIn(value, baseAssignIn(result, value)) : copySymbols(value, baseAssign(result, value));
3071
3069
  }
3072
3070
  } else {
3073
- if (!cloneableTags[tag2]) {
3071
+ if (!cloneableTags[tag]) {
3074
3072
  return object ? value : {};
3075
3073
  }
3076
- result = initCloneByTag(value, tag2, isDeep);
3074
+ result = initCloneByTag(value, tag, isDeep);
3077
3075
  }
3078
3076
  }
3079
3077
  stack || (stack = new Stack());
@@ -3381,7 +3379,10 @@
3381
3379
  if (!relation) {
3382
3380
  throw new Error(`Relation '${relationKey}' not found in collection '${currentCollection.slug}'`);
3383
3381
  }
3384
- currentCollection = relation.target();
3382
+ const target = relation.target();
3383
+ const targetRelationKey = relation.relationName || target.slug;
3384
+ const targetSlug = relation.overrides?.slug ?? targetRelationKey;
3385
+ currentCollection = this.get(targetSlug) || this.normalizeCollection(target);
3385
3386
  if (i2 + 1 < pathSegments.length) ;
3386
3387
  }
3387
3388
  return currentCollection;
@@ -3430,7 +3431,7 @@
3430
3431
  if (!subcollection) {
3431
3432
  throw new Error(`Subcollection '${subcollectionSlug}' not found in ${currentCollection.slug}`);
3432
3433
  }
3433
- currentCollection = subcollection;
3434
+ currentCollection = this.get(subcollection.slug) || this.normalizeCollection(subcollection);
3434
3435
  collections.push(currentCollection);
3435
3436
  }
3436
3437
  }
@@ -3465,16 +3466,15 @@
3465
3466
  const filePath = path__namespace.join(directory, file);
3466
3467
  try {
3467
3468
  const fileUrl = require$$0$2.pathToFileURL(filePath).href;
3468
- const dynamicImport = new Function("url", "return import(url)");
3469
- const module2 = await dynamicImport(fileUrl);
3469
+ const module2 = await import(fileUrl);
3470
3470
  if (module2 && module2.default) {
3471
3471
  collections.push(module2.default);
3472
3472
  } else {
3473
3473
  console.warn(`[loadCollectionsFromDirectory] File ${file} does not have a default export. Skipping.`);
3474
3474
  }
3475
3475
  } catch (err) {
3476
- const message2 = err instanceof Error ? err.message : String(err);
3477
- console.error(`[loadCollectionsFromDirectory] Failed to load collection from ${file}: ${message2}`);
3476
+ const message = err instanceof Error ? err.message : String(err);
3477
+ console.error(`[loadCollectionsFromDirectory] Failed to load collection from ${file}: ${message}`);
3478
3478
  }
3479
3479
  }
3480
3480
  }
@@ -3557,34 +3557,34 @@
3557
3557
  statusCode;
3558
3558
  code;
3559
3559
  details;
3560
- constructor(statusCode, code2, message2, details) {
3561
- super(message2);
3560
+ constructor(statusCode, code2, message, details) {
3561
+ super(message);
3562
3562
  this.name = "ApiError";
3563
3563
  this.statusCode = statusCode;
3564
3564
  this.code = code2;
3565
3565
  this.details = details;
3566
3566
  }
3567
3567
  // ── Factory methods ──────────────────────────────────────────────
3568
- static badRequest(message2, code2 = "BAD_REQUEST", details) {
3569
- return new ApiError(400, code2, message2, details);
3568
+ static badRequest(message, code2 = "BAD_REQUEST", details) {
3569
+ return new ApiError(400, code2, message, details);
3570
3570
  }
3571
- static unauthorized(message2, code2 = "UNAUTHORIZED") {
3572
- return new ApiError(401, code2, message2);
3571
+ static unauthorized(message, code2 = "UNAUTHORIZED") {
3572
+ return new ApiError(401, code2, message);
3573
3573
  }
3574
- static forbidden(message2, code2 = "FORBIDDEN") {
3575
- return new ApiError(403, code2, message2);
3574
+ static forbidden(message, code2 = "FORBIDDEN") {
3575
+ return new ApiError(403, code2, message);
3576
3576
  }
3577
- static notFound(message2, code2 = "NOT_FOUND") {
3578
- return new ApiError(404, code2, message2);
3577
+ static notFound(message, code2 = "NOT_FOUND") {
3578
+ return new ApiError(404, code2, message);
3579
3579
  }
3580
- static conflict(message2, code2 = "CONFLICT") {
3581
- return new ApiError(409, code2, message2);
3580
+ static conflict(message, code2 = "CONFLICT") {
3581
+ return new ApiError(409, code2, message);
3582
3582
  }
3583
- static internal(message2, code2 = "INTERNAL_ERROR") {
3584
- return new ApiError(500, code2, message2);
3583
+ static internal(message, code2 = "INTERNAL_ERROR") {
3584
+ return new ApiError(500, code2, message);
3585
3585
  }
3586
- static serviceUnavailable(message2, code2 = "SERVICE_UNAVAILABLE") {
3587
- return new ApiError(503, code2, message2);
3586
+ static serviceUnavailable(message, code2 = "SERVICE_UNAVAILABLE") {
3587
+ return new ApiError(503, code2, message);
3588
3588
  }
3589
3589
  }
3590
3590
  const errorHandler = (err, c) => {
@@ -3624,7 +3624,8 @@
3624
3624
  console.error(`❌ [API] ${c.req.method} ${c.req.path} → ${statusCode} ${code2}: ${logMessage}`);
3625
3625
  const causePg = error2.cause && typeof error2.cause === "object" ? error2.cause : void 0;
3626
3626
  const pgErrorCode = causePg?.code || error2.code;
3627
- if (pgErrorCode !== "42703" && pgErrorCode !== "42P01") {
3627
+ const suppressStack = pgErrorCode === "42703" || pgErrorCode === "42P01" || statusCode < 500 && code2 === "BAD_REQUEST";
3628
+ if (!suppressStack) {
3628
3629
  console.error(error2.stack || error2);
3629
3630
  }
3630
3631
  let clientMessage = "An unexpected error occurred";
@@ -3712,8 +3713,8 @@
3712
3713
  }
3713
3714
  Object.assign(options2.where, parsedWhere);
3714
3715
  } catch (e) {
3715
- const message2 = e instanceof Error ? e.message : "malformed JSON";
3716
- const err = new Error(`Invalid 'where' filter: ${message2}`);
3716
+ const message = e instanceof Error ? e.message : "malformed JSON";
3717
+ const err = new Error(`Invalid 'where' filter: ${message}`);
3717
3718
  err.code = "BAD_REQUEST";
3718
3719
  err.statusCode = 400;
3719
3720
  throw err;
@@ -3797,11 +3798,24 @@
3797
3798
  collections;
3798
3799
  router;
3799
3800
  driver;
3800
- constructor(collections, driver) {
3801
+ dataHooks;
3802
+ constructor(collections, driver, dataHooks) {
3801
3803
  this.collections = collections;
3802
3804
  this.driver = driver;
3805
+ this.dataHooks = dataHooks;
3803
3806
  this.router = new hono.Hono();
3804
3807
  }
3808
+ /** Build a BackendHookContext from a Hono context */
3809
+ buildHookContext(c, method) {
3810
+ const user = c.get("user");
3811
+ return {
3812
+ requestUser: user ? {
3813
+ userId: user.userId,
3814
+ roles: user.roles ?? []
3815
+ } : void 0,
3816
+ method
3817
+ };
3818
+ }
3805
3819
  /**
3806
3820
  * Generate REST routes using existing DataDriver
3807
3821
  */
@@ -3813,16 +3827,10 @@
3813
3827
  return this.router;
3814
3828
  }
3815
3829
  /**
3816
- * Get the EntityFetchService from a driver if it exposes one (for include support)
3830
+ * Get the typed RestFetchService from a driver if it exposes one (for include support).
3817
3831
  */
3818
3832
  getFetchService(driver) {
3819
- if ("entityService" in driver && typeof driver.entityService === "object" && driver.entityService) {
3820
- const es = driver.entityService;
3821
- if (typeof es.getFetchService === "function") {
3822
- return es.getFetchService();
3823
- }
3824
- }
3825
- return null;
3833
+ return driver.restFetchService;
3826
3834
  }
3827
3835
  /**
3828
3836
  * Create REST routes for a collection using existing Rebase patterns
@@ -3830,15 +3838,26 @@
3830
3838
  createCollectionRoutes(collection) {
3831
3839
  const basePath = `/${collection.slug}`;
3832
3840
  const resolvedCollection = collection;
3841
+ this.router.get(`${basePath}/count`, async (c) => {
3842
+ const queryDict = c.req.query();
3843
+ const queryOptions = parseQueryOptions(queryDict);
3844
+ const searchString = queryDict.searchString;
3845
+ const driver = c.get("driver") || this.driver;
3846
+ const total = await this.countRawEntities(driver, resolvedCollection, queryOptions, searchString);
3847
+ return c.json({
3848
+ count: total
3849
+ });
3850
+ });
3833
3851
  this.router.get(basePath, async (c) => {
3834
3852
  const queryDict = c.req.query();
3835
3853
  const queryOptions = parseQueryOptions(queryDict);
3836
3854
  const searchString = queryDict.searchString;
3837
3855
  const driver = c.get("driver") || this.driver;
3838
3856
  const fetchService = this.getFetchService(driver);
3857
+ const hookCtx = this.buildHookContext(c, "GET");
3839
3858
  if (fetchService) {
3840
3859
  const collectionPath = collection.slug;
3841
- const entities2 = await fetchService.fetchCollectionForRest(collectionPath, {
3860
+ let entities2 = await fetchService.fetchCollectionForRest(collectionPath, {
3842
3861
  filter: queryOptions.where,
3843
3862
  limit: queryOptions.limit,
3844
3863
  offset: queryOptions.offset,
@@ -3846,6 +3865,7 @@
3846
3865
  order: queryOptions.orderBy?.[0]?.direction === "desc" ? "desc" : "asc",
3847
3866
  searchString
3848
3867
  }, queryOptions.include);
3868
+ entities2 = await this.applyAfterReadBatch(collection.slug, entities2, hookCtx);
3849
3869
  const total2 = await this.countRawEntities(driver, resolvedCollection, queryOptions, searchString);
3850
3870
  return c.json({
3851
3871
  data: entities2,
@@ -3857,7 +3877,8 @@
3857
3877
  }
3858
3878
  });
3859
3879
  }
3860
- const entities = await this.fetchRawCollection(driver, resolvedCollection, queryOptions, searchString);
3880
+ let entities = await this.fetchRawCollection(driver, resolvedCollection, queryOptions, searchString);
3881
+ entities = await this.applyAfterReadBatch(collection.slug, entities, hookCtx);
3861
3882
  const total = await this.countRawEntities(driver, resolvedCollection, queryOptions, searchString);
3862
3883
  return c.json({
3863
3884
  data: entities,
@@ -3875,15 +3896,24 @@
3875
3896
  const queryOptions = parseQueryOptions(queryDict);
3876
3897
  const driver = c.get("driver") || this.driver;
3877
3898
  const fetchService = this.getFetchService(driver);
3899
+ const hookCtx = this.buildHookContext(c, "GET");
3878
3900
  if (fetchService) {
3879
3901
  const collectionPath = collection.slug;
3880
- const entity2 = await fetchService.fetchEntityForRest(collectionPath, String(id), queryOptions.include);
3902
+ let entity2 = await fetchService.fetchEntityForRest(collectionPath, String(id), queryOptions.include);
3903
+ if (!entity2) {
3904
+ throw ApiError.notFound("Entity not found");
3905
+ }
3906
+ entity2 = await this.applyAfterRead(collection.slug, entity2, hookCtx);
3881
3907
  if (!entity2) {
3882
3908
  throw ApiError.notFound("Entity not found");
3883
3909
  }
3884
3910
  return c.json(entity2);
3885
3911
  }
3886
- const entity = await this.fetchRawEntity(driver, resolvedCollection, String(id));
3912
+ let entity = await this.fetchRawEntity(driver, resolvedCollection, String(id));
3913
+ if (!entity) {
3914
+ throw ApiError.notFound("Entity not found");
3915
+ }
3916
+ entity = await this.applyAfterRead(collection.slug, entity, hookCtx);
3887
3917
  if (!entity) {
3888
3918
  throw ApiError.notFound("Entity not found");
3889
3919
  }
@@ -3893,14 +3923,24 @@
3893
3923
  try {
3894
3924
  const driver = c.get("driver") || this.driver;
3895
3925
  const path2 = collection.slug;
3896
- const body = await c.req.json().catch(() => ({}));
3926
+ const hookCtx = this.buildHookContext(c, "POST");
3927
+ let body = await c.req.json().catch(() => ({}));
3928
+ if (this.dataHooks?.beforeSave) {
3929
+ body = await this.dataHooks.beforeSave(path2, body, void 0, hookCtx);
3930
+ }
3897
3931
  const entity = await driver.saveEntity({
3898
3932
  path: path2,
3899
3933
  values: body,
3900
3934
  collection: resolvedCollection,
3901
3935
  status: "new"
3902
3936
  });
3903
- return c.json(this.formatResponse(entity), 201);
3937
+ const response = this.formatResponse(entity);
3938
+ if (this.dataHooks?.afterSave) {
3939
+ Promise.resolve(this.dataHooks.afterSave(path2, response, hookCtx)).catch((err) => {
3940
+ console.error("[BackendHooks] data.afterSave error:", err instanceof Error ? err.message : err);
3941
+ });
3942
+ }
3943
+ return c.json(response, 201);
3904
3944
  } catch (error2) {
3905
3945
  const err = error2;
3906
3946
  err.code = err.code || "BAD_REQUEST";
@@ -3911,6 +3951,7 @@
3911
3951
  try {
3912
3952
  const id = c.req.param("id");
3913
3953
  const driver = c.get("driver") || this.driver;
3954
+ const hookCtx = this.buildHookContext(c, "PUT");
3914
3955
  const existingEntity = await driver.fetchEntity({
3915
3956
  path: collection.slug,
3916
3957
  entityId: String(id),
@@ -3919,7 +3960,10 @@
3919
3960
  if (!existingEntity) {
3920
3961
  throw ApiError.notFound("Entity not found");
3921
3962
  }
3922
- const body = await c.req.json().catch(() => ({}));
3963
+ let body = await c.req.json().catch(() => ({}));
3964
+ if (this.dataHooks?.beforeSave) {
3965
+ body = await this.dataHooks.beforeSave(collection.slug, body, String(id), hookCtx);
3966
+ }
3923
3967
  const entity = await driver.saveEntity({
3924
3968
  path: collection.slug,
3925
3969
  entityId: String(id),
@@ -3927,7 +3971,13 @@
3927
3971
  collection: resolvedCollection,
3928
3972
  status: "existing"
3929
3973
  });
3930
- return c.json(this.formatResponse(entity));
3974
+ const response = this.formatResponse(entity);
3975
+ if (this.dataHooks?.afterSave) {
3976
+ Promise.resolve(this.dataHooks.afterSave(collection.slug, response, hookCtx)).catch((err) => {
3977
+ console.error("[BackendHooks] data.afterSave error:", err instanceof Error ? err.message : err);
3978
+ });
3979
+ }
3980
+ return c.json(response);
3931
3981
  } catch (error2) {
3932
3982
  const err = error2;
3933
3983
  err.code = err.code || "BAD_REQUEST";
@@ -3937,6 +3987,7 @@
3937
3987
  this.router.delete(`${basePath}/:id`, async (c) => {
3938
3988
  const id = c.req.param("id");
3939
3989
  const driver = c.get("driver") || this.driver;
3990
+ const hookCtx = this.buildHookContext(c, "DELETE");
3940
3991
  const existingEntity = await driver.fetchEntity({
3941
3992
  path: collection.slug,
3942
3993
  entityId: String(id),
@@ -3945,10 +3996,18 @@
3945
3996
  if (!existingEntity) {
3946
3997
  throw ApiError.notFound("Entity not found");
3947
3998
  }
3999
+ if (this.dataHooks?.beforeDelete) {
4000
+ await this.dataHooks.beforeDelete(collection.slug, String(id), hookCtx);
4001
+ }
3948
4002
  await driver.deleteEntity({
3949
4003
  entity: existingEntity,
3950
4004
  collection: resolvedCollection
3951
4005
  });
4006
+ if (this.dataHooks?.afterDelete) {
4007
+ Promise.resolve(this.dataHooks.afterDelete(collection.slug, String(id), hookCtx)).catch((err) => {
4008
+ console.error("[BackendHooks] data.afterDelete error:", err instanceof Error ? err.message : err);
4009
+ });
4010
+ }
3952
4011
  return new Response(null, {
3953
4012
  status: 204
3954
4013
  });
@@ -3997,7 +4056,18 @@
3997
4056
  const parsed = parseSubPath(rawPath);
3998
4057
  if (!parsed) return next();
3999
4058
  const driver = c.get("driver") || this.driver;
4000
- if (parsed.entityId) {
4059
+ if (parsed.entityId === "count") {
4060
+ const queryDict = c.req.query();
4061
+ const queryOptions = parseQueryOptions(queryDict);
4062
+ const total = driver.countEntities ? await driver.countEntities({
4063
+ path: parsed.collectionPath,
4064
+ filter: queryOptions.where,
4065
+ searchString: queryDict.searchString
4066
+ }) : 0;
4067
+ return c.json({
4068
+ count: total
4069
+ });
4070
+ } else if (parsed.entityId) {
4001
4071
  const entity = await driver.fetchEntity({
4002
4072
  path: parsed.collectionPath,
4003
4073
  entityId: parsed.entityId
@@ -4155,6 +4225,22 @@
4155
4225
  });
4156
4226
  return entity ? this.flattenEntity(entity) : null;
4157
4227
  }
4228
+ /**
4229
+ * Apply data.afterRead hook to a single entity.
4230
+ * Returns the transformed entity, or null to filter it out.
4231
+ */
4232
+ async applyAfterRead(slug, entity, ctx) {
4233
+ if (!this.dataHooks?.afterRead) return entity;
4234
+ return this.dataHooks.afterRead(slug, entity, ctx);
4235
+ }
4236
+ /**
4237
+ * Apply data.afterRead hook to an array of entities, filtering out nulls.
4238
+ */
4239
+ async applyAfterReadBatch(slug, entities, ctx) {
4240
+ if (!this.dataHooks?.afterRead) return entities;
4241
+ const results = await Promise.all(entities.map((e) => this.applyAfterRead(slug, e, ctx)));
4242
+ return results.filter((e) => e !== null);
4243
+ }
4158
4244
  }
4159
4245
  var jws$5 = {};
4160
4246
  var safeBuffer = { exports: {} };
@@ -4736,11 +4822,11 @@
4736
4822
  var toString = tostring;
4737
4823
  var util$4 = require$$5;
4738
4824
  var JWS_REGEX = /^[a-zA-Z0-9\-_]+?\.[a-zA-Z0-9\-_]+?\.([a-zA-Z0-9\-_]+)?$/;
4739
- function isObject$4(thing) {
4825
+ function isObject$3(thing) {
4740
4826
  return Object.prototype.toString.call(thing) === "[object Object]";
4741
4827
  }
4742
4828
  function safeJsonParse(thing) {
4743
- if (isObject$4(thing))
4829
+ if (isObject$3(thing))
4744
4830
  return thing;
4745
4831
  try {
4746
4832
  return JSON.parse(thing);
@@ -4866,7 +4952,7 @@
4866
4952
  return new VerifyStream(opts);
4867
4953
  };
4868
4954
  var jws$4 = jws$5;
4869
- var decode$3 = function(jwt2, options2) {
4955
+ var decode$2 = function(jwt2, options2) {
4870
4956
  options2 = options2 || {};
4871
4957
  var decoded = jws$4.decode(jwt2, options2);
4872
4958
  if (!decoded) {
@@ -4891,21 +4977,21 @@
4891
4977
  }
4892
4978
  return payload;
4893
4979
  };
4894
- var JsonWebTokenError$3 = function(message2, error2) {
4895
- Error.call(this, message2);
4980
+ var JsonWebTokenError$3 = function(message, error2) {
4981
+ Error.call(this, message);
4896
4982
  if (Error.captureStackTrace) {
4897
4983
  Error.captureStackTrace(this, this.constructor);
4898
4984
  }
4899
4985
  this.name = "JsonWebTokenError";
4900
- this.message = message2;
4986
+ this.message = message;
4901
4987
  if (error2) this.inner = error2;
4902
4988
  };
4903
4989
  JsonWebTokenError$3.prototype = Object.create(Error.prototype);
4904
4990
  JsonWebTokenError$3.prototype.constructor = JsonWebTokenError$3;
4905
4991
  var JsonWebTokenError_1 = JsonWebTokenError$3;
4906
4992
  var JsonWebTokenError$2 = JsonWebTokenError_1;
4907
- var NotBeforeError$1 = function(message2, date) {
4908
- JsonWebTokenError$2.call(this, message2);
4993
+ var NotBeforeError$1 = function(message, date) {
4994
+ JsonWebTokenError$2.call(this, message);
4909
4995
  this.name = "NotBeforeError";
4910
4996
  this.date = date;
4911
4997
  };
@@ -4913,8 +4999,8 @@
4913
4999
  NotBeforeError$1.prototype.constructor = NotBeforeError$1;
4914
5000
  var NotBeforeError_1 = NotBeforeError$1;
4915
5001
  var JsonWebTokenError$1 = JsonWebTokenError_1;
4916
- var TokenExpiredError$1 = function(message2, expiredAt) {
4917
- JsonWebTokenError$1.call(this, message2);
5002
+ var TokenExpiredError$1 = function(message, expiredAt) {
5003
+ JsonWebTokenError$1.call(this, message);
4918
5004
  this.name = "TokenExpiredError";
4919
5005
  this.expiredAt = expiredAt;
4920
5006
  };
@@ -5779,7 +5865,7 @@
5779
5865
  parseRange(range2) {
5780
5866
  const memoOpts = (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | (this.options.loose && FLAG_LOOSE);
5781
5867
  const memoKey = memoOpts + ":" + range2;
5782
- const cached = cache2.get(memoKey);
5868
+ const cached = cache.get(memoKey);
5783
5869
  if (cached) {
5784
5870
  return cached;
5785
5871
  }
@@ -5813,7 +5899,7 @@
5813
5899
  rangeMap.delete("");
5814
5900
  }
5815
5901
  const result = [...rangeMap.values()];
5816
- cache2.set(memoKey, result);
5902
+ cache.set(memoKey, result);
5817
5903
  return result;
5818
5904
  }
5819
5905
  intersects(range2, options2) {
@@ -5852,7 +5938,7 @@
5852
5938
  }
5853
5939
  range = Range2;
5854
5940
  const LRU = lrucache;
5855
- const cache2 = new LRU();
5941
+ const cache = new LRU();
5856
5942
  const parseOptions2 = parseOptions_1;
5857
5943
  const Comparator2 = requireComparator();
5858
5944
  const debug2 = debug_1;
@@ -6729,7 +6815,7 @@
6729
6815
  const JsonWebTokenError = JsonWebTokenError_1;
6730
6816
  const NotBeforeError = NotBeforeError_1;
6731
6817
  const TokenExpiredError = TokenExpiredError_1;
6732
- const decode$2 = decode$3;
6818
+ const decode$1 = decode$2;
6733
6819
  const timespan$1 = timespan$2;
6734
6820
  const validateAsymmetricKey$1 = validateAsymmetricKey$2;
6735
6821
  const PS_SUPPORTED$1 = psSupported;
@@ -6783,7 +6869,7 @@
6783
6869
  }
6784
6870
  let decodedToken;
6785
6871
  try {
6786
- decodedToken = decode$2(jwtString, { complete: true });
6872
+ decodedToken = decode$1(jwtString, { complete: true });
6787
6873
  } catch (err) {
6788
6874
  return done(err);
6789
6875
  }
@@ -7043,27 +7129,27 @@
7043
7129
  return value != null && isLength(value.length) && !isFunction(value);
7044
7130
  }
7045
7131
  function isArrayLikeObject(value) {
7046
- return isObjectLike$8(value) && isArrayLike(value);
7132
+ return isObjectLike$7(value) && isArrayLike(value);
7047
7133
  }
7048
7134
  function isFunction(value) {
7049
- var tag2 = isObject$3(value) ? objectToString$6.call(value) : "";
7050
- return tag2 == funcTag || tag2 == genTag;
7135
+ var tag = isObject$2(value) ? objectToString$6.call(value) : "";
7136
+ return tag == funcTag || tag == genTag;
7051
7137
  }
7052
7138
  function isLength(value) {
7053
7139
  return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
7054
7140
  }
7055
- function isObject$3(value) {
7141
+ function isObject$2(value) {
7056
7142
  var type = typeof value;
7057
7143
  return !!value && (type == "object" || type == "function");
7058
7144
  }
7059
- function isObjectLike$8(value) {
7145
+ function isObjectLike$7(value) {
7060
7146
  return !!value && typeof value == "object";
7061
7147
  }
7062
7148
  function isString$2(value) {
7063
- return typeof value == "string" || !isArray$2(value) && isObjectLike$8(value) && objectToString$6.call(value) == stringTag$1;
7149
+ return typeof value == "string" || !isArray$2(value) && isObjectLike$7(value) && objectToString$6.call(value) == stringTag$1;
7064
7150
  }
7065
7151
  function isSymbol$2(value) {
7066
- return typeof value == "symbol" || isObjectLike$8(value) && objectToString$6.call(value) == symbolTag$2;
7152
+ return typeof value == "symbol" || isObjectLike$7(value) && objectToString$6.call(value) == symbolTag$2;
7067
7153
  }
7068
7154
  function toFinite$2(value) {
7069
7155
  if (!value) {
@@ -7087,9 +7173,9 @@
7087
7173
  if (isSymbol$2(value)) {
7088
7174
  return NAN$2;
7089
7175
  }
7090
- if (isObject$3(value)) {
7176
+ if (isObject$2(value)) {
7091
7177
  var other = typeof value.valueOf == "function" ? value.valueOf() : value;
7092
- value = isObject$3(other) ? other + "" : other;
7178
+ value = isObject$2(other) ? other + "" : other;
7093
7179
  }
7094
7180
  if (typeof value != "string") {
7095
7181
  return value === 0 ? value : +value;
@@ -7109,9 +7195,9 @@
7109
7195
  var objectProto$5 = Object.prototype;
7110
7196
  var objectToString$5 = objectProto$5.toString;
7111
7197
  function isBoolean$1(value) {
7112
- return value === true || value === false || isObjectLike$7(value) && objectToString$5.call(value) == boolTag;
7198
+ return value === true || value === false || isObjectLike$6(value) && objectToString$5.call(value) == boolTag;
7113
7199
  }
7114
- function isObjectLike$7(value) {
7200
+ function isObjectLike$6(value) {
7115
7201
  return !!value && typeof value == "object";
7116
7202
  }
7117
7203
  var lodash_isboolean = isBoolean$1;
@@ -7127,15 +7213,15 @@
7127
7213
  function isInteger$1(value) {
7128
7214
  return typeof value == "number" && value == toInteger$1(value);
7129
7215
  }
7130
- function isObject$2(value) {
7216
+ function isObject$1(value) {
7131
7217
  var type = typeof value;
7132
7218
  return !!value && (type == "object" || type == "function");
7133
7219
  }
7134
- function isObjectLike$6(value) {
7220
+ function isObjectLike$5(value) {
7135
7221
  return !!value && typeof value == "object";
7136
7222
  }
7137
7223
  function isSymbol$1(value) {
7138
- return typeof value == "symbol" || isObjectLike$6(value) && objectToString$4.call(value) == symbolTag$1;
7224
+ return typeof value == "symbol" || isObjectLike$5(value) && objectToString$4.call(value) == symbolTag$1;
7139
7225
  }
7140
7226
  function toFinite$1(value) {
7141
7227
  if (!value) {
@@ -7159,9 +7245,9 @@
7159
7245
  if (isSymbol$1(value)) {
7160
7246
  return NAN$1;
7161
7247
  }
7162
- if (isObject$2(value)) {
7248
+ if (isObject$1(value)) {
7163
7249
  var other = typeof value.valueOf == "function" ? value.valueOf() : value;
7164
- value = isObject$2(other) ? other + "" : other;
7250
+ value = isObject$1(other) ? other + "" : other;
7165
7251
  }
7166
7252
  if (typeof value != "string") {
7167
7253
  return value === 0 ? value : +value;
@@ -7174,11 +7260,11 @@
7174
7260
  var numberTag = "[object Number]";
7175
7261
  var objectProto$3 = Object.prototype;
7176
7262
  var objectToString$3 = objectProto$3.toString;
7177
- function isObjectLike$5(value) {
7263
+ function isObjectLike$4(value) {
7178
7264
  return !!value && typeof value == "object";
7179
7265
  }
7180
7266
  function isNumber$1(value) {
7181
- return typeof value == "number" || isObjectLike$5(value) && objectToString$3.call(value) == numberTag;
7267
+ return typeof value == "number" || isObjectLike$4(value) && objectToString$3.call(value) == numberTag;
7182
7268
  }
7183
7269
  var lodash_isnumber = isNumber$1;
7184
7270
  var objectTag = "[object Object]";
@@ -7203,11 +7289,11 @@
7203
7289
  var objectCtorString = funcToString.call(Object);
7204
7290
  var objectToString$2 = objectProto$2.toString;
7205
7291
  var getPrototype = overArg(Object.getPrototypeOf, Object);
7206
- function isObjectLike$4(value) {
7292
+ function isObjectLike$3(value) {
7207
7293
  return !!value && typeof value == "object";
7208
7294
  }
7209
7295
  function isPlainObject$2(value) {
7210
- if (!isObjectLike$4(value) || objectToString$2.call(value) != objectTag || isHostObject(value)) {
7296
+ if (!isObjectLike$3(value) || objectToString$2.call(value) != objectTag || isHostObject(value)) {
7211
7297
  return false;
7212
7298
  }
7213
7299
  var proto = getPrototype(value);
@@ -7222,11 +7308,11 @@
7222
7308
  var objectProto$1 = Object.prototype;
7223
7309
  var objectToString$1 = objectProto$1.toString;
7224
7310
  var isArray$1 = Array.isArray;
7225
- function isObjectLike$3(value) {
7311
+ function isObjectLike$2(value) {
7226
7312
  return !!value && typeof value == "object";
7227
7313
  }
7228
7314
  function isString$1(value) {
7229
- return typeof value == "string" || !isArray$1(value) && isObjectLike$3(value) && objectToString$1.call(value) == stringTag;
7315
+ return typeof value == "string" || !isArray$1(value) && isObjectLike$2(value) && objectToString$1.call(value) == stringTag;
7230
7316
  }
7231
7317
  var lodash_isstring = isString$1;
7232
7318
  var FUNC_ERROR_TEXT = "Expected a function";
@@ -7258,15 +7344,15 @@
7258
7344
  function once$1(func) {
7259
7345
  return before(2, func);
7260
7346
  }
7261
- function isObject$1(value) {
7347
+ function isObject(value) {
7262
7348
  var type = typeof value;
7263
7349
  return !!value && (type == "object" || type == "function");
7264
7350
  }
7265
- function isObjectLike$2(value) {
7351
+ function isObjectLike$1(value) {
7266
7352
  return !!value && typeof value == "object";
7267
7353
  }
7268
7354
  function isSymbol(value) {
7269
- return typeof value == "symbol" || isObjectLike$2(value) && objectToString.call(value) == symbolTag;
7355
+ return typeof value == "symbol" || isObjectLike$1(value) && objectToString.call(value) == symbolTag;
7270
7356
  }
7271
7357
  function toFinite(value) {
7272
7358
  if (!value) {
@@ -7290,9 +7376,9 @@
7290
7376
  if (isSymbol(value)) {
7291
7377
  return NAN;
7292
7378
  }
7293
- if (isObject$1(value)) {
7379
+ if (isObject(value)) {
7294
7380
  var other = typeof value.valueOf == "function" ? value.valueOf() : value;
7295
- value = isObject$1(other) ? other + "" : other;
7381
+ value = isObject(other) ? other + "" : other;
7296
7382
  }
7297
7383
  if (typeof value != "string") {
7298
7384
  return value === 0 ? value : +value;
@@ -7383,7 +7469,7 @@
7383
7469
  "subject",
7384
7470
  "jwtid"
7385
7471
  ];
7386
- var sign$4 = function(payload, secretOrPrivateKey, options2, callback) {
7472
+ var sign$3 = function(payload, secretOrPrivateKey, options2, callback) {
7387
7473
  if (typeof options2 === "function") {
7388
7474
  callback = options2;
7389
7475
  options2 = {};
@@ -7522,9 +7608,9 @@
7522
7608
  }
7523
7609
  };
7524
7610
  var jsonwebtoken = {
7525
- decode: decode$3,
7611
+ decode: decode$2,
7526
7612
  verify,
7527
- sign: sign$4,
7613
+ sign: sign$3,
7528
7614
  JsonWebTokenError: JsonWebTokenError_1,
7529
7615
  NotBeforeError: NotBeforeError_1,
7530
7616
  TokenExpiredError: TokenExpiredError_1
@@ -7975,7 +8061,7 @@
7975
8061
  }
7976
8062
  function createLogger(defaultFields = {}) {
7977
8063
  const minLevel = getMinLevel();
7978
- function emit(level, message2, data) {
8064
+ function emit(level, message, data) {
7979
8065
  if (LOG_PRIORITY[level] < LOG_PRIORITY[minLevel]) return;
7980
8066
  const merged = {
7981
8067
  ...defaultFields,
@@ -7984,7 +8070,7 @@
7984
8070
  if (isProduction$1()) {
7985
8071
  const entry = {
7986
8072
  severity: GCP_SEVERITY[level],
7987
- message: message2,
8073
+ message,
7988
8074
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7989
8075
  ...merged
7990
8076
  };
@@ -7997,7 +8083,7 @@
7997
8083
  } else {
7998
8084
  const prefix = level === "error" ? "❌" : level === "warn" ? "⚠️" : level === "info" ? "ℹ️" : "🐛";
7999
8085
  const extra = Object.keys(merged).length > 0 ? ` ${JSON.stringify(merged)}` : "";
8000
- const out = `${prefix} [${level.toUpperCase()}] ${message2}${extra}`;
8086
+ const out = `${prefix} [${level.toUpperCase()}] ${message}${extra}`;
8001
8087
  if (level === "error") {
8002
8088
  console.error(out);
8003
8089
  } else if (level === "warn") {
@@ -8358,9 +8444,9 @@
8358
8444
  }
8359
8445
  return Function.prototype[Symbol.hasInstance].call(GaxiosError, instance);
8360
8446
  }
8361
- constructor(message2, config, response, error2) {
8447
+ constructor(message, config, response, error2) {
8362
8448
  var _b2;
8363
- super(message2);
8449
+ super(message);
8364
8450
  this.config = config;
8365
8451
  this.response = response;
8366
8452
  this.error = error2;
@@ -14256,8 +14342,8 @@ Content-Type: ${partContentType}\r
14256
14342
  const GOOGLE_TOKEN_URL = "https://www.googleapis.com/oauth2/v4/token";
14257
14343
  const GOOGLE_REVOKE_TOKEN_URL = "https://accounts.google.com/o/oauth2/revoke?token=";
14258
14344
  class ErrorWithCode extends Error {
14259
- constructor(message2, code2) {
14260
- super(message2);
14345
+ constructor(message, code2) {
14346
+ super(message);
14261
14347
  this.code = code2;
14262
14348
  }
14263
14349
  }
@@ -15113,13 +15199,13 @@ Content-Type: ${partContentType}\r
15113
15199
  if (!(error2 instanceof Error))
15114
15200
  throw error2;
15115
15201
  let status = 0;
15116
- let message2 = "";
15202
+ let message = "";
15117
15203
  if (error2 instanceof gaxios_1$2.GaxiosError) {
15118
15204
  status = (_c2 = (_b2 = (_a2 = error2 === null || error2 === void 0 ? void 0 : error2.response) === null || _a2 === void 0 ? void 0 : _a2.data) === null || _b2 === void 0 ? void 0 : _b2.error) === null || _c2 === void 0 ? void 0 : _c2.status;
15119
- message2 = (_f = (_e = (_d = error2 === null || error2 === void 0 ? void 0 : error2.response) === null || _d === void 0 ? void 0 : _d.data) === null || _e === void 0 ? void 0 : _e.error) === null || _f === void 0 ? void 0 : _f.message;
15205
+ message = (_f = (_e = (_d = error2 === null || error2 === void 0 ? void 0 : error2.response) === null || _d === void 0 ? void 0 : _d.data) === null || _e === void 0 ? void 0 : _e.error) === null || _f === void 0 ? void 0 : _f.message;
15120
15206
  }
15121
- if (status && message2) {
15122
- error2.message = `${status}: unable to impersonate: ${message2}`;
15207
+ if (status && message) {
15208
+ error2.message = `${status}: unable to impersonate: ${message}`;
15123
15209
  throw error2;
15124
15210
  } else {
15125
15211
  error2.message = `unable to impersonate: ${error2}`;
@@ -15281,14 +15367,14 @@ Content-Type: ${partContentType}\r
15281
15367
  const errorCode = resp.error;
15282
15368
  const errorDescription = resp.error_description;
15283
15369
  const errorUri = resp.error_uri;
15284
- let message2 = `Error code ${errorCode}`;
15370
+ let message = `Error code ${errorCode}`;
15285
15371
  if (typeof errorDescription !== "undefined") {
15286
- message2 += `: ${errorDescription}`;
15372
+ message += `: ${errorDescription}`;
15287
15373
  }
15288
15374
  if (typeof errorUri !== "undefined") {
15289
- message2 += ` - ${errorUri}`;
15375
+ message += ` - ${errorUri}`;
15290
15376
  }
15291
- const newError = new Error(message2);
15377
+ const newError = new Error(message);
15292
15378
  if (err) {
15293
15379
  const keys2 = Object.keys(err);
15294
15380
  if (err.stack) {
@@ -16016,14 +16102,14 @@ Content-Type: ${partContentType}\r
16016
16102
  }
16017
16103
  }
16018
16104
  awsrequestsigner.AwsRequestSigner = AwsRequestSigner;
16019
- async function sign$3(crypto2, key, msg) {
16105
+ async function sign$2(crypto2, key, msg) {
16020
16106
  return await crypto2.signWithHmacSha256(key, msg);
16021
16107
  }
16022
16108
  async function getSigningKey(crypto2, key, dateStamp, region, serviceName) {
16023
- const kDate = await sign$3(crypto2, `AWS4${key}`, dateStamp);
16024
- const kRegion = await sign$3(crypto2, kDate, region);
16025
- const kService = await sign$3(crypto2, kRegion, serviceName);
16026
- const kSigning = await sign$3(crypto2, kService, "aws4_request");
16109
+ const kDate = await sign$2(crypto2, `AWS4${key}`, dateStamp);
16110
+ const kRegion = await sign$2(crypto2, kDate, region);
16111
+ const kService = await sign$2(crypto2, kRegion, serviceName);
16112
+ const kSigning = await sign$2(crypto2, kService, "aws4_request");
16027
16113
  return kSigning;
16028
16114
  }
16029
16115
  async function generateAuthenticationHeaderMap(options2) {
@@ -16069,7 +16155,7 @@ ${amzDate}
16069
16155
  ${credentialScope}
16070
16156
  ` + await options2.crypto.sha256DigestHex(canonicalRequest);
16071
16157
  const signingKey = await getSigningKey(options2.crypto, options2.securityCredentials.secretAccessKey, dateStamp, options2.region, serviceName);
16072
- const signature = await sign$3(options2.crypto, signingKey, stringToSign);
16158
+ const signature = await sign$2(options2.crypto, signingKey, stringToSign);
16073
16159
  const authorizationHeader = `${AWS_ALGORITHM} Credential=${options2.securityCredentials.accessKeyId}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${(0, crypto_1.fromArrayBufferToHex)(signature)}`;
16074
16160
  return {
16075
16161
  // Do not return x-amz-date if date is available.
@@ -16400,8 +16486,8 @@ ${credentialScope}
16400
16486
  }
16401
16487
  executableResponse.ExecutableResponse = ExecutableResponse;
16402
16488
  class ExecutableResponseError extends Error {
16403
- constructor(message2) {
16404
- super(message2);
16489
+ constructor(message) {
16490
+ super(message);
16405
16491
  Object.setPrototypeOf(this, new.target.prototype);
16406
16492
  }
16407
16493
  }
@@ -16564,8 +16650,8 @@ ${credentialScope}
16564
16650
  const executable_response_1 = executableResponse;
16565
16651
  const pluggable_auth_handler_1 = requirePluggableAuthHandler();
16566
16652
  class ExecutableError extends Error {
16567
- constructor(message2, code2) {
16568
- super(`The executable failed with exit code: ${code2} and error message: ${message2}.`);
16653
+ constructor(message, code2) {
16654
+ super(`The executable failed with exit code: ${code2} and error message: ${message}.`);
16569
16655
  this.code = code2;
16570
16656
  Object.setPrototypeOf(this, new.target.prototype);
16571
16657
  }
@@ -18213,104 +18299,104 @@ ${credentialScope}
18213
18299
  return error2;
18214
18300
  };
18215
18301
  const errorMap = (issue, _ctx) => {
18216
- let message2;
18302
+ let message;
18217
18303
  switch (issue.code) {
18218
18304
  case ZodIssueCode.invalid_type:
18219
18305
  if (issue.received === ZodParsedType.undefined) {
18220
- message2 = "Required";
18306
+ message = "Required";
18221
18307
  } else {
18222
- message2 = `Expected ${issue.expected}, received ${issue.received}`;
18308
+ message = `Expected ${issue.expected}, received ${issue.received}`;
18223
18309
  }
18224
18310
  break;
18225
18311
  case ZodIssueCode.invalid_literal:
18226
- message2 = `Invalid literal value, expected ${JSON.stringify(issue.expected, util$1.jsonStringifyReplacer)}`;
18312
+ message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util$1.jsonStringifyReplacer)}`;
18227
18313
  break;
18228
18314
  case ZodIssueCode.unrecognized_keys:
18229
- message2 = `Unrecognized key(s) in object: ${util$1.joinValues(issue.keys, ", ")}`;
18315
+ message = `Unrecognized key(s) in object: ${util$1.joinValues(issue.keys, ", ")}`;
18230
18316
  break;
18231
18317
  case ZodIssueCode.invalid_union:
18232
- message2 = `Invalid input`;
18318
+ message = `Invalid input`;
18233
18319
  break;
18234
18320
  case ZodIssueCode.invalid_union_discriminator:
18235
- message2 = `Invalid discriminator value. Expected ${util$1.joinValues(issue.options)}`;
18321
+ message = `Invalid discriminator value. Expected ${util$1.joinValues(issue.options)}`;
18236
18322
  break;
18237
18323
  case ZodIssueCode.invalid_enum_value:
18238
- message2 = `Invalid enum value. Expected ${util$1.joinValues(issue.options)}, received '${issue.received}'`;
18324
+ message = `Invalid enum value. Expected ${util$1.joinValues(issue.options)}, received '${issue.received}'`;
18239
18325
  break;
18240
18326
  case ZodIssueCode.invalid_arguments:
18241
- message2 = `Invalid function arguments`;
18327
+ message = `Invalid function arguments`;
18242
18328
  break;
18243
18329
  case ZodIssueCode.invalid_return_type:
18244
- message2 = `Invalid function return type`;
18330
+ message = `Invalid function return type`;
18245
18331
  break;
18246
18332
  case ZodIssueCode.invalid_date:
18247
- message2 = `Invalid date`;
18333
+ message = `Invalid date`;
18248
18334
  break;
18249
18335
  case ZodIssueCode.invalid_string:
18250
18336
  if (typeof issue.validation === "object") {
18251
18337
  if ("includes" in issue.validation) {
18252
- message2 = `Invalid input: must include "${issue.validation.includes}"`;
18338
+ message = `Invalid input: must include "${issue.validation.includes}"`;
18253
18339
  if (typeof issue.validation.position === "number") {
18254
- message2 = `${message2} at one or more positions greater than or equal to ${issue.validation.position}`;
18340
+ message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;
18255
18341
  }
18256
18342
  } else if ("startsWith" in issue.validation) {
18257
- message2 = `Invalid input: must start with "${issue.validation.startsWith}"`;
18343
+ message = `Invalid input: must start with "${issue.validation.startsWith}"`;
18258
18344
  } else if ("endsWith" in issue.validation) {
18259
- message2 = `Invalid input: must end with "${issue.validation.endsWith}"`;
18345
+ message = `Invalid input: must end with "${issue.validation.endsWith}"`;
18260
18346
  } else {
18261
18347
  util$1.assertNever(issue.validation);
18262
18348
  }
18263
18349
  } else if (issue.validation !== "regex") {
18264
- message2 = `Invalid ${issue.validation}`;
18350
+ message = `Invalid ${issue.validation}`;
18265
18351
  } else {
18266
- message2 = "Invalid";
18352
+ message = "Invalid";
18267
18353
  }
18268
18354
  break;
18269
18355
  case ZodIssueCode.too_small:
18270
18356
  if (issue.type === "array")
18271
- message2 = `Array must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`;
18357
+ message = `Array must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`;
18272
18358
  else if (issue.type === "string")
18273
- message2 = `String must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;
18359
+ message = `String must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;
18274
18360
  else if (issue.type === "number")
18275
- message2 = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
18361
+ message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
18276
18362
  else if (issue.type === "bigint")
18277
- message2 = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
18363
+ message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
18278
18364
  else if (issue.type === "date")
18279
- message2 = `Date must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${new Date(Number(issue.minimum))}`;
18365
+ message = `Date must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${new Date(Number(issue.minimum))}`;
18280
18366
  else
18281
- message2 = "Invalid input";
18367
+ message = "Invalid input";
18282
18368
  break;
18283
18369
  case ZodIssueCode.too_big:
18284
18370
  if (issue.type === "array")
18285
- message2 = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`;
18371
+ message = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`;
18286
18372
  else if (issue.type === "string")
18287
- message2 = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;
18373
+ message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;
18288
18374
  else if (issue.type === "number")
18289
- message2 = `Number must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
18375
+ message = `Number must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
18290
18376
  else if (issue.type === "bigint")
18291
- message2 = `BigInt must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
18377
+ message = `BigInt must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
18292
18378
  else if (issue.type === "date")
18293
- message2 = `Date must be ${issue.exact ? `exactly` : issue.inclusive ? `smaller than or equal to` : `smaller than`} ${new Date(Number(issue.maximum))}`;
18379
+ message = `Date must be ${issue.exact ? `exactly` : issue.inclusive ? `smaller than or equal to` : `smaller than`} ${new Date(Number(issue.maximum))}`;
18294
18380
  else
18295
- message2 = "Invalid input";
18381
+ message = "Invalid input";
18296
18382
  break;
18297
18383
  case ZodIssueCode.custom:
18298
- message2 = `Invalid input`;
18384
+ message = `Invalid input`;
18299
18385
  break;
18300
18386
  case ZodIssueCode.invalid_intersection_types:
18301
- message2 = `Intersection results could not be merged`;
18387
+ message = `Intersection results could not be merged`;
18302
18388
  break;
18303
18389
  case ZodIssueCode.not_multiple_of:
18304
- message2 = `Number must be a multiple of ${issue.multipleOf}`;
18390
+ message = `Number must be a multiple of ${issue.multipleOf}`;
18305
18391
  break;
18306
18392
  case ZodIssueCode.not_finite:
18307
- message2 = "Number must be finite";
18393
+ message = "Number must be finite";
18308
18394
  break;
18309
18395
  default:
18310
- message2 = _ctx.defaultError;
18396
+ message = _ctx.defaultError;
18311
18397
  util$1.assertNever(issue);
18312
18398
  }
18313
- return { message: message2 };
18399
+ return { message };
18314
18400
  };
18315
18401
  let overrideErrorMap = errorMap;
18316
18402
  function getErrorMap() {
@@ -18425,8 +18511,8 @@ ${credentialScope}
18425
18511
  const isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
18426
18512
  var errorUtil;
18427
18513
  (function(errorUtil2) {
18428
- errorUtil2.errToObj = (message2) => typeof message2 === "string" ? { message: message2 } : message2 || {};
18429
- errorUtil2.toString = (message2) => typeof message2 === "string" ? message2 : message2?.message;
18514
+ errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};
18515
+ errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message;
18430
18516
  })(errorUtil || (errorUtil = {}));
18431
18517
  class ParseInputLazyPath {
18432
18518
  constructor(parent, value, path2, key) {
@@ -18476,16 +18562,16 @@ ${credentialScope}
18476
18562
  if (errorMap2)
18477
18563
  return { errorMap: errorMap2, description: description2 };
18478
18564
  const customMap = (iss, ctx) => {
18479
- const { message: message2 } = params;
18565
+ const { message } = params;
18480
18566
  if (iss.code === "invalid_enum_value") {
18481
- return { message: message2 ?? ctx.defaultError };
18567
+ return { message: message ?? ctx.defaultError };
18482
18568
  }
18483
18569
  if (typeof ctx.data === "undefined") {
18484
- return { message: message2 ?? required_error ?? ctx.defaultError };
18570
+ return { message: message ?? required_error ?? ctx.defaultError };
18485
18571
  }
18486
18572
  if (iss.code !== "invalid_type")
18487
18573
  return { message: ctx.defaultError };
18488
- return { message: message2 ?? invalid_type_error ?? ctx.defaultError };
18574
+ return { message: message ?? invalid_type_error ?? ctx.defaultError };
18489
18575
  };
18490
18576
  return { errorMap: customMap, description: description2 };
18491
18577
  }
@@ -18611,14 +18697,14 @@ ${credentialScope}
18611
18697
  const result = await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult));
18612
18698
  return handleResult(ctx, result);
18613
18699
  }
18614
- refine(check, message2) {
18700
+ refine(check, message) {
18615
18701
  const getIssueProperties = (val) => {
18616
- if (typeof message2 === "string" || typeof message2 === "undefined") {
18617
- return { message: message2 };
18618
- } else if (typeof message2 === "function") {
18619
- return message2(val);
18702
+ if (typeof message === "string" || typeof message === "undefined") {
18703
+ return { message };
18704
+ } else if (typeof message === "function") {
18705
+ return message(val);
18620
18706
  } else {
18621
- return message2;
18707
+ return message;
18622
18708
  }
18623
18709
  };
18624
18710
  return this._refinement((val, ctx) => {
@@ -19154,11 +19240,11 @@ ${credentialScope}
19154
19240
  }
19155
19241
  return { status: status.value, value: input.data };
19156
19242
  }
19157
- _regex(regex2, validation, message2) {
19243
+ _regex(regex2, validation, message) {
19158
19244
  return this.refinement((data) => regex2.test(data), {
19159
19245
  validation,
19160
19246
  code: ZodIssueCode.invalid_string,
19161
- ...errorUtil.errToObj(message2)
19247
+ ...errorUtil.errToObj(message)
19162
19248
  });
19163
19249
  }
19164
19250
  _addCheck(check) {
@@ -19167,37 +19253,37 @@ ${credentialScope}
19167
19253
  checks: [...this._def.checks, check]
19168
19254
  });
19169
19255
  }
19170
- email(message2) {
19171
- return this._addCheck({ kind: "email", ...errorUtil.errToObj(message2) });
19256
+ email(message) {
19257
+ return this._addCheck({ kind: "email", ...errorUtil.errToObj(message) });
19172
19258
  }
19173
- url(message2) {
19174
- return this._addCheck({ kind: "url", ...errorUtil.errToObj(message2) });
19259
+ url(message) {
19260
+ return this._addCheck({ kind: "url", ...errorUtil.errToObj(message) });
19175
19261
  }
19176
- emoji(message2) {
19177
- return this._addCheck({ kind: "emoji", ...errorUtil.errToObj(message2) });
19262
+ emoji(message) {
19263
+ return this._addCheck({ kind: "emoji", ...errorUtil.errToObj(message) });
19178
19264
  }
19179
- uuid(message2) {
19180
- return this._addCheck({ kind: "uuid", ...errorUtil.errToObj(message2) });
19265
+ uuid(message) {
19266
+ return this._addCheck({ kind: "uuid", ...errorUtil.errToObj(message) });
19181
19267
  }
19182
- nanoid(message2) {
19183
- return this._addCheck({ kind: "nanoid", ...errorUtil.errToObj(message2) });
19268
+ nanoid(message) {
19269
+ return this._addCheck({ kind: "nanoid", ...errorUtil.errToObj(message) });
19184
19270
  }
19185
- cuid(message2) {
19186
- return this._addCheck({ kind: "cuid", ...errorUtil.errToObj(message2) });
19271
+ cuid(message) {
19272
+ return this._addCheck({ kind: "cuid", ...errorUtil.errToObj(message) });
19187
19273
  }
19188
- cuid2(message2) {
19189
- return this._addCheck({ kind: "cuid2", ...errorUtil.errToObj(message2) });
19274
+ cuid2(message) {
19275
+ return this._addCheck({ kind: "cuid2", ...errorUtil.errToObj(message) });
19190
19276
  }
19191
- ulid(message2) {
19192
- return this._addCheck({ kind: "ulid", ...errorUtil.errToObj(message2) });
19277
+ ulid(message) {
19278
+ return this._addCheck({ kind: "ulid", ...errorUtil.errToObj(message) });
19193
19279
  }
19194
- base64(message2) {
19195
- return this._addCheck({ kind: "base64", ...errorUtil.errToObj(message2) });
19280
+ base64(message) {
19281
+ return this._addCheck({ kind: "base64", ...errorUtil.errToObj(message) });
19196
19282
  }
19197
- base64url(message2) {
19283
+ base64url(message) {
19198
19284
  return this._addCheck({
19199
19285
  kind: "base64url",
19200
- ...errorUtil.errToObj(message2)
19286
+ ...errorUtil.errToObj(message)
19201
19287
  });
19202
19288
  }
19203
19289
  jwt(options2) {
@@ -19227,8 +19313,8 @@ ${credentialScope}
19227
19313
  ...errorUtil.errToObj(options2?.message)
19228
19314
  });
19229
19315
  }
19230
- date(message2) {
19231
- return this._addCheck({ kind: "date", message: message2 });
19316
+ date(message) {
19317
+ return this._addCheck({ kind: "date", message });
19232
19318
  }
19233
19319
  time(options2) {
19234
19320
  if (typeof options2 === "string") {
@@ -19244,14 +19330,14 @@ ${credentialScope}
19244
19330
  ...errorUtil.errToObj(options2?.message)
19245
19331
  });
19246
19332
  }
19247
- duration(message2) {
19248
- return this._addCheck({ kind: "duration", ...errorUtil.errToObj(message2) });
19333
+ duration(message) {
19334
+ return this._addCheck({ kind: "duration", ...errorUtil.errToObj(message) });
19249
19335
  }
19250
- regex(regex2, message2) {
19336
+ regex(regex2, message) {
19251
19337
  return this._addCheck({
19252
19338
  kind: "regex",
19253
19339
  regex: regex2,
19254
- ...errorUtil.errToObj(message2)
19340
+ ...errorUtil.errToObj(message)
19255
19341
  });
19256
19342
  }
19257
19343
  includes(value, options2) {
@@ -19262,46 +19348,46 @@ ${credentialScope}
19262
19348
  ...errorUtil.errToObj(options2?.message)
19263
19349
  });
19264
19350
  }
19265
- startsWith(value, message2) {
19351
+ startsWith(value, message) {
19266
19352
  return this._addCheck({
19267
19353
  kind: "startsWith",
19268
19354
  value,
19269
- ...errorUtil.errToObj(message2)
19355
+ ...errorUtil.errToObj(message)
19270
19356
  });
19271
19357
  }
19272
- endsWith(value, message2) {
19358
+ endsWith(value, message) {
19273
19359
  return this._addCheck({
19274
19360
  kind: "endsWith",
19275
19361
  value,
19276
- ...errorUtil.errToObj(message2)
19362
+ ...errorUtil.errToObj(message)
19277
19363
  });
19278
19364
  }
19279
- min(minLength, message2) {
19365
+ min(minLength, message) {
19280
19366
  return this._addCheck({
19281
19367
  kind: "min",
19282
19368
  value: minLength,
19283
- ...errorUtil.errToObj(message2)
19369
+ ...errorUtil.errToObj(message)
19284
19370
  });
19285
19371
  }
19286
- max(maxLength, message2) {
19372
+ max(maxLength, message) {
19287
19373
  return this._addCheck({
19288
19374
  kind: "max",
19289
19375
  value: maxLength,
19290
- ...errorUtil.errToObj(message2)
19376
+ ...errorUtil.errToObj(message)
19291
19377
  });
19292
19378
  }
19293
- length(len2, message2) {
19379
+ length(len2, message) {
19294
19380
  return this._addCheck({
19295
19381
  kind: "length",
19296
19382
  value: len2,
19297
- ...errorUtil.errToObj(message2)
19383
+ ...errorUtil.errToObj(message)
19298
19384
  });
19299
19385
  }
19300
19386
  /**
19301
19387
  * Equivalent to `.min(1)`
19302
19388
  */
19303
- nonempty(message2) {
19304
- return this.min(1, errorUtil.errToObj(message2));
19389
+ nonempty(message) {
19390
+ return this.min(1, errorUtil.errToObj(message));
19305
19391
  }
19306
19392
  trim() {
19307
19393
  return new ZodString({
@@ -19494,19 +19580,19 @@ ${credentialScope}
19494
19580
  }
19495
19581
  return { status: status.value, value: input.data };
19496
19582
  }
19497
- gte(value, message2) {
19498
- return this.setLimit("min", value, true, errorUtil.toString(message2));
19583
+ gte(value, message) {
19584
+ return this.setLimit("min", value, true, errorUtil.toString(message));
19499
19585
  }
19500
- gt(value, message2) {
19501
- return this.setLimit("min", value, false, errorUtil.toString(message2));
19586
+ gt(value, message) {
19587
+ return this.setLimit("min", value, false, errorUtil.toString(message));
19502
19588
  }
19503
- lte(value, message2) {
19504
- return this.setLimit("max", value, true, errorUtil.toString(message2));
19589
+ lte(value, message) {
19590
+ return this.setLimit("max", value, true, errorUtil.toString(message));
19505
19591
  }
19506
- lt(value, message2) {
19507
- return this.setLimit("max", value, false, errorUtil.toString(message2));
19592
+ lt(value, message) {
19593
+ return this.setLimit("max", value, false, errorUtil.toString(message));
19508
19594
  }
19509
- setLimit(kind, value, inclusive, message2) {
19595
+ setLimit(kind, value, inclusive, message) {
19510
19596
  return new ZodNumber({
19511
19597
  ...this._def,
19512
19598
  checks: [
@@ -19515,7 +19601,7 @@ ${credentialScope}
19515
19601
  kind,
19516
19602
  value,
19517
19603
  inclusive,
19518
- message: errorUtil.toString(message2)
19604
+ message: errorUtil.toString(message)
19519
19605
  }
19520
19606
  ]
19521
19607
  });
@@ -19526,68 +19612,68 @@ ${credentialScope}
19526
19612
  checks: [...this._def.checks, check]
19527
19613
  });
19528
19614
  }
19529
- int(message2) {
19615
+ int(message) {
19530
19616
  return this._addCheck({
19531
19617
  kind: "int",
19532
- message: errorUtil.toString(message2)
19618
+ message: errorUtil.toString(message)
19533
19619
  });
19534
19620
  }
19535
- positive(message2) {
19621
+ positive(message) {
19536
19622
  return this._addCheck({
19537
19623
  kind: "min",
19538
19624
  value: 0,
19539
19625
  inclusive: false,
19540
- message: errorUtil.toString(message2)
19626
+ message: errorUtil.toString(message)
19541
19627
  });
19542
19628
  }
19543
- negative(message2) {
19629
+ negative(message) {
19544
19630
  return this._addCheck({
19545
19631
  kind: "max",
19546
19632
  value: 0,
19547
19633
  inclusive: false,
19548
- message: errorUtil.toString(message2)
19634
+ message: errorUtil.toString(message)
19549
19635
  });
19550
19636
  }
19551
- nonpositive(message2) {
19637
+ nonpositive(message) {
19552
19638
  return this._addCheck({
19553
19639
  kind: "max",
19554
19640
  value: 0,
19555
19641
  inclusive: true,
19556
- message: errorUtil.toString(message2)
19642
+ message: errorUtil.toString(message)
19557
19643
  });
19558
19644
  }
19559
- nonnegative(message2) {
19645
+ nonnegative(message) {
19560
19646
  return this._addCheck({
19561
19647
  kind: "min",
19562
19648
  value: 0,
19563
19649
  inclusive: true,
19564
- message: errorUtil.toString(message2)
19650
+ message: errorUtil.toString(message)
19565
19651
  });
19566
19652
  }
19567
- multipleOf(value, message2) {
19653
+ multipleOf(value, message) {
19568
19654
  return this._addCheck({
19569
19655
  kind: "multipleOf",
19570
19656
  value,
19571
- message: errorUtil.toString(message2)
19657
+ message: errorUtil.toString(message)
19572
19658
  });
19573
19659
  }
19574
- finite(message2) {
19660
+ finite(message) {
19575
19661
  return this._addCheck({
19576
19662
  kind: "finite",
19577
- message: errorUtil.toString(message2)
19663
+ message: errorUtil.toString(message)
19578
19664
  });
19579
19665
  }
19580
- safe(message2) {
19666
+ safe(message) {
19581
19667
  return this._addCheck({
19582
19668
  kind: "min",
19583
19669
  inclusive: true,
19584
19670
  value: Number.MIN_SAFE_INTEGER,
19585
- message: errorUtil.toString(message2)
19671
+ message: errorUtil.toString(message)
19586
19672
  })._addCheck({
19587
19673
  kind: "max",
19588
19674
  inclusive: true,
19589
19675
  value: Number.MAX_SAFE_INTEGER,
19590
- message: errorUtil.toString(message2)
19676
+ message: errorUtil.toString(message)
19591
19677
  });
19592
19678
  }
19593
19679
  get minValue() {
@@ -19710,19 +19796,19 @@ ${credentialScope}
19710
19796
  });
19711
19797
  return INVALID;
19712
19798
  }
19713
- gte(value, message2) {
19714
- return this.setLimit("min", value, true, errorUtil.toString(message2));
19799
+ gte(value, message) {
19800
+ return this.setLimit("min", value, true, errorUtil.toString(message));
19715
19801
  }
19716
- gt(value, message2) {
19717
- return this.setLimit("min", value, false, errorUtil.toString(message2));
19802
+ gt(value, message) {
19803
+ return this.setLimit("min", value, false, errorUtil.toString(message));
19718
19804
  }
19719
- lte(value, message2) {
19720
- return this.setLimit("max", value, true, errorUtil.toString(message2));
19805
+ lte(value, message) {
19806
+ return this.setLimit("max", value, true, errorUtil.toString(message));
19721
19807
  }
19722
- lt(value, message2) {
19723
- return this.setLimit("max", value, false, errorUtil.toString(message2));
19808
+ lt(value, message) {
19809
+ return this.setLimit("max", value, false, errorUtil.toString(message));
19724
19810
  }
19725
- setLimit(kind, value, inclusive, message2) {
19811
+ setLimit(kind, value, inclusive, message) {
19726
19812
  return new ZodBigInt({
19727
19813
  ...this._def,
19728
19814
  checks: [
@@ -19731,7 +19817,7 @@ ${credentialScope}
19731
19817
  kind,
19732
19818
  value,
19733
19819
  inclusive,
19734
- message: errorUtil.toString(message2)
19820
+ message: errorUtil.toString(message)
19735
19821
  }
19736
19822
  ]
19737
19823
  });
@@ -19742,43 +19828,43 @@ ${credentialScope}
19742
19828
  checks: [...this._def.checks, check]
19743
19829
  });
19744
19830
  }
19745
- positive(message2) {
19831
+ positive(message) {
19746
19832
  return this._addCheck({
19747
19833
  kind: "min",
19748
19834
  value: BigInt(0),
19749
19835
  inclusive: false,
19750
- message: errorUtil.toString(message2)
19836
+ message: errorUtil.toString(message)
19751
19837
  });
19752
19838
  }
19753
- negative(message2) {
19839
+ negative(message) {
19754
19840
  return this._addCheck({
19755
19841
  kind: "max",
19756
19842
  value: BigInt(0),
19757
19843
  inclusive: false,
19758
- message: errorUtil.toString(message2)
19844
+ message: errorUtil.toString(message)
19759
19845
  });
19760
19846
  }
19761
- nonpositive(message2) {
19847
+ nonpositive(message) {
19762
19848
  return this._addCheck({
19763
19849
  kind: "max",
19764
19850
  value: BigInt(0),
19765
19851
  inclusive: true,
19766
- message: errorUtil.toString(message2)
19852
+ message: errorUtil.toString(message)
19767
19853
  });
19768
19854
  }
19769
- nonnegative(message2) {
19855
+ nonnegative(message) {
19770
19856
  return this._addCheck({
19771
19857
  kind: "min",
19772
19858
  value: BigInt(0),
19773
19859
  inclusive: true,
19774
- message: errorUtil.toString(message2)
19860
+ message: errorUtil.toString(message)
19775
19861
  });
19776
19862
  }
19777
- multipleOf(value, message2) {
19863
+ multipleOf(value, message) {
19778
19864
  return this._addCheck({
19779
19865
  kind: "multipleOf",
19780
19866
  value,
19781
- message: errorUtil.toString(message2)
19867
+ message: errorUtil.toString(message)
19782
19868
  });
19783
19869
  }
19784
19870
  get minValue() {
@@ -19901,18 +19987,18 @@ ${credentialScope}
19901
19987
  checks: [...this._def.checks, check]
19902
19988
  });
19903
19989
  }
19904
- min(minDate, message2) {
19990
+ min(minDate, message) {
19905
19991
  return this._addCheck({
19906
19992
  kind: "min",
19907
19993
  value: minDate.getTime(),
19908
- message: errorUtil.toString(message2)
19994
+ message: errorUtil.toString(message)
19909
19995
  });
19910
19996
  }
19911
- max(maxDate, message2) {
19997
+ max(maxDate, message) {
19912
19998
  return this._addCheck({
19913
19999
  kind: "max",
19914
20000
  value: maxDate.getTime(),
19915
- message: errorUtil.toString(message2)
20001
+ message: errorUtil.toString(message)
19916
20002
  });
19917
20003
  }
19918
20004
  get minDate() {
@@ -20144,26 +20230,26 @@ ${credentialScope}
20144
20230
  get element() {
20145
20231
  return this._def.type;
20146
20232
  }
20147
- min(minLength, message2) {
20233
+ min(minLength, message) {
20148
20234
  return new ZodArray({
20149
20235
  ...this._def,
20150
- minLength: { value: minLength, message: errorUtil.toString(message2) }
20236
+ minLength: { value: minLength, message: errorUtil.toString(message) }
20151
20237
  });
20152
20238
  }
20153
- max(maxLength, message2) {
20239
+ max(maxLength, message) {
20154
20240
  return new ZodArray({
20155
20241
  ...this._def,
20156
- maxLength: { value: maxLength, message: errorUtil.toString(message2) }
20242
+ maxLength: { value: maxLength, message: errorUtil.toString(message) }
20157
20243
  });
20158
20244
  }
20159
- length(len2, message2) {
20245
+ length(len2, message) {
20160
20246
  return new ZodArray({
20161
20247
  ...this._def,
20162
- exactLength: { value: len2, message: errorUtil.toString(message2) }
20248
+ exactLength: { value: len2, message: errorUtil.toString(message) }
20163
20249
  });
20164
20250
  }
20165
- nonempty(message2) {
20166
- return this.min(1, message2);
20251
+ nonempty(message) {
20252
+ return this.min(1, message);
20167
20253
  }
20168
20254
  }
20169
20255
  ZodArray.create = (schema, params) => {
@@ -20306,17 +20392,17 @@ ${credentialScope}
20306
20392
  get shape() {
20307
20393
  return this._def.shape();
20308
20394
  }
20309
- strict(message2) {
20395
+ strict(message) {
20310
20396
  errorUtil.errToObj;
20311
20397
  return new ZodObject({
20312
20398
  ...this._def,
20313
20399
  unknownKeys: "strict",
20314
- ...message2 !== void 0 ? {
20400
+ ...message !== void 0 ? {
20315
20401
  errorMap: (issue, ctx) => {
20316
20402
  const defaultError = this._def.errorMap?.(issue, ctx).message ?? ctx.defaultError;
20317
20403
  if (issue.code === "unrecognized_keys")
20318
20404
  return {
20319
- message: errorUtil.errToObj(message2).message ?? defaultError
20405
+ message: errorUtil.errToObj(message).message ?? defaultError
20320
20406
  };
20321
20407
  return {
20322
20408
  message: defaultError
@@ -20912,23 +20998,23 @@ ${credentialScope}
20912
20998
  return finalizeSet(elements);
20913
20999
  }
20914
21000
  }
20915
- min(minSize, message2) {
21001
+ min(minSize, message) {
20916
21002
  return new ZodSet({
20917
21003
  ...this._def,
20918
- minSize: { value: minSize, message: errorUtil.toString(message2) }
21004
+ minSize: { value: minSize, message: errorUtil.toString(message) }
20919
21005
  });
20920
21006
  }
20921
- max(maxSize, message2) {
21007
+ max(maxSize, message) {
20922
21008
  return new ZodSet({
20923
21009
  ...this._def,
20924
- maxSize: { value: maxSize, message: errorUtil.toString(message2) }
21010
+ maxSize: { value: maxSize, message: errorUtil.toString(message) }
20925
21011
  });
20926
21012
  }
20927
- size(size, message2) {
20928
- return this.min(size, message2).max(size, message2);
21013
+ size(size, message) {
21014
+ return this.min(size, message).max(size, message);
20929
21015
  }
20930
- nonempty(message2) {
20931
- return this.min(1, message2);
21016
+ nonempty(message) {
21017
+ return this.min(1, message);
20932
21018
  }
20933
21019
  }
20934
21020
  ZodSet.create = (valueType, params) => {
@@ -21538,32 +21624,125 @@ ${credentialScope}
21538
21624
  ZodPromise.create;
21539
21625
  ZodOptional.create;
21540
21626
  ZodNullable.create;
21541
- function createGoogleProvider(clientId) {
21542
- const googleClient = new src$4.OAuth2Client(clientId);
21627
+ function createGoogleProvider(config) {
21628
+ const clientId = typeof config === "string" ? config : config.clientId;
21629
+ const clientSecret = typeof config === "string" ? void 0 : config.clientSecret;
21630
+ const googleClient = new src$4.OAuth2Client(clientId, clientSecret);
21543
21631
  return {
21544
21632
  id: "google",
21545
21633
  schema: objectType({
21546
- idToken: stringType().min(1, "ID token is required")
21634
+ idToken: stringType().min(1).optional(),
21635
+ accessToken: stringType().min(1).optional(),
21636
+ code: stringType().min(1).optional(),
21637
+ redirectUri: stringType().min(1).optional()
21638
+ }).refine((data) => data.idToken || data.accessToken || data.code && data.redirectUri, {
21639
+ message: "One of idToken, accessToken, or code+redirectUri is required"
21547
21640
  }),
21548
21641
  verify: async (payload) => {
21549
21642
  try {
21550
- const ticket = await googleClient.verifyIdToken({
21551
- idToken: payload.idToken,
21552
- audience: clientId
21553
- });
21554
- const content = ticket.getPayload();
21555
- if (!content) {
21556
- return null;
21643
+ if (payload.idToken) {
21644
+ const ticket = await googleClient.verifyIdToken({
21645
+ idToken: payload.idToken,
21646
+ audience: clientId
21647
+ });
21648
+ const content = ticket.getPayload();
21649
+ if (!content) {
21650
+ throw new Error("Google ID token payload was empty");
21651
+ }
21652
+ return {
21653
+ providerId: content.sub,
21654
+ email: content.email || "",
21655
+ displayName: content.name || null,
21656
+ photoUrl: content.picture || null
21657
+ };
21557
21658
  }
21558
- return {
21559
- providerId: content.sub,
21560
- email: content.email || "",
21561
- displayName: content.name || null,
21562
- photoUrl: content.picture || null
21563
- };
21659
+ if (payload.accessToken) {
21660
+ const res = await fetch("https://www.googleapis.com/oauth2/v3/userinfo", {
21661
+ headers: {
21662
+ Authorization: `Bearer ${payload.accessToken}`
21663
+ }
21664
+ });
21665
+ if (!res.ok) {
21666
+ throw new Error(`Google userinfo request failed with status ${res.status}`);
21667
+ }
21668
+ const info = await res.json();
21669
+ if (!info.sub || !info.email) {
21670
+ throw new Error("Google userinfo response missing sub or email");
21671
+ }
21672
+ return {
21673
+ providerId: info.sub,
21674
+ email: info.email,
21675
+ displayName: info.name || null,
21676
+ photoUrl: info.picture || null
21677
+ };
21678
+ }
21679
+ if (payload.code && payload.redirectUri) {
21680
+ if (!clientSecret) {
21681
+ throw new Error("Google authorization code flow requires clientSecret. Configure GOOGLE_CLIENT_SECRET in your environment.");
21682
+ }
21683
+ const tokenResponse = await fetch("https://oauth2.googleapis.com/token", {
21684
+ method: "POST",
21685
+ headers: {
21686
+ "Content-Type": "application/x-www-form-urlencoded"
21687
+ },
21688
+ body: new URLSearchParams({
21689
+ code: payload.code,
21690
+ client_id: clientId,
21691
+ client_secret: clientSecret,
21692
+ redirect_uri: payload.redirectUri,
21693
+ grant_type: "authorization_code"
21694
+ })
21695
+ });
21696
+ if (!tokenResponse.ok) {
21697
+ const errorBody = await tokenResponse.text();
21698
+ throw new Error(`Google token exchange failed (${tokenResponse.status}): ${errorBody}`);
21699
+ }
21700
+ const tokenData = await tokenResponse.json();
21701
+ if (tokenData.error) {
21702
+ throw new Error(`Google token exchange error: ${tokenData.error} – ${tokenData.error_description || "no details"}`);
21703
+ }
21704
+ if (tokenData.id_token) {
21705
+ const ticket = await googleClient.verifyIdToken({
21706
+ idToken: tokenData.id_token,
21707
+ audience: clientId
21708
+ });
21709
+ const content = ticket.getPayload();
21710
+ if (!content) {
21711
+ throw new Error("Google ID token payload was empty after code exchange");
21712
+ }
21713
+ return {
21714
+ providerId: content.sub,
21715
+ email: content.email || "",
21716
+ displayName: content.name || null,
21717
+ photoUrl: content.picture || null
21718
+ };
21719
+ }
21720
+ if (tokenData.access_token) {
21721
+ const userInfoRes = await fetch("https://www.googleapis.com/oauth2/v3/userinfo", {
21722
+ headers: {
21723
+ Authorization: `Bearer ${tokenData.access_token}`
21724
+ }
21725
+ });
21726
+ if (!userInfoRes.ok) {
21727
+ throw new Error(`Google userinfo request failed after code exchange (${userInfoRes.status})`);
21728
+ }
21729
+ const info = await userInfoRes.json();
21730
+ if (!info.sub || !info.email) {
21731
+ return null;
21732
+ }
21733
+ return {
21734
+ providerId: info.sub,
21735
+ email: info.email,
21736
+ displayName: info.name || null,
21737
+ photoUrl: info.picture || null
21738
+ };
21739
+ }
21740
+ throw new Error("Google token exchange returned neither id_token nor access_token");
21741
+ }
21742
+ throw new Error("No valid Google credential provided (expected idToken, accessToken, or code+redirectUri)");
21564
21743
  } catch (error2) {
21565
- console.error("Failed to verify Google ID token:", error2);
21566
- return null;
21744
+ console.error("Google OAuth verification failed:", error2);
21745
+ throw error2;
21567
21746
  }
21568
21747
  }
21569
21748
  };
@@ -21755,1002 +21934,16 @@ ${credentialScope}
21755
21934
  }
21756
21935
  };
21757
21936
  }
21758
- const encoder = new TextEncoder();
21759
- const decoder = new TextDecoder();
21760
- function concat(...buffers) {
21761
- const size = buffers.reduce((acc, { length }) => acc + length, 0);
21762
- const buf = new Uint8Array(size);
21763
- let i2 = 0;
21764
- for (const buffer of buffers) {
21765
- buf.set(buffer, i2);
21766
- i2 += buffer.length;
21767
- }
21768
- return buf;
21769
- }
21770
- function encode$4(string) {
21771
- const bytes = new Uint8Array(string.length);
21772
- for (let i2 = 0; i2 < string.length; i2++) {
21773
- const code2 = string.charCodeAt(i2);
21774
- if (code2 > 127) {
21775
- throw new TypeError("non-ASCII string encountered in encode()");
21776
- }
21777
- bytes[i2] = code2;
21778
- }
21779
- return bytes;
21780
- }
21781
- function encodeBase64(input) {
21782
- if (Uint8Array.prototype.toBase64) {
21783
- return input.toBase64();
21784
- }
21785
- const CHUNK_SIZE = 32768;
21786
- const arr = [];
21787
- for (let i2 = 0; i2 < input.length; i2 += CHUNK_SIZE) {
21788
- arr.push(String.fromCharCode.apply(null, input.subarray(i2, i2 + CHUNK_SIZE)));
21789
- }
21790
- return btoa(arr.join(""));
21791
- }
21792
- function decodeBase64(encoded) {
21793
- if (Uint8Array.fromBase64) {
21794
- return Uint8Array.fromBase64(encoded);
21795
- }
21796
- const binary = atob(encoded);
21797
- const bytes = new Uint8Array(binary.length);
21798
- for (let i2 = 0; i2 < binary.length; i2++) {
21799
- bytes[i2] = binary.charCodeAt(i2);
21800
- }
21801
- return bytes;
21802
- }
21803
- function decode$1(input) {
21804
- if (Uint8Array.fromBase64) {
21805
- return Uint8Array.fromBase64(typeof input === "string" ? input : decoder.decode(input), {
21806
- alphabet: "base64url"
21807
- });
21808
- }
21809
- let encoded = input;
21810
- if (encoded instanceof Uint8Array) {
21811
- encoded = decoder.decode(encoded);
21812
- }
21813
- encoded = encoded.replace(/-/g, "+").replace(/_/g, "/");
21814
- try {
21815
- return decodeBase64(encoded);
21816
- } catch {
21817
- throw new TypeError("The input to be decoded is not correctly encoded.");
21818
- }
21819
- }
21820
- function encode$3(input) {
21821
- let unencoded = input;
21822
- if (typeof unencoded === "string") {
21823
- unencoded = encoder.encode(unencoded);
21824
- }
21825
- if (Uint8Array.prototype.toBase64) {
21826
- return unencoded.toBase64({ alphabet: "base64url", omitPadding: true });
21827
- }
21828
- return encodeBase64(unencoded).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
21829
- }
21830
- const unusable = (name2, prop = "algorithm.name") => new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name2}`);
21831
- const isAlgorithm = (algorithm, name2) => algorithm.name === name2;
21832
- function getHashLength(hash) {
21833
- return parseInt(hash.name.slice(4), 10);
21834
- }
21835
- function checkHashLength(algorithm, expected) {
21836
- const actual = getHashLength(algorithm.hash);
21837
- if (actual !== expected)
21838
- throw unusable(`SHA-${expected}`, "algorithm.hash");
21839
- }
21840
- function getNamedCurve(alg) {
21841
- switch (alg) {
21842
- case "ES256":
21843
- return "P-256";
21844
- case "ES384":
21845
- return "P-384";
21846
- case "ES512":
21847
- return "P-521";
21848
- default:
21849
- throw new Error("unreachable");
21850
- }
21851
- }
21852
- function checkUsage(key, usage) {
21853
- if (!key.usages.includes(usage)) {
21854
- throw new TypeError(`CryptoKey does not support this operation, its usages must include ${usage}.`);
21855
- }
21856
- }
21857
- function checkSigCryptoKey(key, alg, usage) {
21858
- switch (alg) {
21859
- case "HS256":
21860
- case "HS384":
21861
- case "HS512": {
21862
- if (!isAlgorithm(key.algorithm, "HMAC"))
21863
- throw unusable("HMAC");
21864
- checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
21865
- break;
21866
- }
21867
- case "RS256":
21868
- case "RS384":
21869
- case "RS512": {
21870
- if (!isAlgorithm(key.algorithm, "RSASSA-PKCS1-v1_5"))
21871
- throw unusable("RSASSA-PKCS1-v1_5");
21872
- checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
21873
- break;
21874
- }
21875
- case "PS256":
21876
- case "PS384":
21877
- case "PS512": {
21878
- if (!isAlgorithm(key.algorithm, "RSA-PSS"))
21879
- throw unusable("RSA-PSS");
21880
- checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
21881
- break;
21882
- }
21883
- case "Ed25519":
21884
- case "EdDSA": {
21885
- if (!isAlgorithm(key.algorithm, "Ed25519"))
21886
- throw unusable("Ed25519");
21887
- break;
21888
- }
21889
- case "ML-DSA-44":
21890
- case "ML-DSA-65":
21891
- case "ML-DSA-87": {
21892
- if (!isAlgorithm(key.algorithm, alg))
21893
- throw unusable(alg);
21894
- break;
21895
- }
21896
- case "ES256":
21897
- case "ES384":
21898
- case "ES512": {
21899
- if (!isAlgorithm(key.algorithm, "ECDSA"))
21900
- throw unusable("ECDSA");
21901
- const expected = getNamedCurve(alg);
21902
- const actual = key.algorithm.namedCurve;
21903
- if (actual !== expected)
21904
- throw unusable(expected, "algorithm.namedCurve");
21905
- break;
21906
- }
21907
- default:
21908
- throw new TypeError("CryptoKey does not support this operation");
21909
- }
21910
- checkUsage(key, usage);
21911
- }
21912
- function message(msg, actual, ...types2) {
21913
- types2 = types2.filter(Boolean);
21914
- if (types2.length > 2) {
21915
- const last = types2.pop();
21916
- msg += `one of type ${types2.join(", ")}, or ${last}.`;
21917
- } else if (types2.length === 2) {
21918
- msg += `one of type ${types2[0]} or ${types2[1]}.`;
21919
- } else {
21920
- msg += `of type ${types2[0]}.`;
21921
- }
21922
- if (actual == null) {
21923
- msg += ` Received ${actual}`;
21924
- } else if (typeof actual === "function" && actual.name) {
21925
- msg += ` Received function ${actual.name}`;
21926
- } else if (typeof actual === "object" && actual != null) {
21927
- if (actual.constructor?.name) {
21928
- msg += ` Received an instance of ${actual.constructor.name}`;
21929
- }
21930
- }
21931
- return msg;
21932
- }
21933
- const invalidKeyInput = (actual, ...types2) => message("Key must be ", actual, ...types2);
21934
- const withAlg = (alg, actual, ...types2) => message(`Key for the ${alg} algorithm must be `, actual, ...types2);
21935
- class JOSEError extends Error {
21936
- static code = "ERR_JOSE_GENERIC";
21937
- code = "ERR_JOSE_GENERIC";
21938
- constructor(message2, options2) {
21939
- super(message2, options2);
21940
- this.name = this.constructor.name;
21941
- Error.captureStackTrace?.(this, this.constructor);
21942
- }
21943
- }
21944
- class JOSENotSupported extends JOSEError {
21945
- static code = "ERR_JOSE_NOT_SUPPORTED";
21946
- code = "ERR_JOSE_NOT_SUPPORTED";
21947
- }
21948
- class JWSInvalid extends JOSEError {
21949
- static code = "ERR_JWS_INVALID";
21950
- code = "ERR_JWS_INVALID";
21951
- }
21952
- class JWTInvalid extends JOSEError {
21953
- static code = "ERR_JWT_INVALID";
21954
- code = "ERR_JWT_INVALID";
21955
- }
21956
- const isCryptoKey = (key) => {
21957
- if (key?.[Symbol.toStringTag] === "CryptoKey")
21958
- return true;
21959
- try {
21960
- return key instanceof CryptoKey;
21961
- } catch {
21962
- return false;
21963
- }
21964
- };
21965
- const isKeyObject = (key) => key?.[Symbol.toStringTag] === "KeyObject";
21966
- const isKeyLike = (key) => isCryptoKey(key) || isKeyObject(key);
21967
- function assertNotSet(value, name2) {
21968
- if (value) {
21969
- throw new TypeError(`${name2} can only be called once`);
21970
- }
21971
- }
21972
- const isObjectLike$1 = (value) => typeof value === "object" && value !== null;
21973
- function isObject(input) {
21974
- if (!isObjectLike$1(input) || Object.prototype.toString.call(input) !== "[object Object]") {
21975
- return false;
21976
- }
21977
- if (Object.getPrototypeOf(input) === null) {
21978
- return true;
21979
- }
21980
- let proto = input;
21981
- while (Object.getPrototypeOf(proto) !== null) {
21982
- proto = Object.getPrototypeOf(proto);
21983
- }
21984
- return Object.getPrototypeOf(input) === proto;
21985
- }
21986
- function isDisjoint(...headers) {
21987
- const sources = headers.filter(Boolean);
21988
- if (sources.length === 0 || sources.length === 1) {
21989
- return true;
21990
- }
21991
- let acc;
21992
- for (const header of sources) {
21993
- const parameters = Object.keys(header);
21994
- if (!acc || acc.size === 0) {
21995
- acc = new Set(parameters);
21996
- continue;
21997
- }
21998
- for (const parameter of parameters) {
21999
- if (acc.has(parameter)) {
22000
- return false;
22001
- }
22002
- acc.add(parameter);
22003
- }
22004
- }
22005
- return true;
22006
- }
22007
- const isJWK = (key) => isObject(key) && typeof key.kty === "string";
22008
- const isPrivateJWK = (key) => key.kty !== "oct" && (key.kty === "AKP" && typeof key.priv === "string" || typeof key.d === "string");
22009
- const isPublicJWK = (key) => key.kty !== "oct" && key.d === void 0 && key.priv === void 0;
22010
- const isSecretJWK = (key) => key.kty === "oct" && typeof key.k === "string";
22011
- function checkKeyLength(alg, key) {
22012
- if (alg.startsWith("RS") || alg.startsWith("PS")) {
22013
- const { modulusLength } = key.algorithm;
22014
- if (typeof modulusLength !== "number" || modulusLength < 2048) {
22015
- throw new TypeError(`${alg} requires key modulusLength to be 2048 bits or larger`);
22016
- }
22017
- }
22018
- }
22019
- function subtleAlgorithm(alg, algorithm) {
22020
- const hash = `SHA-${alg.slice(-3)}`;
22021
- switch (alg) {
22022
- case "HS256":
22023
- case "HS384":
22024
- case "HS512":
22025
- return { hash, name: "HMAC" };
22026
- case "PS256":
22027
- case "PS384":
22028
- case "PS512":
22029
- return { hash, name: "RSA-PSS", saltLength: parseInt(alg.slice(-3), 10) >> 3 };
22030
- case "RS256":
22031
- case "RS384":
22032
- case "RS512":
22033
- return { hash, name: "RSASSA-PKCS1-v1_5" };
22034
- case "ES256":
22035
- case "ES384":
22036
- case "ES512":
22037
- return { hash, name: "ECDSA", namedCurve: algorithm.namedCurve };
22038
- case "Ed25519":
22039
- case "EdDSA":
22040
- return { name: "Ed25519" };
22041
- case "ML-DSA-44":
22042
- case "ML-DSA-65":
22043
- case "ML-DSA-87":
22044
- return { name: alg };
22045
- default:
22046
- throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
22047
- }
22048
- }
22049
- async function getSigKey(alg, key, usage) {
22050
- if (key instanceof Uint8Array) {
22051
- if (!alg.startsWith("HS")) {
22052
- throw new TypeError(invalidKeyInput(key, "CryptoKey", "KeyObject", "JSON Web Key"));
22053
- }
22054
- return crypto.subtle.importKey("raw", key, { hash: `SHA-${alg.slice(-3)}`, name: "HMAC" }, false, [usage]);
22055
- }
22056
- checkSigCryptoKey(key, alg, usage);
22057
- return key;
22058
- }
22059
- async function sign$2(alg, key, data) {
22060
- const cryptoKey = await getSigKey(alg, key, "sign");
22061
- checkKeyLength(alg, cryptoKey);
22062
- const signature = await crypto.subtle.sign(subtleAlgorithm(alg, cryptoKey.algorithm), cryptoKey, data);
22063
- return new Uint8Array(signature);
22064
- }
22065
- const unsupportedAlg = 'Invalid or unsupported JWK "alg" (Algorithm) Parameter value';
22066
- function subtleMapping(jwk) {
22067
- let algorithm;
22068
- let keyUsages;
22069
- switch (jwk.kty) {
22070
- case "AKP": {
22071
- switch (jwk.alg) {
22072
- case "ML-DSA-44":
22073
- case "ML-DSA-65":
22074
- case "ML-DSA-87":
22075
- algorithm = { name: jwk.alg };
22076
- keyUsages = jwk.priv ? ["sign"] : ["verify"];
22077
- break;
22078
- default:
22079
- throw new JOSENotSupported(unsupportedAlg);
22080
- }
22081
- break;
22082
- }
22083
- case "RSA": {
22084
- switch (jwk.alg) {
22085
- case "PS256":
22086
- case "PS384":
22087
- case "PS512":
22088
- algorithm = { name: "RSA-PSS", hash: `SHA-${jwk.alg.slice(-3)}` };
22089
- keyUsages = jwk.d ? ["sign"] : ["verify"];
22090
- break;
22091
- case "RS256":
22092
- case "RS384":
22093
- case "RS512":
22094
- algorithm = { name: "RSASSA-PKCS1-v1_5", hash: `SHA-${jwk.alg.slice(-3)}` };
22095
- keyUsages = jwk.d ? ["sign"] : ["verify"];
22096
- break;
22097
- case "RSA-OAEP":
22098
- case "RSA-OAEP-256":
22099
- case "RSA-OAEP-384":
22100
- case "RSA-OAEP-512":
22101
- algorithm = {
22102
- name: "RSA-OAEP",
22103
- hash: `SHA-${parseInt(jwk.alg.slice(-3), 10) || 1}`
22104
- };
22105
- keyUsages = jwk.d ? ["decrypt", "unwrapKey"] : ["encrypt", "wrapKey"];
22106
- break;
22107
- default:
22108
- throw new JOSENotSupported(unsupportedAlg);
22109
- }
22110
- break;
22111
- }
22112
- case "EC": {
22113
- switch (jwk.alg) {
22114
- case "ES256":
22115
- case "ES384":
22116
- case "ES512":
22117
- algorithm = {
22118
- name: "ECDSA",
22119
- namedCurve: { ES256: "P-256", ES384: "P-384", ES512: "P-521" }[jwk.alg]
22120
- };
22121
- keyUsages = jwk.d ? ["sign"] : ["verify"];
22122
- break;
22123
- case "ECDH-ES":
22124
- case "ECDH-ES+A128KW":
22125
- case "ECDH-ES+A192KW":
22126
- case "ECDH-ES+A256KW":
22127
- algorithm = { name: "ECDH", namedCurve: jwk.crv };
22128
- keyUsages = jwk.d ? ["deriveBits"] : [];
22129
- break;
22130
- default:
22131
- throw new JOSENotSupported(unsupportedAlg);
22132
- }
22133
- break;
22134
- }
22135
- case "OKP": {
22136
- switch (jwk.alg) {
22137
- case "Ed25519":
22138
- case "EdDSA":
22139
- algorithm = { name: "Ed25519" };
22140
- keyUsages = jwk.d ? ["sign"] : ["verify"];
22141
- break;
22142
- case "ECDH-ES":
22143
- case "ECDH-ES+A128KW":
22144
- case "ECDH-ES+A192KW":
22145
- case "ECDH-ES+A256KW":
22146
- algorithm = { name: jwk.crv };
22147
- keyUsages = jwk.d ? ["deriveBits"] : [];
22148
- break;
22149
- default:
22150
- throw new JOSENotSupported(unsupportedAlg);
22151
- }
22152
- break;
22153
- }
22154
- default:
22155
- throw new JOSENotSupported('Invalid or unsupported JWK "kty" (Key Type) Parameter value');
22156
- }
22157
- return { algorithm, keyUsages };
22158
- }
22159
- async function jwkToKey(jwk) {
22160
- if (!jwk.alg) {
22161
- throw new TypeError('"alg" argument is required when "jwk.alg" is not present');
22162
- }
22163
- const { algorithm, keyUsages } = subtleMapping(jwk);
22164
- const keyData = { ...jwk };
22165
- if (keyData.kty !== "AKP") {
22166
- delete keyData.alg;
22167
- }
22168
- delete keyData.use;
22169
- return crypto.subtle.importKey("jwk", keyData, algorithm, jwk.ext ?? (jwk.d || jwk.priv ? false : true), jwk.key_ops ?? keyUsages);
22170
- }
22171
- const unusableForAlg = "given KeyObject instance cannot be used for this algorithm";
22172
- let cache;
22173
- const handleJWK = async (key, jwk, alg, freeze = false) => {
22174
- cache ||= /* @__PURE__ */ new WeakMap();
22175
- let cached = cache.get(key);
22176
- if (cached?.[alg]) {
22177
- return cached[alg];
22178
- }
22179
- const cryptoKey = await jwkToKey({ ...jwk, alg });
22180
- if (freeze)
22181
- Object.freeze(key);
22182
- if (!cached) {
22183
- cache.set(key, { [alg]: cryptoKey });
22184
- } else {
22185
- cached[alg] = cryptoKey;
22186
- }
22187
- return cryptoKey;
22188
- };
22189
- const handleKeyObject = (keyObject, alg) => {
22190
- cache ||= /* @__PURE__ */ new WeakMap();
22191
- let cached = cache.get(keyObject);
22192
- if (cached?.[alg]) {
22193
- return cached[alg];
22194
- }
22195
- const isPublic = keyObject.type === "public";
22196
- const extractable = isPublic ? true : false;
22197
- let cryptoKey;
22198
- if (keyObject.asymmetricKeyType === "x25519") {
22199
- switch (alg) {
22200
- case "ECDH-ES":
22201
- case "ECDH-ES+A128KW":
22202
- case "ECDH-ES+A192KW":
22203
- case "ECDH-ES+A256KW":
22204
- break;
22205
- default:
22206
- throw new TypeError(unusableForAlg);
22207
- }
22208
- cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, isPublic ? [] : ["deriveBits"]);
22209
- }
22210
- if (keyObject.asymmetricKeyType === "ed25519") {
22211
- if (alg !== "EdDSA" && alg !== "Ed25519") {
22212
- throw new TypeError(unusableForAlg);
22213
- }
22214
- cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [
22215
- isPublic ? "verify" : "sign"
22216
- ]);
22217
- }
22218
- switch (keyObject.asymmetricKeyType) {
22219
- case "ml-dsa-44":
22220
- case "ml-dsa-65":
22221
- case "ml-dsa-87": {
22222
- if (alg !== keyObject.asymmetricKeyType.toUpperCase()) {
22223
- throw new TypeError(unusableForAlg);
22224
- }
22225
- cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [
22226
- isPublic ? "verify" : "sign"
22227
- ]);
22228
- }
22229
- }
22230
- if (keyObject.asymmetricKeyType === "rsa") {
22231
- let hash;
22232
- switch (alg) {
22233
- case "RSA-OAEP":
22234
- hash = "SHA-1";
22235
- break;
22236
- case "RS256":
22237
- case "PS256":
22238
- case "RSA-OAEP-256":
22239
- hash = "SHA-256";
22240
- break;
22241
- case "RS384":
22242
- case "PS384":
22243
- case "RSA-OAEP-384":
22244
- hash = "SHA-384";
22245
- break;
22246
- case "RS512":
22247
- case "PS512":
22248
- case "RSA-OAEP-512":
22249
- hash = "SHA-512";
22250
- break;
22251
- default:
22252
- throw new TypeError(unusableForAlg);
22253
- }
22254
- if (alg.startsWith("RSA-OAEP")) {
22255
- return keyObject.toCryptoKey({
22256
- name: "RSA-OAEP",
22257
- hash
22258
- }, extractable, isPublic ? ["encrypt"] : ["decrypt"]);
22259
- }
22260
- cryptoKey = keyObject.toCryptoKey({
22261
- name: alg.startsWith("PS") ? "RSA-PSS" : "RSASSA-PKCS1-v1_5",
22262
- hash
22263
- }, extractable, [isPublic ? "verify" : "sign"]);
22264
- }
22265
- if (keyObject.asymmetricKeyType === "ec") {
22266
- const nist = /* @__PURE__ */ new Map([
22267
- ["prime256v1", "P-256"],
22268
- ["secp384r1", "P-384"],
22269
- ["secp521r1", "P-521"]
22270
- ]);
22271
- const namedCurve = nist.get(keyObject.asymmetricKeyDetails?.namedCurve);
22272
- if (!namedCurve) {
22273
- throw new TypeError(unusableForAlg);
22274
- }
22275
- const expectedCurve = { ES256: "P-256", ES384: "P-384", ES512: "P-521" };
22276
- if (expectedCurve[alg] && namedCurve === expectedCurve[alg]) {
22277
- cryptoKey = keyObject.toCryptoKey({
22278
- name: "ECDSA",
22279
- namedCurve
22280
- }, extractable, [isPublic ? "verify" : "sign"]);
22281
- }
22282
- if (alg.startsWith("ECDH-ES")) {
22283
- cryptoKey = keyObject.toCryptoKey({
22284
- name: "ECDH",
22285
- namedCurve
22286
- }, extractable, isPublic ? [] : ["deriveBits"]);
22287
- }
22288
- }
22289
- if (!cryptoKey) {
22290
- throw new TypeError(unusableForAlg);
22291
- }
22292
- if (!cached) {
22293
- cache.set(keyObject, { [alg]: cryptoKey });
22294
- } else {
22295
- cached[alg] = cryptoKey;
22296
- }
22297
- return cryptoKey;
22298
- };
22299
- async function normalizeKey$1(key, alg) {
22300
- if (key instanceof Uint8Array) {
22301
- return key;
22302
- }
22303
- if (isCryptoKey(key)) {
22304
- return key;
22305
- }
22306
- if (isKeyObject(key)) {
22307
- if (key.type === "secret") {
22308
- return key.export();
22309
- }
22310
- if ("toCryptoKey" in key && typeof key.toCryptoKey === "function") {
22311
- try {
22312
- return handleKeyObject(key, alg);
22313
- } catch (err) {
22314
- if (err instanceof TypeError) {
22315
- throw err;
22316
- }
22317
- }
22318
- }
22319
- let jwk = key.export({ format: "jwk" });
22320
- return handleJWK(key, jwk, alg);
22321
- }
22322
- if (isJWK(key)) {
22323
- if (key.k) {
22324
- return decode$1(key.k);
22325
- }
22326
- return handleJWK(key, key, alg, true);
22327
- }
22328
- throw new Error("unreachable");
22329
- }
22330
- function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) {
22331
- if (joseHeader.crit !== void 0 && protectedHeader?.crit === void 0) {
22332
- throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
22333
- }
22334
- if (!protectedHeader || protectedHeader.crit === void 0) {
22335
- return /* @__PURE__ */ new Set();
22336
- }
22337
- if (!Array.isArray(protectedHeader.crit) || protectedHeader.crit.length === 0 || protectedHeader.crit.some((input) => typeof input !== "string" || input.length === 0)) {
22338
- throw new Err('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');
22339
- }
22340
- let recognized;
22341
- if (recognizedOption !== void 0) {
22342
- recognized = new Map([...Object.entries(recognizedOption), ...recognizedDefault.entries()]);
22343
- } else {
22344
- recognized = recognizedDefault;
22345
- }
22346
- for (const parameter of protectedHeader.crit) {
22347
- if (!recognized.has(parameter)) {
22348
- throw new JOSENotSupported(`Extension Header Parameter "${parameter}" is not recognized`);
22349
- }
22350
- if (joseHeader[parameter] === void 0) {
22351
- throw new Err(`Extension Header Parameter "${parameter}" is missing`);
22352
- }
22353
- if (recognized.get(parameter) && protectedHeader[parameter] === void 0) {
22354
- throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);
22355
- }
22356
- }
22357
- return new Set(protectedHeader.crit);
22358
- }
22359
- const tag = (key) => key?.[Symbol.toStringTag];
22360
- const jwkMatchesOp = (alg, key, usage) => {
22361
- if (key.use !== void 0) {
22362
- let expected;
22363
- switch (usage) {
22364
- case "sign":
22365
- case "verify":
22366
- expected = "sig";
22367
- break;
22368
- case "encrypt":
22369
- case "decrypt":
22370
- expected = "enc";
22371
- break;
22372
- }
22373
- if (key.use !== expected) {
22374
- throw new TypeError(`Invalid key for this operation, its "use" must be "${expected}" when present`);
22375
- }
22376
- }
22377
- if (key.alg !== void 0 && key.alg !== alg) {
22378
- throw new TypeError(`Invalid key for this operation, its "alg" must be "${alg}" when present`);
22379
- }
22380
- if (Array.isArray(key.key_ops)) {
22381
- let expectedKeyOp;
22382
- switch (true) {
22383
- case usage === "sign":
22384
- case alg === "dir":
22385
- case alg.includes("CBC-HS"):
22386
- expectedKeyOp = usage;
22387
- break;
22388
- case alg.startsWith("PBES2"):
22389
- expectedKeyOp = "deriveBits";
22390
- break;
22391
- case /^A\d{3}(?:GCM)?(?:KW)?$/.test(alg):
22392
- if (!alg.includes("GCM") && alg.endsWith("KW")) {
22393
- expectedKeyOp = "unwrapKey";
22394
- } else {
22395
- expectedKeyOp = usage;
22396
- }
22397
- break;
22398
- case usage === "encrypt":
22399
- expectedKeyOp = "wrapKey";
22400
- break;
22401
- case usage === "decrypt":
22402
- expectedKeyOp = alg.startsWith("RSA") ? "unwrapKey" : "deriveBits";
22403
- break;
22404
- }
22405
- if (expectedKeyOp && key.key_ops?.includes?.(expectedKeyOp) === false) {
22406
- throw new TypeError(`Invalid key for this operation, its "key_ops" must include "${expectedKeyOp}" when present`);
22407
- }
22408
- }
22409
- return true;
22410
- };
22411
- const symmetricTypeCheck = (alg, key, usage) => {
22412
- if (key instanceof Uint8Array)
22413
- return;
22414
- if (isJWK(key)) {
22415
- if (isSecretJWK(key) && jwkMatchesOp(alg, key, usage))
22416
- return;
22417
- throw new TypeError(`JSON Web Key for symmetric algorithms must have JWK "kty" (Key Type) equal to "oct" and the JWK "k" (Key Value) present`);
22418
- }
22419
- if (!isKeyLike(key)) {
22420
- throw new TypeError(withAlg(alg, key, "CryptoKey", "KeyObject", "JSON Web Key", "Uint8Array"));
22421
- }
22422
- if (key.type !== "secret") {
22423
- throw new TypeError(`${tag(key)} instances for symmetric algorithms must be of type "secret"`);
22424
- }
22425
- };
22426
- const asymmetricTypeCheck = (alg, key, usage) => {
22427
- if (isJWK(key)) {
22428
- switch (usage) {
22429
- case "decrypt":
22430
- case "sign":
22431
- if (isPrivateJWK(key) && jwkMatchesOp(alg, key, usage))
22432
- return;
22433
- throw new TypeError(`JSON Web Key for this operation must be a private JWK`);
22434
- case "encrypt":
22435
- case "verify":
22436
- if (isPublicJWK(key) && jwkMatchesOp(alg, key, usage))
22437
- return;
22438
- throw new TypeError(`JSON Web Key for this operation must be a public JWK`);
22439
- }
22440
- }
22441
- if (!isKeyLike(key)) {
22442
- throw new TypeError(withAlg(alg, key, "CryptoKey", "KeyObject", "JSON Web Key"));
22443
- }
22444
- if (key.type === "secret") {
22445
- throw new TypeError(`${tag(key)} instances for asymmetric algorithms must not be of type "secret"`);
22446
- }
22447
- if (key.type === "public") {
22448
- switch (usage) {
22449
- case "sign":
22450
- throw new TypeError(`${tag(key)} instances for asymmetric algorithm signing must be of type "private"`);
22451
- case "decrypt":
22452
- throw new TypeError(`${tag(key)} instances for asymmetric algorithm decryption must be of type "private"`);
22453
- }
22454
- }
22455
- if (key.type === "private") {
22456
- switch (usage) {
22457
- case "verify":
22458
- throw new TypeError(`${tag(key)} instances for asymmetric algorithm verifying must be of type "public"`);
22459
- case "encrypt":
22460
- throw new TypeError(`${tag(key)} instances for asymmetric algorithm encryption must be of type "public"`);
22461
- }
22462
- }
22463
- };
22464
- function checkKeyType(alg, key, usage) {
22465
- switch (alg.substring(0, 2)) {
22466
- case "A1":
22467
- case "A2":
22468
- case "di":
22469
- case "HS":
22470
- case "PB":
22471
- symmetricTypeCheck(alg, key, usage);
22472
- break;
22473
- default:
22474
- asymmetricTypeCheck(alg, key, usage);
22475
- }
22476
- }
22477
- const epoch = (date) => Math.floor(date.getTime() / 1e3);
22478
- const minute = 60;
22479
- const hour = minute * 60;
22480
- const day = hour * 24;
22481
- const week = day * 7;
22482
- const year = day * 365.25;
22483
- const REGEX = /^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i;
22484
- function secs(str) {
22485
- const matched = REGEX.exec(str);
22486
- if (!matched || matched[4] && matched[1]) {
22487
- throw new TypeError("Invalid time period format");
22488
- }
22489
- const value = parseFloat(matched[2]);
22490
- const unit = matched[3].toLowerCase();
22491
- let numericDate;
22492
- switch (unit) {
22493
- case "sec":
22494
- case "secs":
22495
- case "second":
22496
- case "seconds":
22497
- case "s":
22498
- numericDate = Math.round(value);
22499
- break;
22500
- case "minute":
22501
- case "minutes":
22502
- case "min":
22503
- case "mins":
22504
- case "m":
22505
- numericDate = Math.round(value * minute);
22506
- break;
22507
- case "hour":
22508
- case "hours":
22509
- case "hr":
22510
- case "hrs":
22511
- case "h":
22512
- numericDate = Math.round(value * hour);
22513
- break;
22514
- case "day":
22515
- case "days":
22516
- case "d":
22517
- numericDate = Math.round(value * day);
22518
- break;
22519
- case "week":
22520
- case "weeks":
22521
- case "w":
22522
- numericDate = Math.round(value * week);
22523
- break;
22524
- default:
22525
- numericDate = Math.round(value * year);
22526
- break;
22527
- }
22528
- if (matched[1] === "-" || matched[4] === "ago") {
22529
- return -numericDate;
22530
- }
22531
- return numericDate;
22532
- }
22533
- function validateInput(label, input) {
22534
- if (!Number.isFinite(input)) {
22535
- throw new TypeError(`Invalid ${label} input`);
22536
- }
22537
- return input;
22538
- }
22539
- class JWTClaimsBuilder {
22540
- #payload;
22541
- constructor(payload) {
22542
- if (!isObject(payload)) {
22543
- throw new TypeError("JWT Claims Set MUST be an object");
22544
- }
22545
- this.#payload = structuredClone(payload);
22546
- }
22547
- data() {
22548
- return encoder.encode(JSON.stringify(this.#payload));
22549
- }
22550
- get iss() {
22551
- return this.#payload.iss;
22552
- }
22553
- set iss(value) {
22554
- this.#payload.iss = value;
22555
- }
22556
- get sub() {
22557
- return this.#payload.sub;
22558
- }
22559
- set sub(value) {
22560
- this.#payload.sub = value;
22561
- }
22562
- get aud() {
22563
- return this.#payload.aud;
22564
- }
22565
- set aud(value) {
22566
- this.#payload.aud = value;
22567
- }
22568
- set jti(value) {
22569
- this.#payload.jti = value;
22570
- }
22571
- set nbf(value) {
22572
- if (typeof value === "number") {
22573
- this.#payload.nbf = validateInput("setNotBefore", value);
22574
- } else if (value instanceof Date) {
22575
- this.#payload.nbf = validateInput("setNotBefore", epoch(value));
22576
- } else {
22577
- this.#payload.nbf = epoch(/* @__PURE__ */ new Date()) + secs(value);
22578
- }
22579
- }
22580
- set exp(value) {
22581
- if (typeof value === "number") {
22582
- this.#payload.exp = validateInput("setExpirationTime", value);
22583
- } else if (value instanceof Date) {
22584
- this.#payload.exp = validateInput("setExpirationTime", epoch(value));
22585
- } else {
22586
- this.#payload.exp = epoch(/* @__PURE__ */ new Date()) + secs(value);
22587
- }
22588
- }
22589
- set iat(value) {
22590
- if (value === void 0) {
22591
- this.#payload.iat = epoch(/* @__PURE__ */ new Date());
22592
- } else if (value instanceof Date) {
22593
- this.#payload.iat = validateInput("setIssuedAt", epoch(value));
22594
- } else if (typeof value === "string") {
22595
- this.#payload.iat = validateInput("setIssuedAt", epoch(/* @__PURE__ */ new Date()) + secs(value));
22596
- } else {
22597
- this.#payload.iat = validateInput("setIssuedAt", value);
22598
- }
22599
- }
22600
- }
22601
- class FlattenedSign {
22602
- #payload;
22603
- #protectedHeader;
22604
- #unprotectedHeader;
22605
- constructor(payload) {
22606
- if (!(payload instanceof Uint8Array)) {
22607
- throw new TypeError("payload must be an instance of Uint8Array");
22608
- }
22609
- this.#payload = payload;
22610
- }
22611
- setProtectedHeader(protectedHeader) {
22612
- assertNotSet(this.#protectedHeader, "setProtectedHeader");
22613
- this.#protectedHeader = protectedHeader;
22614
- return this;
22615
- }
22616
- setUnprotectedHeader(unprotectedHeader) {
22617
- assertNotSet(this.#unprotectedHeader, "setUnprotectedHeader");
22618
- this.#unprotectedHeader = unprotectedHeader;
22619
- return this;
22620
- }
22621
- async sign(key, options2) {
22622
- if (!this.#protectedHeader && !this.#unprotectedHeader) {
22623
- throw new JWSInvalid("either setProtectedHeader or setUnprotectedHeader must be called before #sign()");
22624
- }
22625
- if (!isDisjoint(this.#protectedHeader, this.#unprotectedHeader)) {
22626
- throw new JWSInvalid("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");
22627
- }
22628
- const joseHeader = {
22629
- ...this.#protectedHeader,
22630
- ...this.#unprotectedHeader
22631
- };
22632
- const extensions2 = validateCrit(JWSInvalid, /* @__PURE__ */ new Map([["b64", true]]), options2?.crit, this.#protectedHeader, joseHeader);
22633
- let b64 = true;
22634
- if (extensions2.has("b64")) {
22635
- b64 = this.#protectedHeader.b64;
22636
- if (typeof b64 !== "boolean") {
22637
- throw new JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean');
22638
- }
22639
- }
22640
- const { alg } = joseHeader;
22641
- if (typeof alg !== "string" || !alg) {
22642
- throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
22643
- }
22644
- checkKeyType(alg, key, "sign");
22645
- let payloadS;
22646
- let payloadB;
22647
- if (b64) {
22648
- payloadS = encode$3(this.#payload);
22649
- payloadB = encode$4(payloadS);
22650
- } else {
22651
- payloadB = this.#payload;
22652
- payloadS = "";
22653
- }
22654
- let protectedHeaderString;
22655
- let protectedHeaderBytes;
22656
- if (this.#protectedHeader) {
22657
- protectedHeaderString = encode$3(JSON.stringify(this.#protectedHeader));
22658
- protectedHeaderBytes = encode$4(protectedHeaderString);
22659
- } else {
22660
- protectedHeaderString = "";
22661
- protectedHeaderBytes = new Uint8Array();
22662
- }
22663
- const data = concat(protectedHeaderBytes, encode$4("."), payloadB);
22664
- const k = await normalizeKey$1(key, alg);
22665
- const signature = await sign$2(alg, k, data);
22666
- const jws2 = {
22667
- signature: encode$3(signature),
22668
- payload: payloadS
22669
- };
22670
- if (this.#unprotectedHeader) {
22671
- jws2.header = this.#unprotectedHeader;
22672
- }
22673
- if (this.#protectedHeader) {
22674
- jws2.protected = protectedHeaderString;
22675
- }
22676
- return jws2;
22677
- }
22678
- }
22679
- class CompactSign {
22680
- #flattened;
22681
- constructor(payload) {
22682
- this.#flattened = new FlattenedSign(payload);
22683
- }
22684
- setProtectedHeader(protectedHeader) {
22685
- this.#flattened.setProtectedHeader(protectedHeader);
22686
- return this;
22687
- }
22688
- async sign(key, options2) {
22689
- const jws2 = await this.#flattened.sign(key, options2);
22690
- if (jws2.payload === void 0) {
22691
- throw new TypeError("use the flattened module for creating JWS with b64: false");
22692
- }
22693
- return `${jws2.protected}.${jws2.payload}.${jws2.signature}`;
22694
- }
22695
- }
22696
- class SignJWT {
22697
- #protectedHeader;
22698
- #jwt;
22699
- constructor(payload = {}) {
22700
- this.#jwt = new JWTClaimsBuilder(payload);
22701
- }
22702
- setIssuer(issuer) {
22703
- this.#jwt.iss = issuer;
22704
- return this;
22705
- }
22706
- setSubject(subject) {
22707
- this.#jwt.sub = subject;
22708
- return this;
22709
- }
22710
- setAudience(audience) {
22711
- this.#jwt.aud = audience;
22712
- return this;
22713
- }
22714
- setJti(jwtId) {
22715
- this.#jwt.jti = jwtId;
22716
- return this;
22717
- }
22718
- setNotBefore(input) {
22719
- this.#jwt.nbf = input;
22720
- return this;
22721
- }
22722
- setExpirationTime(input) {
22723
- this.#jwt.exp = input;
22724
- return this;
22725
- }
22726
- setIssuedAt(input) {
22727
- this.#jwt.iat = input;
22728
- return this;
22729
- }
22730
- setProtectedHeader(protectedHeader) {
22731
- this.#protectedHeader = protectedHeader;
22732
- return this;
22733
- }
22734
- async sign(key, options2) {
22735
- const sig = new CompactSign(this.#jwt.data());
22736
- sig.setProtectedHeader(this.#protectedHeader);
22737
- if (Array.isArray(this.#protectedHeader?.crit) && this.#protectedHeader.crit.includes("b64") && this.#protectedHeader.b64 === false) {
22738
- throw new JWTInvalid("JWTs MUST NOT use unencoded payload");
22739
- }
22740
- return sig.sign(key, options2);
22741
- }
22742
- }
22743
21937
  function createAppleProvider(config) {
22744
21938
  async function generateClientSecret() {
22745
- const key = require$$0$5.createPrivateKey({
22746
- key: config.privateKey,
22747
- format: "pem"
21939
+ return jwt.sign({}, config.privateKey, {
21940
+ algorithm: "ES256",
21941
+ keyid: config.keyId,
21942
+ issuer: config.teamId,
21943
+ expiresIn: "180d",
21944
+ audience: "https://appleid.apple.com",
21945
+ subject: config.clientId
22748
21946
  });
22749
- const now = Math.floor(Date.now() / 1e3);
22750
- return new SignJWT({}).setProtectedHeader({
22751
- alg: "ES256",
22752
- kid: config.keyId
22753
- }).setIssuer(config.teamId).setIssuedAt(now).setExpirationTime(now + 86400 * 180).setAudience("https://appleid.apple.com").setSubject(config.clientId).sign(key);
22754
21947
  }
22755
21948
  return {
22756
21949
  id: "apple",
@@ -23558,7 +22751,7 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
23558
22751
  windowMs = 15 * 60 * 1e3,
23559
22752
  limit = 100,
23560
22753
  keyGenerator = defaultKeyGenerator,
23561
- message: message2 = "Too many requests, please try again later."
22754
+ message = "Too many requests, please try again later."
23562
22755
  } = options2;
23563
22756
  const store = /* @__PURE__ */ new Map();
23564
22757
  const cleanupInterval = setInterval(() => {
@@ -23593,7 +22786,7 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
23593
22786
  c.header("X-RateLimit-Reset", String(Math.ceil((now + retryAfterMs) / 1e3)));
23594
22787
  return c.json({
23595
22788
  error: {
23596
- message: message2,
22789
+ message,
23597
22790
  code: "RATE_LIMITED"
23598
22791
  }
23599
22792
  }, 429);
@@ -23605,7 +22798,12 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
23605
22798
  };
23606
22799
  }
23607
22800
  function defaultKeyGenerator(c) {
23608
- return c.req.header("x-forwarded-for")?.split(",")[0]?.trim() || c.req.header("x-real-ip") || "unknown";
22801
+ const forwardedFor = c.req.header("x-forwarded-for");
22802
+ if (forwardedFor) {
22803
+ const ips = forwardedFor.split(",");
22804
+ return ips[ips.length - 1].trim();
22805
+ }
22806
+ return c.req.header("x-real-ip") || "unknown";
23609
22807
  }
23610
22808
  const defaultAuthLimiter = createRateLimiter({
23611
22809
  windowMs: 15 * 60 * 1e3,
@@ -23752,7 +22950,11 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
23752
22950
  passwordHash,
23753
22951
  displayName: displayName || void 0
23754
22952
  });
23755
- if (config.defaultRole) {
22953
+ const existingUsers = await authRepo.listUsers();
22954
+ const isFirstUser = existingUsers.length === 1 && existingUsers[0].id === user.id;
22955
+ if (isFirstUser) {
22956
+ await authRepo.setUserRoles(user.id, ["admin"]);
22957
+ } else if (config.defaultRole) {
23756
22958
  await authRepo.assignDefaultRole(user.id, config.defaultRole);
23757
22959
  }
23758
22960
  const {
@@ -23793,7 +22995,13 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
23793
22995
  for (const provider of config.oauthProviders) {
23794
22996
  router.post(`/${provider.id}`, defaultAuthLimiter, async (c) => {
23795
22997
  const payload = parseBody2(provider.schema, await c.req.json());
23796
- const externalUser = await provider.verify(payload);
22998
+ let externalUser;
22999
+ try {
23000
+ externalUser = await provider.verify(payload);
23001
+ } catch (err) {
23002
+ const msg = err instanceof Error ? err.message : String(err);
23003
+ throw ApiError.unauthorized(`${provider.id} login failed: ${msg}`, "OAUTH_ERROR");
23004
+ }
23797
23005
  if (!externalUser) {
23798
23006
  throw ApiError.unauthorized(`Invalid ${provider.id} credentials`, "INVALID_TOKEN");
23799
23007
  }
@@ -23817,7 +23025,11 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
23817
23025
  await authRepo.linkUserIdentity(user.id, provider.id, externalUser.providerId, {
23818
23026
  email: externalUser.email
23819
23027
  });
23820
- if (config.defaultRole) {
23028
+ const allUsers = await authRepo.listUsers();
23029
+ const isFirstUser = allUsers.length === 1 && allUsers[0].id === user.id;
23030
+ if (isFirstUser) {
23031
+ await authRepo.setUserRoles(user.id, ["admin"]);
23032
+ } else if (config.defaultRole) {
23821
23033
  await authRepo.assignDefaultRole(user.id, config.defaultRole);
23822
23034
  }
23823
23035
  sendWelcomeEmail({
@@ -24173,8 +23385,45 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
24173
23385
  const authRepo = config.authRepo;
24174
23386
  const {
24175
23387
  emailService,
24176
- emailConfig
23388
+ emailConfig,
23389
+ hooks
24177
23390
  } = config;
23391
+ function buildHookContext(c, method) {
23392
+ const user = c.get("user");
23393
+ return {
23394
+ requestUser: user ? {
23395
+ userId: user.userId,
23396
+ roles: user.roles ?? []
23397
+ } : void 0,
23398
+ method
23399
+ };
23400
+ }
23401
+ async function applyUserAfterRead(user, ctx) {
23402
+ if (!hooks?.users?.afterRead) return user;
23403
+ return hooks.users.afterRead(user, ctx);
23404
+ }
23405
+ async function applyUserAfterReadBatch(users, ctx) {
23406
+ if (!hooks?.users?.afterRead) return users;
23407
+ const results = await Promise.all(users.map((u) => applyUserAfterRead(u, ctx)));
23408
+ return results.filter((u) => u !== null);
23409
+ }
23410
+ async function applyRoleAfterReadBatch(roles, ctx) {
23411
+ if (!hooks?.roles?.afterRead) return roles;
23412
+ const results = await Promise.all(roles.map((r) => hooks.roles.afterRead(r, ctx)));
23413
+ return results.filter((r) => r !== null);
23414
+ }
23415
+ function toAdminUser(u, roles) {
23416
+ return {
23417
+ uid: u.id,
23418
+ email: u.email,
23419
+ displayName: u.displayName ?? null,
23420
+ photoURL: u.photoUrl ?? null,
23421
+ provider: "custom",
23422
+ roles,
23423
+ createdAt: u.createdAt instanceof Date ? u.createdAt.toISOString() : u.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
23424
+ updatedAt: u.updatedAt instanceof Date ? u.updatedAt.toISOString() : u.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString()
23425
+ };
23426
+ }
24178
23427
  router.onError(errorHandler);
24179
23428
  router.use("/*", createRequireAuth({
24180
23429
  serviceKey: config.serviceKey
@@ -24225,6 +23474,7 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
24225
23474
  const search = c.req.query("search");
24226
23475
  const orderBy = c.req.query("orderBy");
24227
23476
  const orderDir = c.req.query("orderDir");
23477
+ const hookCtx = buildHookContext(c, "GET");
24228
23478
  if (limitParam !== void 0 || search) {
24229
23479
  const limit = limitParam ? parseInt(limitParam, 10) : 25;
24230
23480
  const offset = offsetParam ? parseInt(offsetParam, 10) : 0;
@@ -24236,18 +23486,11 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
24236
23486
  orderDir: orderDir || void 0,
24237
23487
  roleId: c.req.query("role") || void 0
24238
23488
  });
24239
- const usersWithRoles2 = await Promise.all(result.users.map(async (u) => {
23489
+ let usersWithRoles2 = await Promise.all(result.users.map(async (u) => {
24240
23490
  const roles = await authRepo.getUserRoleIds(u.id);
24241
- return {
24242
- uid: u.id,
24243
- email: u.email,
24244
- displayName: u.displayName,
24245
- photoURL: u.photoUrl,
24246
- roles,
24247
- createdAt: u.createdAt,
24248
- updatedAt: u.updatedAt
24249
- };
23491
+ return toAdminUser(u, roles);
24250
23492
  }));
23493
+ usersWithRoles2 = await applyUserAfterReadBatch(usersWithRoles2, hookCtx);
24251
23494
  return c.json({
24252
23495
  users: usersWithRoles2,
24253
23496
  total: result.total,
@@ -24256,18 +23499,11 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
24256
23499
  });
24257
23500
  }
24258
23501
  const users = await authRepo.listUsers();
24259
- const usersWithRoles = await Promise.all(users.map(async (u) => {
23502
+ let usersWithRoles = await Promise.all(users.map(async (u) => {
24260
23503
  const roles = await authRepo.getUserRoleIds(u.id);
24261
- return {
24262
- uid: u.id,
24263
- email: u.email,
24264
- displayName: u.displayName,
24265
- photoURL: u.photoUrl,
24266
- roles,
24267
- createdAt: u.createdAt,
24268
- updatedAt: u.updatedAt
24269
- };
23504
+ return toAdminUser(u, roles);
24270
23505
  }));
23506
+ usersWithRoles = await applyUserAfterReadBatch(usersWithRoles, hookCtx);
24271
23507
  return c.json({
24272
23508
  users: usersWithRoles
24273
23509
  });
@@ -24278,21 +23514,19 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
24278
23514
  if (!result) {
24279
23515
  throw ApiError.notFound("User not found");
24280
23516
  }
23517
+ const hookCtx = buildHookContext(c, "GET");
23518
+ let adminUser = toAdminUser(result.user, result.roles.map((r) => r.id));
23519
+ adminUser = await applyUserAfterRead(adminUser, hookCtx);
23520
+ if (!adminUser) {
23521
+ throw ApiError.notFound("User not found");
23522
+ }
24281
23523
  return c.json({
24282
- user: {
24283
- uid: result.user.id,
24284
- email: result.user.email,
24285
- displayName: result.user.displayName,
24286
- photoURL: result.user.photoUrl,
24287
- roles: result.roles.map((r) => r.id),
24288
- createdAt: result.user.createdAt,
24289
- updatedAt: result.user.updatedAt
24290
- }
23524
+ user: adminUser
24291
23525
  });
24292
23526
  });
24293
23527
  router.post("/users", requireAdmin, async (c) => {
24294
23528
  const body = await c.req.json();
24295
- const {
23529
+ let {
24296
23530
  email,
24297
23531
  displayName,
24298
23532
  password,
@@ -24301,6 +23535,17 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
24301
23535
  if (!email) {
24302
23536
  throw ApiError.badRequest("Email is required", "INVALID_INPUT");
24303
23537
  }
23538
+ const hookCtx = buildHookContext(c, "POST");
23539
+ if (hooks?.users?.beforeSave) {
23540
+ const hooked = await hooks.users.beforeSave({
23541
+ email,
23542
+ displayName,
23543
+ roles
23544
+ }, hookCtx);
23545
+ email = hooked.email ?? email;
23546
+ displayName = hooked.displayName ?? displayName;
23547
+ roles = hooked.roles ?? roles;
23548
+ }
24304
23549
  const existing = await authRepo.getUserByEmail(email);
24305
23550
  if (existing) {
24306
23551
  throw ApiError.conflict("Email already exists", "EMAIL_EXISTS");
@@ -24356,13 +23601,14 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
24356
23601
  } else if (!password) {
24357
23602
  temporaryPassword = clearPassword;
24358
23603
  }
23604
+ const createdAdminUser = toAdminUser(user, userRoles);
23605
+ if (hooks?.users?.afterSave) {
23606
+ Promise.resolve(hooks.users.afterSave(createdAdminUser, hookCtx)).catch((err) => {
23607
+ console.error("[BackendHooks] users.afterSave error:", err instanceof Error ? err.message : err);
23608
+ });
23609
+ }
24359
23610
  return c.json({
24360
- user: {
24361
- uid: user.id,
24362
- email: user.email,
24363
- displayName: user.displayName,
24364
- roles: userRoles
24365
- },
23611
+ user: createdAdminUser,
24366
23612
  invitationSent,
24367
23613
  ...temporaryPassword ? {
24368
23614
  temporaryPassword
@@ -24432,7 +23678,7 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
24432
23678
  router.put("/users/:userId", requireAdmin, async (c) => {
24433
23679
  const userId = c.req.param("userId");
24434
23680
  const body = await c.req.json();
24435
- const {
23681
+ let {
24436
23682
  email,
24437
23683
  displayName,
24438
23684
  password,
@@ -24442,6 +23688,17 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
24442
23688
  if (!existing) {
24443
23689
  throw ApiError.notFound("User not found");
24444
23690
  }
23691
+ const hookCtx = buildHookContext(c, "PUT");
23692
+ if (hooks?.users?.beforeSave) {
23693
+ const hooked = await hooks.users.beforeSave({
23694
+ email,
23695
+ displayName,
23696
+ roles
23697
+ }, hookCtx);
23698
+ email = hooked.email ?? email;
23699
+ displayName = hooked.displayName ?? displayName;
23700
+ roles = hooked.roles ?? roles;
23701
+ }
24445
23702
  const updates = {};
24446
23703
  if (email !== void 0) updates.email = email.toLowerCase();
24447
23704
  if (displayName !== void 0) updates.displayName = displayName;
@@ -24459,13 +23716,14 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
24459
23716
  await authRepo.setUserRoles(userId, roles);
24460
23717
  }
24461
23718
  const result = await authRepo.getUserWithRoles(userId);
23719
+ const updatedAdminUser = toAdminUser(result.user, result.roles.map((r) => r.id));
23720
+ if (hooks?.users?.afterSave) {
23721
+ Promise.resolve(hooks.users.afterSave(updatedAdminUser, hookCtx)).catch((err) => {
23722
+ console.error("[BackendHooks] users.afterSave error:", err instanceof Error ? err.message : err);
23723
+ });
23724
+ }
24462
23725
  return c.json({
24463
- user: {
24464
- uid: result.user.id,
24465
- email: result.user.email,
24466
- displayName: result.user.displayName,
24467
- roles: result.roles.map((r) => r.id)
24468
- }
23726
+ user: updatedAdminUser
24469
23727
  });
24470
23728
  });
24471
23729
  router.delete("/users/:userId", requireAdmin, async (c) => {
@@ -24479,21 +23737,33 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
24479
23737
  if (!existing) {
24480
23738
  throw ApiError.notFound("User not found");
24481
23739
  }
23740
+ const hookCtx = buildHookContext(c, "DELETE");
23741
+ if (hooks?.users?.beforeDelete) {
23742
+ await hooks.users.beforeDelete(userId, hookCtx);
23743
+ }
24482
23744
  await authRepo.deleteUser(userId);
23745
+ if (hooks?.users?.afterDelete) {
23746
+ Promise.resolve(hooks.users.afterDelete(userId, hookCtx)).catch((err) => {
23747
+ console.error("[BackendHooks] users.afterDelete error:", err instanceof Error ? err.message : err);
23748
+ });
23749
+ }
24483
23750
  return c.json({
24484
23751
  success: true
24485
23752
  });
24486
23753
  });
24487
23754
  router.get("/roles", requireAdmin, async (c) => {
24488
23755
  const roles = await authRepo.listRoles();
23756
+ const hookCtx = buildHookContext(c, "GET");
23757
+ let adminRoles = roles.map((r) => ({
23758
+ id: r.id,
23759
+ name: r.name,
23760
+ isAdmin: r.isAdmin,
23761
+ defaultPermissions: r.defaultPermissions,
23762
+ config: r.config
23763
+ }));
23764
+ adminRoles = await applyRoleAfterReadBatch(adminRoles, hookCtx);
24489
23765
  return c.json({
24490
- roles: roles.map((r) => ({
24491
- id: r.id,
24492
- name: r.name,
24493
- isAdmin: r.isAdmin,
24494
- defaultPermissions: r.defaultPermissions,
24495
- config: r.config
24496
- }))
23766
+ roles: adminRoles
24497
23767
  });
24498
23768
  });
24499
23769
  router.get("/roles/:roleId", requireAdmin, async (c) => {
@@ -24656,10 +23926,10 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
24656
23926
  * Includes a path traversal guard to prevent escaping the base directory.
24657
23927
  */
24658
23928
  getFullPath(storagePath, bucket) {
24659
- const parts = bucket ? [this.basePath, bucket, storagePath] : [this.basePath, storagePath];
24660
- const resolved = path__namespace.resolve(path__namespace.join(...parts));
24661
- if (!resolved.startsWith(this.basePath + path__namespace.sep) && resolved !== this.basePath) {
24662
- throw new Error("Path traversal detected: resolved storage path is outside the base directory.");
23929
+ const bucketPath = bucket ? path__namespace.join(this.basePath, bucket) : this.basePath;
23930
+ const resolved = path__namespace.resolve(path__namespace.join(bucketPath, storagePath));
23931
+ if (!resolved.startsWith(bucketPath + path__namespace.sep) && resolved !== bucketPath) {
23932
+ throw new Error("Path traversal detected: resolved storage path is outside the bucket directory.");
24663
23933
  }
24664
23934
  return resolved;
24665
23935
  }
@@ -24806,17 +24076,34 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
24806
24076
  }
24807
24077
  }
24808
24078
  resolvedPath = normalizeStoragePath(resolvedPath);
24079
+ if (!resolvedPath) {
24080
+ return;
24081
+ }
24809
24082
  const fullPath = this.getFullPath(resolvedPath, resolvedBucket);
24810
24083
  try {
24811
- await unlink(fullPath);
24812
- try {
24813
- await unlink(`${fullPath}.metadata.json`);
24814
- } catch {
24084
+ await access(fullPath, fs__namespace.constants.F_OK);
24085
+ } catch {
24086
+ return;
24087
+ }
24088
+ try {
24089
+ const stats = await stat(fullPath);
24090
+ if (stats.isDirectory()) {
24091
+ await fs__namespace.promises.rmdir(fullPath);
24092
+ } else {
24093
+ await unlink(fullPath);
24094
+ try {
24095
+ await unlink(`${fullPath}.metadata.json`);
24096
+ } catch {
24097
+ }
24815
24098
  }
24816
24099
  } catch (error2) {
24817
- if (error2 instanceof Error && error2.code !== "ENOENT") {
24818
- throw error2;
24100
+ if (error2 instanceof Error) {
24101
+ const code2 = error2.code;
24102
+ if (code2 === "ENOENT" || code2 === "ENOTEMPTY") {
24103
+ return;
24104
+ }
24819
24105
  }
24106
+ throw error2;
24820
24107
  }
24821
24108
  }
24822
24109
  async listObjects(prefix, options2) {
@@ -24923,7 +24210,8 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
24923
24210
  * Get the bucket name - either from parameter or config
24924
24211
  */
24925
24212
  getBucket(bucket) {
24926
- return bucket ?? this.config.bucket;
24213
+ if (!bucket || bucket === "default") return this.config.bucket;
24214
+ return bucket;
24927
24215
  }
24928
24216
  async putObject({
24929
24217
  file,
@@ -25211,11 +24499,18 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
25211
24499
  const fileContent = fs__namespace.readFileSync(absolutePath);
25212
24500
  return c.body(new Uint8Array(fileContent));
25213
24501
  }
25214
- const downloadConfig = await controller.getSignedUrl(filePath);
25215
- if (downloadConfig.fileNotFound || !downloadConfig.url) {
24502
+ const {
24503
+ bucket: parsedBucket,
24504
+ resolvedPath: parsedPath
24505
+ } = parseBucketAndPath(filePath);
24506
+ const fileObject = await controller.getObject(parsedPath, parsedBucket);
24507
+ if (!fileObject) {
25216
24508
  throw ApiError.notFound("File not found");
25217
24509
  }
25218
- return c.redirect(downloadConfig.url);
24510
+ c.header("Content-Type", fileObject.type || "application/octet-stream");
24511
+ c.header("Cache-Control", "public, max-age=3600, immutable");
24512
+ const buf = await fileObject.arrayBuffer();
24513
+ return c.body(new Uint8Array(buf));
25219
24514
  });
25220
24515
  router.get("/metadata/*", readAuthMiddleware, async (c) => {
25221
24516
  const rawPath = extractWildcardPath(c);
@@ -25265,7 +24560,7 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
25265
24560
  const maxResults = c.req.query("maxResults");
25266
24561
  const pageToken = c.req.query("pageToken");
25267
24562
  const result = await controller.listObjects(storagePrefix, {
25268
- bucket,
24563
+ bucket: bucket ?? (controller.getType() === "local" ? "default" : void 0),
25269
24564
  maxResults: maxResults ? parseInt(maxResults, 10) : void 0,
25270
24565
  pageToken
25271
24566
  });
@@ -25274,6 +24569,40 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
25274
24569
  data: result
25275
24570
  });
25276
24571
  });
24572
+ router.post("/folder", writeAuthMiddleware, async (c) => {
24573
+ const body = await c.req.json();
24574
+ const folderPath = body.path;
24575
+ if (!folderPath || typeof folderPath !== "string") {
24576
+ throw ApiError.badRequest("Folder path is required");
24577
+ }
24578
+ const {
24579
+ bucket,
24580
+ resolvedPath
24581
+ } = parseBucketAndPath(folderPath);
24582
+ if (!resolvedPath || resolvedPath.trim() === "") {
24583
+ throw ApiError.badRequest("Invalid folder path");
24584
+ }
24585
+ if (controller.getType() === "local") {
24586
+ const localController = controller;
24587
+ const absolutePath = localController.getAbsolutePath(resolvedPath, bucket);
24588
+ fs__namespace.mkdirSync(absolutePath, {
24589
+ recursive: true
24590
+ });
24591
+ } else {
24592
+ const key = resolvedPath.endsWith("/") ? resolvedPath : resolvedPath + "/";
24593
+ const emptyFile = new File([], key, {
24594
+ type: "application/x-directory"
24595
+ });
24596
+ await controller.putObject({
24597
+ file: emptyFile,
24598
+ key
24599
+ });
24600
+ }
24601
+ return c.json({
24602
+ success: true,
24603
+ message: "Folder created"
24604
+ }, 201);
24605
+ });
25277
24606
  return router;
25278
24607
  }
25279
24608
  const DEFAULT_STORAGE_ID = "(default)";
@@ -25397,8 +24726,8 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
25397
24726
  status;
25398
24727
  code;
25399
24728
  details;
25400
- constructor(status, message2, code2, details) {
25401
- super(message2);
24729
+ constructor(status, message, code2, details) {
24730
+ super(message);
25402
24731
  this.name = "RebaseApiError";
25403
24732
  this.status = status;
25404
24733
  this.code = code2;
@@ -25728,20 +25057,21 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
25728
25057
  refreshToken: session.refreshToken
25729
25058
  };
25730
25059
  }
25731
- async function signInWithGoogle(idToken) {
25060
+ async function signInWithGoogle(tokenOrPayload) {
25732
25061
  const fetchFn = getFetch();
25062
+ const body = typeof tokenOrPayload === "string" ? {
25063
+ idToken: tokenOrPayload
25064
+ } : tokenOrPayload;
25733
25065
  const res = await fetchFn(authUrl("/google"), {
25734
25066
  method: "POST",
25735
25067
  headers: {
25736
25068
  "Content-Type": "application/json"
25737
25069
  },
25738
- body: JSON.stringify({
25739
- idToken
25740
- })
25070
+ body: JSON.stringify(body)
25741
25071
  });
25742
- const body = await res.json().catch(() => ({}));
25743
- if (!res.ok) throwApiError(res.status, body, res.statusText);
25744
- const session = handleAuthResponse(body, "SIGNED_IN");
25072
+ const responseBody = await res.json().catch(() => ({}));
25073
+ if (!res.ok) throwApiError(res.status, responseBody, res.statusText);
25074
+ const session = handleAuthResponse(responseBody, "SIGNED_IN");
25745
25075
  return {
25746
25076
  user: session.user,
25747
25077
  accessToken: session.accessToken,
@@ -26369,6 +25699,18 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
26369
25699
  method: "DELETE"
26370
25700
  });
26371
25701
  },
25702
+ async count(params) {
25703
+ const countParams = {
25704
+ ...params,
25705
+ limit: void 0,
25706
+ offset: void 0
25707
+ };
25708
+ const qs = buildQueryString(countParams);
25709
+ const raw = await transport.request(basePath + "/count" + qs, {
25710
+ method: "GET"
25711
+ });
25712
+ return raw.count ?? 0;
25713
+ },
26372
25714
  // Fluent builder instantiation
26373
25715
  where(column, operator, value) {
26374
25716
  return new QueryBuilder(client).where(column, operator, value);
@@ -26391,6 +25733,25 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
26391
25733
  };
26392
25734
  return client;
26393
25735
  }
25736
+ function createFunctionsClient(transport) {
25737
+ return {
25738
+ async invoke(name2, payload, options2) {
25739
+ const method = options2?.method ?? "POST";
25740
+ const subPath = options2?.path ? `/${options2.path.replace(/^\//, "")}` : "";
25741
+ const routePath = `/functions/${encodeURIComponent(name2)}${subPath}`;
25742
+ const init = {
25743
+ method
25744
+ };
25745
+ if (payload !== void 0 && method !== "GET") {
25746
+ init.body = JSON.stringify(payload);
25747
+ }
25748
+ if (options2?.headers) {
25749
+ init.headers = options2.headers;
25750
+ }
25751
+ return transport.request(routePath, init);
25752
+ }
25753
+ };
25754
+ }
26394
25755
  function createStorage(transport) {
26395
25756
  const urlsCache = /* @__PURE__ */ new Map();
26396
25757
  async function putObject({
@@ -26524,6 +25885,7 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
26524
25885
  const admin = createAdmin(transport, options2.admin);
26525
25886
  const cron = createCron(transport, options2.cron);
26526
25887
  const storage = createStorage(transport);
25888
+ const functions = createFunctionsClient(transport);
26527
25889
  let ws;
26528
25890
  if (!options2.onUnauthorized) {
26529
25891
  transport.setOnUnauthorized(async () => {
@@ -26562,6 +25924,7 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
26562
25924
  auth,
26563
25925
  admin,
26564
25926
  cron,
25927
+ functions,
26565
25928
  storage,
26566
25929
  ws,
26567
25930
  setToken: transport.setToken,
@@ -27375,7 +26738,7 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
27375
26738
  });
27376
26739
  return options2;
27377
26740
  };
27378
- module2.exports._logFunc = (logger2, level, defaults, data, message2, ...args) => {
26741
+ module2.exports._logFunc = (logger2, level, defaults, data, message, ...args) => {
27379
26742
  let entry = {};
27380
26743
  Object.keys(defaults || {}).forEach((key) => {
27381
26744
  if (key !== "level") {
@@ -27387,7 +26750,7 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
27387
26750
  entry[key] = data[key];
27388
26751
  }
27389
26752
  });
27390
- logger2[level](entry, message2, ...args);
26753
+ logger2[level](entry, message, ...args);
27391
26754
  };
27392
26755
  module2.exports.getLogger = (options2, defaults) => {
27393
26756
  options2 = options2 || {};
@@ -27404,8 +26767,8 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
27404
26767
  logger2 = createDefaultLogger(levels);
27405
26768
  }
27406
26769
  levels.forEach((level) => {
27407
- response[level] = (data, message2, ...args) => {
27408
- module2.exports._logFunc(logger2, level, defaults, data, message2, ...args);
26770
+ response[level] = (data, message, ...args) => {
26771
+ module2.exports._logFunc(logger2, level, defaults, data, message, ...args);
27409
26772
  };
27410
26773
  });
27411
26774
  return response;
@@ -27588,7 +26951,7 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
27588
26951
  }
27589
26952
  levelNames.set(level, levelName);
27590
26953
  });
27591
- let print2 = (level, entry, message2, ...args) => {
26954
+ let print2 = (level, entry, message, ...args) => {
27592
26955
  let prefix = "";
27593
26956
  if (entry) {
27594
26957
  if (entry.tnx === "server") {
@@ -27603,8 +26966,8 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
27603
26966
  prefix = "[#" + entry.cid + "] " + prefix;
27604
26967
  }
27605
26968
  }
27606
- message2 = util2.format(message2, ...args);
27607
- message2.split(/\r?\n/).forEach((line) => {
26969
+ message = util2.format(message, ...args);
26970
+ message.split(/\r?\n/).forEach((line) => {
27608
26971
  console.log("[%s] %s %s", (/* @__PURE__ */ new Date()).toISOString().substr(0, 19).replace(/T/, " "), levelNames.get(level), prefix + line);
27609
26972
  });
27610
26973
  };
@@ -34100,8 +33463,8 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
34100
33463
  * @param {Object} message String, Buffer or a Stream
34101
33464
  * @param {Function} callback Callback to return once sending is completed
34102
33465
  */
34103
- send(envelope, message2, done) {
34104
- if (!message2) {
33466
+ send(envelope, message, done) {
33467
+ if (!message) {
34105
33468
  return done(this._formatError("Empty message", "EMESSAGE", false, "API"));
34106
33469
  }
34107
33470
  const isDestroyedMessage = this._isDestroyedMessage("send message");
@@ -34121,17 +33484,17 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
34121
33484
  returned = true;
34122
33485
  done(...arguments);
34123
33486
  };
34124
- if (typeof message2.on === "function") {
34125
- message2.on("error", (err) => callback(this._formatError(err, "ESTREAM", false, "API")));
33487
+ if (typeof message.on === "function") {
33488
+ message.on("error", (err) => callback(this._formatError(err, "ESTREAM", false, "API")));
34126
33489
  }
34127
33490
  let startTime = Date.now();
34128
33491
  this._setEnvelope(envelope, (err, info) => {
34129
33492
  if (err) {
34130
33493
  let stream3 = new PassThrough();
34131
- if (typeof message2.pipe === "function") {
34132
- message2.pipe(stream3);
33494
+ if (typeof message.pipe === "function") {
33495
+ message.pipe(stream3);
34133
33496
  } else {
34134
- stream3.write(message2);
33497
+ stream3.write(message);
34135
33498
  stream3.end();
34136
33499
  }
34137
33500
  return callback(err);
@@ -34147,10 +33510,10 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
34147
33510
  info.response = str;
34148
33511
  return callback(null, info);
34149
33512
  });
34150
- if (typeof message2.pipe === "function") {
34151
- message2.pipe(stream2);
33513
+ if (typeof message.pipe === "function") {
33514
+ message.pipe(stream2);
34152
33515
  } else {
34153
- stream2.write(message2);
33516
+ stream2.write(message);
34154
33517
  stream2.end();
34155
33518
  }
34156
33519
  });
@@ -34263,12 +33626,12 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
34263
33626
  this.emit("error", err);
34264
33627
  this.close();
34265
33628
  }
34266
- _formatError(message2, type, response, command) {
33629
+ _formatError(message, type, response, command) {
34267
33630
  let err;
34268
- if (/Error\]$/i.test(Object.prototype.toString.call(message2))) {
34269
- err = message2;
33631
+ if (/Error\]$/i.test(Object.prototype.toString.call(message))) {
33632
+ err = message;
34270
33633
  } else {
34271
- err = new Error(message2);
33634
+ err = new Error(message);
34272
33635
  }
34273
33636
  if (type && type !== "Error") {
34274
33637
  err.code = type;
@@ -34911,14 +34274,14 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
34911
34274
  * @param {String} str Message from the server
34912
34275
  */
34913
34276
  _actionMAIL(str, callback) {
34914
- let message2, curRecipient;
34277
+ let message, curRecipient;
34915
34278
  if (Number(str.charAt(0)) !== 2) {
34916
34279
  if (this._usingSmtpUtf8 && /^550 /.test(str) && /[\x80-\uFFFF]/.test(this._envelope.from)) {
34917
- message2 = "Internationalized mailbox name not allowed";
34280
+ message = "Internationalized mailbox name not allowed";
34918
34281
  } else {
34919
- message2 = "Mail command failed";
34282
+ message = "Mail command failed";
34920
34283
  }
34921
- return callback(this._formatError(message2, "EENVELOPE", str, "MAIL FROM"));
34284
+ return callback(this._formatError(message, "EENVELOPE", str, "MAIL FROM"));
34922
34285
  }
34923
34286
  if (!this._envelope.rcptQueue.length) {
34924
34287
  return callback(this._formatError("Can't send mail - no recipients defined", "EENVELOPE", false, "API"));
@@ -34949,15 +34312,15 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
34949
34312
  * @param {String} str Message from the server
34950
34313
  */
34951
34314
  _actionRCPT(str, callback) {
34952
- let message2, err, curRecipient = this._recipientQueue.shift();
34315
+ let message, err, curRecipient = this._recipientQueue.shift();
34953
34316
  if (Number(str.charAt(0)) !== 2) {
34954
34317
  if (this._usingSmtpUtf8 && /^553 /.test(str) && /[\x80-\uFFFF]/.test(curRecipient)) {
34955
- message2 = "Internationalized mailbox name not allowed";
34318
+ message = "Internationalized mailbox name not allowed";
34956
34319
  } else {
34957
- message2 = "Recipient command failed";
34320
+ message = "Recipient command failed";
34958
34321
  }
34959
34322
  this._envelope.rejected.push(curRecipient);
34960
- err = this._formatError(message2, "EENVELOPE", str, "RCPT TO");
34323
+ err = this._formatError(message, "EENVELOPE", str, "RCPT TO");
34961
34324
  err.recipient = curRecipient;
34962
34325
  this._envelope.rejectedErrors.push(err);
34963
34326
  } else {
@@ -37673,9 +37036,9 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
37673
37036
  replyTo: options2.replyTo
37674
37037
  });
37675
37038
  } catch (error2) {
37676
- const message2 = error2 instanceof Error ? error2.message : String(error2);
37677
- console.error("Failed to send email:", message2);
37678
- throw new Error(`Failed to send email: ${message2}`);
37039
+ const message = error2 instanceof Error ? error2.message : String(error2);
37040
+ console.error("Failed to send email:", message);
37041
+ throw new Error(`Failed to send email: ${message}`);
37679
37042
  }
37680
37043
  }
37681
37044
  /**
@@ -37689,8 +37052,8 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
37689
37052
  await this.transporter.verify();
37690
37053
  return true;
37691
37054
  } catch (error2) {
37692
- const message2 = error2 instanceof Error ? error2.message : String(error2);
37693
- console.error("SMTP connection verification failed:", message2);
37055
+ const message = error2 instanceof Error ? error2.message : String(error2);
37056
+ console.error("SMTP connection verification failed:", message);
37694
37057
  return false;
37695
37058
  }
37696
37059
  }
@@ -37889,7 +37252,7 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
37889
37252
  const {
37890
37253
  createGoogleProvider: createGoogleProvider2
37891
37254
  } = await Promise.resolve().then(() => index);
37892
- oauthProviders.push(createGoogleProvider2(config.auth.google.clientId));
37255
+ oauthProviders.push(createGoogleProvider2(config.auth.google));
37893
37256
  }
37894
37257
  if (config.auth.linkedin?.clientId && config.auth.linkedin?.clientSecret) {
37895
37258
  const {
@@ -37970,7 +37333,8 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
37970
37333
  authRepo: authConfigResult.authRepository ?? authConfigResult.userService,
37971
37334
  emailService: authConfigResult.emailService,
37972
37335
  emailConfig: config.auth.email,
37973
- serviceKey
37336
+ serviceKey,
37337
+ hooks: config.hooks
37974
37338
  });
37975
37339
  config.app.route(`${basePath}/admin`, adminRoutes);
37976
37340
  }
@@ -38028,7 +37392,7 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
38028
37392
  });
38029
37393
  dataRouter.route("/", historyRoutes);
38030
37394
  }
38031
- const restGenerator = new RestApiGenerator(activeCollections, defaultDriver);
37395
+ const restGenerator = new RestApiGenerator(activeCollections, defaultDriver, config.hooks?.data);
38032
37396
  dataRouter.route("/", restGenerator.generateRoutes());
38033
37397
  config.app.route(`${basePath}/data`, dataRouter);
38034
37398
  }
@@ -38089,6 +37453,13 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
38089
37453
  }
38090
37454
  _initRebase(serverClient);
38091
37455
  logger.info("Rebase singleton initialized");
37456
+ if (defaultDriverResult.internals) {
37457
+ const internals = defaultDriverResult.internals;
37458
+ const driver = internals.driver;
37459
+ if (driver && "client" in driver) {
37460
+ driver.client = serverClient;
37461
+ }
37462
+ }
38092
37463
  if (config.functionsDir) {
38093
37464
  const {
38094
37465
  loadFunctionsFromDirectory: loadFunctionsFromDirectory2
@@ -38222,10 +37593,10 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
38222
37593
  shutdown
38223
37594
  };
38224
37595
  }
38225
- function devAssert(condition, message2) {
37596
+ function devAssert(condition, message) {
38226
37597
  const booleanCondition = Boolean(condition);
38227
37598
  if (!booleanCondition) {
38228
- throw new Error(message2);
37599
+ throw new Error(message);
38229
37600
  }
38230
37601
  }
38231
37602
  function isPromise(value) {
@@ -38234,11 +37605,11 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
38234
37605
  function isObjectLike(value) {
38235
37606
  return typeof value == "object" && value !== null;
38236
37607
  }
38237
- function invariant(condition, message2) {
37608
+ function invariant(condition, message) {
38238
37609
  const booleanCondition = Boolean(condition);
38239
37610
  if (!booleanCondition) {
38240
37611
  throw new Error(
38241
- message2 != null ? message2 : "Unexpected invariant triggered."
37612
+ message != null ? message : "Unexpected invariant triggered."
38242
37613
  );
38243
37614
  }
38244
37615
  }
@@ -38357,10 +37728,10 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
38357
37728
  /**
38358
37729
  * @deprecated Please use the `GraphQLErrorOptions` constructor overload instead.
38359
37730
  */
38360
- constructor(message2, ...rawArgs) {
37731
+ constructor(message, ...rawArgs) {
38361
37732
  var _this$nodes, _nodeLocations$, _ref;
38362
37733
  const { nodes, source, positions, path: path2, originalError, extensions: extensions2 } = toNormalizedOptions(rawArgs);
38363
- super(message2);
37734
+ super(message);
38364
37735
  this.name = "GraphQLError";
38365
37736
  this.path = path2 !== null && path2 !== void 0 ? path2 : void 0;
38366
37737
  this.originalError = originalError !== null && originalError !== void 0 ? originalError : void 0;
@@ -39378,14 +38749,14 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
39378
38749
  return "[" + items.join(", ") + "]";
39379
38750
  }
39380
38751
  function getObjectTag(object) {
39381
- const tag2 = Object.prototype.toString.call(object).replace(/^\[object /, "").replace(/]$/, "");
39382
- if (tag2 === "Object" && typeof object.constructor === "function") {
38752
+ const tag = Object.prototype.toString.call(object).replace(/^\[object /, "").replace(/]$/, "");
38753
+ if (tag === "Object" && typeof object.constructor === "function") {
39383
38754
  const name2 = object.constructor.name;
39384
38755
  if (typeof name2 === "string" && name2 !== "") {
39385
38756
  return name2;
39386
38757
  }
39387
38758
  }
39388
- return tag2;
38759
+ return tag;
39389
38760
  }
39390
38761
  const isProduction = globalThis.process && // eslint-disable-next-line no-undef
39391
38762
  process.env.NODE_ENV === "production";
@@ -40783,22 +40154,22 @@ spurious results.`);
40783
40154
  const MAX_SUGGESTIONS = 5;
40784
40155
  function didYouMean(firstArg, secondArg) {
40785
40156
  const [subMessage, suggestionsArg] = secondArg ? [firstArg, secondArg] : [void 0, firstArg];
40786
- let message2 = " Did you mean ";
40157
+ let message = " Did you mean ";
40787
40158
  if (subMessage) {
40788
- message2 += subMessage + " ";
40159
+ message += subMessage + " ";
40789
40160
  }
40790
40161
  const suggestions = suggestionsArg.map((x) => `"${x}"`);
40791
40162
  switch (suggestions.length) {
40792
40163
  case 0:
40793
40164
  return "";
40794
40165
  case 1:
40795
- return message2 + suggestions[0] + "?";
40166
+ return message + suggestions[0] + "?";
40796
40167
  case 2:
40797
- return message2 + suggestions[0] + " or " + suggestions[1] + "?";
40168
+ return message + suggestions[0] + " or " + suggestions[1] + "?";
40798
40169
  }
40799
40170
  const selected = suggestions.slice(0, MAX_SUGGESTIONS);
40800
40171
  const lastItem = selected.pop();
40801
- return message2 + selected.join(", ") + ", or " + lastItem + "?";
40172
+ return message + selected.join(", ") + ", or " + lastItem + "?";
40802
40173
  }
40803
40174
  function identityFunc(x) {
40804
40175
  return x;
@@ -43442,10 +42813,10 @@ spurious results.`);
43442
42813
  this._errors = [];
43443
42814
  this.schema = schema;
43444
42815
  }
43445
- reportError(message2, nodes) {
42816
+ reportError(message, nodes) {
43446
42817
  const _nodes = Array.isArray(nodes) ? nodes.filter(Boolean) : nodes;
43447
42818
  this._errors.push(
43448
- new GraphQLError(message2, {
42819
+ new GraphQLError(message, {
43449
42820
  nodes: _nodes
43450
42821
  })
43451
42822
  );
@@ -47828,9 +47199,9 @@ spurious results.`);
47828
47199
  };
47829
47200
  }
47830
47201
  return {
47831
- errors: messages.map((message2) => {
47202
+ errors: messages.map((message) => {
47832
47203
  return {
47833
- message: message2
47204
+ message
47834
47205
  };
47835
47206
  })
47836
47207
  };
@@ -48967,7 +48338,9 @@ export default ${safeId}Collection;
48967
48338
  * Setup Hono middleware
48968
48339
  */
48969
48340
  setupMiddleware() {
48970
- this.router.use("/*", secureHeaders.secureHeaders());
48341
+ this.router.use("/*", secureHeaders.secureHeaders({
48342
+ crossOriginOpenerPolicy: "same-origin-allow-popups"
48343
+ }));
48971
48344
  if (this.config.cors) {
48972
48345
  const origin = this.config.cors.origin;
48973
48346
  this.router.use("/*", cors.cors({
@@ -49054,9 +48427,9 @@ export default ${safeId}Collection;
49054
48427
  if (process.env.NODE_ENV === "production") {
49055
48428
  console.warn("[RebaseApiServer] Schema Editor is disabled in production environments for security.");
49056
48429
  } else {
48430
+ this.router.use(`${basePath}/schema-editor/*`, requireAuth, requireAdmin);
49057
48431
  const schemaEditorRoutes2 = createSchemaEditorRoutes(this.config.collectionsDir);
49058
48432
  this.router.route(`${basePath}/schema-editor`, schemaEditorRoutes2);
49059
- this.router.use(`${basePath}/schema-editor/*`, requireAuth, requireAdmin);
49060
48433
  }
49061
48434
  }
49062
48435
  this.router.get(`${basePath}/docs`, (c) => {
@@ -49170,8 +48543,8 @@ export default ${safeId}Collection;
49170
48543
  Hint: ensure the function exports a Hono app created with the same hono version as the server.
49171
48544
  The loader checks for .fetch() and .routes — any Hono-compatible app will work.`);
49172
48545
  } catch (err) {
49173
- const message2 = err instanceof Error ? err.message : String(err);
49174
- console.error(`[functions] Failed to load ${file}: ${message2}`);
48546
+ const message = err instanceof Error ? err.message : String(err);
48547
+ console.error(`[functions] Failed to load ${file}: ${message}`);
49175
48548
  }
49176
48549
  }
49177
48550
  }
@@ -49243,8 +48616,8 @@ export default ${safeId}Collection;
49243
48616
  });
49244
48617
  console.log(`⏰ Loaded cron job: ${id} (${definition.schedule})`);
49245
48618
  } catch (err) {
49246
- const message2 = err instanceof Error ? err.message : String(err);
49247
- console.error(`[cron] Failed to load ${file}: ${message2}`);
48619
+ const message = err instanceof Error ? err.message : String(err);
48620
+ console.error(`[cron] Failed to load ${file}: ${message}`);
49248
48621
  }
49249
48622
  }
49250
48623
  }
@@ -49254,46 +48627,98 @@ export default ${safeId}Collection;
49254
48627
  __proto__: null,
49255
48628
  loadCronJobsFromDirectory
49256
48629
  }, Symbol.toStringTag, { value: "Module" }));
48630
+ function expandCronField(field, min, max) {
48631
+ const results = /* @__PURE__ */ new Set();
48632
+ for (const segment of field.split(",")) {
48633
+ const trimmed = segment.trim();
48634
+ if (trimmed === "*") {
48635
+ for (let i2 = min; i2 <= max; i2++) results.add(i2);
48636
+ } else if (trimmed.includes("/")) {
48637
+ const [rangeStr, stepStr] = trimmed.split("/");
48638
+ const step = parseInt(stepStr, 10);
48639
+ if (isNaN(step) || step <= 0) {
48640
+ throw new Error(`Invalid step value "${stepStr}" in cron field "${field}"`);
48641
+ }
48642
+ let start = min;
48643
+ let end = max;
48644
+ if (rangeStr !== "*") {
48645
+ if (rangeStr.includes("-")) {
48646
+ const [a2, b] = rangeStr.split("-").map(Number);
48647
+ start = a2;
48648
+ end = b;
48649
+ } else {
48650
+ start = parseInt(rangeStr, 10);
48651
+ }
48652
+ }
48653
+ for (let i2 = start; i2 <= end; i2 += step) results.add(i2);
48654
+ } else if (trimmed.includes("-")) {
48655
+ const [a2, b] = trimmed.split("-").map(Number);
48656
+ for (let i2 = a2; i2 <= b; i2++) results.add(i2);
48657
+ } else {
48658
+ const val = parseInt(trimmed, 10);
48659
+ if (isNaN(val)) {
48660
+ throw new Error(`Invalid value "${trimmed}" in cron field "${field}"`);
48661
+ }
48662
+ results.add(val);
48663
+ }
48664
+ }
48665
+ return [...results].sort((a2, b) => a2 - b);
48666
+ }
48667
+ function validateCronExpression(schedule) {
48668
+ if (!schedule || typeof schedule !== "string") {
48669
+ return {
48670
+ valid: false,
48671
+ reason: "Schedule must be a non-empty string"
48672
+ };
48673
+ }
48674
+ const parts = schedule.trim().split(/\s+/);
48675
+ if (parts.length !== 5) {
48676
+ return {
48677
+ valid: false,
48678
+ reason: `Expected 5 fields, got ${parts.length}`
48679
+ };
48680
+ }
48681
+ const fieldRanges = [["minute", 0, 59], ["hour", 0, 23], ["day of month", 1, 31], ["month", 1, 12], ["day of week", 0, 6]];
48682
+ for (let i2 = 0; i2 < 5; i2++) {
48683
+ const [name2, min, max] = fieldRanges[i2];
48684
+ try {
48685
+ const values2 = expandCronField(parts[i2], min, max);
48686
+ if (values2.length === 0) {
48687
+ return {
48688
+ valid: false,
48689
+ reason: `${name2} field "${parts[i2]}" produces no values`
48690
+ };
48691
+ }
48692
+ for (const v of values2) {
48693
+ if (v < min || v > max) {
48694
+ return {
48695
+ valid: false,
48696
+ reason: `${name2} field value ${v} out of range [${min}–${max}]`
48697
+ };
48698
+ }
48699
+ }
48700
+ } catch (err) {
48701
+ return {
48702
+ valid: false,
48703
+ reason: `${name2} field: ${err instanceof Error ? err.message : String(err)}`
48704
+ };
48705
+ }
48706
+ }
48707
+ return {
48708
+ valid: true
48709
+ };
48710
+ }
49257
48711
  function parseCronExpression(expression, after) {
49258
48712
  const parts = expression.trim().split(/\s+/);
49259
48713
  if (parts.length < 5) {
49260
48714
  throw new Error(`Invalid cron expression: "${expression}". Expected 5 fields.`);
49261
48715
  }
49262
48716
  const [minField, hourField, domField, monField, dowField] = parts;
49263
- const expand = (field, min, max) => {
49264
- const results = /* @__PURE__ */ new Set();
49265
- for (const segment of field.split(",")) {
49266
- if (segment === "*") {
49267
- for (let i2 = min; i2 <= max; i2++) results.add(i2);
49268
- } else if (segment.includes("/")) {
49269
- const [rangeStr, stepStr] = segment.split("/");
49270
- const step = parseInt(stepStr, 10);
49271
- let start = min;
49272
- let end = max;
49273
- if (rangeStr !== "*") {
49274
- if (rangeStr.includes("-")) {
49275
- const [a2, b] = rangeStr.split("-").map(Number);
49276
- start = a2;
49277
- end = b;
49278
- } else {
49279
- start = parseInt(rangeStr, 10);
49280
- }
49281
- }
49282
- for (let i2 = start; i2 <= end; i2 += step) results.add(i2);
49283
- } else if (segment.includes("-")) {
49284
- const [a2, b] = segment.split("-").map(Number);
49285
- for (let i2 = a2; i2 <= b; i2++) results.add(i2);
49286
- } else {
49287
- results.add(parseInt(segment, 10));
49288
- }
49289
- }
49290
- return [...results].sort((a2, b) => a2 - b);
49291
- };
49292
- const minutes = expand(minField, 0, 59);
49293
- const hours = expand(hourField, 0, 23);
49294
- const doms = expand(domField, 1, 31);
49295
- const months = expand(monField, 1, 12);
49296
- const dows = expand(dowField, 0, 6);
48717
+ const minutes = expandCronField(minField, 0, 59);
48718
+ const hours = expandCronField(hourField, 0, 23);
48719
+ const doms = expandCronField(domField, 1, 31);
48720
+ const months = expandCronField(monField, 1, 12);
48721
+ const dows = expandCronField(dowField, 0, 6);
49297
48722
  const candidate = new Date(after);
49298
48723
  candidate.setSeconds(0, 0);
49299
48724
  candidate.setMinutes(candidate.getMinutes() + 1);
@@ -49302,9 +48727,9 @@ export default ${safeId}Collection;
49302
48727
  const month = candidate.getMonth() + 1;
49303
48728
  const dom = candidate.getDate();
49304
48729
  const dow = candidate.getDay();
49305
- const hour2 = candidate.getHours();
49306
- const minute2 = candidate.getMinutes();
49307
- if (months.includes(month) && doms.includes(dom) && dows.includes(dow) && hours.includes(hour2) && minutes.includes(minute2)) {
48730
+ const hour = candidate.getHours();
48731
+ const minute = candidate.getMinutes();
48732
+ if (months.includes(month) && doms.includes(dom) && dows.includes(dow) && hours.includes(hour) && minutes.includes(minute)) {
49308
48733
  return candidate;
49309
48734
  }
49310
48735
  candidate.setMinutes(candidate.getMinutes() + 1);
@@ -49314,6 +48739,7 @@ export default ${safeId}Collection;
49314
48739
  return fallback;
49315
48740
  }
49316
48741
  const MAX_LOGS_PER_JOB = 50;
48742
+ const MIN_SCHEDULE_INTERVAL_MS = 5e3;
49317
48743
  class CronScheduler {
49318
48744
  jobs = /* @__PURE__ */ new Map();
49319
48745
  started = false;
@@ -49335,23 +48761,39 @@ export default ${safeId}Collection;
49335
48761
  }
49336
48762
  /**
49337
48763
  * Register a batch of loaded cron jobs.
48764
+ *
48765
+ * If the scheduler is already started, newly registered jobs are
48766
+ * automatically scheduled (so late-registered jobs don't sit idle).
48767
+ *
48768
+ * Validates the cron schedule on registration — invalid schedules
48769
+ * are rejected with a warning and the job is NOT registered.
49338
48770
  */
49339
48771
  registerJobs(loadedJobs) {
49340
48772
  for (const loaded of loadedJobs) {
48773
+ const validation = validateCronExpression(loaded.definition.schedule);
48774
+ if (!validation.valid) {
48775
+ console.error(`[cron] Rejecting job "${loaded.id}": invalid schedule "${loaded.definition.schedule}" — ${validation.reason}`);
48776
+ continue;
48777
+ }
49341
48778
  const existing = this.jobs.get(loaded.id);
49342
48779
  if (existing) {
49343
48780
  console.warn(`[cron] Duplicate cron job id: "${loaded.id}". Overwriting.`);
49344
48781
  this.stopJob(loaded.id);
49345
48782
  }
48783
+ const enabled = loaded.definition.enabled !== false;
49346
48784
  this.jobs.set(loaded.id, {
49347
48785
  id: loaded.id,
49348
48786
  definition: loaded.definition,
49349
- enabled: loaded.definition.enabled !== false,
49350
- state: loaded.definition.enabled !== false ? "idle" : "disabled",
48787
+ enabled,
48788
+ state: enabled ? "idle" : "disabled",
49351
48789
  totalRuns: 0,
49352
48790
  totalFailures: 0,
49353
- logs: []
48791
+ logs: [],
48792
+ executing: false
49354
48793
  });
48794
+ if (this.started && enabled) {
48795
+ this.scheduleNext(loaded.id);
48796
+ }
49355
48797
  }
49356
48798
  }
49357
48799
  /**
@@ -49385,6 +48827,9 @@ export default ${safeId}Collection;
49385
48827
  }
49386
48828
  /**
49387
48829
  * Stop the scheduler and clear all timers.
48830
+ *
48831
+ * Currently-executing handlers run to completion (they are async),
48832
+ * but no further scheduling occurs after stop.
49388
48833
  */
49389
48834
  stop() {
49390
48835
  this.started = false;
@@ -49443,32 +48888,81 @@ export default ${safeId}Collection;
49443
48888
  }
49444
48889
  /**
49445
48890
  * Manually trigger a job execution immediately.
48891
+ *
48892
+ * Returns `undefined` if the job doesn't exist.
48893
+ * If the job is currently executing, returns the log entry with
48894
+ * a `skipped: true` result rather than running concurrently.
49446
48895
  */
49447
48896
  async triggerJob(id) {
49448
48897
  const job = this.jobs.get(id);
49449
48898
  if (!job) return void 0;
48899
+ if (job.executing) {
48900
+ console.warn(`[cron] Skipping manual trigger of "${id}" — already executing`);
48901
+ const logEntry = {
48902
+ jobId: id,
48903
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
48904
+ finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
48905
+ durationMs: 0,
48906
+ success: true,
48907
+ result: {
48908
+ skipped: true,
48909
+ reason: "already_executing"
48910
+ },
48911
+ logs: ["Skipped: job is already running"],
48912
+ manual: true
48913
+ };
48914
+ job.logs.push(logEntry);
48915
+ if (job.logs.length > MAX_LOGS_PER_JOB) job.logs.shift();
48916
+ return logEntry;
48917
+ }
49450
48918
  return this.executeJob(job, true);
49451
48919
  }
49452
48920
  // ─── Internal ────────────────────────────────────────────────────
48921
+ /**
48922
+ * Schedule the next execution for a job.
48923
+ *
48924
+ * Safety guarantees:
48925
+ * 1. Clears any existing timer first (prevents leaked/duplicate timers)
48926
+ * 2. Enforces a minimum delay to prevent tight loops from jitter
48927
+ * 3. Unref's the timer so it doesn't prevent process exit
48928
+ * 4. Re-checks enabled & started state before executing
48929
+ * 5. Concurrency guard prevents overlapping handler executions
48930
+ */
49453
48931
  scheduleNext(id) {
49454
48932
  const job = this.jobs.get(id);
49455
48933
  if (!job || !job.enabled || !this.started) return;
48934
+ this.stopJob(id);
49456
48935
  try {
49457
48936
  const now = /* @__PURE__ */ new Date();
49458
48937
  const nextRun = parseCronExpression(job.definition.schedule, now);
49459
48938
  job.nextRunAt = nextRun;
49460
- const delay = Math.max(nextRun.getTime() - now.getTime(), 0);
49461
- job.timerId = setTimeout(async () => {
48939
+ const rawDelay = nextRun.getTime() - now.getTime();
48940
+ const delay = Math.max(rawDelay, MIN_SCHEDULE_INTERVAL_MS);
48941
+ const timer = setTimeout(async () => {
49462
48942
  if (!job.enabled || !this.started) return;
48943
+ if (job.executing) {
48944
+ console.warn(`[cron] Skipping scheduled run of "${id}" — still executing from previous run`);
48945
+ this.scheduleNext(id);
48946
+ return;
48947
+ }
49463
48948
  await this.executeJob(job, false);
49464
- this.scheduleNext(id);
48949
+ if (this.started && job.enabled) {
48950
+ this.scheduleNext(id);
48951
+ }
49465
48952
  }, delay);
48953
+ if (timer && typeof timer === "object" && "unref" in timer) {
48954
+ timer.unref();
48955
+ }
48956
+ job.timerId = timer;
49466
48957
  } catch (err) {
49467
48958
  console.error(`[cron] Failed to schedule "${id}":`, err);
49468
48959
  job.state = "error";
49469
48960
  job.lastError = err instanceof Error ? err.message : String(err);
49470
48961
  }
49471
48962
  }
48963
+ /**
48964
+ * Stop a single job's timer and clear its next run state.
48965
+ */
49472
48966
  stopJob(id) {
49473
48967
  const job = this.jobs.get(id);
49474
48968
  if (job?.timerId) {
@@ -49477,9 +48971,19 @@ export default ${safeId}Collection;
49477
48971
  job.nextRunAt = void 0;
49478
48972
  }
49479
48973
  }
48974
+ /**
48975
+ * Execute a job's handler with full isolation and safety.
48976
+ *
48977
+ * - Sets a concurrency flag to prevent overlapping runs
48978
+ * - Wraps handler in a timeout race
48979
+ * - Captures all logs, errors, and results
48980
+ * - Persists to store (non-blocking) if available
48981
+ * - Always restores state even on catastrophic errors
48982
+ */
49480
48983
  async executeJob(job, manual) {
49481
48984
  const startedAt = /* @__PURE__ */ new Date();
49482
48985
  const capturedLogs = [];
48986
+ job.executing = true;
49483
48987
  const ctx = {
49484
48988
  jobId: job.id,
49485
48989
  scheduledAt: startedAt,
@@ -49498,14 +49002,21 @@ export default ${safeId}Collection;
49498
49002
  try {
49499
49003
  const timeout = (job.definition.timeoutSeconds ?? 300) * 1e3;
49500
49004
  const handlerPromise = Promise.resolve(job.definition.handler(ctx));
49005
+ let timeoutHandle;
49501
49006
  const timeoutPromise = new Promise((_, reject) => {
49502
- setTimeout(() => reject(new Error(`Cron job "${job.id}" timed out after ${timeout}ms`)), timeout);
49007
+ timeoutHandle = setTimeout(() => reject(new Error(`Cron job "${job.id}" timed out after ${timeout}ms`)), timeout);
49503
49008
  });
49504
- result = await Promise.race([handlerPromise, timeoutPromise]);
49009
+ try {
49010
+ result = await Promise.race([handlerPromise, timeoutPromise]);
49011
+ } finally {
49012
+ clearTimeout(timeoutHandle);
49013
+ }
49505
49014
  } catch (err) {
49506
49015
  success = false;
49507
49016
  error2 = err instanceof Error ? err.message : String(err);
49508
49017
  job.totalFailures++;
49018
+ } finally {
49019
+ job.executing = false;
49509
49020
  }
49510
49021
  const finishedAt = /* @__PURE__ */ new Date();
49511
49022
  const durationMs = finishedAt.getTime() - startedAt.getTime();
@@ -49528,8 +49039,8 @@ export default ${safeId}Collection;
49528
49039
  job.logs.shift();
49529
49040
  }
49530
49041
  if (this.store) {
49531
- this.store.insertLog(logEntry).catch((err) => {
49532
- console.error(`[cron] Failed to persist log for "${job.id}":`, err);
49042
+ this.store.insertLog(logEntry).catch((persistErr) => {
49043
+ console.error(`[cron] Failed to persist log for "${job.id}":`, persistErr);
49533
49044
  });
49534
49045
  }
49535
49046
  if (success) {
@@ -49558,7 +49069,8 @@ export default ${safeId}Collection;
49558
49069
  }
49559
49070
  const cronScheduler = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
49560
49071
  __proto__: null,
49561
- CronScheduler
49072
+ CronScheduler,
49073
+ validateCronExpression
49562
49074
  }, Symbol.toStringTag, { value: "Module" }));
49563
49075
  function createCronRoutes(scheduler) {
49564
49076
  const router = new hono.Hono();
@@ -49960,6 +49472,7 @@ export default ${safeId}Collection;
49960
49472
  exports2.resetConsole = resetConsole;
49961
49473
  exports2.serveSPA = serveSPA;
49962
49474
  exports2.strictAuthLimiter = strictAuthLimiter;
49475
+ exports2.validateCronExpression = validateCronExpression;
49963
49476
  exports2.validatePasswordStrength = validatePasswordStrength;
49964
49477
  exports2.verifyAccessToken = verifyAccessToken;
49965
49478
  exports2.verifyPassword = verifyPassword;