vinext 1.3.1 → 1.4.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 (234) hide show
  1. package/README.md +5 -2
  2. package/THIRD_PARTY_LICENSES.md +47 -0
  3. package/dist/_virtual/_rolldown/runtime.js +3 -2
  4. package/dist/build/prerender.js +1 -1
  5. package/dist/build/report.d.ts +0 -14
  6. package/dist/build/report.js +1 -51
  7. package/dist/check.js +1 -1
  8. package/dist/cli.js +3 -0
  9. package/dist/client/dev-error-overlay.js +1 -1
  10. package/dist/client/navigation-runtime.d.ts +13 -1
  11. package/dist/client/navigation-runtime.js +1 -1
  12. package/dist/config/next-config.d.ts +19 -0
  13. package/dist/config/next-config.js +64 -1
  14. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/dbcs-codec.js +327 -0
  15. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/dbcs-data.js +123 -0
  16. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/index.js +29 -0
  17. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/internal.js +134 -0
  18. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-codec.js +50 -0
  19. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-data-generated.js +455 -0
  20. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-data.js +147 -0
  21. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/big5-added.json.js +169 -0
  22. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp936.json.js +2584 -0
  23. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp949.json.js +2220 -0
  24. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp950.json.js +227 -0
  25. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/eucjp.json.js +425 -0
  26. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/gb18030-ranges.json.js +427 -0
  27. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/gbk-added.json.js +229 -0
  28. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/shiftjis.json.js +292 -0
  29. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/utf16.js +106 -0
  30. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/utf7.js +182 -0
  31. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/bom-handling.js +42 -0
  32. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/extend-node.js +147 -0
  33. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/index.js +94 -0
  34. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/streams.js +95 -0
  35. package/dist/deps/.pnpm/safer-buffer@2.1.2/deps/safer-buffer/safer.js +45 -0
  36. package/dist/entries/app-rsc-entry.js +17 -48
  37. package/dist/entries/app-rsc-manifest.js +3 -4
  38. package/dist/entries/app-ssr-entry.js +1 -0
  39. package/dist/entries/pages-server-entry.js +33 -8
  40. package/dist/index.js +83 -70
  41. package/dist/init-cloudflare.d.ts +1 -3
  42. package/dist/init-cloudflare.js +10 -48
  43. package/dist/init-platform.d.ts +2 -0
  44. package/dist/init-platform.js +4 -0
  45. package/dist/plugins/extensionless-dynamic-import.js +6 -2
  46. package/dist/plugins/next-intl-catalog.d.ts +12 -0
  47. package/dist/plugins/next-intl-catalog.js +85 -0
  48. package/dist/plugins/pages-node-externals.d.ts +1 -0
  49. package/dist/plugins/pages-node-externals.js +1 -1
  50. package/dist/plugins/use-cache-callable.d.ts +1 -1
  51. package/dist/plugins/use-cache-callable.js +136 -94
  52. package/dist/routing/app-route-graph.d.ts +6 -0
  53. package/dist/routing/app-route-graph.js +9 -1
  54. package/dist/server/api-handler.js +19 -4
  55. package/dist/server/app-bfcache-identity.js +1 -1
  56. package/dist/server/app-browser-entry.js +79 -63
  57. package/dist/server/app-browser-history-controller.d.ts +5 -4
  58. package/dist/server/app-browser-history-controller.js +93 -15
  59. package/dist/server/app-browser-navigation-controller.d.ts +2 -2
  60. package/dist/server/app-browser-navigation-controller.js +1 -2
  61. package/dist/server/app-browser-rsc-redirect.js +4 -4
  62. package/dist/server/app-browser-server-action-client.d.ts +2 -0
  63. package/dist/server/app-browser-server-action-client.js +4 -3
  64. package/dist/server/app-browser-state.d.ts +2 -4
  65. package/dist/server/app-browser-state.js +9 -4
  66. package/dist/server/app-browser-supplemental-refresh.js +16 -1
  67. package/dist/server/app-browser-visible-commit.d.ts +1 -1
  68. package/dist/server/app-browser-visible-commit.js +2 -12
  69. package/dist/server/app-elements-wire.d.ts +6 -38
  70. package/dist/server/app-elements-wire.js +4 -41
  71. package/dist/server/app-elements.d.ts +2 -2
  72. package/dist/server/app-elements.js +2 -2
  73. package/dist/server/app-history-state.d.ts +2 -2
  74. package/dist/server/app-history-state.js +5 -2
  75. package/dist/server/app-mounted-layouts.d.ts +21 -0
  76. package/dist/server/app-mounted-layouts.js +67 -0
  77. package/dist/server/app-optimistic-routing.d.ts +19 -1
  78. package/dist/server/app-optimistic-routing.js +42 -2
  79. package/dist/server/app-page-boundary-render.js +7 -6
  80. package/dist/server/app-page-boundary.js +2 -2
  81. package/dist/server/app-page-cache-finalizer.d.ts +12 -1
  82. package/dist/server/app-page-cache-finalizer.js +70 -29
  83. package/dist/server/app-page-cache.d.ts +13 -1
  84. package/dist/server/app-page-cache.js +31 -9
  85. package/dist/server/app-page-dispatch.d.ts +5 -10
  86. package/dist/server/app-page-dispatch.js +84 -154
  87. package/dist/server/app-page-element-builder.d.ts +2 -2
  88. package/dist/server/app-page-element-builder.js +10 -9
  89. package/dist/server/app-page-execution.d.ts +17 -52
  90. package/dist/server/app-page-execution.js +99 -95
  91. package/dist/server/app-page-head.d.ts +13 -0
  92. package/dist/server/app-page-head.js +44 -16
  93. package/dist/server/app-page-http-access-fallback-metadata.d.ts +1 -0
  94. package/dist/server/app-page-http-access-fallback-metadata.js +2 -2
  95. package/dist/server/app-page-layout-gate.d.ts +35 -0
  96. package/dist/server/app-page-layout-gate.js +50 -0
  97. package/dist/server/app-page-params.d.ts +0 -1
  98. package/dist/server/app-page-params.js +1 -14
  99. package/dist/server/app-page-probe.d.ts +3 -21
  100. package/dist/server/app-page-probe.js +4 -37
  101. package/dist/server/app-page-render.d.ts +2 -12
  102. package/dist/server/app-page-render.js +89 -220
  103. package/dist/server/app-page-request.d.ts +1 -3
  104. package/dist/server/app-page-request.js +1 -1
  105. package/dist/server/app-page-response.js +3 -3
  106. package/dist/server/app-page-route-wiring.d.ts +13 -6
  107. package/dist/server/app-page-route-wiring.js +67 -61
  108. package/dist/server/app-page-rsc-render-status.d.ts +27 -1
  109. package/dist/server/app-page-rsc-render-status.js +121 -13
  110. package/dist/server/app-page-stream.d.ts +2 -0
  111. package/dist/server/app-page-stream.js +2 -2
  112. package/dist/server/app-pages-bridge.d.ts +4 -0
  113. package/dist/server/app-pages-bridge.js +7 -3
  114. package/dist/server/app-render-dependency.d.ts +11 -4
  115. package/dist/server/app-render-dependency.js +86 -38
  116. package/dist/server/app-request-stage-dispatch.js +1 -1
  117. package/dist/server/app-route-handler-cache.js +2 -2
  118. package/dist/server/app-route-handler-dispatch.js +14 -9
  119. package/dist/server/app-route-handler-execution.js +8 -3
  120. package/dist/server/app-route-handler-policy.d.ts +1 -1
  121. package/dist/server/app-route-handler-policy.js +3 -3
  122. package/dist/server/app-route-handler-response.js +1 -1
  123. package/dist/server/app-route-handler-runtime.js +17 -4
  124. package/dist/server/app-rsc-cache-busting.d.ts +2 -2
  125. package/dist/server/app-rsc-cache-busting.js +4 -4
  126. package/dist/server/app-rsc-error-handler.d.ts +2 -1
  127. package/dist/server/app-rsc-error-handler.js +9 -1
  128. package/dist/server/app-rsc-errors.d.ts +8 -0
  129. package/dist/server/app-rsc-errors.js +8 -1
  130. package/dist/server/app-rsc-handler.d.ts +5 -5
  131. package/dist/server/app-rsc-handler.js +30 -24
  132. package/dist/server/app-rsc-request-normalization.d.ts +0 -4
  133. package/dist/server/app-rsc-request-normalization.js +1 -4
  134. package/dist/server/app-rsc-response-finalizer.js +2 -2
  135. package/dist/server/app-rsc-response-stage.js +5 -3
  136. package/dist/server/app-server-action-execution.d.ts +3 -1
  137. package/dist/server/app-server-action-execution.js +7 -4
  138. package/dist/server/app-ssr-entry.d.ts +2 -0
  139. package/dist/server/app-ssr-entry.js +9 -8
  140. package/dist/server/app-ssr-stream.js +1 -1
  141. package/dist/server/app-visited-response-cache.d.ts +36 -1
  142. package/dist/server/app-visited-response-cache.js +46 -5
  143. package/dist/server/app-worker-stages.d.ts +25 -3
  144. package/dist/server/app-worker-stages.js +45 -6
  145. package/dist/server/artifact-compatibility.d.ts +0 -1
  146. package/dist/server/artifact-compatibility.js +1 -10
  147. package/dist/server/cache-proof.d.ts +1 -115
  148. package/dist/server/cache-proof.js +1 -544
  149. package/dist/server/cacheability-request.js +13 -8
  150. package/dist/server/dev-server.js +4 -3
  151. package/dist/server/headers.d.ts +6 -3
  152. package/dist/server/headers.js +9 -5
  153. package/dist/server/isr-cache.d.ts +8 -2
  154. package/dist/server/isr-cache.js +26 -1
  155. package/dist/server/metadata-route-response.js +32 -15
  156. package/dist/server/multi-stage.d.ts +52 -11
  157. package/dist/server/multi-stage.js +13 -1
  158. package/dist/server/navigation-planner.js +1 -1
  159. package/dist/server/pages-api-route.js +28 -19
  160. package/dist/server/pages-media-type.d.ts +21 -1
  161. package/dist/server/pages-media-type.js +69 -5
  162. package/dist/server/pages-node-compat.js +52 -27
  163. package/dist/server/pages-page-handler.js +11 -20
  164. package/dist/server/pages-request-pipeline.d.ts +8 -0
  165. package/dist/server/pages-request-pipeline.js +2 -2
  166. package/dist/server/pages-request-stage-entry.js +14 -12
  167. package/dist/server/pages-response-stage-entry.js +9 -3
  168. package/dist/server/prod-server.js +5 -1
  169. package/dist/server/request-pipeline.d.ts +6 -0
  170. package/dist/server/request-pipeline.js +21 -1
  171. package/dist/server/shared-cache-identity.d.ts +23 -0
  172. package/dist/server/shared-cache-identity.js +36 -0
  173. package/dist/server/worker-stages.d.ts +16 -3
  174. package/dist/server/worker-stages.js +23 -4
  175. package/dist/shims/cache-handler.js +2 -2
  176. package/dist/shims/cache-request-state.d.ts +17 -20
  177. package/dist/shims/cache-request-state.js +16 -21
  178. package/dist/shims/cache-runtime.js +27 -11
  179. package/dist/shims/cache.d.ts +8 -7
  180. package/dist/shims/cache.js +17 -19
  181. package/dist/shims/cacheability-classification.d.ts +2 -0
  182. package/dist/shims/cdn-cache.d.ts +22 -5
  183. package/dist/shims/client-page-root.js +2 -2
  184. package/dist/shims/dynamic.js +9 -6
  185. package/dist/shims/error-boundary.js +2 -2
  186. package/dist/shims/fetch-cache-state.d.ts +5 -1
  187. package/dist/shims/fetch-cache-state.js +1 -3
  188. package/dist/shims/fetch-cache.d.ts +2 -1
  189. package/dist/shims/fetch-cache.js +34 -24
  190. package/dist/shims/form.js +2 -2
  191. package/dist/shims/headers.d.ts +8 -23
  192. package/dist/shims/headers.js +17 -67
  193. package/dist/shims/internal/navigation-untracked.js +1 -1
  194. package/dist/shims/link.js +3 -1
  195. package/dist/shims/metadata.d.ts +23 -21
  196. package/dist/shims/metadata.js +62 -24
  197. package/dist/shims/navigation-server.js +1 -1
  198. package/dist/shims/navigation.d.ts +74 -7
  199. package/dist/shims/navigation.js +183 -29
  200. package/dist/shims/navigation.react-server.js +2 -2
  201. package/dist/shims/request-state-types.d.ts +2 -2
  202. package/dist/shims/slot.d.ts +12 -0
  203. package/dist/shims/slot.js +37 -9
  204. package/dist/shims/unified-request-context.d.ts +1 -1
  205. package/dist/shims/unified-request-context.js +2 -3
  206. package/dist/utils/cache-control-metadata.d.ts +5 -0
  207. package/dist/utils/cache-control-metadata.js +9 -1
  208. package/dist/utils/project.d.ts +2 -2
  209. package/dist/utils/project.js +3 -16
  210. package/dist/utils/regex.d.ts +5 -0
  211. package/dist/utils/regex.js +11 -1
  212. package/dist/utils/text-stream.d.ts +10 -5
  213. package/dist/utils/text-stream.js +6 -6
  214. package/package.json +2 -1
  215. package/dist/build/layout-classification-types.d.ts +0 -60
  216. package/dist/build/layout-classification-types.js +0 -1
  217. package/dist/build/layout-classification.d.ts +0 -62
  218. package/dist/build/layout-classification.js +0 -98
  219. package/dist/build/route-classification-injector.d.ts +0 -33
  220. package/dist/build/route-classification-injector.js +0 -59
  221. package/dist/build/route-classification-manifest.d.ts +0 -54
  222. package/dist/build/route-classification-manifest.js +0 -143
  223. package/dist/server/app-browser-client-reuse-manifest.d.ts +0 -11
  224. package/dist/server/app-browser-client-reuse-manifest.js +0 -101
  225. package/dist/server/app-layout-param-observation.d.ts +0 -42
  226. package/dist/server/app-layout-param-observation.js +0 -168
  227. package/dist/server/client-reuse-manifest.d.ts +0 -103
  228. package/dist/server/client-reuse-manifest.js +0 -209
  229. package/dist/server/skip-cache-proof.d.ts +0 -60
  230. package/dist/server/skip-cache-proof.js +0 -168
  231. package/dist/server/static-layout-client-reuse-proof.d.ts +0 -14
  232. package/dist/server/static-layout-client-reuse-proof.js +0 -33
  233. package/dist/utils/sorted-array.d.ts +0 -8
  234. package/dist/utils/sorted-array.js +0 -20
package/README.md CHANGED
@@ -137,7 +137,7 @@ files to `.cjs`) when an unambiguous default Vite config requires the ESM migrat
137
137
  `"type": "commonjs"` is never changed. Direct `vite dev` and `vite build` do not perform these
138
138
  wrapper compatibility steps.
139
139
 
140
- `@vinext/cloudflare deploy` options: `--preview`, `--env <name>`, `--name <name>`, `--skip-build`, `--dry-run`, `--warm-cache`, `--traffic-aware-warm-cache`.
140
+ `@vinext/cloudflare deploy` options: `--preview`, `--env <name>`, `--name <name>`, `--vite-config <path>`, `--skip-build`, `--dry-run`, `--warm-cache`, `--traffic-aware-warm-cache`.
141
141
 
142
142
  `vinext init` prompts for a deployment target, defaulting to Cloudflare. Agents must ask the
143
143
  user which target they want, then pass `--platform=cloudflare` or `--platform=node`.
@@ -147,6 +147,8 @@ Other options: `--port <port>` (default: 3001), `--skip-check`, `--force`.
147
147
  Cloudflare init uses `cf` and `cloudflare.config.ts` by default. Both `vinext init`
148
148
  and `create-vinext-app` accept `--legacy-wrangler-cloudflare-init` to retain the
149
149
  legacy Wrangler setup. Existing Wrangler configs are not automatically migrated.
150
+ If a root Wrangler config belongs to another Worker, `vinext init --ignore-wrangler-config`
151
+ sets up `cloudflare.config.ts` and leaves that file untouched.
150
152
  `vinext init --name <name>` sets the Worker name in the generated config instead of
151
153
  deriving it from `package.json`. An existing config keeps its own Worker name, and init
152
154
  prints a warning.
@@ -360,7 +362,8 @@ The init command also auto-detects and fixes common migration issues:
360
362
  - Resolves tsconfig.json path aliases automatically with Vite's native resolver
361
363
  - Detects MDX usage and configures `@mdx-js/rollup`
362
364
  - Renames CJS config files (postcss.config.js, etc.) to `.cjs` when needed
363
- - Detects native Node.js modules (sharp, resvg, satori, lightningcss, @napi-rs/canvas) and auto-stubs them for Workers. If you encounter others that need stubbing, PRs are welcome.
365
+
366
+ vinext does not stub native Node.js modules such as `sharp`, `@resvg/resvg-js` or `@napi-rs/canvas`. Workers cannot load Node-API addons, so importing one into Worker code fails the build or the request. If a dependency imports one on a code path that never runs on Workers, alias it to a module of your own with `resolve.alias` in `vite.config.ts`. Configs generated by earlier versions of `vinext init` may contain `resolve.alias` entries pointing at `empty-stub.js`, a file init never created; delete them.
364
367
 
365
368
  Both App Router and Pages Router work on Workers with full client-side hydration.
366
369
 
@@ -49,3 +49,50 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
49
49
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50
50
  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
51
51
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52
+
53
+ ## iconv-lite (version 0.4.24)
54
+
55
+ Copyright (c) 2011 Alexander Shtuchkin
56
+
57
+ Permission is hereby granted, free of charge, to any person obtaining
58
+ a copy of this software and associated documentation files (the
59
+ "Software"), to deal in the Software without restriction, including
60
+ without limitation the rights to use, copy, modify, merge, publish,
61
+ distribute, sublicense, and/or sell copies of the Software, and to
62
+ permit persons to whom the Software is furnished to do so, subject to
63
+ the following conditions:
64
+
65
+ The above copyright notice and this permission notice shall be
66
+ included in all copies or substantial portions of the Software.
67
+
68
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
69
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
70
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
71
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
72
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
73
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
74
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
75
+
76
+ ## safer-buffer (version 2.1.2)
77
+
78
+ MIT License
79
+
80
+ Copyright (c) 2018 Nikita Skovoroda <chalkerx@gmail.com>
81
+
82
+ Permission is hereby granted, free of charge, to any person obtaining a copy
83
+ of this software and associated documentation files (the "Software"), to deal
84
+ in the Software without restriction, including without limitation the rights
85
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
86
+ copies of the Software, and to permit persons to whom the Software is
87
+ furnished to do so, subject to the following conditions:
88
+
89
+ The above copyright notice and this permission notice shall be included in all
90
+ copies or substantial portions of the Software.
91
+
92
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
93
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
94
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
95
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
96
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
97
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
98
+ SOFTWARE.
@@ -1,4 +1,4 @@
1
- import "node:module";
1
+ import { createRequire } from "node:module";
2
2
  //#region \0rolldown/runtime.js
3
3
  var __create = Object.create;
4
4
  var __defProp = Object.defineProperty;
@@ -21,5 +21,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
21
21
  value: mod,
22
22
  enumerable: true
23
23
  }) : target, mod));
24
+ var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
24
25
  //#endregion
25
- export { __commonJSMin, __toESM };
26
+ export { __commonJSMin, __require, __toESM };
@@ -12,10 +12,10 @@ import { NoOpCacheHandler, getCacheHandler, setCacheHandler } from "../shims/cac
12
12
  import { headersContextFromRequest, runWithHeadersContext } from "../shims/headers.js";
13
13
  import { _consumeRequestScopedCacheLife } from "../shims/cache-request-state.js";
14
14
  import { normalizeStaticPathsEntry } from "../routing/route-pattern.js";
15
- import { createRscRequestUrl } from "../server/app-rsc-cache-busting.js";
16
15
  import { readPrerenderSecret } from "./server-manifest.js";
17
16
  import { buildPregeneratedConcretePathTable } from "../server/prerender-manifest.js";
18
17
  import { concatUint8Arrays, decodeRscEmbeddedChunk } from "../server/app-rsc-embedded-chunks.js";
18
+ import { createRscRequestUrl } from "../server/app-rsc-cache-busting.js";
19
19
  import { navigationRuntimeRscBootstrapExpression } from "../server/app-ssr-stream.js";
20
20
  import { encodePrerenderRouteParams, serializePrerenderRouteParamsHeader } from "../server/prerender-route-params.js";
21
21
  import { startProdServer } from "../server/prod-server.js";
@@ -1,5 +1,4 @@
1
1
  import { AppRoute } from "../routing/app-route-graph.js";
2
- import { LayoutBuildClassification } from "./layout-classification-types.js";
3
2
  import { Route } from "../routing/pages-router.js";
4
3
  import { PrerenderResult } from "./prerender.js";
5
4
  //#region src/build/report.d.ts
@@ -77,19 +76,6 @@ export declare function extractExportConstNumber(code: string, name: string): nu
77
76
  * null — no `revalidate` key found (fully static)
78
77
  */
79
78
  export declare function extractGetStaticPropsRevalidate(code: string): number | false | null;
80
- /**
81
- * Classifies a layout file by its segment config exports (`dynamic`, `revalidate`).
82
- *
83
- * Returns a tagged `LayoutBuildClassification` carrying both the decision and
84
- * the specific segment-config field that produced it. `{ kind: "absent" }`
85
- * means no segment config is present and the caller should defer to the next
86
- * layer (module graph analysis).
87
- *
88
- * Unlike page classification, positive `revalidate` values are not meaningful
89
- * for layout skip decisions — ISR is a page-level concept. Only the extremes
90
- * (`revalidate = 0` → dynamic, `revalidate = Infinity` → static) are decisive.
91
- */
92
- export declare function classifyLayoutSegmentConfig(code: string): LayoutBuildClassification;
93
79
  /**
94
80
  * Classifies a Pages Router page file by reading its source and examining
95
81
  * which data-fetching exports it contains.
@@ -392,56 +392,6 @@ function propertyName(key) {
392
392
  return null;
393
393
  }
394
394
  /**
395
- * Classifies a layout file by its segment config exports (`dynamic`, `revalidate`).
396
- *
397
- * Returns a tagged `LayoutBuildClassification` carrying both the decision and
398
- * the specific segment-config field that produced it. `{ kind: "absent" }`
399
- * means no segment config is present and the caller should defer to the next
400
- * layer (module graph analysis).
401
- *
402
- * Unlike page classification, positive `revalidate` values are not meaningful
403
- * for layout skip decisions — ISR is a page-level concept. Only the extremes
404
- * (`revalidate = 0` → dynamic, `revalidate = Infinity` → static) are decisive.
405
- */
406
- function classifyLayoutSegmentConfig(code) {
407
- const program = parseRouteModule(code);
408
- const dynamicValue = program ? extractExportConstStringFromProgram(program, "dynamic") : null;
409
- if (dynamicValue === "force-dynamic") return {
410
- kind: "dynamic",
411
- reason: {
412
- layer: "segment-config",
413
- key: "dynamic",
414
- value: "force-dynamic"
415
- }
416
- };
417
- if (dynamicValue === "force-static" || dynamicValue === "error") return {
418
- kind: "static",
419
- reason: {
420
- layer: "segment-config",
421
- key: "dynamic",
422
- value: dynamicValue
423
- }
424
- };
425
- const revalidateValue = program ? extractExportConstNumberFromProgram(program, "revalidate") : null;
426
- if (revalidateValue === Infinity) return {
427
- kind: "static",
428
- reason: {
429
- layer: "segment-config",
430
- key: "revalidate",
431
- value: Infinity
432
- }
433
- };
434
- if (revalidateValue === 0) return {
435
- kind: "dynamic",
436
- reason: {
437
- layer: "segment-config",
438
- key: "revalidate",
439
- value: 0
440
- }
441
- };
442
- return { kind: "absent" };
443
- }
444
- /**
445
395
  * Classifies a Pages Router page file by reading its source and examining
446
396
  * which data-fetching exports it contains.
447
397
  *
@@ -675,4 +625,4 @@ async function printBuildReport(options) {
675
625
  }
676
626
  }
677
627
  //#endregion
678
- export { buildReportRows, classifyAppRoute, classifyAppRouteHandler, classifyLayoutSegmentConfig, classifyPagesRoute, extractExportConstNumber, extractExportConstString, extractGetStaticPropsRevalidate, extractMiddlewareMatcherConfig, extractMiddlewareMatcherConfigValue, formatBuildReport, getAppRouteRenderEntryPath, hasExportedName, hasNamedExport, hasRuntimeExportedName, printBuildReport };
628
+ export { buildReportRows, classifyAppRoute, classifyAppRouteHandler, classifyPagesRoute, extractExportConstNumber, extractExportConstString, extractGetStaticPropsRevalidate, extractMiddlewareMatcherConfig, extractMiddlewareMatcherConfigValue, formatBuildReport, getAppRouteRenderEntryPath, hasExportedName, hasNamedExport, hasRuntimeExportedName, printBuildReport };
package/dist/check.js CHANGED
@@ -438,7 +438,7 @@ const LIBRARY_SUPPORT = {
438
438
  },
439
439
  "next-intl": {
440
440
  status: "supported",
441
- detail: "createNextIntlPlugin is only optional with the request config at (src/)i18n/request.*; its experimental messages, precompile and extract options don't work (they need webpack/Turbopack loaders)"
441
+ detail: "createNextIntlPlugin is only optional with the request config at (src/)i18n/request.*; its experimental extract option doesn't work (it needs a webpack/Turbopack loader)"
442
442
  },
443
443
  "@clerk/nextjs": {
444
444
  status: "supported",
package/dist/cli.js CHANGED
@@ -284,6 +284,9 @@ function printHelp(cmd) {
284
284
  (Response Store or Workers Cache, default: prompt with No)
285
285
  --legacy-wrangler-cloudflare-init
286
286
  Use the legacy Wrangler setup instead of cf
287
+ --ignore-wrangler-config
288
+ Set up cf even if a root Wrangler config exists
289
+ (use when it belongs to an unrelated Worker)
287
290
  --cdn-cache <type> Cloudflare CDN cache: none, response-store, workers-cache,
288
291
  static-assets, or data-cache
289
292
  (default: none; response-store is the default cache choice)
@@ -1,7 +1,7 @@
1
1
  import { isNavigationSignalError } from "../utils/navigation-signal.js";
2
- import { VINEXT_DEV_ERROR_RECOVERY_EVENT } from "../utils/dev-error-recovery-event.js";
3
2
  import { VINEXT_ORIGINAL_STACK_TRACE_ENDPOINT } from "../utils/dev-stack-sourcemap-endpoint.js";
4
3
  import { dismissOverlay, expandOverlay, getOverlaySnapshot, minimizeOverlay, reportToOverlay, setOverlayIndex, subscribeOverlay, updateOverlayErrorStack } from "./dev-error-overlay-store.js";
4
+ import { VINEXT_DEV_ERROR_RECOVERY_EVENT } from "../utils/dev-error-recovery-event.js";
5
5
  import { Fragment, useEffect, useMemo, useState, useSyncExternalStore } from "react";
6
6
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
7
7
  import { createRoot } from "react-dom/client";
@@ -1,5 +1,6 @@
1
1
  import { BrowserRouteManifest, BrowserRouteManifestWire } from "../routing/browser-route-manifest.js";
2
2
  import { AppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
3
+ import { CachedRscResponse } from "../shims/navigation.js";
3
4
  //#region src/client/navigation-runtime.d.ts
4
5
  type NavigationRuntimeSnapshot = {
5
6
  pathname: string;
@@ -42,7 +43,9 @@ type NavigationRuntimeTraversalIntent = {
42
43
  };
43
44
  export type NavigationRuntimeNavigate = (href: string, redirectDepth?: number, navigationKind?: NavigationRuntimeKind, historyUpdateMode?: NavigationRuntimeHistoryUpdateMode, previousNextUrlOverride?: string | null, programmaticTransition?: boolean, traversalIntent?: NavigationRuntimeTraversalIntent, scrollIntent?: AppRouterScrollIntent | null, visibleCommitMode?: NavigationRuntimeVisibleCommitMode, bypassNavigationCache?: boolean) => Promise<void>;
44
45
  export type NavigationRuntimeFunctions = {
45
- clearNavigationCaches?: () => void;
46
+ clearNavigationCaches?: (options?: {
47
+ pingVisibleLinks?: boolean;
48
+ }) => void;
46
49
  commitHashNavigation?: (href: string, historyUpdateMode: NavigationRuntimeHistoryUpdateMode, scroll: boolean) => void;
47
50
  navigateExternal?: (href: string, historyUpdateMode: NavigationRuntimeHistoryUpdateMode) => Promise<void>;
48
51
  navigate?: NavigationRuntimeNavigate;
@@ -57,6 +60,15 @@ export type NavigationRuntimeFunctions = {
57
60
  notifyLinkNavigationStart?: () => void;
58
61
  pingVisibleLinks?: () => void;
59
62
  preparePrefetchResponse?: (response: Response) => Promise<unknown>;
63
+ /**
64
+ * The visited (BFCache) response a full prefetch can be fulfilled from, and
65
+ * until when a navigation would still reuse it (null if it wouldn't).
66
+ */
67
+ readVisitedResponseForFullPrefetch?: (rscUrls: readonly string[], interceptionContext: string | null, mountedSlotsHeader: string | null) => {
68
+ navigatedAt: number;
69
+ navigationFreshUntil: number | null;
70
+ response: CachedRscResponse;
71
+ } | null;
60
72
  claimCurrentHistoryTreeSnapshot?: (historyUpdateMode: NavigationRuntimeHistoryUpdateMode, previousHistoryState: unknown) => void;
61
73
  commitAppOwnedHistoryStateWrite?: (historyUpdateMode: NavigationRuntimeHistoryUpdateMode, previousHistoryState: unknown) => void;
62
74
  /**
@@ -26,7 +26,7 @@ function readRuntimeWindow() {
26
26
  }
27
27
  function isNavigationRuntimeFunctions(value) {
28
28
  if (!isUnknownRecord(value)) return false;
29
- return isOptionalRuntimeFunction(Reflect.get(value, "clearNavigationCaches")) && isOptionalRuntimeFunction(Reflect.get(value, "commitHashNavigation")) && isOptionalRuntimeFunction(Reflect.get(value, "navigateExternal")) && isOptionalRuntimeFunction(Reflect.get(value, "navigate")) && isOptionalRuntimeFunction(Reflect.get(value, "getPrefetchRouterState")) && isOptionalRuntimeFunction(Reflect.get(value, "notifyLinkNavigationStart")) && isOptionalRuntimeFunction(Reflect.get(value, "pingVisibleLinks")) && isOptionalRuntimeFunction(Reflect.get(value, "preparePrefetchResponse")) && isOptionalRuntimeFunction(Reflect.get(value, "claimCurrentHistoryTreeSnapshot")) && isOptionalRuntimeFunction(Reflect.get(value, "commitAppOwnedHistoryStateWrite")) && isOptionalRuntimeFunction(Reflect.get(value, "discardPendingNavigation")) && isOptionalRuntimeFunction(Reflect.get(value, "flushCommittingNavigationUrl")) && isOptionalRuntimeFunction(Reflect.get(value, "loadRouteManifest"));
29
+ return isOptionalRuntimeFunction(Reflect.get(value, "clearNavigationCaches")) && isOptionalRuntimeFunction(Reflect.get(value, "commitHashNavigation")) && isOptionalRuntimeFunction(Reflect.get(value, "navigateExternal")) && isOptionalRuntimeFunction(Reflect.get(value, "navigate")) && isOptionalRuntimeFunction(Reflect.get(value, "getPrefetchRouterState")) && isOptionalRuntimeFunction(Reflect.get(value, "notifyLinkNavigationStart")) && isOptionalRuntimeFunction(Reflect.get(value, "pingVisibleLinks")) && isOptionalRuntimeFunction(Reflect.get(value, "preparePrefetchResponse")) && isOptionalRuntimeFunction(Reflect.get(value, "readVisitedResponseForFullPrefetch")) && isOptionalRuntimeFunction(Reflect.get(value, "claimCurrentHistoryTreeSnapshot")) && isOptionalRuntimeFunction(Reflect.get(value, "commitAppOwnedHistoryStateWrite")) && isOptionalRuntimeFunction(Reflect.get(value, "discardPendingNavigation")) && isOptionalRuntimeFunction(Reflect.get(value, "flushCommittingNavigationUrl")) && isOptionalRuntimeFunction(Reflect.get(value, "loadRouteManifest"));
30
30
  }
31
31
  function isNavigationRuntimeRscChunk(value) {
32
32
  if (typeof value === "string") return true;
@@ -102,6 +102,18 @@ export type MdxOptions = {
102
102
  rehypePlugins?: unknown[];
103
103
  recmaPlugins?: unknown[];
104
104
  };
105
+ /**
106
+ * The webpack/Turbopack rule `createNextIntlPlugin` adds for its
107
+ * `experimental.messages` catalogs. vinext runs the same loader on the files it matches.
108
+ */
109
+ export type NextIntlCatalogLoader = {
110
+ /** Absolute catalog directories (the rule's `include`). */
111
+ include: string[];
112
+ /** Catalog file extension test (the rule's `test`). */
113
+ test: RegExp;
114
+ /** The loader's `options`. */
115
+ options: Record<string, unknown>;
116
+ };
105
117
  export type PrefetchInliningConfig = false | {
106
118
  maxBundleSize: number;
107
119
  maxSize: number;
@@ -352,6 +364,11 @@ export type ResolvedNextConfig = {
352
364
  /** Server globals injected into instrumentation.ts by wrapped webpack configs. */
353
365
  instrumentationServerValueInjections: Record<string, unknown>;
354
366
  cacheComponents: boolean;
367
+ /**
368
+ * `experimental.cachedNavigations`: lets the client cache the static stage of
369
+ * navigation responses. Requires `cacheComponents`.
370
+ */
371
+ cachedNavigations: boolean;
355
372
  appNavFailHandling: boolean;
356
373
  /**
357
374
  * Enables the experimental App Router gesture transition API:
@@ -374,6 +391,8 @@ export type ResolvedNextConfig = {
374
391
  i18n: NextI18nConfig | null;
375
392
  /** MDX remark/rehype/recma plugins extracted from @next/mdx config */
376
393
  mdx: MdxOptions | null;
394
+ /** next-intl's message catalog loader rule from `createNextIntlPlugin`. */
395
+ nextIntlCatalogLoader: NextIntlCatalogLoader | null;
377
396
  /** Explicit module aliases preserved from wrapped next.config plugins. */
378
397
  aliases: Record<string, string>;
379
398
  /** Extra allowed origins for dev server access (from allowedDevOrigins). */
@@ -1,4 +1,5 @@
1
1
  import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
+ import { escapeRegExp } from "../utils/regex.js";
2
3
  import { DEFAULT_PAGE_EXTENSIONS, normalizePageExtensions } from "../routing/file-matcher.js";
3
4
  import { loadCommonJsModule, shouldRetryAsCommonJs } from "../utils/commonjs-loader.js";
4
5
  import { isUnknownRecord } from "../utils/record.js";
@@ -884,6 +885,7 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
884
885
  resolveExtensions: null,
885
886
  serverResolveExtensions: null,
886
887
  cacheComponents: false,
888
+ cachedNavigations: false,
887
889
  appNavFailHandling: false,
888
890
  gestureTransition: false,
889
891
  prefetchInlining: false,
@@ -897,6 +899,7 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
897
899
  images: void 0,
898
900
  i18n: null,
899
901
  mdx: null,
902
+ nextIntlCatalogLoader: null,
900
903
  aliases: {},
901
904
  allowedDevOrigins: [],
902
905
  serverActionsAllowedOrigins: [],
@@ -1049,7 +1052,7 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
1049
1052
  if (rawLightningCssFeatures && !useLightningcss) console.warn("[vinext] experimental.lightningCssFeatures is set but experimental.useLightningcss is not enabled. The lightningCssFeatures option has no effect without useLightningcss.");
1050
1053
  if (experimental?.cachedNavigations === true && !cacheComponents) console.warn("[vinext] `experimental.cachedNavigations` requires `cacheComponents: true` to have any effect. Set `cacheComponents: true` in your next.config, or remove `experimental.cachedNavigations`.");
1051
1054
  if (config.webpack !== void 0) {
1052
- if (mdx || Object.keys(webpackProbe.aliases).length > 0 || webpackProbe.resolveExtensionsCustomized || webpackProbe.instrumentationClientRouteManifest !== void 0) console.warn("[vinext] next.config option \"webpack\" is only partially supported. vinext preserves resolve.alias, resolve.extensions, MDX loader settings, and instrumentation-client route manifests, but other webpack customization is ignored");
1055
+ if (mdx || Object.keys(webpackProbe.aliases).length > 0 || webpackProbe.resolveExtensionsCustomized || webpackProbe.instrumentationClientRouteManifest !== void 0 || webpackProbe.nextIntlCatalogLoader !== null) console.warn("[vinext] next.config option \"webpack\" is only partially supported. vinext preserves resolve.alias, resolve.extensions, MDX loader settings, next-intl message catalog loaders, and instrumentation-client route manifests, but other webpack customization is ignored");
1053
1056
  else console.warn("[vinext] next.config option \"webpack\" is not yet supported and will be ignored");
1054
1057
  }
1055
1058
  const output = readOptionalString(config.output) ?? "";
@@ -1099,6 +1102,7 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
1099
1102
  instrumentationClientRouteManifest: webpackProbe.instrumentationClientRouteManifest,
1100
1103
  instrumentationServerValueInjections: webpackProbe.instrumentationServerValueInjections,
1101
1104
  cacheComponents,
1105
+ cachedNavigations: cacheComponents && experimental?.cachedNavigations === true,
1102
1106
  appNavFailHandling: experimental?.appNavFailHandling === true,
1103
1107
  gestureTransition: experimental?.gestureTransition === true,
1104
1108
  prefetchInlining,
@@ -1108,6 +1112,7 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
1108
1112
  images,
1109
1113
  i18n,
1110
1114
  mdx,
1115
+ nextIntlCatalogLoader: webpackProbe.nextIntlCatalogLoader ?? extractTurbopackNextIntlCatalogLoader(config, root),
1111
1116
  aliases,
1112
1117
  allowedDevOrigins,
1113
1118
  serverActionsAllowedOrigins,
@@ -1144,6 +1149,7 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
1144
1149
  lightningCssFeatures
1145
1150
  };
1146
1151
  detectNextIntlConfig(root, resolved);
1152
+ if (resolved.aliases["use-intl/format-message"]?.includes("format-only") && resolved.nextIntlCatalogLoader === null) console.warn("[vinext] next-intl's `experimental.messages.precompile` is enabled, but vinext could not find next-intl's catalog loader in the webpack or Turbopack config. Messages with arguments or rich text will render their raw ICU source; remove `precompile` to format them at runtime");
1147
1153
  if (resolved.basePath !== "" && resolved.basePath !== "/" && resolved.assetPrefix === "") resolved.assetPrefix = resolved.basePath;
1148
1154
  return resolved;
1149
1155
  }
@@ -1180,10 +1186,36 @@ function extractTurboAliases(config, root) {
1180
1186
  ...normalizeAliasEntries(readOptionalRecord(topLevelTurbopack?.resolveAlias), root)
1181
1187
  };
1182
1188
  }
1189
+ function extractTurbopackNextIntlCatalogLoader(config, root) {
1190
+ const experimental = readOptionalRecord(config.experimental);
1191
+ for (const turbo of [readOptionalRecord(config.turbopack), readOptionalRecord(experimental?.turbo)]) {
1192
+ const rules = readOptionalRecord(turbo?.rules);
1193
+ for (const [glob, entry] of Object.entries(rules ?? {})) {
1194
+ const extension = /^\*(\.[^*/{}]+)$/.exec(glob)?.[1];
1195
+ if (!extension) continue;
1196
+ for (const rule of Array.isArray(entry) ? entry : [entry]) {
1197
+ if (!isUnknownRecord(rule) || !Array.isArray(rule.loaders)) continue;
1198
+ const loader = rule.loaders.find((use) => isUnknownRecord(use) && use.loader === NEXT_INTL_CATALOG_LOADER);
1199
+ if (!isUnknownRecord(loader) || !isUnknownRecord(loader.options)) continue;
1200
+ const condition = readOptionalRecord(rule.condition);
1201
+ const dirs = typeof condition?.path === "string" ? /^(?:\{([^{}]+)\}|([^{}]+))\/\*\*\/\*$/.exec(condition.path) : null;
1202
+ const include = (dirs?.[1]?.split(",") ?? (dirs?.[2] ? [dirs[2]] : [])).map((dir) => path.resolve(root, dir));
1203
+ if (include.length === 0) continue;
1204
+ return {
1205
+ include,
1206
+ test: new RegExp(`${escapeRegExp(extension)}$`),
1207
+ options: loader.options
1208
+ };
1209
+ }
1210
+ }
1211
+ }
1212
+ return null;
1213
+ }
1183
1214
  async function probeWebpackConfig(config, root, dev) {
1184
1215
  if (typeof config.webpack !== "function") return {
1185
1216
  aliases: {},
1186
1217
  mdx: null,
1218
+ nextIntlCatalogLoader: null,
1187
1219
  resolveExtensions: null,
1188
1220
  serverResolveExtensions: null,
1189
1221
  resolveExtensionsCustomized: false,
@@ -1204,6 +1236,7 @@ async function probeWebpackConfig(config, root, dev) {
1204
1236
  return {
1205
1237
  aliases: normalizeAliasEntries(clientProbe.config.resolve?.alias, root),
1206
1238
  mdx: extractMdxOptionsFromRules(clientProbe.rules),
1239
+ nextIntlCatalogLoader: extractNextIntlCatalogLoader(clientProbe.rules),
1207
1240
  resolveExtensions: clientProbe.resolveExtensions,
1208
1241
  serverResolveExtensions: serverProbe.resolveExtensions,
1209
1242
  resolveExtensionsCustomized: clientProbe.resolveExtensions !== null || serverProbe.resolveExtensions !== null,
@@ -1214,6 +1247,7 @@ async function probeWebpackConfig(config, root, dev) {
1214
1247
  return {
1215
1248
  aliases: {},
1216
1249
  mdx: null,
1250
+ nextIntlCatalogLoader: null,
1217
1251
  resolveExtensions: null,
1218
1252
  serverResolveExtensions: null,
1219
1253
  resolveExtensionsCustomized: false,
@@ -1246,6 +1280,35 @@ function extractInstrumentationClientRouteManifest(rules) {
1246
1280
  for (const rule of rules) visit(rule);
1247
1281
  return manifest;
1248
1282
  }
1283
+ const NEXT_INTL_CATALOG_LOADER = "next-intl/extractor/catalogLoader";
1284
+ function extractNextIntlCatalogLoader(rules) {
1285
+ let catalogLoader = null;
1286
+ const visit = (rule) => {
1287
+ if (!rule || typeof rule !== "object") return;
1288
+ if (Array.isArray(rule)) {
1289
+ for (const child of rule) visit(child);
1290
+ return;
1291
+ }
1292
+ if (Array.isArray(rule.oneOf)) for (const child of rule.oneOf) visit(child);
1293
+ if (Array.isArray(rule.rules)) for (const child of rule.rules) visit(child);
1294
+ if (!(rule.test instanceof RegExp)) return;
1295
+ const include = typeof rule.include === "string" ? [rule.include] : rule.include;
1296
+ if (!Array.isArray(include) || include.length === 0) return;
1297
+ if (!include.every((dir) => typeof dir === "string")) return;
1298
+ const uses = Array.isArray(rule.use) ? rule.use : rule.use ? [rule.use] : [];
1299
+ for (const use of uses) {
1300
+ if (!isUnknownRecord(use) || use.loader !== NEXT_INTL_CATALOG_LOADER) continue;
1301
+ if (!isUnknownRecord(use.options)) continue;
1302
+ catalogLoader = {
1303
+ include,
1304
+ test: rule.test,
1305
+ options: use.options
1306
+ };
1307
+ }
1308
+ };
1309
+ for (const rule of rules) visit(rule);
1310
+ return catalogLoader;
1311
+ }
1249
1312
  function matchesWebpackCondition(condition, value) {
1250
1313
  if (typeof condition === "string") return value.startsWith(condition);
1251
1314
  if (condition instanceof RegExp) {