vinext 1.0.0-beta.0 → 1.0.0-beta.2

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 (305) hide show
  1. package/README.md +21 -2
  2. package/dist/build/assets-ignore.js +1 -1
  3. package/dist/build/clean-output.js +1 -1
  4. package/dist/build/client-build-config.js +7 -4
  5. package/dist/build/css-url-assets.js +3 -3
  6. package/dist/build/google-fonts/fallback-metrics.js +1 -1
  7. package/dist/build/google-fonts/font-metadata.js +1 -1
  8. package/dist/build/inject-pregenerated-paths.js +1 -1
  9. package/dist/build/inline-css.js +2 -5
  10. package/dist/build/module-dependency-cache.d.ts +4 -0
  11. package/dist/build/module-dependency-cache.js +13 -0
  12. package/dist/build/next-client-runtime-manifests.js +1 -1
  13. package/dist/build/pages-client-assets-module.js +1 -1
  14. package/dist/build/precompress.js +7 -7
  15. package/dist/build/prerender-paths.d.ts +2 -2
  16. package/dist/build/prerender-paths.js +10 -15
  17. package/dist/build/prerender-server-pool.js +2 -2
  18. package/dist/build/prerender.js +1 -1
  19. package/dist/build/preview-credentials.d.ts +11 -0
  20. package/dist/build/preview-credentials.js +19 -0
  21. package/dist/build/report.d.ts +8 -4
  22. package/dist/build/report.js +14 -6
  23. package/dist/build/run-prerender.d.ts +2 -11
  24. package/dist/build/run-prerender.js +2 -10
  25. package/dist/build/server-manifest.js +1 -1
  26. package/dist/build/ssr-manifest.d.ts +4 -0
  27. package/dist/build/ssr-manifest.js +10 -6
  28. package/dist/build/standalone.js +37 -37
  29. package/dist/cache/cache-adapters-virtual.d.ts +1 -17
  30. package/dist/cache/cache-adapters-virtual.js +20 -11
  31. package/dist/check.d.ts +0 -16
  32. package/dist/check.js +27 -36
  33. package/dist/cli.js +61 -55
  34. package/dist/client/instrumentation-client-inject.js +1 -1
  35. package/dist/client/pages-router-link-navigation.js +1 -1
  36. package/dist/config/config-matchers.d.ts +13 -37
  37. package/dist/config/config-matchers.js +33 -123
  38. package/dist/config/dotenv.js +1 -1
  39. package/dist/config/next-config.d.ts +7 -3
  40. package/dist/config/next-config.js +84 -15
  41. package/dist/config/prerender.d.ts +2 -2
  42. package/dist/config/prerender.js +7 -15
  43. package/dist/config/request-context.d.ts +14 -0
  44. package/dist/config/request-context.js +26 -0
  45. package/dist/config/server-external-packages.js +1 -1
  46. package/dist/config/tsconfig-paths.js +2 -2
  47. package/dist/{node_modules/.pnpm/am-i-vibing@0.5.0/node_modules → deps/.pnpm/am-i-vibing@0.5.0/deps}/am-i-vibing/dist/detector-1yx2Hoe0.js +2 -2
  48. package/dist/deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js +50 -0
  49. package/dist/entries/app-rsc-entry.js +39 -14
  50. package/dist/entries/app-rsc-manifest.js +21 -4
  51. package/dist/entries/pages-client-entry.js +6 -5
  52. package/dist/entries/pages-server-entry.js +18 -28
  53. package/dist/entries/runtime-entry-module.js +2 -2
  54. package/dist/index.js +314 -230
  55. package/dist/init-cloudflare.js +1 -1
  56. package/dist/init-platform.js +1 -1
  57. package/dist/init.d.ts +6 -4
  58. package/dist/init.js +25 -27
  59. package/dist/plugins/ast-utils.js +1 -1
  60. package/dist/plugins/dynamic-preload-metadata.js +7 -7
  61. package/dist/plugins/extensionless-dynamic-import.js +1 -1
  62. package/dist/plugins/fonts.js +3 -3
  63. package/dist/plugins/ignore-dynamic-requests.js +13 -8
  64. package/dist/plugins/import-meta-url.js +16 -17
  65. package/dist/plugins/middleware-export-validation.js +1 -1
  66. package/dist/plugins/middleware-server-only.js +2 -2
  67. package/dist/plugins/og-asset-ownership.js +7 -6
  68. package/dist/plugins/og-assets.js +5 -6
  69. package/dist/plugins/optimize-imports.js +12 -13
  70. package/dist/plugins/postcss.js +1 -1
  71. package/dist/plugins/remove-console.js +1 -1
  72. package/dist/plugins/require-context.js +1 -1
  73. package/dist/plugins/sass.js +2 -2
  74. package/dist/plugins/server-externals-manifest.js +1 -1
  75. package/dist/plugins/strip-server-exports.js +1 -1
  76. package/dist/plugins/styled-jsx.js +3 -2
  77. package/dist/plugins/typeof-window.js +1 -1
  78. package/dist/routing/app-route-graph.d.ts +16 -15
  79. package/dist/routing/app-route-graph.js +86 -88
  80. package/dist/routing/app-router.d.ts +0 -5
  81. package/dist/routing/app-router.js +12 -11
  82. package/dist/routing/file-matcher.d.ts +13 -28
  83. package/dist/routing/file-matcher.js +31 -44
  84. package/dist/routing/pages-router.js +26 -32
  85. package/dist/routing/route-matching.d.ts +14 -1
  86. package/dist/routing/route-matching.js +13 -1
  87. package/dist/routing/route-pattern.d.ts +2 -1
  88. package/dist/routing/route-pattern.js +7 -4
  89. package/dist/routing/route-trie.d.ts +5 -1
  90. package/dist/routing/route-trie.js +5 -2
  91. package/dist/server/api-handler.js +41 -33
  92. package/dist/server/app-browser-entry.js +18 -11
  93. package/dist/server/app-browser-history-controller.d.ts +1 -1
  94. package/dist/server/app-browser-history-controller.js +3 -3
  95. package/dist/server/app-browser-navigation-controller.js +4 -2
  96. package/dist/server/app-browser-server-action-client.js +1 -1
  97. package/dist/server/app-elements-wire.d.ts +2 -1
  98. package/dist/server/app-fallback-renderer.d.ts +11 -0
  99. package/dist/server/app-fallback-renderer.js +16 -2
  100. package/dist/server/app-middleware.js +2 -1
  101. package/dist/server/app-page-boundary-render.d.ts +26 -2
  102. package/dist/server/app-page-boundary-render.js +190 -55
  103. package/dist/server/app-page-cache-finalizer.d.ts +1 -1
  104. package/dist/server/app-page-cache.d.ts +1 -1
  105. package/dist/server/app-page-dispatch.d.ts +12 -2
  106. package/dist/server/app-page-dispatch.js +37 -51
  107. package/dist/server/app-page-element-builder.d.ts +8 -2
  108. package/dist/server/app-page-element-builder.js +112 -27
  109. package/dist/server/app-page-execution.d.ts +3 -1
  110. package/dist/server/app-page-execution.js +31 -39
  111. package/dist/server/app-page-head.d.ts +54 -2
  112. package/dist/server/app-page-head.js +164 -78
  113. package/dist/server/app-page-http-access-fallback-metadata.d.ts +29 -0
  114. package/dist/server/app-page-http-access-fallback-metadata.js +106 -0
  115. package/dist/server/app-page-render.d.ts +2 -2
  116. package/dist/server/app-page-render.js +1 -1
  117. package/dist/server/app-page-request.d.ts +12 -0
  118. package/dist/server/app-page-request.js +134 -14
  119. package/dist/server/app-page-route-wiring.d.ts +9 -0
  120. package/dist/server/app-page-route-wiring.js +44 -4
  121. package/dist/server/app-post-middleware-context.d.ts +1 -1
  122. package/dist/server/app-post-middleware-context.js +1 -1
  123. package/dist/server/app-route-handler-dispatch.js +31 -17
  124. package/dist/server/app-route-handler-execution.d.ts +6 -1
  125. package/dist/server/app-route-handler-execution.js +41 -15
  126. package/dist/server/app-route-handler-policy.d.ts +2 -0
  127. package/dist/server/app-route-handler-policy.js +3 -3
  128. package/dist/server/app-route-module-loader.d.ts +3 -1
  129. package/dist/server/app-route-module-loader.js +1 -0
  130. package/dist/server/app-route-tree-prefetch.js +1 -1
  131. package/dist/server/app-rsc-cache-busting.d.ts +1 -1
  132. package/dist/server/app-rsc-cache-busting.js +1 -1
  133. package/dist/server/app-rsc-errors.d.ts +1 -1
  134. package/dist/server/app-rsc-errors.js +12 -2
  135. package/dist/server/app-rsc-handler.d.ts +10 -5
  136. package/dist/server/app-rsc-handler.js +51 -23
  137. package/dist/server/app-rsc-redirect-flight.d.ts +66 -0
  138. package/dist/server/app-rsc-redirect-flight.js +71 -0
  139. package/dist/server/app-rsc-request-normalization.d.ts +3 -2
  140. package/dist/server/app-rsc-request-normalization.js +8 -2
  141. package/dist/server/app-rsc-response-finalizer.d.ts +2 -2
  142. package/dist/server/app-rsc-response-finalizer.js +5 -11
  143. package/dist/server/app-rsc-route-matching.d.ts +20 -0
  144. package/dist/server/app-rsc-route-matching.js +87 -11
  145. package/dist/server/app-segment-config.js +15 -5
  146. package/dist/server/app-server-action-execution.d.ts +3 -1
  147. package/dist/server/app-server-action-execution.js +8 -6
  148. package/dist/server/app-ssr-entry.js +4 -1
  149. package/dist/server/app-ssr-stream.d.ts +2 -7
  150. package/dist/server/app-ssr-stream.js +5 -10
  151. package/dist/server/cache-proof.js +1 -1
  152. package/dist/server/config-headers.d.ts +24 -0
  153. package/dist/server/config-headers.js +52 -0
  154. package/dist/server/default-global-error-module.d.ts +3 -1
  155. package/dist/server/default-not-found-module.d.ts +3 -1
  156. package/dist/server/dev-initial-server-error.d.ts +1 -1
  157. package/dist/server/dev-lockfile.js +2 -3
  158. package/dist/server/dev-route-files.js +1 -1
  159. package/dist/server/dev-server.js +281 -173
  160. package/dist/server/dev-stack-sourcemap.js +4 -3
  161. package/dist/server/headers.d.ts +3 -1
  162. package/dist/server/headers.js +3 -1
  163. package/dist/server/image-optimization.js +2 -2
  164. package/dist/server/implicit-tags.js +2 -1
  165. package/dist/server/instrumentation.js +2 -2
  166. package/dist/server/isr-cache.d.ts +1 -1
  167. package/dist/server/isr-cache.js +1 -1
  168. package/dist/server/metadata-routes.js +4 -4
  169. package/dist/server/middleware-matcher-pattern.d.ts +22 -0
  170. package/dist/server/middleware-matcher-pattern.js +219 -0
  171. package/dist/server/middleware-matcher.d.ts +2 -7
  172. package/dist/server/middleware-matcher.js +13 -60
  173. package/dist/server/middleware-path-to-regexp.d.ts +14 -0
  174. package/dist/server/middleware-path-to-regexp.js +228 -0
  175. package/dist/server/middleware-response-headers.js +1 -1
  176. package/dist/server/middleware-runtime.js +5 -4
  177. package/dist/server/middleware.d.ts +2 -1
  178. package/dist/server/middleware.js +3 -2
  179. package/dist/server/navigation-planner.d.ts +2 -0
  180. package/dist/server/navigation-planner.js +8 -2
  181. package/dist/server/next-error-digest.d.ts +9 -24
  182. package/dist/server/next-error-digest.js +23 -15
  183. package/dist/server/operation-token.js +1 -1
  184. package/dist/server/pages-body-parser-config.js +2 -1
  185. package/dist/server/pages-data-route.d.ts +11 -1
  186. package/dist/server/pages-data-route.js +16 -1
  187. package/dist/server/pages-dev-hydration.d.ts +14 -0
  188. package/dist/server/pages-dev-hydration.js +83 -0
  189. package/dist/server/pages-dev-module-url.js +2 -2
  190. package/dist/server/pages-get-initial-props.d.ts +15 -2
  191. package/dist/server/pages-get-initial-props.js +16 -6
  192. package/dist/server/pages-node-compat.d.ts +13 -6
  193. package/dist/server/pages-node-compat.js +44 -45
  194. package/dist/server/pages-page-data.d.ts +4 -2
  195. package/dist/server/pages-page-data.js +20 -10
  196. package/dist/server/pages-page-handler.d.ts +4 -2
  197. package/dist/server/pages-page-handler.js +74 -43
  198. package/dist/server/pages-page-response.d.ts +2 -2
  199. package/dist/server/pages-page-response.js +1 -1
  200. package/dist/server/pages-preview.d.ts +26 -0
  201. package/dist/server/pages-preview.js +165 -0
  202. package/dist/server/pages-readiness.d.ts +5 -4
  203. package/dist/server/pages-readiness.js +4 -2
  204. package/dist/server/pages-request-pipeline.d.ts +1 -0
  205. package/dist/server/pages-request-pipeline.js +25 -11
  206. package/dist/server/pages-router-entry.js +6 -0
  207. package/dist/server/prerender-route-params.js +2 -2
  208. package/dist/server/prod-server.d.ts +1 -4
  209. package/dist/server/prod-server.js +44 -30
  210. package/dist/server/request-pipeline.d.ts +15 -29
  211. package/dist/server/request-pipeline.js +25 -60
  212. package/dist/server/rsc-stream-hints.js +122 -18
  213. package/dist/server/seed-cache.js +1 -1
  214. package/dist/server/socket-error-backstop.js +1 -1
  215. package/dist/server/static-file-cache.js +7 -8
  216. package/dist/server/worker-utils.js +1 -1
  217. package/dist/shims/app.d.ts +1 -1
  218. package/dist/shims/cache-request-state.d.ts +27 -1
  219. package/dist/shims/cache-request-state.js +60 -1
  220. package/dist/shims/cache-runtime.d.ts +12 -1
  221. package/dist/shims/cache-runtime.js +22 -7
  222. package/dist/shims/cache.d.ts +5 -5
  223. package/dist/shims/cache.js +28 -11
  224. package/dist/shims/constants.js +1 -1
  225. package/dist/shims/document.d.ts +42 -83
  226. package/dist/shims/document.js +62 -53
  227. package/dist/shims/dynamic.d.ts +5 -25
  228. package/dist/shims/dynamic.js +29 -8
  229. package/dist/shims/error-boundary.d.ts +4 -4
  230. package/dist/shims/error.d.ts +22 -6
  231. package/dist/shims/error.js +53 -15
  232. package/dist/shims/fetch-cache.js +13 -4
  233. package/dist/shims/font-google-base.d.ts +11 -4
  234. package/dist/shims/font-local.d.ts +10 -3
  235. package/dist/shims/font-utils.js +1 -1
  236. package/dist/shims/form.d.ts +1 -1
  237. package/dist/shims/head.d.ts +13 -2
  238. package/dist/shims/head.js +6 -6
  239. package/dist/shims/headers.d.ts +28 -31
  240. package/dist/shims/headers.js +115 -53
  241. package/dist/shims/image.d.ts +27 -37
  242. package/dist/shims/image.js +21 -14
  243. package/dist/shims/internal/cookie-serialize.d.ts +3 -1
  244. package/dist/shims/internal/cookie-serialize.js +3 -1
  245. package/dist/shims/internal/hybrid-client-route-owner.js +3 -1
  246. package/dist/shims/internal/pages-data-fetch-dedup.js +5 -3
  247. package/dist/shims/internal/utils.d.ts +3 -3
  248. package/dist/shims/layout-segment-context.d.ts +1 -1
  249. package/dist/shims/legacy-image.d.ts +3 -37
  250. package/dist/shims/legacy-image.js +6 -16
  251. package/dist/shims/link.d.ts +16 -21
  252. package/dist/shims/link.js +25 -13
  253. package/dist/shims/navigation-context-state.d.ts +1 -1
  254. package/dist/shims/navigation-errors.d.ts +2 -1
  255. package/dist/shims/navigation-errors.js +9 -13
  256. package/dist/shims/navigation.d.ts +8 -4
  257. package/dist/shims/navigation.js +29 -18
  258. package/dist/shims/next-shims-augmentations.d.ts +1 -0
  259. package/dist/shims/next-shims-public.d.ts +1 -0
  260. package/dist/shims/public-shim-map.json.js +103 -0
  261. package/dist/shims/readonly-url-search-params.d.ts +3 -3
  262. package/dist/shims/readonly-url-search-params.js +3 -3
  263. package/dist/shims/request-state-types.d.ts +1 -1
  264. package/dist/shims/router-state.d.ts +1 -0
  265. package/dist/shims/router.d.ts +57 -22
  266. package/dist/shims/router.js +178 -46
  267. package/dist/shims/script.d.ts +6 -10
  268. package/dist/shims/script.js +7 -4
  269. package/dist/shims/server.d.ts +45 -22
  270. package/dist/shims/server.js +46 -7
  271. package/dist/shims/slot.d.ts +1 -1
  272. package/dist/shims/thenable-params.js +1 -1
  273. package/dist/shims/unified-request-context.d.ts +1 -1
  274. package/dist/shims/unified-request-context.js +2 -0
  275. package/dist/shims/url-safety.d.ts +1 -1
  276. package/dist/shims/url-safety.js +2 -2
  277. package/dist/typegen.d.ts +8 -2
  278. package/dist/typegen.js +84 -25
  279. package/dist/utils/client-build-manifest.js +2 -2
  280. package/dist/utils/client-entry-manifest.js +1 -1
  281. package/dist/utils/client-runtime-metadata.js +1 -1
  282. package/dist/utils/commonjs-loader.js +3 -3
  283. package/dist/utils/domain-locale.d.ts +2 -2
  284. package/dist/utils/external-url.d.ts +5 -0
  285. package/dist/utils/external-url.js +7 -0
  286. package/dist/utils/mdx-scan.js +1 -1
  287. package/dist/utils/path.d.ts +1 -13
  288. package/dist/utils/path.js +1 -15
  289. package/dist/utils/plugin-options.d.ts +4 -0
  290. package/dist/utils/plugin-options.js +8 -0
  291. package/dist/utils/project.d.ts +0 -6
  292. package/dist/utils/project.js +2 -8
  293. package/dist/utils/public-routes.js +2 -2
  294. package/dist/utils/react-version.js +1 -1
  295. package/dist/utils/redirect-digest.d.ts +9 -0
  296. package/dist/utils/redirect-digest.js +25 -0
  297. package/dist/utils/regex-safety.d.ts +8 -0
  298. package/dist/utils/regex-safety.js +737 -0
  299. package/dist/utils/vinext-root.js +1 -1
  300. package/dist/utils/vite-version.d.ts +5 -2
  301. package/dist/utils/vite-version.js +43 -17
  302. package/package.json +16 -4
  303. /package/dist/build/google-fonts/{fallback-metrics-data.js → fallback-metrics-data.json.js} +0 -0
  304. /package/dist/build/google-fonts/{font-data.js → font-data.json.js} +0 -0
  305. /package/dist/{node_modules/.pnpm/process-ancestry@0.1.0/node_modules → deps/.pnpm/process-ancestry@0.1.0/deps}/process-ancestry/dist/index.js +0 -0
@@ -0,0 +1,737 @@
1
+ //#region src/utils/regex-safety.ts
2
+ const MAX_NODES = 16384;
3
+ const MAX_NESTING_DEPTH = 256;
4
+ const MAX_PATTERN_LENGTH = 65536;
5
+ const MAX_WORDS = 4096;
6
+ const MAX_WORD_SYMBOLS = 32768;
7
+ const MAX_OPAQUE_COMPARISONS = 4096;
8
+ const MAX_SEQUENCE_EXPANSIONS = 256;
9
+ const MAX_SAFE_OVERLAPPING_VARIABLE_BOUNDARIES = 1;
10
+ function canonicalizeIgnoreCase(character) {
11
+ const upper = character.toUpperCase();
12
+ if (upper.length !== 1) return character;
13
+ if (character.charCodeAt(0) >= 128 && upper.charCodeAt(0) < 128) return character;
14
+ return upper;
15
+ }
16
+ function literalSymbol(character, ignoreCase) {
17
+ return {
18
+ kind: "literal",
19
+ key: ignoreCase ? canonicalizeIgnoreCase(character) : character,
20
+ value: character
21
+ };
22
+ }
23
+ function createClassSymbol(values, nonAscii) {
24
+ return {
25
+ kind: "class",
26
+ key: `class:${nonAscii}:${[...values].sort().join("")}`,
27
+ values,
28
+ nonAscii
29
+ };
30
+ }
31
+ function shorthandClassSymbol(shorthand, ignoreCase) {
32
+ if (!"dDwWsS".includes(shorthand)) return null;
33
+ const regexp = new RegExp(`\\${shorthand}`);
34
+ const values = /* @__PURE__ */ new Set();
35
+ for (let code = 0; code <= 127; code++) {
36
+ const character = String.fromCharCode(code);
37
+ if (regexp.test(character)) values.add(ignoreCase ? canonicalizeIgnoreCase(character) : character);
38
+ }
39
+ return createClassSymbol(values, shorthand === "d" || shorthand === "w" ? "none" : shorthand === "s" ? "whitespace" : shorthand === "S" ? "non-whitespace" : "all");
40
+ }
41
+ function unionNonAscii(left, right) {
42
+ if (left === "none") return right;
43
+ if (right === "none" || left === right) return left;
44
+ return "all";
45
+ }
46
+ function simpleClassSymbol(raw, ignoreCase) {
47
+ const end = raw.length - 1;
48
+ if (raw[0] !== "[" || raw[end] !== "]" || raw[1] === "^") return null;
49
+ const values = /* @__PURE__ */ new Set();
50
+ let nonAscii = "none";
51
+ const add = (character) => {
52
+ if (character.charCodeAt(0) > 127) return false;
53
+ values.add(ignoreCase ? canonicalizeIgnoreCase(character) : character);
54
+ return true;
55
+ };
56
+ const addClass = (symbol) => {
57
+ if (symbol.kind !== "class") return false;
58
+ for (const value of symbol.values) values.add(value);
59
+ nonAscii = unionNonAscii(nonAscii, symbol.nonAscii);
60
+ return true;
61
+ };
62
+ for (let index = 1; index < end; index++) {
63
+ const start = raw[index];
64
+ if (start === "\\") {
65
+ const escaped = raw[++index];
66
+ if (escaped === void 0) return null;
67
+ const shorthand = shorthandClassSymbol(escaped, ignoreCase);
68
+ if (shorthand) {
69
+ if (!addClass(shorthand)) return null;
70
+ } else if ("\\-]".includes(escaped)) {
71
+ if (!add(escaped)) return null;
72
+ } else return null;
73
+ continue;
74
+ }
75
+ if (index + 2 < end && raw[index + 1] === "-") {
76
+ const rangeEnd = raw[index + 2];
77
+ if (rangeEnd === "\\") return null;
78
+ const startCode = start.charCodeAt(0);
79
+ const endCode = rangeEnd.charCodeAt(0);
80
+ if (startCode > endCode || endCode > 127) return null;
81
+ for (let code = startCode; code <= endCode; code++) if (!add(String.fromCharCode(code))) return null;
82
+ index += 2;
83
+ } else if (!add(start)) return null;
84
+ }
85
+ if (values.size === 0 && nonAscii === "none") return null;
86
+ return createClassSymbol(values, nonAscii);
87
+ }
88
+ var RegexParser = class {
89
+ pattern;
90
+ ignoreCase;
91
+ index = 0;
92
+ nodes = 0;
93
+ depth = 0;
94
+ exceededBudget = false;
95
+ constructor(pattern, ignoreCase) {
96
+ this.pattern = pattern;
97
+ this.ignoreCase = ignoreCase;
98
+ }
99
+ parse() {
100
+ return this.parseAlternation();
101
+ }
102
+ node(node) {
103
+ this.nodes++;
104
+ if (this.nodes > MAX_NODES) this.exceededBudget = true;
105
+ return node;
106
+ }
107
+ parseAlternation() {
108
+ const branches = [this.parseSequence()];
109
+ while (this.pattern[this.index] === "|") {
110
+ this.index++;
111
+ branches.push(this.parseSequence());
112
+ }
113
+ return branches.length === 1 ? branches[0] : this.node({
114
+ kind: "alternation",
115
+ branches
116
+ });
117
+ }
118
+ parseSequence() {
119
+ const children = [];
120
+ while (this.index < this.pattern.length) {
121
+ const character = this.pattern[this.index];
122
+ if (character === "|" || character === ")") break;
123
+ const term = this.parseTerm();
124
+ if (term.kind === "sequence") children.push(...term.children);
125
+ else children.push(term);
126
+ }
127
+ return children.length === 1 ? children[0] : this.node({
128
+ kind: "sequence",
129
+ children
130
+ });
131
+ }
132
+ parseTerm() {
133
+ const atom = this.parseAtom();
134
+ const quantifier = this.parseQuantifier();
135
+ if (!quantifier) return atom;
136
+ if (this.pattern[this.index] === "?") this.index++;
137
+ if (quantifier.min === 1 && quantifier.max === 1) return atom;
138
+ return this.node({
139
+ kind: "repeat",
140
+ child: atom,
141
+ ...quantifier
142
+ });
143
+ }
144
+ parseAtom() {
145
+ const character = this.pattern[this.index++];
146
+ if (character === "(") return this.parseGroup();
147
+ if (character === "[") return this.parseClass();
148
+ if (character === "\\") return this.parseEscape();
149
+ if (character === "^" || character === "$") return this.node({
150
+ kind: "assertion",
151
+ child: this.node({
152
+ kind: "sequence",
153
+ children: []
154
+ })
155
+ });
156
+ if (character === ".") return this.node({
157
+ kind: "atom",
158
+ symbol: {
159
+ kind: "opaque",
160
+ key: ".",
161
+ pattern: ".",
162
+ ignoreCase: this.ignoreCase
163
+ },
164
+ fixedWidth: true
165
+ });
166
+ return this.node({
167
+ kind: "atom",
168
+ symbol: literalSymbol(character, this.ignoreCase),
169
+ fixedWidth: true
170
+ });
171
+ }
172
+ parseGroup() {
173
+ this.depth++;
174
+ if (this.depth > MAX_NESTING_DEPTH) {
175
+ this.exceededBudget = true;
176
+ this.skipGroup();
177
+ this.depth--;
178
+ return this.node({
179
+ kind: "atom",
180
+ symbol: null,
181
+ fixedWidth: false
182
+ });
183
+ }
184
+ let assertion = false;
185
+ if (this.pattern[this.index] === "?") {
186
+ const marker = this.pattern[this.index + 1];
187
+ if (marker === ":") this.index += 2;
188
+ else if (marker === "=" || marker === "!") {
189
+ assertion = true;
190
+ this.index += 2;
191
+ } else if (marker === "<" && (this.pattern[this.index + 2] === "=" || this.pattern[this.index + 2] === "!")) {
192
+ assertion = true;
193
+ this.index += 3;
194
+ } else if (marker === "<") {
195
+ const nameEnd = this.pattern.indexOf(">", this.index + 2);
196
+ this.index = nameEnd === -1 ? this.pattern.length : nameEnd + 1;
197
+ } else {
198
+ while (this.index < this.pattern.length && this.pattern[this.index] !== ")") this.index++;
199
+ if (this.pattern[this.index] === ")") this.index++;
200
+ this.depth--;
201
+ return this.node({
202
+ kind: "atom",
203
+ symbol: null,
204
+ fixedWidth: false
205
+ });
206
+ }
207
+ }
208
+ const child = this.parseAlternation();
209
+ if (this.pattern[this.index] === ")") this.index++;
210
+ this.depth--;
211
+ return assertion ? this.node({
212
+ kind: "assertion",
213
+ child
214
+ }) : child;
215
+ }
216
+ skipGroup() {
217
+ let depth = 1;
218
+ let inClass = false;
219
+ while (this.index < this.pattern.length && depth > 0) {
220
+ const character = this.pattern[this.index++];
221
+ if (character === "\\") {
222
+ this.index++;
223
+ continue;
224
+ }
225
+ if (character === "[") inClass = true;
226
+ else if (character === "]") inClass = false;
227
+ else if (!inClass && character === "(") depth++;
228
+ else if (!inClass && character === ")") depth--;
229
+ }
230
+ }
231
+ parseClass() {
232
+ const start = this.index - 1;
233
+ while (this.index < this.pattern.length) {
234
+ const character = this.pattern[this.index++];
235
+ if (character === "\\") this.index++;
236
+ else if (character === "]") break;
237
+ }
238
+ const raw = this.pattern.slice(start, this.index);
239
+ return this.node({
240
+ kind: "atom",
241
+ symbol: simpleClassSymbol(raw, this.ignoreCase) ?? {
242
+ kind: "opaque",
243
+ key: raw,
244
+ pattern: raw,
245
+ ignoreCase: this.ignoreCase
246
+ },
247
+ fixedWidth: true
248
+ });
249
+ }
250
+ parseEscape() {
251
+ const escaped = this.pattern[this.index++];
252
+ if (escaped === void 0) return this.node({
253
+ kind: "atom",
254
+ symbol: null,
255
+ fixedWidth: false
256
+ });
257
+ if (escaped === "b" || escaped === "B") return this.node({
258
+ kind: "assertion",
259
+ child: this.node({
260
+ kind: "sequence",
261
+ children: []
262
+ })
263
+ });
264
+ const shorthand = shorthandClassSymbol(escaped, this.ignoreCase);
265
+ if (shorthand) return this.node({
266
+ kind: "atom",
267
+ symbol: shorthand,
268
+ fixedWidth: true
269
+ });
270
+ if (/\d/.test(escaped)) return this.node({
271
+ kind: "atom",
272
+ symbol: null,
273
+ fixedWidth: false
274
+ });
275
+ let literal = null;
276
+ if (escaped === "x" && /^[\da-fA-F]{2}/.test(this.pattern.slice(this.index, this.index + 2))) {
277
+ literal = String.fromCharCode(Number.parseInt(this.pattern.slice(this.index, this.index + 2), 16));
278
+ this.index += 2;
279
+ } else if (escaped === "u" && /^[\da-fA-F]{4}/.test(this.pattern.slice(this.index, this.index + 4))) {
280
+ literal = String.fromCharCode(Number.parseInt(this.pattern.slice(this.index, this.index + 4), 16));
281
+ this.index += 4;
282
+ } else if ("nrtvf0".includes(escaped)) literal = {
283
+ n: "\n",
284
+ r: "\r",
285
+ t: " ",
286
+ v: "\v",
287
+ f: "\f",
288
+ 0: "\0"
289
+ }[escaped];
290
+ else if (!/[A-Za-z]/.test(escaped)) literal = escaped;
291
+ if (literal !== null) return this.node({
292
+ kind: "atom",
293
+ symbol: literalSymbol(literal, this.ignoreCase),
294
+ fixedWidth: true
295
+ });
296
+ const raw = `\\${escaped}`;
297
+ return this.node({
298
+ kind: "atom",
299
+ symbol: {
300
+ kind: "opaque",
301
+ key: raw,
302
+ pattern: raw,
303
+ ignoreCase: this.ignoreCase
304
+ },
305
+ fixedWidth: true
306
+ });
307
+ }
308
+ parseQuantifier() {
309
+ const character = this.pattern[this.index];
310
+ if (character === "*") {
311
+ this.index++;
312
+ return {
313
+ min: 0,
314
+ max: Infinity
315
+ };
316
+ }
317
+ if (character === "+") {
318
+ this.index++;
319
+ return {
320
+ min: 1,
321
+ max: Infinity
322
+ };
323
+ }
324
+ if (character === "?") {
325
+ this.index++;
326
+ return {
327
+ min: 0,
328
+ max: 1
329
+ };
330
+ }
331
+ if (character !== "{") return null;
332
+ const start = this.index;
333
+ let cursor = start + 1;
334
+ while (/\d/.test(this.pattern[cursor] ?? "")) cursor++;
335
+ if (cursor === start + 1) return null;
336
+ const min = Number(this.pattern.slice(start + 1, cursor));
337
+ if (this.pattern[cursor] === "}") {
338
+ this.index = cursor + 1;
339
+ return {
340
+ min,
341
+ max: min
342
+ };
343
+ }
344
+ if (this.pattern[cursor] !== ",") return null;
345
+ cursor++;
346
+ const maxStart = cursor;
347
+ while (/\d/.test(this.pattern[cursor] ?? "")) cursor++;
348
+ if (this.pattern[cursor] !== "}") return null;
349
+ const max = cursor === maxStart ? Infinity : Number(this.pattern.slice(maxStart, cursor));
350
+ this.index = cursor + 1;
351
+ return {
352
+ min,
353
+ max
354
+ };
355
+ }
356
+ };
357
+ function exactWidth(node) {
358
+ switch (node.kind) {
359
+ case "atom": return node.fixedWidth ? 1 : null;
360
+ case "assertion": return 0;
361
+ case "sequence": {
362
+ let width = 0;
363
+ for (const child of node.children) {
364
+ const childWidth = exactWidth(child);
365
+ if (childWidth === null) return null;
366
+ width += childWidth;
367
+ }
368
+ return width;
369
+ }
370
+ case "alternation": {
371
+ let width;
372
+ for (const branch of node.branches) {
373
+ const branchWidth = exactWidth(branch);
374
+ if (branchWidth === null) return null;
375
+ if (width === void 0) width = branchWidth;
376
+ else if (width !== branchWidth) return null;
377
+ }
378
+ return width ?? 0;
379
+ }
380
+ case "repeat": {
381
+ if (node.min !== node.max || !Number.isFinite(node.max)) return null;
382
+ const childWidth = exactWidth(node.child);
383
+ return childWidth === null ? null : childWidth * node.min;
384
+ }
385
+ }
386
+ }
387
+ function containsConsumingRepetition(node) {
388
+ switch (node.kind) {
389
+ case "atom": return false;
390
+ case "assertion": return false;
391
+ case "sequence": return node.children.some(containsConsumingRepetition);
392
+ case "alternation": return node.branches.some(containsConsumingRepetition);
393
+ case "repeat": return node.min !== 1 || node.max !== 1 || containsConsumingRepetition(node.child);
394
+ }
395
+ }
396
+ function containsConsumingAlternation(node) {
397
+ switch (node.kind) {
398
+ case "atom": return false;
399
+ case "assertion": return false;
400
+ case "sequence": return node.children.some(containsConsumingAlternation);
401
+ case "alternation": return true;
402
+ case "repeat": return containsConsumingAlternation(node.child);
403
+ }
404
+ }
405
+ function fixedWords(node, budget) {
406
+ if (budget.exceeded) return null;
407
+ switch (node.kind) {
408
+ case "atom": return node.symbol ? [[node.symbol]] : null;
409
+ case "assertion": return [[]];
410
+ case "sequence": {
411
+ let words = [[]];
412
+ for (const child of node.children) {
413
+ const childWords = fixedWords(child, budget);
414
+ if (!childWords) return null;
415
+ const next = [];
416
+ for (const prefix of words) for (const suffix of childWords) {
417
+ if (++budget.words > MAX_WORDS) {
418
+ budget.exceeded = true;
419
+ return null;
420
+ }
421
+ const word = [...prefix, ...suffix];
422
+ budget.symbols += word.length;
423
+ if (budget.symbols > MAX_WORD_SYMBOLS) {
424
+ budget.exceeded = true;
425
+ return null;
426
+ }
427
+ next.push(word);
428
+ }
429
+ words = next;
430
+ }
431
+ return words;
432
+ }
433
+ case "alternation": {
434
+ const words = [];
435
+ for (const branch of node.branches) {
436
+ const branchWords = fixedWords(branch, budget);
437
+ if (!branchWords) return null;
438
+ words.push(...branchWords);
439
+ if ((budget.words += branchWords.length) > MAX_WORDS) {
440
+ budget.exceeded = true;
441
+ return null;
442
+ }
443
+ }
444
+ return words;
445
+ }
446
+ case "repeat": {
447
+ if (node.min !== node.max || !Number.isFinite(node.max)) return null;
448
+ let words = [[]];
449
+ const childWords = fixedWords(node.child, budget);
450
+ if (!childWords) return null;
451
+ for (let count = 0; count < node.min; count++) {
452
+ const next = [];
453
+ for (const prefix of words) for (const suffix of childWords) {
454
+ if (++budget.words > MAX_WORDS) {
455
+ budget.exceeded = true;
456
+ return null;
457
+ }
458
+ const word = [...prefix, ...suffix];
459
+ budget.symbols += word.length;
460
+ if (budget.symbols > MAX_WORD_SYMBOLS) {
461
+ budget.exceeded = true;
462
+ return null;
463
+ }
464
+ next.push(word);
465
+ }
466
+ words = next;
467
+ }
468
+ return words;
469
+ }
470
+ }
471
+ }
472
+ function createTrieNode() {
473
+ return {
474
+ terminal: false,
475
+ edges: /* @__PURE__ */ new Map(),
476
+ complexEdges: []
477
+ };
478
+ }
479
+ function opaqueMatchesLiteral(opaque, literal) {
480
+ if (opaque.kind !== "opaque" || literal.kind !== "literal") return false;
481
+ try {
482
+ return new RegExp(`^(?:${opaque.pattern})$`, opaque.ignoreCase ? "i" : "").test(literal.value);
483
+ } catch {
484
+ return true;
485
+ }
486
+ }
487
+ function classMatchesLiteral(characterClass, literal) {
488
+ if (characterClass.kind !== "class" || literal.kind !== "literal") return false;
489
+ if (literal.value.charCodeAt(0) <= 127) return characterClass.values.has(literal.key);
490
+ if (characterClass.nonAscii === "all") return true;
491
+ return /\s/.test(literal.value) ? characterClass.nonAscii === "whitespace" : characterClass.nonAscii === "non-whitespace";
492
+ }
493
+ function nonAsciiDomainsOverlap(left, right) {
494
+ if (left === "none" || right === "none") return false;
495
+ if (left === "all" || right === "all") return true;
496
+ return left === right;
497
+ }
498
+ function symbolsMayOverlap(left, right) {
499
+ if (left.kind === "literal" && right.kind === "literal") return left.key === right.key;
500
+ if (left.kind === "class" && right.kind === "literal") return classMatchesLiteral(left, right);
501
+ if (left.kind === "literal" && right.kind === "class") return classMatchesLiteral(right, left);
502
+ if (left.kind === "class" && right.kind === "class") {
503
+ const [smaller, larger] = left.values.size <= right.values.size ? [left.values, right.values] : [right.values, left.values];
504
+ for (const value of smaller) if (larger.has(value)) return true;
505
+ return nonAsciiDomainsOverlap(left.nonAscii, right.nonAscii);
506
+ }
507
+ if (left.kind === "opaque" && right.kind === "literal") return opaqueMatchesLiteral(left, right);
508
+ if (left.kind === "literal" && right.kind === "opaque") return opaqueMatchesLiteral(right, left);
509
+ return true;
510
+ }
511
+ function insertPrefixFreeWord(root, word, comparisons) {
512
+ let node = root;
513
+ for (const symbol of word) {
514
+ if (node.terminal) return false;
515
+ let edge = node.edges.get(symbol.key);
516
+ if (!edge) {
517
+ const candidates = symbol.kind === "literal" ? node.complexEdges : node.edges.values();
518
+ for (const candidate of candidates) {
519
+ if (++comparisons.count > MAX_OPAQUE_COMPARISONS) return false;
520
+ if (symbolsMayOverlap(candidate.symbol, symbol)) return false;
521
+ }
522
+ edge = {
523
+ symbol,
524
+ node: createTrieNode()
525
+ };
526
+ node.edges.set(symbol.key, edge);
527
+ if (symbol.kind !== "literal") node.complexEdges.push(edge);
528
+ }
529
+ node = edge.node;
530
+ }
531
+ if (node.terminal || node.edges.size > 0) return false;
532
+ node.terminal = true;
533
+ return true;
534
+ }
535
+ function hasPrefixFreeFiniteLanguage(node) {
536
+ const budget = {
537
+ words: 0,
538
+ symbols: 0,
539
+ exceeded: false
540
+ };
541
+ const words = fixedWords(node, budget);
542
+ if (!words) return {
543
+ safe: false,
544
+ budgetExceeded: budget.exceeded,
545
+ wordCount: 0
546
+ };
547
+ const root = createTrieNode();
548
+ const comparisons = { count: 0 };
549
+ for (const word of words) if (!insertPrefixFreeWord(root, word, comparisons)) return {
550
+ safe: false,
551
+ budgetExceeded: comparisons.count > MAX_OPAQUE_COMPARISONS,
552
+ wordCount: words.length
553
+ };
554
+ return {
555
+ safe: true,
556
+ budgetExceeded: false,
557
+ wordCount: words.length
558
+ };
559
+ }
560
+ function ambiguousExpansionFactor(node) {
561
+ switch (node.kind) {
562
+ case "atom":
563
+ case "assertion": return 1;
564
+ case "alternation": {
565
+ const result = hasPrefixFreeFiniteLanguage(node);
566
+ if (result.safe) return 1;
567
+ if (result.budgetExceeded || result.wordCount === 0) return 257;
568
+ return result.wordCount;
569
+ }
570
+ case "sequence": {
571
+ let factor = 1;
572
+ for (const child of node.children) {
573
+ factor *= ambiguousExpansionFactor(child);
574
+ if (factor > MAX_SEQUENCE_EXPANSIONS) return factor;
575
+ }
576
+ return factor;
577
+ }
578
+ case "repeat": {
579
+ if (node.min !== node.max || !Number.isFinite(node.max)) return 1;
580
+ const childFactor = ambiguousExpansionFactor(node.child);
581
+ let factor = 1;
582
+ for (let count = 0; count < node.max; count++) {
583
+ factor *= childFactor;
584
+ if (factor > MAX_SEQUENCE_EXPANSIONS) return factor;
585
+ }
586
+ return factor;
587
+ }
588
+ }
589
+ }
590
+ function isNullable(node) {
591
+ switch (node.kind) {
592
+ case "atom": return !node.fixedWidth;
593
+ case "assertion": return true;
594
+ case "sequence": return node.children.every(isNullable);
595
+ case "alternation": return node.branches.some(isNullable);
596
+ case "repeat": return node.min === 0 || isNullable(node.child);
597
+ }
598
+ }
599
+ function firstSymbols(node) {
600
+ switch (node.kind) {
601
+ case "atom": return node.symbol ? [node.symbol] : null;
602
+ case "assertion": return [];
603
+ case "repeat": return firstSymbols(node.child);
604
+ case "alternation": {
605
+ const symbols = [];
606
+ for (const branch of node.branches) {
607
+ const branchSymbols = firstSymbols(branch);
608
+ if (!branchSymbols) return null;
609
+ symbols.push(...branchSymbols);
610
+ }
611
+ return symbols;
612
+ }
613
+ case "sequence": {
614
+ const symbols = [];
615
+ for (const child of node.children) {
616
+ const childSymbols = firstSymbols(child);
617
+ if (!childSymbols) return null;
618
+ symbols.push(...childSymbols);
619
+ if (!isNullable(child)) break;
620
+ }
621
+ return symbols;
622
+ }
623
+ }
624
+ }
625
+ function lastSymbols(node) {
626
+ switch (node.kind) {
627
+ case "atom": return node.symbol ? [node.symbol] : null;
628
+ case "assertion": return [];
629
+ case "repeat": return lastSymbols(node.child);
630
+ case "alternation": {
631
+ const symbols = [];
632
+ for (const branch of node.branches) {
633
+ const branchSymbols = lastSymbols(branch);
634
+ if (!branchSymbols) return null;
635
+ symbols.push(...branchSymbols);
636
+ }
637
+ return symbols;
638
+ }
639
+ case "sequence": {
640
+ const symbols = [];
641
+ for (let index = node.children.length - 1; index >= 0; index--) {
642
+ const child = node.children[index];
643
+ const childSymbols = lastSymbols(child);
644
+ if (!childSymbols) return null;
645
+ symbols.push(...childSymbols);
646
+ if (!isNullable(child)) break;
647
+ }
648
+ return symbols;
649
+ }
650
+ }
651
+ }
652
+ function boundariesMayOverlap(left, right, comparisons) {
653
+ if (!left || !right) return true;
654
+ for (const leftSymbol of left) for (const rightSymbol of right) {
655
+ if (++comparisons.count > MAX_OPAQUE_COMPARISONS) return true;
656
+ if (symbolsMayOverlap(leftSymbol, rightSymbol)) return true;
657
+ }
658
+ return false;
659
+ }
660
+ function findSequenceIssue(node) {
661
+ if (ambiguousExpansionFactor(node) > MAX_SEQUENCE_EXPANSIONS) return "ambiguous sequence expansion";
662
+ let pendingRepetitionEnds = [];
663
+ const comparisons = { count: 0 };
664
+ let overlappingBoundaryCount = 0;
665
+ for (const child of node.children) if (child.kind === "repeat" && (child.min !== child.max || !Number.isFinite(child.max))) {
666
+ const starts = firstSymbols(child);
667
+ if (pendingRepetitionEnds.filter((ends) => boundariesMayOverlap(ends, starts, comparisons)).length > 0) overlappingBoundaryCount++;
668
+ else if (!isNullable(child)) overlappingBoundaryCount = 0;
669
+ if (overlappingBoundaryCount > MAX_SAFE_OVERLAPPING_VARIABLE_BOUNDARIES) return "overlapping sequential repetition";
670
+ const ends = lastSymbols(child);
671
+ pendingRepetitionEnds = isNullable(child) ? [...pendingRepetitionEnds, ends] : [ends];
672
+ } else if (!isNullable(child)) {
673
+ pendingRepetitionEnds = [];
674
+ overlappingBoundaryCount = 0;
675
+ }
676
+ return null;
677
+ }
678
+ function findSafetyIssue(node) {
679
+ switch (node.kind) {
680
+ case "atom": return null;
681
+ case "assertion": return findSafetyIssue(node.child);
682
+ case "sequence": {
683
+ const sequenceIssue = findSequenceIssue(node);
684
+ if (sequenceIssue) return sequenceIssue;
685
+ for (const child of node.children) {
686
+ const issue = findSafetyIssue(child);
687
+ if (issue) return issue;
688
+ }
689
+ return null;
690
+ }
691
+ case "alternation":
692
+ for (const branch of node.branches) {
693
+ const issue = findSafetyIssue(branch);
694
+ if (issue) return issue;
695
+ }
696
+ return null;
697
+ case "repeat": {
698
+ const nestedRepetition = containsConsumingRepetition(node.child);
699
+ if (node.max > 1 && nestedRepetition && exactWidth(node.child) === null) return "nested repetition";
700
+ if (node.max > 1 && containsConsumingAlternation(node.child)) {
701
+ const prefixFree = hasPrefixFreeFiniteLanguage(node.child);
702
+ if (!prefixFree.safe) return prefixFree.budgetExceeded ? "analysis budget exceeded" : "ambiguous alternatives under repetition";
703
+ }
704
+ return findSafetyIssue(node.child);
705
+ }
706
+ }
707
+ }
708
+ function analyzeRegexSafety(pattern, options = {}) {
709
+ if (pattern.length > MAX_PATTERN_LENGTH) return "analysis budget exceeded";
710
+ const parser = new RegexParser(pattern, options.ignoreCase === true);
711
+ const node = parser.parse();
712
+ if (parser.exceededBudget) return "analysis budget exceeded";
713
+ return findSafetyIssue(node);
714
+ }
715
+ function regexAtomsMayOverlap(left, right, ignoreCase = false) {
716
+ const leftParser = new RegexParser(left, ignoreCase);
717
+ const rightParser = new RegexParser(right, ignoreCase);
718
+ const leftNode = leftParser.parse();
719
+ const rightNode = rightParser.parse();
720
+ const leftWords = fixedWords(leftNode, {
721
+ words: 0,
722
+ symbols: 0,
723
+ exceeded: false
724
+ });
725
+ const rightWords = fixedWords(rightNode, {
726
+ words: 0,
727
+ symbols: 0,
728
+ exceeded: false
729
+ });
730
+ if (!leftWords || !rightWords || leftWords.length !== 1 || rightWords.length !== 1) return true;
731
+ const leftSymbol = leftWords[0][0];
732
+ const rightSymbol = rightWords[0][0];
733
+ if (!leftSymbol || !rightSymbol) return true;
734
+ return symbolsMayOverlap(leftSymbol, rightSymbol);
735
+ }
736
+ //#endregion
737
+ export { analyzeRegexSafety, regexAtomsMayOverlap };