vinext 0.1.0 → 0.1.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 (205) hide show
  1. package/README.md +2 -5
  2. package/dist/build/assets-ignore.d.ts +32 -0
  3. package/dist/build/assets-ignore.js +48 -0
  4. package/dist/build/client-build-config.d.ts +33 -1
  5. package/dist/build/client-build-config.js +66 -1
  6. package/dist/check.js +4 -3
  7. package/dist/cli.js +2 -0
  8. package/dist/client/navigation-runtime.d.ts +11 -2
  9. package/dist/client/navigation-runtime.js +1 -1
  10. package/dist/client/vinext-next-data.d.ts +2 -1
  11. package/dist/client/window-next.d.ts +6 -4
  12. package/dist/config/config-matchers.d.ts +31 -5
  13. package/dist/config/config-matchers.js +50 -3
  14. package/dist/config/next-config.d.ts +29 -3
  15. package/dist/config/next-config.js +32 -2
  16. package/dist/deploy.js +47 -304
  17. package/dist/entries/app-rsc-entry.d.ts +8 -2
  18. package/dist/entries/app-rsc-entry.js +61 -5
  19. package/dist/entries/app-rsc-manifest.js +20 -2
  20. package/dist/entries/pages-client-entry.js +1 -1
  21. package/dist/entries/pages-server-entry.js +16 -7
  22. package/dist/index.d.ts +0 -2
  23. package/dist/index.js +233 -280
  24. package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
  25. package/dist/plugins/dynamic-preload-metadata.js +415 -0
  26. package/dist/plugins/og-assets.js +2 -2
  27. package/dist/plugins/optimize-imports.d.ts +8 -4
  28. package/dist/plugins/optimize-imports.js +16 -12
  29. package/dist/plugins/postcss.js +18 -14
  30. package/dist/plugins/require-context.d.ts +6 -0
  31. package/dist/plugins/require-context.js +184 -0
  32. package/dist/plugins/sass.d.ts +53 -24
  33. package/dist/plugins/sass.js +249 -1
  34. package/dist/plugins/wasm-module-import.d.ts +15 -0
  35. package/dist/plugins/wasm-module-import.js +50 -0
  36. package/dist/routing/app-route-graph.d.ts +35 -2
  37. package/dist/routing/app-route-graph.js +179 -8
  38. package/dist/routing/file-matcher.js +1 -1
  39. package/dist/routing/route-pattern.d.ts +2 -1
  40. package/dist/routing/route-pattern.js +16 -1
  41. package/dist/server/api-handler.js +4 -0
  42. package/dist/server/app-browser-entry.js +155 -215
  43. package/dist/server/app-browser-error.d.ts +4 -1
  44. package/dist/server/app-browser-error.js +7 -1
  45. package/dist/server/app-browser-history-controller.d.ts +104 -0
  46. package/dist/server/app-browser-history-controller.js +210 -0
  47. package/dist/server/app-browser-interception-context.d.ts +2 -1
  48. package/dist/server/app-browser-interception-context.js +15 -2
  49. package/dist/server/app-browser-navigation-controller.d.ts +13 -2
  50. package/dist/server/app-browser-navigation-controller.js +83 -4
  51. package/dist/server/app-browser-popstate.d.ts +12 -3
  52. package/dist/server/app-browser-popstate.js +19 -4
  53. package/dist/server/app-browser-rsc-redirect.d.ts +11 -2
  54. package/dist/server/app-browser-rsc-redirect.js +30 -8
  55. package/dist/server/app-browser-state.d.ts +3 -0
  56. package/dist/server/app-browser-state.js +10 -10
  57. package/dist/server/app-browser-visible-commit.js +10 -8
  58. package/dist/server/app-fallback-renderer.d.ts +2 -1
  59. package/dist/server/app-fallback-renderer.js +3 -1
  60. package/dist/server/app-history-state.d.ts +45 -1
  61. package/dist/server/app-history-state.js +109 -1
  62. package/dist/server/app-middleware.js +1 -0
  63. package/dist/server/app-optimistic-routing.js +22 -1
  64. package/dist/server/app-page-boundary-render.d.ts +2 -1
  65. package/dist/server/app-page-boundary-render.js +45 -21
  66. package/dist/server/app-page-cache.js +9 -7
  67. package/dist/server/app-page-dispatch.d.ts +14 -0
  68. package/dist/server/app-page-dispatch.js +21 -6
  69. package/dist/server/app-page-element-builder.d.ts +23 -2
  70. package/dist/server/app-page-element-builder.js +58 -17
  71. package/dist/server/app-page-execution.d.ts +1 -1
  72. package/dist/server/app-page-execution.js +32 -17
  73. package/dist/server/app-page-render.d.ts +7 -1
  74. package/dist/server/app-page-render.js +11 -16
  75. package/dist/server/app-page-request.d.ts +9 -6
  76. package/dist/server/app-page-request.js +14 -10
  77. package/dist/server/app-page-response.d.ts +2 -2
  78. package/dist/server/app-page-response.js +2 -2
  79. package/dist/server/app-page-route-wiring.d.ts +3 -1
  80. package/dist/server/app-page-route-wiring.js +10 -8
  81. package/dist/server/app-page-stream.d.ts +37 -7
  82. package/dist/server/app-page-stream.js +36 -6
  83. package/dist/server/app-pages-bridge.d.ts +16 -0
  84. package/dist/server/app-pages-bridge.js +23 -3
  85. package/dist/server/app-route-handler-cache.d.ts +1 -0
  86. package/dist/server/app-route-handler-cache.js +1 -0
  87. package/dist/server/app-route-handler-dispatch.d.ts +1 -0
  88. package/dist/server/app-route-handler-dispatch.js +2 -0
  89. package/dist/server/app-route-handler-execution.d.ts +1 -0
  90. package/dist/server/app-route-handler-execution.js +1 -0
  91. package/dist/server/app-route-handler-response.js +11 -10
  92. package/dist/server/app-route-handler-runtime.d.ts +1 -0
  93. package/dist/server/app-route-handler-runtime.js +15 -3
  94. package/dist/server/app-rsc-handler.d.ts +1 -0
  95. package/dist/server/app-rsc-handler.js +5 -4
  96. package/dist/server/app-rsc-response-finalizer.js +1 -1
  97. package/dist/server/app-rsc-route-matching.d.ts +20 -1
  98. package/dist/server/app-rsc-route-matching.js +29 -4
  99. package/dist/server/app-server-action-execution.d.ts +22 -1
  100. package/dist/server/app-server-action-execution.js +73 -12
  101. package/dist/server/app-ssr-entry.d.ts +6 -0
  102. package/dist/server/app-ssr-entry.js +19 -3
  103. package/dist/server/app-ssr-stream.js +9 -1
  104. package/dist/server/dev-lockfile.js +2 -1
  105. package/dist/server/dev-server.d.ts +1 -1
  106. package/dist/server/dev-server.js +97 -43
  107. package/dist/server/headers.d.ts +8 -1
  108. package/dist/server/headers.js +8 -1
  109. package/dist/server/instrumentation-runtime.d.ts +6 -0
  110. package/dist/server/instrumentation-runtime.js +8 -0
  111. package/dist/server/isr-cache.d.ts +37 -1
  112. package/dist/server/isr-cache.js +85 -1
  113. package/dist/server/isr-decision.d.ts +79 -0
  114. package/dist/server/isr-decision.js +70 -0
  115. package/dist/server/metadata-route-response.js +5 -3
  116. package/dist/server/middleware-runtime.d.ts +13 -0
  117. package/dist/server/middleware-runtime.js +11 -7
  118. package/dist/server/middleware.js +1 -0
  119. package/dist/server/navigation-planner.d.ts +62 -1
  120. package/dist/server/navigation-planner.js +193 -3
  121. package/dist/server/navigation-trace.d.ts +12 -2
  122. package/dist/server/navigation-trace.js +11 -1
  123. package/dist/server/normalize-path.d.ts +0 -8
  124. package/dist/server/normalize-path.js +3 -1
  125. package/dist/server/otel-tracer-extension.d.ts +45 -0
  126. package/dist/server/otel-tracer-extension.js +89 -0
  127. package/dist/server/pages-api-route.d.ts +14 -3
  128. package/dist/server/pages-api-route.js +6 -1
  129. package/dist/server/pages-asset-tags.d.ts +15 -4
  130. package/dist/server/pages-asset-tags.js +18 -12
  131. package/dist/server/pages-data-route.js +5 -1
  132. package/dist/server/pages-node-compat.d.ts +5 -11
  133. package/dist/server/pages-node-compat.js +175 -118
  134. package/dist/server/pages-page-data.d.ts +38 -7
  135. package/dist/server/pages-page-data.js +64 -18
  136. package/dist/server/pages-page-handler.d.ts +10 -2
  137. package/dist/server/pages-page-handler.js +49 -20
  138. package/dist/server/pages-page-response.d.ts +55 -2
  139. package/dist/server/pages-page-response.js +74 -6
  140. package/dist/server/pages-readiness.d.ts +36 -0
  141. package/dist/server/pages-readiness.js +21 -0
  142. package/dist/server/pages-request-pipeline.d.ts +113 -0
  143. package/dist/server/pages-request-pipeline.js +230 -0
  144. package/dist/server/pages-revalidate.d.ts +15 -0
  145. package/dist/server/pages-revalidate.js +19 -0
  146. package/dist/server/prod-server.d.ts +45 -3
  147. package/dist/server/prod-server.js +182 -234
  148. package/dist/server/socket-error-backstop.d.ts +19 -1
  149. package/dist/server/socket-error-backstop.js +77 -4
  150. package/dist/shims/app-router-scroll.js +22 -4
  151. package/dist/shims/cache-runtime.js +39 -2
  152. package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
  153. package/dist/shims/dynamic-preload-chunks.js +77 -0
  154. package/dist/shims/dynamic.d.ts +4 -0
  155. package/dist/shims/dynamic.js +4 -2
  156. package/dist/shims/error-boundary.d.ts +17 -7
  157. package/dist/shims/error-boundary.js +8 -1
  158. package/dist/shims/error.js +37 -11
  159. package/dist/shims/fetch-cache.d.ts +22 -1
  160. package/dist/shims/fetch-cache.js +28 -1
  161. package/dist/shims/hash-scroll.d.ts +1 -0
  162. package/dist/shims/hash-scroll.js +3 -1
  163. package/dist/shims/head.js +6 -1
  164. package/dist/shims/headers.d.ts +16 -2
  165. package/dist/shims/headers.js +37 -1
  166. package/dist/shims/image-config.js +7 -1
  167. package/dist/shims/internal/app-route-detection.d.ts +6 -3
  168. package/dist/shims/internal/app-route-detection.js +10 -6
  169. package/dist/shims/internal/app-router-context.d.ts +5 -0
  170. package/dist/shims/internal/link-status-registry.d.ts +43 -0
  171. package/dist/shims/internal/link-status-registry.js +42 -0
  172. package/dist/shims/internal/route-pattern-for-warning.d.ts +27 -0
  173. package/dist/shims/internal/route-pattern-for-warning.js +40 -0
  174. package/dist/shims/internal/utils.d.ts +1 -0
  175. package/dist/shims/link.js +20 -6
  176. package/dist/shims/metadata.d.ts +6 -2
  177. package/dist/shims/metadata.js +32 -14
  178. package/dist/shims/navigation.d.ts +9 -18
  179. package/dist/shims/navigation.js +96 -23
  180. package/dist/shims/router-state.d.ts +1 -0
  181. package/dist/shims/router-state.js +2 -0
  182. package/dist/shims/router.d.ts +6 -3
  183. package/dist/shims/router.js +156 -22
  184. package/dist/shims/script-nonce-context.d.ts +1 -1
  185. package/dist/shims/script-nonce-context.js +11 -3
  186. package/dist/shims/server.d.ts +17 -1
  187. package/dist/shims/server.js +31 -6
  188. package/dist/shims/slot.js +1 -1
  189. package/dist/shims/unified-request-context.js +1 -0
  190. package/dist/typegen.js +1 -0
  191. package/dist/utils/client-build-manifest.d.ts +8 -1
  192. package/dist/utils/client-build-manifest.js +41 -6
  193. package/dist/utils/client-entry-manifest.d.ts +11 -0
  194. package/dist/utils/client-entry-manifest.js +29 -0
  195. package/dist/utils/client-runtime-metadata.d.ts +45 -0
  196. package/dist/utils/client-runtime-metadata.js +63 -0
  197. package/dist/utils/hash.d.ts +17 -1
  198. package/dist/utils/hash.js +36 -1
  199. package/dist/utils/lazy-chunks.d.ts +27 -1
  200. package/dist/utils/lazy-chunks.js +65 -1
  201. package/dist/utils/manifest-paths.d.ts +20 -2
  202. package/dist/utils/manifest-paths.js +38 -3
  203. package/dist/utils/path.d.ts +2 -1
  204. package/dist/utils/path.js +5 -1
  205. package/package.json +6 -2
@@ -0,0 +1,13 @@
1
+ import { Plugin } from "vite";
2
+ import MagicString from "magic-string";
3
+
4
+ //#region src/plugins/dynamic-preload-metadata.d.ts
5
+ type TransformResult = {
6
+ code: string;
7
+ map: ReturnType<MagicString["generateMap"]>;
8
+ };
9
+ type ResolveDynamicImport = (specifier: string, importer: string) => Promise<string | null>;
10
+ declare function transformNextDynamicPreloadMetadata(code: string, id: string, root: string, resolveDynamicImport: ResolveDynamicImport): Promise<TransformResult | null>;
11
+ declare function createDynamicPreloadMetadataPlugin(): Plugin;
12
+ //#endregion
13
+ export { createDynamicPreloadMetadataPlugin, transformNextDynamicPreloadMetadata };
@@ -0,0 +1,415 @@
1
+ import { isUnknownRecord } from "../utils/record.js";
2
+ import { relativeWithinRoot, tryRealpathSync } from "../build/ssr-manifest.js";
3
+ import path from "node:path";
4
+ import { parseAst } from "vite";
5
+ import MagicString from "magic-string";
6
+ //#region src/plugins/dynamic-preload-metadata.ts
7
+ function getString(node, key) {
8
+ const value = node[key];
9
+ return typeof value === "string" ? value : null;
10
+ }
11
+ function getNumber(node, key) {
12
+ const value = node[key];
13
+ return typeof value === "number" ? value : null;
14
+ }
15
+ function getArray(node, key) {
16
+ const value = node[key];
17
+ return Array.isArray(value) ? value : [];
18
+ }
19
+ function getBoolean(node, key) {
20
+ return node[key] === true;
21
+ }
22
+ function nodeName(node) {
23
+ if (!isUnknownRecord(node)) return null;
24
+ const name = node.name;
25
+ if (typeof name === "string") return name;
26
+ const value = node.value;
27
+ return typeof value === "string" ? value : null;
28
+ }
29
+ function nodeStringValue(node) {
30
+ if (!isUnknownRecord(node)) return null;
31
+ const value = node.value;
32
+ return typeof value === "string" ? value : null;
33
+ }
34
+ function walkAst(value, visitor) {
35
+ if (!isUnknownRecord(value)) return;
36
+ visitor(value);
37
+ for (const [key, child] of Object.entries(value)) {
38
+ if (key === "parent") continue;
39
+ if (Array.isArray(child)) for (const item of child) walkAst(item, visitor);
40
+ else if (isUnknownRecord(child)) walkAst(child, visitor);
41
+ }
42
+ }
43
+ function importSource(node) {
44
+ const source = node.source;
45
+ if (!isUnknownRecord(source)) return null;
46
+ return nodeStringValue(source);
47
+ }
48
+ function isNextDynamicSource(source) {
49
+ return source === "next/dynamic" || source === "next/dynamic.js";
50
+ }
51
+ function collectDynamicImportLocals(ast) {
52
+ const locals = /* @__PURE__ */ new Set();
53
+ if (!isUnknownRecord(ast)) return locals;
54
+ for (const node of getArray(ast, "body")) {
55
+ if (!isUnknownRecord(node)) continue;
56
+ if (getString(node, "type") !== "ImportDeclaration") continue;
57
+ if (!isNextDynamicSource(importSource(node))) continue;
58
+ for (const specifier of getArray(node, "specifiers")) {
59
+ if (!isUnknownRecord(specifier)) continue;
60
+ if (getString(specifier, "type") !== "ImportDefaultSpecifier") continue;
61
+ const local = nodeName(specifier.local);
62
+ if (local) locals.add(local);
63
+ }
64
+ }
65
+ return locals;
66
+ }
67
+ function isIdentifierNameInSet(node, names) {
68
+ if (!isUnknownRecord(node)) return false;
69
+ return getString(node, "type") === "Identifier" && names.has(getString(node, "name") ?? "");
70
+ }
71
+ function isDynamicCall(node, dynamicLocals) {
72
+ if (getString(node, "type") !== "CallExpression") return false;
73
+ return isIdentifierNameInSet(node.callee, dynamicLocals);
74
+ }
75
+ function addBindingName(pattern, names) {
76
+ if (!isUnknownRecord(pattern)) return;
77
+ const type = getString(pattern, "type");
78
+ if (type === null) return;
79
+ switch (type) {
80
+ case "Identifier": {
81
+ const name = getString(pattern, "name");
82
+ if (name) names.add(name);
83
+ return;
84
+ }
85
+ case "AssignmentPattern":
86
+ addBindingName(pattern.left, names);
87
+ return;
88
+ case "RestElement":
89
+ addBindingName(pattern.argument, names);
90
+ return;
91
+ case "ArrayPattern":
92
+ for (const element of getArray(pattern, "elements")) addBindingName(element, names);
93
+ return;
94
+ case "ObjectPattern":
95
+ for (const property of getArray(pattern, "properties")) {
96
+ if (!isUnknownRecord(property)) continue;
97
+ if (getString(property, "type") === "RestElement") {
98
+ addBindingName(property.argument, names);
99
+ continue;
100
+ }
101
+ addBindingName(property.value, names);
102
+ }
103
+ return;
104
+ default: return;
105
+ }
106
+ }
107
+ function addVariableDeclarationBindingNames(node, names) {
108
+ if (!isUnknownRecord(node) || getString(node, "type") !== "VariableDeclaration") return;
109
+ for (const declaration of getArray(node, "declarations")) if (isUnknownRecord(declaration)) addBindingName(declaration.id, names);
110
+ }
111
+ function collectBlockScopedBindingNames(body) {
112
+ const names = /* @__PURE__ */ new Set();
113
+ for (const statement of body) {
114
+ if (!isUnknownRecord(statement)) continue;
115
+ const type = getString(statement, "type");
116
+ if (type === "VariableDeclaration") {
117
+ if (getString(statement, "kind") !== "var") addVariableDeclarationBindingNames(statement, names);
118
+ continue;
119
+ }
120
+ if (type === "FunctionDeclaration" || type === "ClassDeclaration") {
121
+ const name = nodeName(statement.id);
122
+ if (name) names.add(name);
123
+ }
124
+ }
125
+ return names;
126
+ }
127
+ function collectSwitchScopedBindingNames(node) {
128
+ const names = /* @__PURE__ */ new Set();
129
+ for (const switchCase of getArray(node, "cases")) {
130
+ if (!isUnknownRecord(switchCase)) continue;
131
+ for (const statement of getArray(switchCase, "consequent")) for (const name of collectBlockScopedBindingNames([statement])) names.add(name);
132
+ }
133
+ return names;
134
+ }
135
+ function collectVarBindingNames(value, names) {
136
+ if (!isUnknownRecord(value)) return;
137
+ const type = getString(value, "type");
138
+ if (type === "FunctionDeclaration" || type === "FunctionExpression" || type === "ArrowFunctionExpression") return;
139
+ if (type === "VariableDeclaration" && getString(value, "kind") === "var") addVariableDeclarationBindingNames(value, names);
140
+ for (const [key, child] of Object.entries(value)) {
141
+ if (key === "parent") continue;
142
+ if (Array.isArray(child)) for (const item of child) collectVarBindingNames(item, names);
143
+ else if (isUnknownRecord(child)) collectVarBindingNames(child, names);
144
+ }
145
+ }
146
+ function collectFunctionScopeBindingNames(node) {
147
+ const names = /* @__PURE__ */ new Set();
148
+ if (getString(node, "type") === "FunctionExpression") {
149
+ const name = nodeName(node.id);
150
+ if (name) names.add(name);
151
+ }
152
+ for (const param of getArray(node, "params")) addBindingName(param, names);
153
+ collectVarBindingNames(node.body, names);
154
+ return names;
155
+ }
156
+ function collectForBindingNames(node) {
157
+ const names = /* @__PURE__ */ new Set();
158
+ addVariableDeclarationBindingNames(node.init, names);
159
+ addVariableDeclarationBindingNames(node.left, names);
160
+ return names;
161
+ }
162
+ function withoutBindings(activeNames, localNames) {
163
+ if (activeNames.size === 0 || localNames.size === 0) return activeNames;
164
+ let scoped = null;
165
+ for (const name of localNames) {
166
+ if (!activeNames.has(name)) continue;
167
+ scoped ??= new Set(activeNames);
168
+ scoped.delete(name);
169
+ }
170
+ return scoped ?? activeNames;
171
+ }
172
+ function visitChildren(node, dynamicLocals, visitor) {
173
+ for (const [key, child] of Object.entries(node)) {
174
+ if (key === "parent") continue;
175
+ if (Array.isArray(child)) for (const item of child) visitDynamicCalls(item, dynamicLocals, visitor);
176
+ else if (isUnknownRecord(child)) visitDynamicCalls(child, dynamicLocals, visitor);
177
+ }
178
+ }
179
+ function visitDynamicCalls(value, dynamicLocals, visitor) {
180
+ if (!isUnknownRecord(value) || dynamicLocals.size === 0) return;
181
+ const type = getString(value, "type");
182
+ if (type === "Program") {
183
+ const scoped = withoutBindings(dynamicLocals, collectBlockScopedBindingNames(getArray(value, "body")));
184
+ for (const statement of getArray(value, "body")) visitDynamicCalls(statement, scoped, visitor);
185
+ return;
186
+ }
187
+ if (type === "BlockStatement") {
188
+ const scoped = withoutBindings(dynamicLocals, collectBlockScopedBindingNames(getArray(value, "body")));
189
+ for (const statement of getArray(value, "body")) visitDynamicCalls(statement, scoped, visitor);
190
+ return;
191
+ }
192
+ if (type === "SwitchStatement") {
193
+ visitDynamicCalls(value.discriminant, dynamicLocals, visitor);
194
+ const scoped = withoutBindings(dynamicLocals, collectSwitchScopedBindingNames(value));
195
+ for (const switchCase of getArray(value, "cases")) visitDynamicCalls(switchCase, scoped, visitor);
196
+ return;
197
+ }
198
+ if (type === "FunctionDeclaration" || type === "FunctionExpression" || type === "ArrowFunctionExpression") {
199
+ visitChildren(value, withoutBindings(dynamicLocals, collectFunctionScopeBindingNames(value)), visitor);
200
+ return;
201
+ }
202
+ if (type === "ClassDeclaration" || type === "ClassExpression") {
203
+ const names = /* @__PURE__ */ new Set();
204
+ const name = nodeName(value.id);
205
+ if (name) names.add(name);
206
+ visitChildren(value, withoutBindings(dynamicLocals, names), visitor);
207
+ return;
208
+ }
209
+ if (type === "ForStatement" || type === "ForInStatement" || type === "ForOfStatement") {
210
+ visitChildren(value, withoutBindings(dynamicLocals, collectForBindingNames(value)), visitor);
211
+ return;
212
+ }
213
+ if (type === "CatchClause") {
214
+ const names = /* @__PURE__ */ new Set();
215
+ addBindingName(value.param, names);
216
+ visitChildren(value, withoutBindings(dynamicLocals, names), visitor);
217
+ return;
218
+ }
219
+ if (isDynamicCall(value, dynamicLocals)) visitor(value);
220
+ visitChildren(value, dynamicLocals, visitor);
221
+ }
222
+ function collectImportSpecifiers(node) {
223
+ const specifiers = [];
224
+ const seen = /* @__PURE__ */ new Set();
225
+ walkAst(node, (item) => {
226
+ if (getString(item, "type") === "ImportExpression") {
227
+ const specifier = nodeStringValue(item.source);
228
+ if (specifier && !seen.has(specifier)) {
229
+ seen.add(specifier);
230
+ specifiers.push(specifier);
231
+ }
232
+ return;
233
+ }
234
+ if (getString(item, "type") !== "CallExpression") return;
235
+ const callee = item.callee;
236
+ if (!isUnknownRecord(callee) || getString(callee, "type") !== "Import") return;
237
+ const firstArg = getArray(item, "arguments")[0];
238
+ const specifier = nodeStringValue(firstArg);
239
+ if (specifier && !seen.has(specifier)) {
240
+ seen.add(specifier);
241
+ specifiers.push(specifier);
242
+ }
243
+ });
244
+ return specifiers;
245
+ }
246
+ function propertyKeyName(property) {
247
+ if (!isUnknownRecord(property)) return null;
248
+ if (getBoolean(property, "computed")) return null;
249
+ return nodeName(property.key);
250
+ }
251
+ function objectProperties(node) {
252
+ if (!isUnknownRecord(node) || getString(node, "type") !== "ObjectExpression") return [];
253
+ return getArray(node, "properties").filter(isUnknownRecord);
254
+ }
255
+ function hasObjectProperty(node, name) {
256
+ return objectProperties(node).some((property) => propertyKeyName(property) === name);
257
+ }
258
+ function findObjectProperty(node, name) {
259
+ return objectProperties(node).find((property) => propertyKeyName(property) === name) ?? null;
260
+ }
261
+ function dynamicLoaderNode(firstArg) {
262
+ if (!isUnknownRecord(firstArg) || getString(firstArg, "type") !== "ObjectExpression") return firstArg;
263
+ return (findObjectProperty(firstArg, "loader") ?? findObjectProperty(firstArg, "modules"))?.value;
264
+ }
265
+ function findLastEndedProperty(node) {
266
+ const properties = objectProperties(node);
267
+ for (let index = properties.length - 1; index >= 0; index -= 1) if (getNumber(properties[index], "end") !== null) return properties[index];
268
+ return null;
269
+ }
270
+ function appendObjectProperty(output, objectNode, property) {
271
+ const start = getNumber(objectNode, "start");
272
+ const end = getNumber(objectNode, "end");
273
+ if (start === null || end === null) return false;
274
+ const lastProperty = findLastEndedProperty(objectNode);
275
+ if (!lastProperty) {
276
+ output.appendLeft(start + 1, property);
277
+ return true;
278
+ }
279
+ const propertyEnd = getNumber(lastProperty, "end");
280
+ if (propertyEnd === null) return false;
281
+ output.appendLeft(propertyEnd, `, ${property}`);
282
+ return true;
283
+ }
284
+ function stripComments(source) {
285
+ return source.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/[^\n]*/g, "");
286
+ }
287
+ function insertSecondOptionsArgument(output, code, callNode, firstArg, optionsLiteral) {
288
+ const callEnd = getNumber(callNode, "end");
289
+ const firstArgEnd = getNumber(firstArg, "end");
290
+ if (callEnd === null || firstArgEnd === null) return false;
291
+ const closeParen = callEnd - 1;
292
+ const separator = stripComments(code.slice(firstArgEnd, closeParen)).trimEnd().endsWith(",") ? " " : ", ";
293
+ output.appendLeft(closeParen, `${separator}${optionsLiteral}`);
294
+ return true;
295
+ }
296
+ function cleanResolvedId(id) {
297
+ let start = 0;
298
+ while (start < id.length && id.charCodeAt(start) === 0) start += 1;
299
+ return id.slice(start).replace(/^\/@fs\//, "/").split("?")[0].replace(/\\/g, "/");
300
+ }
301
+ const rootRealpathCache = /* @__PURE__ */ new Map();
302
+ function cachedRootRealpath(root) {
303
+ if (!rootRealpathCache.has(root)) rootRealpathCache.set(root, tryRealpathSync(root));
304
+ return rootRealpathCache.get(root) ?? null;
305
+ }
306
+ /** `code` offset -> human `:line:column` (1-based), for build error messages. */
307
+ function formatNodeLocation(code, node) {
308
+ const start = getNumber(node, "start");
309
+ if (start === null) return "";
310
+ const before = code.slice(0, start);
311
+ return `:${before.split("\n").length}:${start - before.lastIndexOf("\n")}`;
312
+ }
313
+ function toManifestModuleId(root, resolvedId) {
314
+ const cleaned = cleanResolvedId(resolvedId);
315
+ if (!path.isAbsolute(cleaned)) return cleaned.replace(/^\/+/, "");
316
+ const rootCandidates = new Set([root]);
317
+ const realRoot = cachedRootRealpath(root);
318
+ if (realRoot) rootCandidates.add(realRoot);
319
+ const moduleCandidates = new Set([cleaned]);
320
+ const realCleaned = tryRealpathSync(cleaned);
321
+ if (realCleaned) moduleCandidates.add(realCleaned.replace(/\\/g, "/"));
322
+ for (const rootCandidate of rootCandidates) for (const moduleCandidate of moduleCandidates) {
323
+ const relative = relativeWithinRoot(rootCandidate, moduleCandidate);
324
+ if (relative) return relative;
325
+ }
326
+ return null;
327
+ }
328
+ async function resolveManifestModuleIds(specifiers, importer, root, resolveDynamicImport) {
329
+ const resolvedIds = [];
330
+ const seen = /* @__PURE__ */ new Set();
331
+ for (const specifier of specifiers) {
332
+ const resolved = await resolveDynamicImport(specifier, importer);
333
+ const moduleId = resolved ? toManifestModuleId(root, resolved) : null;
334
+ if (!moduleId || seen.has(moduleId)) continue;
335
+ seen.add(moduleId);
336
+ resolvedIds.push(moduleId);
337
+ }
338
+ return resolvedIds;
339
+ }
340
+ function shouldSkipCall(firstArg, secondArg) {
341
+ if (hasObjectProperty(firstArg, "loadableGenerated")) return true;
342
+ return hasObjectProperty(secondArg, "loadableGenerated");
343
+ }
344
+ function applyLoadableGenerated(output, code, callNode, moduleIds) {
345
+ const args = getArray(callNode, "arguments");
346
+ const firstArg = args[0];
347
+ const secondArg = args[1];
348
+ if (!isUnknownRecord(firstArg)) return false;
349
+ if (shouldSkipCall(firstArg, secondArg)) return false;
350
+ const property = `loadableGenerated: { modules: ${JSON.stringify(moduleIds)} }`;
351
+ if (getString(firstArg, "type") === "ObjectExpression") return appendObjectProperty(output, firstArg, property);
352
+ if (secondArg === void 0) return insertSecondOptionsArgument(output, code, callNode, firstArg, `{ ${property} }`);
353
+ if (isUnknownRecord(secondArg) && getString(secondArg, "type") === "ObjectExpression") return appendObjectProperty(output, secondArg, property);
354
+ return false;
355
+ }
356
+ async function transformNextDynamicPreloadMetadata(code, id, root, resolveDynamicImport) {
357
+ if (!code.includes("next/dynamic")) return null;
358
+ let ast;
359
+ try {
360
+ ast = parseAst(code);
361
+ } catch (error) {
362
+ if (typeof process !== "undefined" && process.env?.DEBUG?.includes("vinext")) console.debug(`[vinext] dynamic-preload-metadata: failed to parse ${id}:`, error);
363
+ return null;
364
+ }
365
+ const dynamicLocals = collectDynamicImportLocals(ast);
366
+ if (dynamicLocals.size === 0) return null;
367
+ const output = new MagicString(code);
368
+ let changed = false;
369
+ const pending = [];
370
+ visitDynamicCalls(ast, dynamicLocals, (node) => {
371
+ const args = getArray(node, "arguments");
372
+ if (args.length > 2) throw new Error(`next/dynamic only accepts 2 arguments (${id}${formatNodeLocation(code, node)})`);
373
+ const specifiers = collectImportSpecifiers(dynamicLoaderNode(args[0]));
374
+ if (specifiers.length === 0) return;
375
+ pending.push(resolveManifestModuleIds(specifiers, id, root, resolveDynamicImport).then((moduleIds) => {
376
+ if (moduleIds.length === 0) return;
377
+ if (applyLoadableGenerated(output, code, node, moduleIds)) changed = true;
378
+ }));
379
+ });
380
+ await Promise.all(pending);
381
+ if (!changed) return null;
382
+ return {
383
+ code: output.toString(),
384
+ map: output.generateMap({ hires: "boundary" })
385
+ };
386
+ }
387
+ function createDynamicPreloadMetadataPlugin() {
388
+ let root = process.cwd();
389
+ return {
390
+ name: "vinext:dynamic-preload-metadata",
391
+ configResolved(config) {
392
+ root = config.root;
393
+ },
394
+ transform: {
395
+ filter: {
396
+ id: {
397
+ include: /\.(tsx?|jsx?|mjs)$/,
398
+ exclude: /node_modules/
399
+ },
400
+ code: "next/dynamic"
401
+ },
402
+ async handler(code, id) {
403
+ if (id.includes("node_modules") || id.startsWith("\0")) return null;
404
+ if (!/\.(tsx?|jsx?|mjs)$/.test(id)) return null;
405
+ const result = await transformNextDynamicPreloadMetadata(code, id, root, async (specifier, importer) => {
406
+ return (await this.resolve(specifier, importer, { skipSelf: true }))?.id ?? null;
407
+ });
408
+ if (!result) return null;
409
+ return result;
410
+ }
411
+ }
412
+ };
413
+ }
414
+ //#endregion
415
+ export { createDynamicPreloadMetadataPlugin, transformNextDynamicPreloadMetadata };
@@ -42,7 +42,7 @@ function createOgInlineFetchAssetsPlugin() {
42
42
  return null;
43
43
  }
44
44
  };
45
- if (code.includes("fetch(")) for (const match of code.matchAll(/fetch\(\s*new URL\(\s*(["'])(\.\/[^"']+)\1\s*,\s*import\.meta\.url\s*\)\s*\)(?:\.then\(\s*(?:function\s*\([^)]*\)|\([^)]*\)\s*=>)\s*\{?\s*return\s+[^.]+\.arrayBuffer\(\)\s*\}?\s*\)|\.then\(\s*\([^)]*\)\s*=>\s*[^.]+\.arrayBuffer\(\)\s*\))/g)) {
45
+ if (code.includes("fetch(")) for (const match of code.matchAll(/fetch\(\s*new URL\(\s*(["'])(\.[^"']+)\1\s*,\s*import\.meta\.url\s*\)\s*\)(?:\.then\(\s*(?:function\s*\([^)]*\)|\([^)]*\)\s*=>)\s*\{?\s*return\s+[^.]+\.arrayBuffer\(\)\s*;?\s*\}?\s*,?\s*\)|\.then\(\s*\([^)]*\)\s*=>\s*[^.]+\.arrayBuffer\(\)\s*,?\s*\))/g)) {
46
46
  const fullMatch = match[0];
47
47
  const relPath = match[2];
48
48
  const fileBase64 = await readAsBase64(path.resolve(moduleDir, relPath));
@@ -59,7 +59,7 @@ function createOgInlineFetchAssetsPlugin() {
59
59
  newCode = newCode.replaceAll(fullMatch, inlined);
60
60
  didReplace = true;
61
61
  }
62
- if (code.includes("readFileSync(")) for (const match of newCode.matchAll(/[a-zA-Z_$][a-zA-Z0-9_$]*\.readFileSync\(\s*(?:[a-zA-Z_$][a-zA-Z0-9_$]*\.)?fileURLToPath\(\s*new URL\(\s*(["'])(\.\/[^"']+)\1\s*,\s*import\.meta\.url\s*\)\s*\)\s*\)/g)) {
62
+ if (code.includes("readFileSync(")) for (const match of newCode.matchAll(/[a-zA-Z_$][a-zA-Z0-9_$]*\.readFileSync\(\s*(?:[a-zA-Z_$][a-zA-Z0-9_$]*\.)?fileURLToPath\(\s*new URL\(\s*(["'])(\.[^"']+)\1\s*,\s*import\.meta\.url\s*\)\s*\)\s*\)/g)) {
63
63
  const fullMatch = match[0];
64
64
  const relPath = match[2];
65
65
  const fileBase64 = await readAsBase64(path.resolve(moduleDir, relPath));
@@ -21,11 +21,15 @@ declare const DEFAULT_OPTIMIZE_PACKAGES: string[];
21
21
  * Handles: `export * as X from`, `export { A } from`, `import * as X; export { X }`,
22
22
  * and `export * from "./sub"` (recursively resolves wildcard re-exports).
23
23
  *
24
- * Returns null if the entry cannot be resolved, the file cannot be read, or
25
- * the file has a parse error. Returns an empty map if the file is valid but
26
- * exports nothing.
24
+ * Returns null if `entryPath` is empty, the file cannot be read, or the file
25
+ * has a parse error. Returns an empty map if the file is valid but exports
26
+ * nothing.
27
+ *
28
+ * @param entryPath - Pre-resolved absolute path to the barrel entry file (the
29
+ * caller owns entry resolution + its caching), or null when it could not be
30
+ * resolved.
27
31
  */
28
- declare function buildBarrelExportMap(packageName: string, resolveEntry: (pkg: string) => string | null, readFile: (filepath: string) => Promise<string | null>, cache?: Map<string, BarrelExportMap>): Promise<BarrelExportMap | null>;
32
+ declare function buildBarrelExportMap(entryPath: string | null, readFile: (filepath: string) => Promise<string | null>, cache?: Map<string, BarrelExportMap>): Promise<BarrelExportMap | null>;
29
33
  /**
30
34
  * Creates the vinext:optimize-imports Vite plugin.
31
35
  *
@@ -1,3 +1,4 @@
1
+ import { normalizePathSeparators } from "../utils/path.js";
1
2
  import { getAstName } from "./ast-utils.js";
2
3
  import { createRequire } from "node:module";
3
4
  import path from "node:path";
@@ -185,12 +186,12 @@ async function resolvePackageEntry(packageName, projectRoot, preferReactServer)
185
186
  const dotExport = pkgJson.exports["."];
186
187
  if (dotExport) {
187
188
  const entryPath = resolveExportsValue(dotExport, preferReactServer);
188
- if (entryPath) return path.resolve(pkgDir, entryPath).split(path.sep).join("/");
189
+ if (entryPath) return normalizePathSeparators(path.resolve(pkgDir, entryPath));
189
190
  }
190
191
  }
191
192
  const entryField = pkgJson.module ?? pkgJson.main;
192
- if (typeof entryField === "string") return path.resolve(pkgDir, entryField).split(path.sep).join("/");
193
- return createRequire(path.join(projectRoot, "package.json")).resolve(packageName).split(path.sep).join("/");
193
+ if (typeof entryField === "string") return normalizePathSeparators(path.resolve(pkgDir, entryField));
194
+ return normalizePathSeparators(createRequire(path.join(projectRoot, "package.json")).resolve(packageName));
194
195
  } catch {
195
196
  return null;
196
197
  }
@@ -228,14 +229,14 @@ async function buildExportMapFromFile(filePath, readFile, cache, visited, initia
228
229
  const exportMap = /* @__PURE__ */ new Map();
229
230
  const importBindings = /* @__PURE__ */ new Map();
230
231
  const localDeclarations = /* @__PURE__ */ new Set();
231
- const fileDir = path.dirname(filePath);
232
+ const fileDir = path.posix.dirname(filePath);
232
233
  /**
233
234
  * Normalize a source specifier: resolve relative paths to absolute so that
234
235
  * entries in the export map always store absolute paths for file references.
235
236
  * Bare package specifiers (e.g. "@radix-ui/react-slot") are returned unchanged.
236
237
  */
237
238
  function normalizeSource(source) {
238
- return source.startsWith(".") ? path.resolve(fileDir, source).split(path.sep).join("/") : source;
239
+ return source.startsWith(".") ? path.posix.join(fileDir, source) : source;
239
240
  }
240
241
  function recordLocalDeclaration(node) {
241
242
  if (!node) return;
@@ -297,7 +298,7 @@ async function buildExportMapFromFile(filePath, readFile, cache, visited, initia
297
298
  isNamespace: true
298
299
  });
299
300
  } else if (rawSource.startsWith(".")) {
300
- const subPath = path.resolve(fileDir, rawSource).split(path.sep).join("/");
301
+ const subPath = path.posix.join(fileDir, rawSource);
301
302
  const candidates = [
302
303
  subPath,
303
304
  `${subPath}.js`,
@@ -386,12 +387,15 @@ async function buildExportMapFromFile(filePath, readFile, cache, visited, initia
386
387
  * Handles: `export * as X from`, `export { A } from`, `import * as X; export { X }`,
387
388
  * and `export * from "./sub"` (recursively resolves wildcard re-exports).
388
389
  *
389
- * Returns null if the entry cannot be resolved, the file cannot be read, or
390
- * the file has a parse error. Returns an empty map if the file is valid but
391
- * exports nothing.
390
+ * Returns null if `entryPath` is empty, the file cannot be read, or the file
391
+ * has a parse error. Returns an empty map if the file is valid but exports
392
+ * nothing.
393
+ *
394
+ * @param entryPath - Pre-resolved absolute path to the barrel entry file (the
395
+ * caller owns entry resolution + its caching), or null when it could not be
396
+ * resolved.
392
397
  */
393
- async function buildBarrelExportMap(packageName, resolveEntry, readFile, cache) {
394
- const entryPath = resolveEntry(packageName);
398
+ async function buildBarrelExportMap(entryPath, readFile, cache) {
395
399
  if (!entryPath) return null;
396
400
  const exportMapCache = cache ?? /* @__PURE__ */ new Map();
397
401
  const cached = exportMapCache.get(entryPath);
@@ -466,7 +470,7 @@ function createOptimizeImportsPlugin(getNextConfig, getRoot) {
466
470
  barrelEntry = await resolvePackageEntry(importSource, root, preferReactServer);
467
471
  entryPathCache.set(cacheKey, barrelEntry ?? null);
468
472
  }
469
- const exportMap = await buildBarrelExportMap(importSource, () => barrelEntry ?? null, readFileSafe, barrelCaches.exportMapCache);
473
+ const exportMap = await buildBarrelExportMap(barrelEntry, readFileSafe, barrelCaches.exportMapCache);
470
474
  if (!exportMap || !barrelEntry) continue;
471
475
  const envKey = preferReactServer ? "rsc" : "ssr";
472
476
  const registeredKey = `${envKey}:${barrelEntry}`;
@@ -73,20 +73,24 @@ async function resolvePostcssStringPluginsUncached(projectRoot) {
73
73
  if (!config || !Array.isArray(config.plugins)) return;
74
74
  if (!config.plugins.some((p) => typeof p === "string" || Array.isArray(p) && typeof p[0] === "string")) return;
75
75
  const req = createRequire(path.join(projectRoot, "package.json"));
76
- return { plugins: await Promise.all(config.plugins.filter(Boolean).map(async (plugin) => {
77
- if (typeof plugin === "string") {
78
- const mod = await import(pathToFileURL(req.resolve(plugin)).href);
79
- const fn = mod.default ?? mod;
80
- return typeof fn === "function" ? fn() : fn;
81
- }
82
- if (Array.isArray(plugin) && typeof plugin[0] === "string") {
83
- const [name, options] = plugin;
84
- const mod = await import(pathToFileURL(req.resolve(name)).href);
85
- const fn = mod.default ?? mod;
86
- return typeof fn === "function" ? fn(options) : fn;
87
- }
88
- return plugin;
89
- })) };
76
+ try {
77
+ return { plugins: await Promise.all(config.plugins.filter(Boolean).map(async (plugin) => {
78
+ if (typeof plugin === "string") {
79
+ const mod = await import(pathToFileURL(req.resolve(plugin)).href);
80
+ const fn = mod.default ?? mod;
81
+ return typeof fn === "function" ? fn() : fn;
82
+ }
83
+ if (Array.isArray(plugin) && typeof plugin[0] === "string") {
84
+ const [name, options] = plugin;
85
+ const mod = await import(pathToFileURL(req.resolve(name)).href);
86
+ const fn = mod.default ?? mod;
87
+ return typeof fn === "function" ? fn(options) : fn;
88
+ }
89
+ return plugin;
90
+ })) };
91
+ } catch {
92
+ return;
93
+ }
90
94
  }
91
95
  //#endregion
92
96
  export { postcssCache, resolvePostcssStringPlugins };
@@ -0,0 +1,6 @@
1
+ import { Plugin } from "vite";
2
+
3
+ //#region src/plugins/require-context.d.ts
4
+ declare function createRequireContextPlugin(): Plugin;
5
+ //#endregion
6
+ export { createRequireContextPlugin };