@wular/pnext 0.1.7 → 0.1.9

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 (172) hide show
  1. package/dist/server/_chunks/{aliases-j47a10ce.js → aliases-fhv4dt06.js} +7 -5
  2. package/dist/server/_chunks/{analyze-arswqe6s.js → analyze-09kx9q6r.js} +17 -13
  3. package/dist/server/_chunks/{boot-af0mv3dy.js → boot-8aj7efqk.js} +13 -11
  4. package/dist/server/_chunks/{build-spy3dxp4.js → build-jda155c9.js} +7 -5
  5. package/dist/server/_chunks/{build-tier-m7yvqz61.js → build-tier-qrkpfsk1.js} +59 -75
  6. package/dist/server/_chunks/{build-t9h0hec3.js → build-wspv5h60.js} +1004 -1191
  7. package/dist/server/_chunks/{compile-53j02j27.js → compile-040r79gj.js} +2 -2
  8. package/dist/server/_chunks/{config-n2z7yxps.js → config-7h84p6q8.js} +6 -4
  9. package/dist/server/_chunks/{config-1yzwexq6.js → config-d4hqyygy.js} +12 -3
  10. package/dist/server/_chunks/{create-meec9hs6.js → create-skj8wzt5.js} +4 -3
  11. package/dist/server/_chunks/{dev-fjmqg6en.js → dev-pennd36n.js} +2 -2
  12. package/dist/server/_chunks/{generate-n9sh6hzt.js → generate-d8vb1d21.js} +5 -4
  13. package/dist/server/_chunks/{index-eeaanp2e.js → index-0qt2vapb.js} +3 -3
  14. package/dist/server/_chunks/{index-91x12ykq.js → index-0r5eqfc7.js} +6 -1
  15. package/dist/server/_chunks/{index-9ych9ma8.js → index-0wm2p3ks.js} +2 -2
  16. package/dist/server/_chunks/{index-357na4a8.js → index-141vcwk6.js} +1 -1
  17. package/dist/server/_chunks/{index-2dv4y4wd.js → index-1y0cesgn.js} +16 -10
  18. package/dist/server/_chunks/{index-ytjvpbm2.js → index-26gwrm07.js} +3 -3
  19. package/dist/server/_chunks/{index-8k7pfejn.js → index-3r6qpe8a.js} +7 -7
  20. package/dist/server/_chunks/{index-rn8dyr1f.js → index-42fef2rv.js} +8 -48
  21. package/dist/server/_chunks/{index-ncnes8c6.js → index-47gx7trn.js} +2 -2
  22. package/dist/server/_chunks/{index-20ppawv7.js → index-4qsce64w.js} +3 -3
  23. package/dist/server/_chunks/{index-1011cscr.js → index-4vf121ws.js} +61 -29
  24. package/dist/server/_chunks/{index-cf4rvxv6.js → index-52k54ykj.js} +1 -1
  25. package/dist/server/_chunks/{index-nyrba2kr.js → index-53fnn598.js} +11 -11
  26. package/dist/server/_chunks/{index-4hgjrqh7.js → index-6tb725m8.js} +2 -2
  27. package/dist/server/_chunks/{index-3xbr4eyv.js → index-912z4mfx.js} +3 -3
  28. package/dist/server/_chunks/{index-sjpckxqn.js → index-9f49w76j.js} +1 -1
  29. package/dist/server/_chunks/{index-jepjvcrf.js → index-aarf1brn.js} +1 -1
  30. package/dist/server/_chunks/{index-9n2914ww.js → index-akkrvjn6.js} +1 -1
  31. package/dist/server/_chunks/index-bzd2ef7t.js +10 -0
  32. package/dist/server/_chunks/{index-sv8m6789.js → index-cqcwwxfp.js} +5 -5
  33. package/dist/server/_chunks/{index-yz54pxrh.js → index-d1jsmhhk.js} +4 -9
  34. package/dist/server/_chunks/{index-vvmmknm1.js → index-da0fphj0.js} +19 -15
  35. package/dist/server/_chunks/{index-sctcgyvv.js → index-drwv61cc.js} +2 -2
  36. package/dist/server/_chunks/{index-z84ab1w0.js → index-e176wk6x.js} +3 -3
  37. package/dist/server/_chunks/{index-9hx2641q.js → index-entm8bmz.js} +1 -1
  38. package/dist/server/_chunks/index-fpghsgb4.js +352 -0
  39. package/dist/server/_chunks/{index-jx7bqvw1.js → index-hr63fvzn.js} +1 -1
  40. package/dist/server/_chunks/{index-eajaspjk.js → index-j0m1jxqa.js} +1 -1
  41. package/dist/server/_chunks/index-jbj7ehef.js +50 -0
  42. package/dist/server/_chunks/{index-egykcqg3.js → index-jexsy9a8.js} +1 -1
  43. package/dist/server/_chunks/{index-fkp000p1.js → index-jjppzw0s.js} +2 -2
  44. package/dist/server/_chunks/index-jt8e1pje.js +12 -0
  45. package/dist/server/_chunks/{index-ggk2j965.js → index-kpdph69z.js} +56 -50
  46. package/dist/server/_chunks/{index-6e4fqv30.js → index-m63czgq5.js} +2 -0
  47. package/dist/server/_chunks/{index-c0g2wf3z.js → index-md5jchzy.js} +1 -1
  48. package/dist/server/_chunks/{index-tvqkq6e6.js → index-n814hcky.js} +1 -1
  49. package/dist/server/_chunks/{index-06nyqntx.js → index-q3r9z8mq.js} +1 -1
  50. package/dist/server/_chunks/{index-4q2gbfwk.js → index-qjrh7w2g.js} +2 -2
  51. package/dist/server/_chunks/{index-3b3at80h.js → index-s61bx2aj.js} +6 -3
  52. package/dist/server/_chunks/{index-ym67zqxp.js → index-tf4j19ge.js} +1 -1
  53. package/dist/server/_chunks/{index-qn4z5s3c.js → index-typcbcsv.js} +3 -3
  54. package/dist/server/_chunks/{index-p77b4kcx.js → index-veycp46e.js} +1 -1
  55. package/dist/server/_chunks/{index-11sfk4hb.js → index-vmr35jjw.js} +1 -1
  56. package/dist/server/_chunks/{index-kq8kpzye.js → index-vqs3rebe.js} +3 -3
  57. package/dist/server/_chunks/{index-danncfhy.js → index-wm36rj4v.js} +1 -1
  58. package/dist/server/_chunks/{index-z4z9zv3b.js → index-x9c55pzy.js} +141 -3
  59. package/dist/server/_chunks/{index-y2jr2n72.js → index-xrsg0041.js} +4 -4
  60. package/dist/server/_chunks/{index-k1g3epw0.js → index-xs3411qh.js} +10 -10
  61. package/dist/server/_chunks/{index-0374j2b9.js → index-y4d02znn.js} +1 -1
  62. package/dist/server/_chunks/{index-wpfhfbs4.js → index-y71a76dn.js} +4 -4
  63. package/dist/server/_chunks/{index-qm6kmhqs.js → index-y7mzvq2q.js} +1 -1
  64. package/dist/server/_chunks/{index-hkdfj58q.js → index-y9bygr95.js} +1 -1
  65. package/dist/server/_chunks/{index-3tf1xjsp.js → index-yghskk8w.js} +11 -11
  66. package/dist/server/_chunks/{index-5gyr4emz.js → index-yzcpr3yw.js} +4 -4
  67. package/dist/server/_chunks/{index-x93hv0sc.js → index-zedjt25v.js} +23 -10
  68. package/dist/server/_chunks/{index-tq0pc7eg.js → index-zfrwq472.js} +3 -3
  69. package/dist/server/_chunks/{loader-7yw0j98z.js → loader-w1e0n5sm.js} +12 -10
  70. package/dist/server/_chunks/{modules-jn8bmbn8.js → modules-730j14cm.js} +14 -12
  71. package/dist/server/_chunks/{pipeline-yy9jhydf.js → pipeline-yjdnwbhm.js} +25 -21
  72. package/dist/server/_chunks/{production-jar9ztm3.js → production-1xe9b7wd.js} +14 -3
  73. package/dist/server/_chunks/{proxy-config-j84dgksn.js → proxy-config-9r9e0jvn.js} +7 -5
  74. package/dist/server/_chunks/{proxy-w1d0wmsn.js → proxy-pnevsbfd.js} +12 -10
  75. package/dist/server/_chunks/{router-k1reahfn.js → router-rzge0vz8.js} +10 -7
  76. package/dist/server/_chunks/{routes-2s277fc6.js → routes-0x8wjvcj.js} +12 -10
  77. package/dist/server/_chunks/{run-pvd8bs1t.js → run-tk90r3ac.js} +5 -4
  78. package/dist/server/_chunks/{server-mt4a994c.js → server-gev78ejc.js} +38 -34
  79. package/dist/server/_chunks/{tsconfig-defaults-1nb3308g.js → tsconfig-defaults-qe9wd6ne.js} +5 -4
  80. package/dist/server/_chunks/{typegen-0qr0459b.js → typegen-0yw8sry8.js} +15 -13
  81. package/dist/server/cli/index.js +12 -15
  82. package/dist/server/cli/start.js +35 -14
  83. package/dist/server/compat/next/cache.js +5 -5
  84. package/dist/server/compat/next/config-headers.js +8 -6
  85. package/dist/server/compat/next/config-loader.js +1 -1
  86. package/dist/server/compat/next/dist/server/web/spec-extension/revalidate.js +5 -5
  87. package/dist/server/compat/next/dist/server/web/spec-extension/unstable-cache.js +5 -5
  88. package/dist/server/compat/next/dist/server/web/spec-extension/unstable-no-store.js +5 -5
  89. package/dist/server/compat/next/dynamic.js +3 -14
  90. package/dist/server/compat/next/font/cache.js +6 -4
  91. package/dist/server/compat/next/font/local.js +7 -5
  92. package/dist/server/compat/next/font/runtime.js +7 -5
  93. package/dist/server/compat/next/headers.js +4 -4
  94. package/dist/server/compat/next/image/config.js +2 -2
  95. package/dist/server/compat/next/image/optimizer.js +3 -3
  96. package/dist/server/compat/next/image/static-metadata.js +4 -4
  97. package/dist/server/compat/next/legacy-request-apis.js +3 -3
  98. package/dist/server/compat/next/link-transform.js +4 -3
  99. package/dist/server/compat/next/navigation.js +5 -4
  100. package/dist/server/compat/next/redirects.js +8 -6
  101. package/dist/server/compat/next/resource-hints.js +2 -2
  102. package/dist/server/compat/next/rewrites.js +7 -5
  103. package/dist/server/compat/next/root-params.js +3 -3
  104. package/dist/server/compat/next/route-state.js +2 -2
  105. package/dist/server/compat/next/script.js +2 -2
  106. package/dist/server/compat/next/server.js +5 -5
  107. package/dist/server/generation.json +1 -1
  108. package/package.json +1 -1
  109. package/reference/compat.md +1 -1
  110. package/reference/config.md +2 -2
  111. package/reference/dev.md +1 -1
  112. package/reference/getting-started.md +1 -1
  113. package/reference/rendering.md +4 -4
  114. package/src/api/dynamic.tsx +84 -4
  115. package/src/cli/adapters/vercel-warm.ts +40 -29
  116. package/src/cli/adapters/vercel.ts +101 -1265
  117. package/src/cli/analyze.ts +3 -2
  118. package/src/cli/build/cache.ts +6 -6
  119. package/src/cli/build.ts +33 -33
  120. package/src/cli/index.ts +4 -6
  121. package/src/cli/serve/pipeline.ts +16 -10
  122. package/src/cli/serve/standalone-worker.ts +8 -0
  123. package/src/cli/serve/standalone.ts +727 -0
  124. package/src/cli/start.ts +29 -8
  125. package/src/client/build.ts +1 -1
  126. package/src/client/reference-stub.ts +2 -34
  127. package/src/compat/actions/extensions.ts +3 -2
  128. package/src/compat/bundler/require-context.ts +2 -1
  129. package/src/compat/bundler/webpack-loaders.ts +3 -2
  130. package/src/compat/bundler/worker.ts +2 -2
  131. package/src/compat/css/inline-css.ts +1 -1
  132. package/src/compat/export/build-complete.ts +1 -1
  133. package/src/compat/export/emit.ts +4 -4
  134. package/src/compat/export/standalone.ts +30 -65
  135. package/src/compat/image-optimizer/optimize.ts +1 -1
  136. package/src/compat/lifecycle/instrumentation-client.ts +4 -3
  137. package/src/compat/metadata-artifacts.ts +1 -1
  138. package/src/compat/next/config-loader.ts +3 -0
  139. package/src/compat/next/dynamic.tsx +10 -23
  140. package/src/compat/next/font/cache.ts +2 -1
  141. package/src/compat/next/font/runtime.ts +1 -1
  142. package/src/compat/register/image.ts +1 -1
  143. package/src/compat/typecheck/check.ts +6 -4
  144. package/src/config.ts +28 -5
  145. package/src/css/assets.ts +1 -1
  146. package/src/css/build.ts +16 -9
  147. package/src/dev/client-chunk-store.ts +2 -1
  148. package/src/dev/restart/client-key.ts +2 -1
  149. package/src/dev/restart/global-css.ts +2 -1
  150. package/src/dev/restart/route-bundle-key.ts +2 -1
  151. package/src/dev/restart/route-facts.ts +2 -1
  152. package/src/dev/server.ts +8 -7
  153. package/src/out-paths.ts +10 -0
  154. package/src/render/renderer.ts +1 -1
  155. package/src/resolve/dynamic.ts +4 -0
  156. package/src/resolve/engine.ts +2 -12
  157. package/src/resolve/scan-facts.ts +185 -1
  158. package/src/routing/metadata-files.ts +1 -1
  159. package/src/runtime/loader.ts +5 -3
  160. package/src/runtime/module-cache.ts +2 -1
  161. package/src/runtime/modules.ts +50 -16
  162. package/src/runtime/prebundle.ts +23 -3
  163. package/src/runtime/production.ts +105 -40
  164. package/src/runtime/release-graph.ts +21 -13
  165. package/src/runtime/vendor-build.ts +45 -23
  166. package/src/types.ts +2 -3
  167. package/src/utils/directive.ts +40 -0
  168. package/src/utils/fs.ts +7 -2
  169. package/src/utils/resource-query.ts +12 -0
  170. package/dist/server/_chunks/index-tqn2qnnn.js +0 -241
  171. package/dist/server/_chunks/index-y36a0ybw.js +0 -57
  172. package/src/cli/serve/entry.ts +0 -52
@@ -10,10 +10,10 @@ import {
10
10
  buildClientEntries,
11
11
  emitStaticClientChunks,
12
12
  startClientSources
13
- } from "./index-nyrba2kr.js";
13
+ } from "./index-53fnn598.js";
14
14
  import {
15
15
  writeTypegen
16
- } from "./index-wpfhfbs4.js";
16
+ } from "./index-y71a76dn.js";
17
17
  import {
18
18
  handleRouteModule,
19
19
  staticRouteParams
@@ -23,23 +23,23 @@ import {
23
23
  assertNoServerActionsWithoutCompat,
24
24
  materializeRouteFacts,
25
25
  scanRoutes
26
- } from "./index-8k7pfejn.js";
26
+ } from "./index-3r6qpe8a.js";
27
27
  import {
28
- compiledSpecifiersManifestSuffix,
29
28
  devServerModuleHref,
30
29
  resetModuleGraphFailure,
31
30
  setEmitCompiledSpecifiersManifest,
32
31
  setReleaseCompile
33
- } from "./index-1011cscr.js";
32
+ } from "./index-4vf121ws.js";
34
33
  import"./index-n4hxpng2.js";
35
34
  import"./index-x3yn4ywm.js";
36
35
  import {
36
+ cacheRoot as cacheRoot2,
37
37
  compiledSourceGraph,
38
38
  flushDevModuleCaches,
39
39
  registerServerRuntime
40
- } from "./index-vvmmknm1.js";
41
- import"./index-91x12ykq.js";
42
- import"./index-tvqkq6e6.js";
40
+ } from "./index-da0fphj0.js";
41
+ import"./index-0r5eqfc7.js";
42
+ import"./index-n814hcky.js";
43
43
  import {
44
44
  clientEntryName,
45
45
  defaultNotFoundDocument,
@@ -61,21 +61,22 @@ import {
61
61
  staticParamsFor,
62
62
  staticRouteMetadataKey,
63
63
  withDynamicMetadataRoutes
64
- } from "./index-3tf1xjsp.js";
64
+ } from "./index-yghskk8w.js";
65
65
  import {
66
66
  findLayouts
67
- } from "./index-jepjvcrf.js";
67
+ } from "./index-aarf1brn.js";
68
68
  import {
69
69
  findProxyFile,
70
70
  proxyExternalLoadTarget,
71
71
  proxyRoutePatterns,
72
72
  validateProxyFiles
73
- } from "./index-kq8kpzye.js";
73
+ } from "./index-vqs3rebe.js";
74
74
  import {
75
75
  serverBundleTargetForRuntime,
76
76
  throwIfModuleGraphFailed
77
- } from "./index-3xbr4eyv.js";
78
- import"./index-rn8dyr1f.js";
77
+ } from "./index-912z4mfx.js";
78
+ import"./index-42fef2rv.js";
79
+ import"./index-jbj7ehef.js";
79
80
  import {
80
81
  buildGlobalCss,
81
82
  buildNotFoundCss,
@@ -83,21 +84,21 @@ import {
83
84
  globalCssSources,
84
85
  prepareRouteCssChunks,
85
86
  warmCssPipeline
86
- } from "./index-2dv4y4wd.js";
87
+ } from "./index-1y0cesgn.js";
87
88
  import {
88
89
  createVerboseLogger
89
90
  } from "./index-73z4esab.js";
90
91
  import {
91
92
  emittedAssetNames,
92
93
  registerCssRuntime
93
- } from "./index-y2jr2n72.js";
94
+ } from "./index-xrsg0041.js";
94
95
  import {
95
96
  nextCompatEnabled
96
97
  } from "./index-web361b8.js";
97
98
  import"./index-knp0s912.js";
98
99
  import {
99
100
  frameworkFingerprint
100
- } from "./index-c0g2wf3z.js";
101
+ } from "./index-md5jchzy.js";
101
102
  import"./index-ye9hmsvf.js";
102
103
  import {
103
104
  setRequestRuntime
@@ -109,10 +110,10 @@ import {
109
110
  } from "./index-fp8r0sqs.js";
110
111
  import"./index-cjgqs13g.js";
111
112
  import"./index-yhxkxghe.js";
112
- import"./index-fkp000p1.js";
113
+ import"./index-jjppzw0s.js";
113
114
  import {
114
115
  interceptionMarkerLevels
115
- } from "./index-p77b4kcx.js";
116
+ } from "./index-veycp46e.js";
116
117
  import {
117
118
  ensureEmptyDir,
118
119
  listFiles,
@@ -122,7 +123,7 @@ import {
122
123
  toPosixPath,
123
124
  writeFileAtomic,
124
125
  writeText
125
- } from "./index-20ppawv7.js";
126
+ } from "./index-4qsce64w.js";
126
127
  import {
127
128
  cacheRoot,
128
129
  namedBunBinary
@@ -130,24 +131,27 @@ import {
130
131
  import"./index-vz0km5qk.js";
131
132
  import {
132
133
  bootstrapCompat
133
- } from "./index-5gyr4emz.js";
134
+ } from "./index-yzcpr3yw.js";
134
135
  import {
135
- readPrebundleStamp,
136
- runtimeEntryDirs,
137
- runtimeEntryFiles
138
- } from "./index-y36a0ybw.js";
139
- import {
140
- DEFAULT_OUT_DIR,
141
136
  devOutSegment,
137
+ frameworkRuntimeSpecifiers,
142
138
  loadConfig,
143
139
  pathToFileHref
144
- } from "./index-x93hv0sc.js";
140
+ } from "./index-zedjt25v.js";
141
+ import {
142
+ outCachePath
143
+ } from "./index-bzd2ef7t.js";
145
144
  import"./index-jcsjq3d1.js";
146
145
  import {
146
+ PREBUNDLE_STAMP,
147
147
  buildIndexFile,
148
+ buildManifestFile,
149
+ prebundledFile,
148
150
  readBuildIndex,
149
- releaseSourceFile
150
- } from "./index-tqn2qnnn.js";
151
+ readPrebundleStamp,
152
+ releaseSourceFile,
153
+ standaloneOriginsFile
154
+ } from "./index-fpghsgb4.js";
151
155
  import {
152
156
  bold,
153
157
  cyan,
@@ -170,21 +174,22 @@ import {
170
174
  } from "./index-kresp2n8.js";
171
175
  import"./index-e3a6yx84.js";
172
176
  import {
173
- importSpecifiers,
174
- scanFactsStats
175
- } from "./index-z4z9zv3b.js";
176
- import {
177
- resolveImport,
178
- workspacePackageRoots
179
- } from "./index-yz54pxrh.js";
177
+ importMetaRefs,
178
+ moduleSpecifierEdges,
179
+ scanFactsStats,
180
+ spliceSource
181
+ } from "./index-x9c55pzy.js";
182
+ import"./index-d1jsmhhk.js";
180
183
  import"./index-7wc9n8be.js";
181
184
  import"./index-pym1cezq.js";
185
+ import {
186
+ splitResourceQuery
187
+ } from "./index-jt8e1pje.js";
182
188
  import {
183
189
  buildParallelPhaseError,
184
190
  clearBuildParallelPhases,
185
191
  getBuildExtensions,
186
192
  getCompatModeExtensions,
187
- getImportAliasExtensions,
188
193
  getRenderExtensions,
189
194
  runInitHooks,
190
195
  withRouteRuntime
@@ -193,192 +198,19 @@ import {
193
198
  escapeRegex
194
199
  } from "./index-qjj6gddn.js";
195
200
  import"./index-4399bvd2.js";
196
- import {
197
- __require
198
- } from "./index-rt9qq1va.js";
201
+ import"./index-rt9qq1va.js";
199
202
 
200
203
  // src/cli/build.ts
201
- import { copyFile as copyFile2, mkdir as mkdir4, rename as rename2, writeFile as writeFile3 } from "fs/promises";
202
- import { existsSync as existsSync4, readFileSync as readFileSync4, readdirSync as readdirSync2, realpathSync as realpathSync3, statSync as statSync2 } from "fs";
204
+ import { copyFile as copyFile3, mkdir as mkdir4, rename as rename3, writeFile as writeFile2 } from "fs/promises";
205
+ import { existsSync as existsSync5, readFileSync as readFileSync3, readdirSync as readdirSync3, realpathSync as realpathSync3, statSync as statSync2 } from "fs";
203
206
  import { createRequire } from "module";
204
207
  import path5 from "path";
205
208
  import { fileURLToPath as fileURLToPath3 } from "url";
206
209
 
207
210
  // src/cli/adapters/vercel.ts
208
- import { copyFile, link, mkdir, readFile, rename, rm, symlink, writeFile } from "fs/promises";
209
- import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync, realpathSync as realpathSync2, rmSync, statSync } from "fs";
210
- import { builtinModules } from "module";
211
- import path2 from "path";
212
- import { fileURLToPath as fileURLToPath2 } from "url";
213
-
214
- // src/cli/adapters/vercel-warm.ts
215
- import { fileURLToPath } from "url";
216
-
217
- // src/runtime/release-graph.ts
218
- import { existsSync, readFileSync, realpathSync } from "fs";
211
+ import { copyFile, cp, mkdir, readFile, readdir, rename, rm } from "fs/promises";
212
+ import { constants, existsSync, readdirSync } from "fs";
219
213
  import path from "path";
220
- var layerDirs = {
221
- "server:server": "rsc",
222
- "client:client": "ssr"
223
- };
224
- var layers = Object.keys(layerDirs);
225
- var frameworkRoot = realpathSync(path.resolve(__PNEXT_PACKAGE_ROOT__ + "/src/runtime", "..", ".."));
226
-
227
- // src/cli/adapters/vercel-warm.ts
228
- var DONE_MARKER = "pnext-warm-done:";
229
- var COMPILED_MARKER = "pnext-warm-compiled";
230
- var ATTEMPT_TIMEOUT_MS = 10 * 60000;
231
- var MAX_ATTEMPTS = 3;
232
- var FULL_MODE_FLAG = "--full";
233
- function startWarmChild(config, mode = "full") {
234
- const children = new Set;
235
- let disposed = false;
236
- const spawn = () => {
237
- if (disposed)
238
- return;
239
- const child = spawnWarmProcess(config, mode);
240
- if (!child)
241
- return;
242
- children.add(child);
243
- child.exited.finally(() => children.delete(child));
244
- forwardWarmStderr(child);
245
- return child;
246
- };
247
- const killOnExit = () => kill();
248
- const kill = () => {
249
- if (disposed)
250
- return;
251
- disposed = true;
252
- process.off("exit", killOnExit);
253
- for (const child of children)
254
- child.kill();
255
- children.clear();
256
- };
257
- process.once("exit", killOnExit);
258
- const first = spawn();
259
- return {
260
- prewarm(files) {
261
- if (!first || files.length === 0)
262
- return;
263
- try {
264
- first.stdin.write(`${JSON.stringify({ prewarm: files })}
265
- `);
266
- first.stdin.flush();
267
- } catch {}
268
- },
269
- finish: (log, onCompiled, facts = { clientReferences: [] }) => warmWithRestarts(first, spawn, mode, log, facts, onCompiled).finally(kill),
270
- kill
271
- };
272
- }
273
- async function forwardWarmStderr(child) {
274
- try {
275
- const reader = child.stderr.getReader();
276
- for (;; ) {
277
- const { done, value } = await reader.read();
278
- if (done)
279
- return;
280
- process.stderr.write(value);
281
- }
282
- } catch {}
283
- }
284
- function spawnWarmProcess(config, mode) {
285
- const entry = fileURLToPath(new URL(Bun.pathToFileURL(__PNEXT_PACKAGE_ROOT__ + "/src/cli/adapters/vercel-warm.ts").href));
286
- const argv = mode === "full" ? [config.root, FULL_MODE_FLAG] : [config.root];
287
- try {
288
- return Bun.spawn([namedBunBinary("pnext-warm"), "--conditions=react-server", entry, ...argv], {
289
- cwd: config.root,
290
- stdin: "pipe",
291
- stdout: "pipe",
292
- stderr: "pipe",
293
- env: process.env
294
- });
295
- } catch {
296
- return;
297
- }
298
- }
299
- async function warmWithRestarts(first, spawn, mode, log, facts, onCompiled) {
300
- const finished = new Map;
301
- const compiled = () => [...finished.values()].filter((file) => Boolean(file));
302
- let fired = false;
303
- const fireOnCompiled = onCompiled ? () => {
304
- if (fired)
305
- return;
306
- fired = true;
307
- onCompiled(compiled());
308
- } : undefined;
309
- let child = first;
310
- for (let attempt = 1;attempt <= MAX_ATTEMPTS && child; attempt++) {
311
- const before = finished.size;
312
- const failure = await runAttempt(child, {
313
- skip: [...finished.keys()],
314
- compiled: Object.fromEntries([...finished].filter((entry) => Boolean(entry[1]))),
315
- ...facts
316
- }, finished, fireOnCompiled);
317
- if (!failure) {
318
- log.log(`warmed ${compiled().length} modules`);
319
- return compiled();
320
- }
321
- child = finished.size > before && attempt < MAX_ATTEMPTS ? spawn() : undefined;
322
- if (child)
323
- log.log(`warm-up ${failure} after ${finished.size} files; restarting past them`);
324
- else
325
- warmIncomplete(failure, finished.size, mode);
326
- }
327
- fireOnCompiled?.();
328
- return compiled();
329
- }
330
- async function runAttempt(child, request, finished, onCompiled) {
331
- try {
332
- child.stdin.write(`${JSON.stringify(request)}
333
- `);
334
- child.stdin.end();
335
- } catch {}
336
- const timeout = setTimeout(() => child.kill("SIGKILL"), ATTEMPT_TIMEOUT_MS);
337
- timeout.unref?.();
338
- const processLine = (line) => {
339
- if (!line)
340
- return;
341
- if (line === COMPILED_MARKER) {
342
- onCompiled?.();
343
- return;
344
- }
345
- if (!line.startsWith(DONE_MARKER)) {
346
- console.log(line);
347
- return;
348
- }
349
- const [source, artifact] = line.slice(DONE_MARKER.length).split("\t");
350
- if (source)
351
- finished.set(source, artifact || undefined);
352
- };
353
- const reader = child.stdout.getReader();
354
- const decoder = new TextDecoder;
355
- let buffer = "";
356
- for (;; ) {
357
- const { done, value } = await reader.read();
358
- if (done)
359
- break;
360
- buffer += decoder.decode(value, { stream: true });
361
- let newline;
362
- while ((newline = buffer.indexOf(`
363
- `)) >= 0) {
364
- processLine(buffer.slice(0, newline));
365
- buffer = buffer.slice(newline + 1);
366
- }
367
- }
368
- if (buffer)
369
- processLine(buffer);
370
- const code = await child.exited.finally(() => clearTimeout(timeout));
371
- if (code === 0)
372
- return;
373
- return child.signalCode ? `was killed by ${child.signalCode}` : `exited with code ${code}`;
374
- }
375
- function warmIncomplete(failure, done, mode) {
376
- console.warn(`pnext build: module warm-up ${failure} after warming ${done} file(s). ` + (mode === "full" ? "The function ships without the rest of its module cache and may fail to render those " + "routes at request time, where Vercel's filesystem is read-only." : "The production server compiles the rest on the first request that needs them."));
377
- }
378
- if (false) {}
379
-
380
- // src/cli/adapters/vercel.ts
381
- var RUNTIME_ROOT = "/var/task";
382
214
  var SERVER_FUNCTION = "_pnext";
383
215
  var FUNCTION_PLATFORM = {
384
216
  architecture: "x86_64",
@@ -386,127 +218,20 @@ var FUNCTION_PLATFORM = {
386
218
  cpu: "x64",
387
219
  libc: "glibc"
388
220
  };
389
- var prunedDirNames = [
390
- "node_modules",
391
- ".git",
392
- ".next",
393
- ".pnext",
394
- ".turbo",
395
- ".cache",
396
- ".vercel",
397
- ".tmp"
398
- ];
399
- var droppedFileSuffixes = [
400
- ".map",
401
- ".d.ts",
402
- ".d.mts",
403
- ".d.cts",
404
- ".DS_Store",
405
- compiledSpecifiersManifestSuffix
406
- ];
407
- var packPruningEnabled = true;
408
- function packRules(config) {
409
- const devPaths = new Set([config.outRootPath, path2.resolve(config.root, DEFAULT_OUT_DIR)].map((root) => path2.resolve(root, devOutSegment)).filter((dev) => !isInsideDir(dev, config.outPath)));
410
- devPaths.add(path2.join(config.outRootPath, "pnext-pages-compat"));
411
- if (!packPruningEnabled) {
412
- return {
413
- prunedDirs: new Set(["node_modules", ".git"]),
414
- droppedSuffixes: [],
415
- compiled: new Set,
416
- keep: new Set,
417
- keepPaths: new Set([path2.resolve(config.outPath)]),
418
- devPaths
419
- };
420
- }
421
- const keep = new Set(config.adapter?.keep ?? []);
422
- const extra = config.adapter?.exclude ?? [];
423
- const isSuffix = (entry) => entry.startsWith(".") && !prunedDirNames.includes(entry);
424
- return {
425
- prunedDirs: new Set([...prunedDirNames, ...extra.filter((entry) => !isSuffix(entry))].filter((name) => !keep.has(name))),
426
- droppedSuffixes: [...droppedFileSuffixes, ...extra.filter(isSuffix)].filter((suffix) => !keep.has(suffix)),
427
- compiled: new Set,
428
- keep,
429
- keepPaths: new Set([path2.resolve(config.outPath), path2.resolve(config.root, DEFAULT_OUT_DIR)]),
430
- devPaths
431
- };
432
- }
433
- function withinKeepPath(pack, source) {
434
- const resolved = path2.resolve(source);
435
- for (const keep of pack.keepPaths) {
436
- if (resolved === keep || resolved.startsWith(`${keep}${path2.sep}`))
437
- return true;
438
- }
439
- return false;
440
- }
441
- function shipsDir(pack, name, source, isLink = false) {
442
- if (pack.devPaths.has(path2.resolve(source)))
443
- return false;
444
- if (!pack.prunedDirs.has(name))
445
- return true;
446
- return !isLink && withinKeepPath(pack, source);
447
- }
448
- function shipsFile(pack, name, source) {
449
- if (pack.droppedSuffixes.some((suffix) => name.endsWith(suffix)))
450
- return false;
451
- if (!pack.compiled.has(path2.resolve(source)) || withinKeepPath(pack, source))
452
- return true;
453
- return [...pack.keep].some((entry) => name === entry || entry.startsWith(".") && name.endsWith(entry));
454
- }
455
- function releaseCompiledSources(config) {
456
- flushDevModuleCaches();
457
- const index = readBuildIndex(config.outPath);
458
- const graph = compiledSourceGraph(config.outPath, config.workspaceRoot);
459
- const queue = Object.keys(index.modules).map((key) => releaseSourceFile(key.slice(key.indexOf(":", key.indexOf(":") + 1) + 1), config.root, config.workspaceRoot));
460
- if (index.proxy)
461
- queue.push(path2.resolve(config.root, index.proxy.file));
462
- const script = /\.(?:[cm]?[jt]s|[jt]sx)$/;
463
- const frozen = (dir, pattern) => (readDirEntries(dir) ?? []).filter((entry) => pattern.test(entry.name) && script.test(entry.name)).forEach((entry) => queue.push(path2.join(dir, entry.name)));
464
- frozen(config.root, /^(?:pnext|next)\.config\./);
465
- if (index.instrumentation) {
466
- for (const dir of [config.root, path2.join(config.root, "src")])
467
- frozen(dir, /^instrumentation\./);
468
- }
469
- const compiled = new Set;
470
- for (const file of queue) {
471
- if (compiled.has(file))
472
- continue;
473
- compiled.add(file);
474
- let real = file;
475
- try {
476
- real = realpathSync2(file);
477
- } catch {
478
- continue;
479
- }
480
- compiled.add(real);
481
- queue.push(...graph.get(file) ?? [], ...graph.get(real) ?? []);
482
- }
483
- return compiled;
484
- }
221
+ var functionDroppedPackages = [/^sharp$/, /^@img\/sharp-libvips/];
485
222
  async function writeVercelOutput(config, manifest, options = {}) {
486
223
  const log = createVerboseLogger(options.verbose ?? false, "vercel");
487
- const outputPath = path2.join(config.root, ".vercel", "output");
224
+ const outputPath = path.join(config.root, ".vercel", "output");
225
+ const staticPath = path.join(config.outPath, "static");
488
226
  const staticFiles = manifest.staticFiles ?? {};
489
- const warm = options.warm ?? startWarmChild(config);
490
227
  await log.step("prepare output directory", () => emptyDir(outputPath));
491
- let resolveWarmedModules;
492
- const warmedModulesEarly = new Promise((resolve) => {
493
- resolveWarmedModules = resolve;
494
- });
495
- const warmSettled = warm.finish(log, (modules) => resolveWarmedModules(modules), {
496
- globalCss: globalCssSources(config),
497
- clientReferences: [...compiledClientReferenceFiles()]
498
- });
499
- warmSettled.catch(() => {
500
- return;
501
- });
502
- const warmedModules = await log.step("warm module cache (compiled)", () => warmedModulesEarly);
503
- const functionPath = path2.join(outputPath, "functions", `${SERVER_FUNCTION}.func`);
504
- await writeServerFunction(config, manifest, functionPath, warmedModules, warmSettled, log);
505
- await log.step("copy static files", () => copyStaticFiles(path2.join(config.outPath, "public"), path2.join(outputPath, "static"), (relative) => !staticFiles[relative] || canServeStaticOnVercel(staticFiles[relative])));
506
- const overrides = await staticOverrides(path2.join(config.outPath, "public"), staticFiles);
228
+ const functionPath = path.join(outputPath, "functions", `${SERVER_FUNCTION}.func`);
229
+ await writeServerFunction(config.outPath, manifest, functionPath, log);
230
+ await log.step("copy static files", () => copyStaticFiles(staticPath, path.join(outputPath, "static"), (relative) => !staticFiles[relative] || canServeStaticOnVercel(staticFiles[relative])));
231
+ const overrides = await staticOverrides(staticPath, staticFiles);
507
232
  const routes = [
508
233
  ...compatStaticRewrite(config, outputPath),
509
- ...await immutableAssetRoutes(path2.join(config.outPath, "public"), manifest.publicAssets),
234
+ ...await immutableAssetRoutes(staticPath, manifest.publicAssets),
510
235
  ...await proxyRoutes(config),
511
236
  ...staticHeaderRoutes(staticFiles),
512
237
  { handle: "filesystem" },
@@ -517,17 +242,17 @@ async function writeVercelOutput(config, manifest, options = {}) {
517
242
  routes,
518
243
  ...Object.keys(overrides).length > 0 ? { overrides } : {}
519
244
  };
520
- await writeText(path2.join(outputPath, "config.json"), `${JSON.stringify(vercelConfig, null, 2)}
245
+ await writeText(path.join(outputPath, "config.json"), `${JSON.stringify(vercelConfig, null, 2)}
521
246
  `);
522
247
  }
523
248
  async function emptyDir(dir) {
524
- const parent = path2.dirname(dir);
249
+ const parent = path.dirname(dir);
525
250
  await mkdir(parent, { recursive: true });
526
- const staleMarker = `${path2.basename(dir)}.stale-`;
527
- if (existsSync2(dir)) {
528
- await rename(dir, path2.join(parent, `${staleMarker}${process.pid.toString(36)}-${Date.now().toString(36)}`));
251
+ const staleMarker = `${path.basename(dir)}.stale-`;
252
+ if (existsSync(dir)) {
253
+ await rename(dir, path.join(parent, `${staleMarker}${process.pid.toString(36)}-${Date.now().toString(36)}`));
529
254
  }
530
- const stale = readdirSync(parent).filter((entry) => entry.startsWith(staleMarker)).map((entry) => path2.join(parent, entry));
255
+ const stale = readdirSync(parent).filter((entry) => entry.startsWith(staleMarker)).map((entry) => path.join(parent, entry));
531
256
  await mkdir(dir, { recursive: true });
532
257
  if (stale.length > 0) {
533
258
  Bun.spawn(["rm", "-rf", ...stale], { stdout: "ignore", stderr: "ignore" });
@@ -536,692 +261,140 @@ async function emptyDir(dir) {
536
261
  function compatStaticRewrite(config, outputPath) {
537
262
  if (!nextCompatEnabled(config))
538
263
  return [];
539
- const staticDir = path2.join(outputPath, "static");
540
- const names = readdirSyncSafe(path2.join(staticDir, "assets")).filter((name) => !existsSync2(path2.join(staticDir, "_next", "static", name)));
264
+ const staticDir = path.join(outputPath, "static");
265
+ const names = readdirSyncSafe(path.join(staticDir, "assets")).filter((name) => !existsSync(path.join(staticDir, "_next", "static", name)));
541
266
  if (names.length === 0)
542
267
  return [];
543
268
  const alternation = names.map((name) => name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
544
- return [{ src: `^/_next/static/(${alternation})(/.*)?$`, dest: "/assets/$1$2", continue: true }];
545
- }
546
- function readdirSyncSafe(dir) {
547
- return existsSync2(dir) ? readdirSync(dir) : [];
548
- }
549
- async function proxyRoutes(config) {
550
- const proxyFile = findProxyFile(config);
551
- if (!proxyFile)
552
- return [];
553
- const proxyModule = await import(pathToFileHref(proxyFile));
554
- return [...proxyRoutePatterns(proxyModule.config), "^.*(?:%|//).*$"].map((src) => ({
555
- src,
556
- dest: `/${SERVER_FUNCTION}`
557
- }));
558
- }
559
- async function writeServerFunction(config, manifest, functionPath, warmedModules, warmSettled, log) {
560
- const workspaceRoot = config.workspaceRoot;
561
- await mkdir(functionPath, { recursive: true });
562
- const pack = packRules(config);
563
- const framework = await resolveFrameworkPackage(workspaceRoot);
564
- const { root: pnextRoot, inWorkspace: pnextInWorkspace, targetRel: pnextTargetRel } = framework;
565
- const release = releaseEntries(config, manifest);
566
- const prebundle = release ? readPrebundleStamp(pnextRoot, frameworkFingerprint()) : undefined;
567
- const closure = await traceNodeModulesClosure(config, manifest, functionPath, framework, [...warmedModules, ...release ?? []], pack, log, Boolean(release));
568
- const replicaPathFor = (file) => {
569
- if (isInsideDir(pnextRoot, file)) {
570
- return path2.join(functionPath, pnextTargetRel, path2.relative(pnextRoot, file));
571
- }
572
- if (isInsideDir(workspaceRoot, file)) {
573
- return path2.join(functionPath, path2.relative(workspaceRoot, file));
574
- }
575
- return;
576
- };
577
- const appRel = path2.relative(workspaceRoot, config.root);
578
- const packageRoots = workspacePackageRoots(workspaceRoot).map((root) => path2.resolve(root));
579
- const neededRoots = new Set;
580
- for (const file of closure.tracedFiles) {
581
- const root = packageRoots.find((candidate) => isInsideDir(candidate, file));
582
- if (root)
583
- neededRoots.add(root);
584
- }
585
- for (const relative of closure.workspacePackages) {
586
- neededRoots.add(path2.resolve(workspaceRoot, relative));
587
- }
588
- if (!release) {
589
- for (const file of globalCssSources(config)) {
590
- const root = packageRoots.find((candidate) => isInsideDir(candidate, file));
591
- if (root)
592
- neededRoots.add(root);
593
- }
594
- addWorkspaceDependencies(neededRoots, packageRoots, [path2.resolve(config.root), ...neededRoots]);
595
- }
596
- neededRoots.delete(path2.resolve(config.root));
597
- neededRoots.delete(pnextRoot);
598
- await log.step("await handler warm-up", () => warmSettled);
599
- const roots = neededRoots.size + 2;
600
- await log.step(`copy function tree (${closure.packageCount} packages, ${roots} roots)`, () => Promise.all([
601
- closure.copy(),
602
- copyTree(config.root, path2.join(functionPath, appRel), release ? { ...pack, compiled: releaseCompiledSources(config) } : pack, ["public", ".vercel", ".next", ".turbo"]),
603
- copyPackageTree(pnextRoot, path2.join(functionPath, pnextTargetRel), pack, prebundle && ["config", "dist", ...prebundle.source]),
604
- ...[...neededRoots].map((packageRoot) => copyPackageTree(packageRoot, path2.join(functionPath, path2.relative(workspaceRoot, packageRoot)), pack)),
605
- ...["package.json", "tsconfig.json", "bunfig.toml"].map((name) => path2.join(workspaceRoot, name)).filter((file) => existsSync2(file)).map((file) => copyFile(file, path2.join(functionPath, path2.basename(file))))
606
- ]));
607
- await log.step("rewrite baked paths", () => rewriteBakedPaths(path2.join(functionPath, appRel, path2.relative(config.root, config.outPath)), [
608
- ...pnextInWorkspace ? [] : [[pnextRoot, toPosixPath(path2.join(RUNTIME_ROOT, pnextTargetRel))]],
609
- [workspaceRoot, RUNTIME_ROOT]
610
- ]));
611
- await log.step("inject compat tsconfig paths", () => injectCompatPaths(config, functionPath, pnextRoot, replicaPathFor));
612
- const startEntry = toPosixPath(path2.join(pnextTargetRel, prebundle ? "dist/server/cli/start.js" : "src/cli/start.ts"));
613
- await writeText(path2.join(functionPath, "index.mjs"), `import path from 'node:path';
614
- import { createRequestHandler } from ${JSON.stringify(`./${startEntry}`)};
615
-
616
- const handlerPromise = createRequestHandler({
617
- root: path.join(import.meta.dirname, ${JSON.stringify(appRel)}),
618
- });
619
-
620
- async function handler(request) {
621
- return (await handlerPromise)(request);
622
- }
623
-
624
- // Callable for the Node-style launcher, \`fetch\` for the Bun runtime.
625
- export default Object.assign(handler, { fetch: handler });
626
- `);
627
- const maxDuration = manifest.routes.reduce((max, route) => route.maxDuration ? Math.max(max ?? 0, route.maxDuration) : max, undefined);
628
- await writeText(path2.join(functionPath, ".vc-config.json"), `${JSON.stringify({
629
- runtime: "bun1.4.x",
630
- handler: "index.mjs",
631
- launcherType: "Nodejs",
632
- architecture: FUNCTION_PLATFORM.architecture,
633
- useWebApi: true,
634
- supportsResponseStreaming: true,
635
- ...maxDuration ? { maxDuration } : {}
636
- }, null, 2)}
637
- `);
638
- }
639
- function addWorkspaceDependencies(roots, packageRoots, from) {
640
- const byName = new Map;
641
- for (const root of packageRoots) {
642
- const name = packageManifest(root)?.name;
643
- if (name && !byName.has(name))
644
- byName.set(name, root);
645
- }
646
- const queue = [...from];
647
- const seen = new Set(queue);
648
- while (queue.length > 0) {
649
- const manifest = packageManifest(queue.pop());
650
- if (!manifest)
651
- continue;
652
- for (const field of ["dependencies", "optionalDependencies"]) {
653
- for (const name of Object.keys(manifest[field] ?? {})) {
654
- const root = byName.get(name);
655
- if (!root || seen.has(root))
656
- continue;
657
- seen.add(root);
658
- roots.add(root);
659
- queue.push(root);
660
- }
661
- }
662
- }
663
- }
664
- var manifests = new Map;
665
- function packageManifest(root) {
666
- const cached = manifests.get(root);
667
- if (cached !== undefined || manifests.has(root))
668
- return cached;
669
- let parsed;
670
- try {
671
- parsed = JSON.parse(readFileSync2(path2.join(root, "package.json"), "utf8"));
672
- } catch {
673
- parsed = undefined;
674
- }
675
- manifests.set(root, parsed);
676
- return parsed;
677
- }
678
- async function copyTree(from, to, pack, excludeNames = [], visited = new Set([realDir(from) ?? path2.resolve(from)])) {
679
- const exclude = new Set(excludeNames);
680
- const clone = directoryCloneEnabled ? await directoryCloner() : null;
681
- if (exclude.size === 0 && !existsSync2(to)) {
682
- await mkdir(path2.dirname(to), { recursive: true });
683
- if (clone?.(from, to))
684
- return normalizeClone(to, from, pack, visited);
685
- }
686
- const entries = readDirEntries(from);
687
- if (!entries)
688
- return;
689
- await mkdir(to, { recursive: true });
690
- await Promise.all(entries.map(async (entry) => {
691
- const source = path2.join(from, entry.name);
692
- const target = path2.join(to, entry.name);
693
- if (exclude.has(entry.name) || !shipsDir(pack, entry.name, source, entry.isSymbolicLink()))
694
- return;
695
- if (entry.isSymbolicLink()) {
696
- const link2 = resolveLinkTarget(source);
697
- if (!link2)
698
- return;
699
- if (link2.isDirectory) {
700
- if (visited.has(link2.path))
701
- return;
702
- visited.add(link2.path);
703
- return copyTree(link2.path, target, pack, [], visited);
704
- }
705
- return shipsFile(pack, entry.name, source) ? linkOrCopyFile(link2.path, target) : undefined;
706
- }
707
- if (entry.isDirectory() && clone?.(source, target)) {
708
- return normalizeClone(target, source, pack, visited);
709
- }
710
- if (entry.isDirectory())
711
- return copyTree(source, target, pack, [], visited);
712
- if (entry.isFile() && shipsFile(pack, entry.name, source))
713
- return linkOrCopyFile(source, target);
714
- }));
715
- }
716
- function readDirEntries(dir) {
717
- try {
718
- return readdirSync(dir, { withFileTypes: true });
719
- } catch (error) {
720
- if (error.code === "ENOENT")
721
- return;
722
- throw error;
723
- }
724
- }
725
- var directoryCloneEnabled = true;
726
- var cloner;
727
- async function directoryCloner() {
728
- if (cloner !== undefined)
729
- return cloner;
730
- cloner = null;
731
- if (process.platform === "darwin") {
732
- try {
733
- const { dlopen } = await import("bun:ffi");
734
- const { symbols } = dlopen("libSystem.B.dylib", {
735
- clonefile: { args: ["cstring", "cstring", "i32"], returns: "i32" }
736
- });
737
- cloner = (from, to) => symbols.clonefile(Buffer.from(`${from}\x00`), Buffer.from(`${to}\x00`), 0) === 0;
738
- } catch {}
739
- }
740
- return cloner;
741
- }
742
- async function normalizeClone(dir, from, pack, visited) {
743
- const stack = [[dir, from]];
744
- const pending = [];
745
- while (stack.length > 0) {
746
- const [current, currentFrom] = stack.pop();
747
- for (const entry of readdirSync(current, { withFileTypes: true })) {
748
- const full = path2.join(current, entry.name);
749
- const source = path2.join(currentFrom, entry.name);
750
- if (!shipsDir(pack, entry.name, source, entry.isSymbolicLink())) {
751
- rmSync(full, { recursive: true, force: true });
752
- } else if (entry.isSymbolicLink()) {
753
- const link2 = resolveLinkTarget(source);
754
- rmSync(full, { force: true });
755
- if (!link2)
756
- continue;
757
- if (link2.isDirectory) {
758
- if (visited.has(link2.path))
759
- continue;
760
- visited.add(link2.path);
761
- pending.push(copyTree(link2.path, full, pack, [], visited));
762
- } else if (shipsFile(pack, entry.name, source)) {
763
- pending.push(linkOrCopyFile(link2.path, full));
764
- }
765
- } else if (entry.isDirectory()) {
766
- stack.push([full, source]);
767
- } else if (!shipsFile(pack, entry.name, source)) {
768
- rmSync(full, { force: true });
769
- }
770
- }
771
- }
772
- await Promise.all(pending);
773
- }
774
- async function resolveFrameworkPackage(workspaceRoot) {
775
- const root = path2.resolve(__PNEXT_PACKAGE_ROOT__ + "/src/cli/adapters", "../../..");
776
- const packageJson = await readPackageJson(root);
777
- const packageName = packageJson?.name ?? "pnext";
778
- const inWorkspace = isInsideDir(workspaceRoot, root) && !root.includes("node_modules");
779
- return {
780
- root,
781
- packageName,
782
- dependencies: Object.keys(packageJson?.dependencies ?? {}),
783
- optionalDependencies: Object.keys(packageJson?.optionalDependencies ?? {}),
784
- inWorkspace,
785
- targetRel: inWorkspace ? path2.relative(workspaceRoot, root) : path2.join("node_modules", packageName)
786
- };
787
- }
788
- var packageCopyExcludes = [
789
- "node_modules",
790
- ".cache",
791
- ".vercel",
792
- ".next",
793
- ".pnext",
794
- ".turbo",
795
- "test",
796
- "tests",
797
- "__tests__"
798
- ];
799
- async function copyPackageTree(from, to, pack, only) {
800
- const files = only ?? (await readPackageJson(from))?.files;
801
- if (!files?.length || files.some((entry) => /[*?[\]{}!]/.test(entry))) {
802
- return copyTree(from, to, pack, packageCopyExcludes);
803
- }
804
- await mkdir(to, { recursive: true });
805
- await Promise.all([...files, "package.json", "tsconfig.json"].map(async (name) => {
806
- const source = path2.join(from, name);
807
- const stats = statSync(source, { throwIfNoEntry: false });
808
- if (!stats)
809
- return;
810
- if (stats.isDirectory())
811
- return copyTree(source, path2.join(to, name), pack);
812
- if (!shipsFile(pack, name, source))
813
- return;
814
- await mkdir(path2.dirname(path2.join(to, name)), { recursive: true });
815
- return linkOrCopyFile(source, path2.join(to, name));
816
- }));
817
- }
818
- async function readPackageJson(dir) {
819
- const file = path2.join(dir, "package.json");
820
- if (!existsSync2(file))
821
- return;
822
- return JSON.parse(await readFile(file, "utf8"));
823
- }
824
- var dependencyClosureEnabled = true;
825
- function skipDependencyClosure() {
826
- return !dependencyClosureEnabled;
827
- }
828
- async function linkOrCopyFile(from, to) {
829
- try {
830
- await link(from, to);
831
- } catch {
832
- await copyFile(from, to).catch((error) => {
833
- if (error.code !== "ENOENT")
834
- throw error;
835
- });
836
- }
837
- }
838
- function resolveLinkTarget(link2) {
839
- const resolved = realDir(link2) ?? realFile(link2);
840
- if (!resolved)
841
- return;
842
- try {
843
- return { path: resolved, isDirectory: statSync(resolved).isDirectory() };
844
- } catch {
845
- return;
846
- }
847
- }
848
- function realFile(file) {
849
- try {
850
- return realpathSync2(file);
851
- } catch {
852
- return;
853
- }
269
+ return [{ src: `^/_next/static/(${alternation})(/.*)?$`, dest: "/assets/$1$2", continue: true }];
854
270
  }
855
- function isInsideDir(root, file) {
856
- const relative = path2.relative(root, file);
857
- return relative === "" || !relative.startsWith("..") && !path2.isAbsolute(relative);
271
+ function readdirSyncSafe(dir) {
272
+ return existsSync(dir) ? readdirSync(dir) : [];
858
273
  }
859
- function isFrameworkOwnedAliasTarget(frameworkRoot2, target) {
860
- if (!path2.isAbsolute(target) || !isInsideDir(frameworkRoot2, target))
861
- return false;
862
- return !path2.relative(frameworkRoot2, target).split(path2.sep).includes("node_modules");
274
+ async function proxyRoutes(config) {
275
+ const proxyFile = findProxyFile(config);
276
+ if (!proxyFile)
277
+ return [];
278
+ const proxyModule = await import(pathToFileHref(proxyFile));
279
+ return [...proxyRoutePatterns(proxyModule.config), "^.*(?:%|//).*$"].map((src) => ({
280
+ src,
281
+ dest: `/${SERVER_FUNCTION}`
282
+ }));
863
283
  }
864
- function frameworkOwnedAliases(config, frameworkRoot2) {
865
- return Object.entries(getImportAliasExtensions().aliases(config, "server")).filter(([, target]) => isFrameworkOwnedAliasTarget(frameworkRoot2, target));
284
+ async function writeServerFunction(standalonePath, manifest, functionPath, log) {
285
+ await mkdir(path.dirname(functionPath), { recursive: true });
286
+ await log.step("copy standalone", () => cp(standalonePath, functionPath, { recursive: true, verbatimSymlinks: true }));
287
+ const modules = path.join(functionPath, "node_modules");
288
+ const packages = await packageDirs(modules);
289
+ await Promise.all([...packages].filter(([name]) => functionDroppedPackages.some((pattern) => pattern.test(name))).map(([, dirs]) => Promise.all(dirs.map((dir) => rm(dir, { recursive: true, force: true })))));
290
+ await log.step("platform natives", () => replaceHostNatives(packages, log));
291
+ await writeText(path.join(functionPath, "index.mjs"), `import { createRequestHandler } from './server/entry.js';
292
+
293
+ const handlerPromise = createRequestHandler({ root: import.meta.dirname });
294
+
295
+ async function handler(request) {
296
+ return (await handlerPromise)(request);
866
297
  }
867
- async function injectCompatPaths(config, functionPath, frameworkRoot2, replicaPathFor) {
868
- const aliasTargets = frameworkOwnedAliases(config, frameworkRoot2).map(([specifier, target]) => [specifier, replicaPathFor(target)]).filter((entry) => Boolean(entry[1]));
869
- if (aliasTargets.length === 0)
870
- return;
871
- for (const file of walkTsconfigFiles(functionPath)) {
872
- let parsed;
873
- try {
874
- const source = stripJsonComments(await readFile(file, "utf8")).replace(/,\s*([}\]])/g, "$1");
875
- parsed = JSON.parse(source);
876
- } catch (error) {
877
- console.warn(`vercel adapter: could not update ${file}:`, error);
878
- continue;
879
- }
880
- const dir = path2.dirname(file);
881
- const compilerOptions = parsed.compilerOptions ??= {};
882
- const paths = compilerOptions.paths ??= {};
883
- for (const [specifier, target] of aliasTargets) {
884
- if (paths[specifier])
885
- continue;
886
- const relative = toPosixPath(path2.relative(dir, target));
887
- paths[specifier] = [relative.startsWith(".") ? relative : `./${relative}`];
888
- }
889
- compilerOptions.baseUrl ??= ".";
890
- await rm(file);
891
- await writeFile(file, `${JSON.stringify(parsed, null, 2)}
298
+
299
+ // Callable for the Node-style launcher, \`fetch\` for the Bun runtime.
300
+ export default Object.assign(handler, { fetch: handler });
301
+ `);
302
+ const maxDuration = manifest.routes.reduce((max, route) => route.maxDuration ? Math.max(max ?? 0, route.maxDuration) : max, undefined);
303
+ await writeText(path.join(functionPath, ".vc-config.json"), `${JSON.stringify({
304
+ runtime: "bun1.4.x",
305
+ handler: "index.mjs",
306
+ launcherType: "Nodejs",
307
+ architecture: FUNCTION_PLATFORM.architecture,
308
+ useWebApi: true,
309
+ supportsResponseStreaming: true,
310
+ ...maxDuration ? { maxDuration } : {}
311
+ }, null, 2)}
892
312
  `);
893
- }
894
313
  }
895
- function stripJsonComments(source) {
896
- let result = "";
897
- let inString = false;
898
- for (let index = 0;index < source.length; index++) {
899
- const char = source[index];
900
- if (inString) {
901
- result += char;
902
- if (char === "\\") {
903
- result += source[++index] ?? "";
904
- } else if (char === '"') {
905
- inString = false;
314
+ async function packageDirs(modules) {
315
+ const found = new Map;
316
+ const visit = async (dir, depth) => {
317
+ const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
318
+ for (const entry of entries) {
319
+ if (!entry.isDirectory())
320
+ continue;
321
+ const full = path.join(dir, entry.name);
322
+ if (entry.name === ".bun" || entry.name === ".pnpm") {
323
+ for (const store of await readdir(full, { withFileTypes: true }).catch(() => []))
324
+ if (store.isDirectory())
325
+ await visit(path.join(full, store.name, "node_modules"), 0);
326
+ } else if (entry.name.startsWith("@") && depth === 0) {
327
+ await visit(full, 1);
328
+ } else if (existsSync(path.join(full, "package.json"))) {
329
+ const name = depth === 1 ? `${path.basename(dir)}/${entry.name}` : entry.name;
330
+ found.set(name, [...found.get(name) ?? [], full]);
331
+ await visit(path.join(full, "node_modules"), 0);
906
332
  }
907
- continue;
908
- }
909
- if (char === '"') {
910
- inString = true;
911
- result += char;
912
- continue;
913
- }
914
- if (char === "/" && source[index + 1] === "/") {
915
- while (index < source.length && source[index] !== `
916
- `)
917
- index++;
918
- result += `
919
- `;
920
- continue;
921
- }
922
- if (char === "/" && source[index + 1] === "*") {
923
- index += 2;
924
- while (index < source.length && !(source[index] === "*" && source[index + 1] === "/"))
925
- index++;
926
- index++;
927
- continue;
928
333
  }
929
- result += char;
930
- }
931
- return result;
334
+ };
335
+ await visit(modules, 0);
336
+ return found;
932
337
  }
933
- var bakedPathFileFilter = /\.(?:m?js|cjs|jsx|tsx?|json|html|css)$/;
934
- var BAKED_PATH_CONCURRENCY = 64;
935
- async function rewriteBakedPaths(dir, replacements) {
936
- if (!existsSync2(dir))
338
+ async function readPackageJson(dir) {
339
+ try {
340
+ return JSON.parse(await readFile(path.join(dir, "package.json"), "utf8"));
341
+ } catch {
937
342
  return;
938
- const files = (await listFiles(dir)).filter((file) => bakedPathFileFilter.test(file));
939
- for (let i = 0;i < files.length; i += BAKED_PATH_CONCURRENCY) {
940
- await Promise.all(files.slice(i, i + BAKED_PATH_CONCURRENCY).map(async (file) => {
941
- const source = await readFile(file, "utf8");
942
- let rewritten = source;
943
- for (const [from, to] of replacements) {
944
- if (rewritten.includes(from))
945
- rewritten = rewritten.replaceAll(from, to);
946
- }
947
- if (rewritten === source)
948
- return;
949
- await rm(file);
950
- await writeFile(file, rewritten);
951
- }));
952
343
  }
953
344
  }
954
- async function artifactSpecifiers(file) {
955
- const sidecar = await readFile(`${file}${compiledSpecifiersManifestSuffix}`, "utf8").catch(() => null);
956
- if (sidecar !== null) {
957
- try {
958
- const parsed = JSON.parse(sidecar);
959
- if (Array.isArray(parsed) && parsed.every((entry) => typeof entry === "string")) {
960
- return parsed;
961
- }
962
- } catch {}
345
+ async function replaceHostNatives(packages, log) {
346
+ const manifests = new Map;
347
+ for (const [name, dirs] of packages) {
348
+ const json = await readPackageJson(dirs[0]);
349
+ if (json)
350
+ manifests.set(name, json);
963
351
  }
964
- const source = await readFile(file, "utf8").catch(() => null);
965
- return source === null ? null : importSpecifiers(source, file);
966
- }
967
- async function traceNodeModulesClosure(config, manifest, functionPath, framework, warmedModules, pack, log, release = false) {
968
- const workspaceRoot = config.workspaceRoot;
969
- const specifiers = new Set;
970
- const tracedFiles = new Set;
971
- const hrefPackageDirs = new Set;
972
- const frameworkAliasedSpecifiers = new Set(frameworkOwnedAliases(config, path2.resolve(framework.root)).map(([specifier]) => specifier));
973
- await log.step("trace runtime imports", async () => {
974
- const queue2 = [];
975
- const seen2 = tracedFiles;
976
- const enqueue = (file) => {
977
- if (!file)
978
- return;
979
- const resolved = path2.resolve(file);
980
- if (seen2.has(resolved) || !existsSync2(resolved))
981
- return;
982
- seen2.add(resolved);
983
- queue2.push(resolved);
984
- };
985
- if (!release) {
986
- for (const route of manifest.routes) {
987
- if (route.kind === "handler")
988
- enqueue(route.file);
989
- }
990
- enqueue(findProxyFile(config) ?? undefined);
991
- enqueue(path2.join(config.root, "pnext.config.ts"));
992
- enqueue(path2.join(config.root, "next.config.js"));
993
- }
994
- for (const file of warmedModules)
995
- enqueue(file);
996
- const visit = async (file) => {
997
- if (!scriptFilePattern.test(file))
998
- return;
999
- const found = await artifactSpecifiers(file);
1000
- if (found === null)
1001
- return;
1002
- for (const specifier of found) {
1003
- if (frameworkAliasedSpecifiers.has(specifier))
1004
- continue;
1005
- const absolute = absolutePathFromSpecifier(specifier);
1006
- if (absolute && isInsideDir(framework.root, absolute))
1007
- continue;
1008
- if (absolute) {
1009
- const name2 = packageNameFromPath(absolute);
1010
- if (name2) {
1011
- specifiers.add(name2);
1012
- hrefPackageDirs.add(packageDirFromPath(absolute, name2));
1013
- } else if (isInsideDir(config.outPath, absolute))
1014
- enqueue(absolute);
1015
- continue;
1016
- }
1017
- if (/^(?:node:|bun$|bun:|data:)/.test(specifier))
1018
- continue;
1019
- const resolved = resolveImport(config.root, file, specifier, config.workspaceRoot);
1020
- if (resolved && isInsideDir(workspaceRoot, resolved) && !resolved.includes("node_modules")) {
1021
- enqueue(resolved);
1022
- }
1023
- const installed = specifier.startsWith(".") && resolved && packageNameFromPath(resolved);
1024
- if (installed) {
1025
- specifiers.add(installed);
1026
- hrefPackageDirs.add(packageDirFromPath(resolved, installed));
1027
- }
1028
- const name = packageNameFromSpecifier(specifier);
1029
- if (name)
1030
- specifiers.add(name);
1031
- }
1032
- };
1033
- const READ_BATCH = 64;
1034
- for (let frontier = queue2.splice(0);frontier.length > 0; frontier = queue2.splice(0)) {
1035
- for (let index = 0;index < frontier.length; index += READ_BATCH) {
1036
- await Promise.all(frontier.slice(index, index + READ_BATCH).map(visit));
1037
- }
1038
- }
1039
- log.log(`traced ${seen2.size} runtime modules`);
1040
- });
1041
- const packageDirs = new Map;
1042
- const nestedCopies = new Map;
1043
- const workspaceLinks = new Map;
1044
352
  const hostNatives = new Map;
1045
- const appDependencies = await declaredDependencies(config.root);
1046
- const runtimeDependencies = release ? await frameworkRuntimePackages(framework.root) : undefined;
1047
- const queue = [
1048
- ...framework.dependencies.filter((name) => !runtimeDependencies || runtimeDependencies.has(name)).map((name) => ({ name, from: framework.root })),
1049
- ...framework.optionalDependencies.filter((name) => appDependencies.has(name)).map((name) => ({ name, from: framework.root })),
1050
- ...[...specifiers].map((name) => ({ name, from: workspaceRoot }))
1051
- ];
1052
- const seen = new Set;
1053
- while (queue.length > 0) {
1054
- const { name, from, owner } = queue.shift();
1055
- if (seen.has(name))
1056
- continue;
1057
- seen.add(name);
1058
- if (name === framework.packageName) {
1059
- if (framework.inWorkspace)
1060
- workspaceLinks.set(name, framework.targetRel);
1061
- continue;
1062
- }
1063
- const dir = resolvePackageDir(name, [from, workspaceRoot, config.root]);
1064
- if (!dir)
353
+ for (const [name, json] of manifests) {
354
+ if (!(json.os ?? json.cpu) || matchesFunctionPlatform(json))
1065
355
  continue;
1066
- const workspaceRelative = path2.relative(workspaceRoot, dir);
1067
- if (!workspaceRelative.startsWith("..") && !workspaceRelative.startsWith("node_modules")) {
1068
- workspaceLinks.set(name, workspaceRelative);
1069
- continue;
1070
- }
1071
- const packageJson = await readPackageJson(dir);
1072
- const platformBound = Boolean(packageJson?.os ?? packageJson?.cpu);
1073
- if (packageJson && platformBound && !matchesFunctionPlatform(packageJson)) {
1074
- hostNatives.set(name, { dir, owner });
1075
- continue;
1076
- }
1077
- packageDirs.set(name, dir);
1078
- if (!packageJson)
1079
- continue;
1080
- const expand = async (packageDir, packageJson2, target) => {
1081
- const self = { name: packageJson2?.name ?? name, version: packageJson2?.version ?? "" };
1082
- for (const dependency of [
1083
- ...Object.keys(packageJson2?.dependencies ?? {}),
1084
- ...Object.keys(packageJson2?.optionalDependencies ?? {})
1085
- ]) {
1086
- const nested = path2.join(packageDir, "node_modules", dependency);
1087
- const nestedJson = existsSync2(path2.join(nested, "package.json")) ? await readPackageJson(nested) : undefined;
1088
- if (!nestedJson || nestedJson.os || nestedJson.cpu) {
1089
- queue.push({ name: dependency, from: packageDir, owner: self });
1090
- continue;
1091
- }
1092
- const nestedTarget = path2.join(target, "node_modules", dependency);
1093
- if (nestedCopies.has(nestedTarget))
1094
- continue;
1095
- nestedCopies.set(nestedTarget, nested);
1096
- await expand(nested, nestedJson, nestedTarget);
1097
- }
1098
- };
1099
- await expand(dir, packageJson, path2.join("node_modules", name));
1100
- }
1101
- if (hostNatives.size > 0 && !skipDependencyClosure()) {
1102
- const targets = await log.step(`resolve ${FUNCTION_PLATFORM.os}-${FUNCTION_PLATFORM.cpu} natives (${hostNatives.size} packages)`, () => platformNativePackages(hostNatives, log));
1103
- for (const [name, dir] of targets)
1104
- packageDirs.set(name, dir);
1105
- }
1106
- const copy = async () => {
1107
- const entries = skipDependencyClosure() ? [] : [...packageDirs];
1108
- const batchSize = 16;
1109
- for (let index = 0;index < entries.length; index += batchSize) {
1110
- await Promise.all(entries.slice(index, index + batchSize).map(async ([name, dir]) => {
1111
- const target = path2.join(functionPath, "node_modules", name);
1112
- await mkdir(path2.dirname(target), { recursive: true });
1113
- await copyTree(dir, target, pack);
1114
- }));
1115
- }
1116
- for (const [target, dir] of skipDependencyClosure() ? [] : nestedCopies) {
1117
- await mkdir(path2.dirname(path2.join(functionPath, target)), { recursive: true });
1118
- await copyTree(dir, path2.join(functionPath, target), pack);
1119
- }
1120
- for (const dir of skipDependencyClosure() ? [] : hrefPackageDirs) {
1121
- const relative = path2.relative(workspaceRoot, dir);
1122
- const target = path2.join(functionPath, relative);
1123
- if (relative.startsWith("..") || existsSync2(target))
1124
- continue;
1125
- await mkdir(path2.dirname(target), { recursive: true });
1126
- await copyTree(dir, target, pack);
1127
- }
1128
- for (const [name, workspaceRelative] of workspaceLinks) {
1129
- const linkPath = path2.join(functionPath, "node_modules", name);
1130
- await mkdir(path2.dirname(linkPath), { recursive: true });
1131
- const target = path2.relative(path2.dirname(linkPath), path2.join(functionPath, workspaceRelative));
1132
- if (!existsSync2(linkPath))
1133
- await symlink(target, linkPath, "dir");
1134
- }
1135
- };
1136
- return {
1137
- tracedFiles,
1138
- workspacePackages: [...workspaceLinks.values()],
1139
- packageCount: packageDirs.size,
1140
- copy
1141
- };
1142
- }
1143
- function releaseEntries(config, manifest) {
1144
- if (!existsSync2(buildIndexFile(config.outPath)))
1145
- return;
1146
- const index = readBuildIndex(config.outPath);
1147
- return [
1148
- ...Object.values(index.modules),
1149
- index.nextConfig,
1150
- index.instrumentation?.file,
1151
- index.instrumentation?.edge,
1152
- ...Object.values(index.compat?.cacheHandlers ?? {}),
1153
- manifest.proxyModule
1154
- ].filter((artifact) => artifact !== undefined).map((artifact) => path2.resolve(config.outPath, artifact));
1155
- }
1156
- async function frameworkRuntimePackages(frameworkRoot2) {
1157
- const src = path2.join(frameworkRoot2, "src");
1158
- const scanners = {
1159
- ts: new Bun.Transpiler({ loader: "ts" }),
1160
- tsx: new Bun.Transpiler({ loader: "tsx" })
1161
- };
1162
- const queue = [
1163
- ...runtimeEntryFiles.map((file) => path2.join(src, file)),
1164
- ...runtimeEntryDirs.flatMap((dir) => listSourceFiles(path2.join(src, dir)).filter((file) => /(?<!\.d)\.tsx?$/.test(file)))
1165
- ];
1166
- const seen = new Set(queue);
1167
- const packages = new Set;
1168
- for (const file of queue) {
1169
- const scanner = file.endsWith(".tsx") || file.endsWith(".jsx") ? scanners.tsx : scanners.ts;
1170
- for (const edge of scanner.scanImports(await readFile(file, "utf8"))) {
1171
- if (edge.kind !== "import-statement" && edge.kind !== "dynamic-import")
1172
- continue;
1173
- if (!edge.path.startsWith(".")) {
1174
- const name = packageNameFromSpecifier(edge.path);
1175
- if (name)
1176
- packages.add(name);
1177
- continue;
1178
- }
1179
- const target = resolveFrom(edge.path, path2.dirname(file));
1180
- if (target && !seen.has(target) && isInsideDir(src, target) && scriptFilePattern.test(target)) {
1181
- seen.add(target);
1182
- queue.push(target);
1183
- }
1184
- }
356
+ const owner = [...manifests].find(([, candidate]) => candidate.optionalDependencies?.[name]);
357
+ hostNatives.set(name, {
358
+ dirs: packages.get(name),
359
+ owner: owner && { name: owner[0], version: owner[1].version ?? "" }
360
+ });
1185
361
  }
1186
- return packages;
1187
- }
1188
- function resolveFrom(specifier, dir) {
1189
- try {
1190
- return Bun.resolveSync(specifier, dir);
1191
- } catch {
362
+ if (hostNatives.size === 0)
1192
363
  return;
364
+ const targets = await platformNativePackages(hostNatives, manifests, log);
365
+ for (const [name, dir] of targets) {
366
+ for (const host of hostNatives.get(name)?.dirs ?? []) {
367
+ const target = path.join(path.dirname(host), name.split("/").at(-1));
368
+ await rm(host, { recursive: true, force: true });
369
+ await cp(dir, target, { recursive: true, dereference: true });
370
+ }
1193
371
  }
1194
372
  }
1195
- function listSourceFiles(dir) {
1196
- return readdirSync(dir, { withFileTypes: true }).flatMap((entry) => entry.isDirectory() ? listSourceFiles(path2.join(dir, entry.name)) : [path2.join(dir, entry.name)]);
1197
- }
1198
- async function platformNativePackages(hostNatives, log) {
373
+ async function platformNativePackages(hostNatives, manifests, log) {
1199
374
  const owners = new Map;
1200
- for (const [name, { dir, owner }] of hostNatives) {
1201
- const spec = owner ?? { name, version: (await readPackageJson(dir))?.version ?? "" };
375
+ for (const [name, { owner }] of hostNatives) {
376
+ const spec = owner ?? { name, version: manifests.get(name)?.version ?? "" };
1202
377
  if (spec.version)
1203
378
  owners.set(spec.name, spec.version);
1204
379
  }
1205
380
  const specs = [...owners].map(([name, version]) => `${name}@${version}`).sort();
1206
- const fallback = () => new Map([...hostNatives].map(([name, { dir }]) => [name, dir]));
1207
381
  if (specs.length === 0)
1208
- return fallback();
382
+ return new Map;
1209
383
  try {
1210
384
  const installed = await crossPlatformInstall(specs);
1211
385
  const matches = new Map;
1212
386
  for (const [name, dir] of installed) {
1213
- const packageJson = await readPackageJson(dir);
1214
- if (packageJson && matchesFunctionPlatform(packageJson))
387
+ const json = await readPackageJson(dir);
388
+ if (json && (json.os ?? json.cpu) && matchesFunctionPlatform(json))
1215
389
  matches.set(name, dir);
1216
390
  }
1217
- if (matches.size === 0) {
391
+ if (matches.size === 0)
1218
392
  throw new Error(`no ${FUNCTION_PLATFORM.os} builds in ${specs.join(" ")}`);
1219
- }
1220
393
  return matches;
1221
394
  } catch (error) {
1222
395
  console.warn(`vercel adapter: could not fetch ${FUNCTION_PLATFORM.os}-${FUNCTION_PLATFORM.cpu} native packages; the function will carry this machine's builds and fail at runtime:`, error);
1223
396
  log.log("falling back to host native packages");
1224
- return fallback();
397
+ return new Map;
1225
398
  }
1226
399
  }
1227
400
  function matchesFunctionPlatform(packageJson) {
@@ -1236,13 +409,13 @@ function matchesFunctionPlatform(packageJson) {
1236
409
  }
1237
410
  async function crossPlatformInstall(specs) {
1238
411
  const key = Bun.hash.xxHash3(`${FUNCTION_PLATFORM.os}-${FUNCTION_PLATFORM.cpu}\x00${specs.join("\x00")}`).toString(16);
1239
- const dir = path2.join(cacheRoot(), "vercel-natives", key);
1240
- const modules = path2.join(dir, "node_modules");
1241
- if (!existsSync2(modules)) {
412
+ const dir = path.join(cacheRoot(), "vercel-natives", key);
413
+ const modules = path.join(dir, "node_modules");
414
+ if (!existsSync(modules)) {
1242
415
  const staging = `${dir}.${process.pid.toString(36)}`;
1243
416
  await rm(staging, { recursive: true, force: true });
1244
417
  await mkdir(staging, { recursive: true });
1245
- await writeText(path2.join(staging, "package.json"), `{"name":"pnext-natives"}
418
+ await writeText(path.join(staging, "package.json"), `{"name":"pnext-natives"}
1246
419
  `);
1247
420
  const install = Bun.spawn([
1248
421
  "bun",
@@ -1267,101 +440,25 @@ async function crossPlatformInstall(specs) {
1267
440
  if (entry.startsWith("."))
1268
441
  continue;
1269
442
  if (!entry.startsWith("@")) {
1270
- installed.set(entry, path2.join(modules, entry));
443
+ installed.set(entry, path.join(modules, entry));
1271
444
  continue;
1272
445
  }
1273
- for (const scoped of readdirSync(path2.join(modules, entry))) {
1274
- installed.set(`${entry}/${scoped}`, path2.join(modules, entry, scoped));
446
+ for (const scoped of readdirSync(path.join(modules, entry))) {
447
+ installed.set(`${entry}/${scoped}`, path.join(modules, entry, scoped));
1275
448
  }
1276
449
  }
1277
450
  return installed;
1278
451
  }
1279
- var scriptFilePattern = /\.(?:m?js|cjs|jsx|tsx?)$/;
1280
- var skippedScanDirs = new Set(["node_modules", ".git", ".next", ".pnext", ".turbo", ".vercel"]);
1281
- function* walkTsconfigFiles(root) {
1282
- const stack = [root];
1283
- while (stack.length > 0) {
1284
- const dir = stack.pop();
1285
- for (const entry of readdirSync(dir, { withFileTypes: true })) {
1286
- const full = path2.join(dir, entry.name);
1287
- if (entry.isDirectory()) {
1288
- if (!skippedScanDirs.has(entry.name))
1289
- stack.push(full);
1290
- } else if (entry.isFile() && entry.name === "tsconfig.json") {
1291
- yield full;
1292
- }
1293
- }
1294
- }
1295
- }
1296
- async function declaredDependencies(root) {
1297
- const packageJson = await readPackageJson(root);
1298
- return new Set(["dependencies", "optionalDependencies", "devDependencies"].flatMap((field) => Object.keys(packageJson?.[field] ?? {})));
1299
- }
1300
- function absolutePathFromSpecifier(specifier) {
1301
- if (specifier.startsWith("file://"))
1302
- return fileURLToPath2(specifier);
1303
- return path2.isAbsolute(specifier) ? specifier : undefined;
1304
- }
1305
- function packageDirFromPath(file, name) {
1306
- const posix = toPosixPath(file);
1307
- const marker = `/node_modules/${name}/`;
1308
- return posix.slice(0, posix.lastIndexOf(marker) + marker.length - 1);
1309
- }
1310
- function packageNameFromPath(file) {
1311
- const parts = toPosixPath(file).split("/node_modules/");
1312
- const tail = parts.at(-1);
1313
- if (parts.length < 2 || !tail)
1314
- return;
1315
- const segments = tail.split("/");
1316
- return segments[0]?.startsWith("@") ? segments.slice(0, 2).join("/") : segments[0];
1317
- }
1318
- function packageNameFromSpecifier(specifier) {
1319
- if (/^[./#]|^file:|^node:|^data:/.test(specifier))
1320
- return;
1321
- if (specifier === "bun" || specifier.startsWith("bun:"))
1322
- return;
1323
- if (specifier.includes(":"))
1324
- return;
1325
- if (specifier.startsWith("@") && !/^@[^/]+\/[^/]+/.test(specifier))
1326
- return;
1327
- const parts = specifier.split("/");
1328
- const name = specifier.startsWith("@") ? parts.slice(0, 2).join("/") : parts[0];
1329
- if (!name || builtinModules.includes(name))
1330
- return;
1331
- return name;
1332
- }
1333
- function resolvePackageDir(name, fromDirs) {
1334
- for (const from of fromDirs) {
1335
- let dir = path2.resolve(from);
1336
- while (true) {
1337
- const candidate = path2.join(dir, "node_modules", name);
1338
- if (existsSync2(path2.join(candidate, "package.json")))
1339
- return realDir(candidate);
1340
- const parent = path2.dirname(dir);
1341
- if (parent === dir)
1342
- break;
1343
- dir = parent;
1344
- }
1345
- }
1346
- return;
1347
- }
1348
- function realDir(dir) {
1349
- try {
1350
- return statSync(dir).isDirectory() ? realpathSync2(dir) : undefined;
1351
- } catch {
1352
- return;
1353
- }
1354
- }
1355
452
  async function copyStaticFiles(from, to, shouldCopy = () => true) {
1356
- const files = (await listFiles(from)).filter((file) => shouldCopy(toPosixPath(path2.relative(from, file))));
1357
- const directories = new Set(files.map((file) => path2.dirname(path2.join(to, path2.relative(from, file)))));
453
+ const files = (await listFiles(from)).filter((file) => shouldCopy(toPosixPath(path.relative(from, file))));
454
+ const directories = new Set(files.map((file) => path.dirname(path.join(to, path.relative(from, file)))));
1358
455
  await Promise.all([...directories].map((dir) => mkdir(dir, { recursive: true })));
1359
- await Promise.all(files.map((file) => linkOrCopyFile(file, path2.join(to, path2.relative(from, file)))));
456
+ await Promise.all(files.map((file) => copyFile(file, path.join(to, path.relative(from, file)), constants.COPYFILE_FICLONE)));
1360
457
  }
1361
458
  async function staticOverrides(publicPath, staticFiles) {
1362
459
  const overrides = {};
1363
460
  for (const file of await listFiles(publicPath)) {
1364
- const relative = toPosixPath(path2.relative(publicPath, file));
461
+ const relative = toPosixPath(path.relative(publicPath, file));
1365
462
  if (!relative.endsWith("/index.html"))
1366
463
  continue;
1367
464
  overrides[relative] = { path: relative.replace(/\/index\.html$/, "") };
@@ -1377,9 +474,9 @@ async function staticOverrides(publicPath, staticFiles) {
1377
474
  }
1378
475
  async function immutableAssetRoutes(publicDir, publicAssets = []) {
1379
476
  const app = new Set(publicAssets);
1380
- const built = publicAssets.length > 0 ? (await listFiles(publicDir)).map((file) => toPosixPath(path2.relative(publicDir, file))).filter((relative) => !app.has(relative) && immutableAssetPath(relative)) : [];
477
+ const built = publicAssets.length > 0 ? (await listFiles(publicDir)).map((file) => toPosixPath(path.relative(publicDir, file))).filter((relative) => !app.has(relative) && immutableAssetPath(relative)) : [];
1381
478
  const patterns = immutableAssetPatterns(built, publicAssets);
1382
- return routeSources(patterns, (source) => `^/(?:${source})`).map((src) => ({
479
+ return routeSources(patterns, (source) => `^/(?:${source})$`).map((src) => ({
1383
480
  src,
1384
481
  headers: { "cache-control": immutableCacheControl },
1385
482
  continue: true,
@@ -1389,13 +486,13 @@ async function immutableAssetRoutes(publicDir, publicAssets = []) {
1389
486
  function immutableAssetPatterns(built, publicAssets) {
1390
487
  const appDirs = new Set(publicAssets.flatMap(ancestorDirs));
1391
488
  const prefixes = [...new Set(immutableAssetPrefixes())];
1392
- const patterns = prefixes.filter((prefix) => !appDirs.has(prefix)).map(escapeRegex);
489
+ const patterns = prefixes.filter((prefix) => !appDirs.has(prefix)).map((prefix) => `${escapeRegex(prefix)}.+`);
1393
490
  for (const relative of built) {
1394
491
  const prefix = prefixes.find((prefix2) => relative.startsWith(prefix2));
1395
492
  if (!prefix || !appDirs.has(prefix))
1396
493
  continue;
1397
494
  const dir = ancestorDirs(relative).find((dir2) => dir2.length > prefix.length && !appDirs.has(dir2));
1398
- patterns.push(dir ? escapeRegex(requestPath(dir)) : `${escapeRegex(requestPath(relative))}$`);
495
+ patterns.push(dir ? `${escapeRegex(requestPath(dir))}.+` : escapeRegex(requestPath(relative)));
1399
496
  }
1400
497
  return [...new Set(patterns)];
1401
498
  }
@@ -1437,33 +534,199 @@ function staticHeaderRoutes(staticFiles) {
1437
534
  groups.set(key, group);
1438
535
  group.patterns.push(servedPathPattern(relative));
1439
536
  }
1440
- return [...groups.values()].flatMap(({ headers, patterns }) => routeSources(patterns, (source) => `^/(?:${source})$`).map((src) => ({
1441
- src,
1442
- methods: ["GET", "HEAD"],
1443
- headers,
1444
- continue: true,
1445
- important: true
1446
- })));
537
+ return [...groups.values()].flatMap(({ headers, patterns }) => routeSources(patterns, (source) => `^/(?:${source})$`).map((src) => ({
538
+ src,
539
+ methods: ["GET", "HEAD"],
540
+ headers,
541
+ continue: true,
542
+ important: true
543
+ })));
544
+ }
545
+ function routeSources(patterns, wrap) {
546
+ const sources = [];
547
+ for (const pattern of patterns) {
548
+ const last = sources.length - 1;
549
+ if (last >= 0 && wrap(`${sources[last]}|${pattern}`).length <= maxRouteSourceLength) {
550
+ sources[last] += `|${pattern}`;
551
+ } else {
552
+ sources.push(pattern);
553
+ }
554
+ }
555
+ return sources.map(wrap);
556
+ }
557
+ function servedPathPattern(relative) {
558
+ if (relative === "index.html")
559
+ return "(?:index\\.html)?";
560
+ if (!relative.endsWith("/index.html"))
561
+ return escapeRegex(relative);
562
+ return `${escapeRegex(relative.slice(0, -"/index.html".length))}(?:/|/index\\.html)?`;
563
+ }
564
+
565
+ // src/cli/adapters/vercel-warm.ts
566
+ import { fileURLToPath } from "url";
567
+
568
+ // src/runtime/release-graph.ts
569
+ import { existsSync as existsSync2, readFileSync, realpathSync } from "fs";
570
+ import path2 from "path";
571
+ var layerDirs = {
572
+ "server:server": "rsc",
573
+ "client:client": "ssr"
574
+ };
575
+ var layers = Object.keys(layerDirs);
576
+ var frameworkRoot = realpathSync(path2.resolve(__PNEXT_PACKAGE_ROOT__ + "/src/runtime", "..", ".."));
577
+
578
+ // src/cli/adapters/vercel-warm.ts
579
+ var DONE_MARKER = "pnext-warm-done:";
580
+ var COMPILED_MARKER = "pnext-warm-compiled";
581
+ var ATTEMPT_TIMEOUT_MS = 10 * 60000;
582
+ var MAX_ATTEMPTS = 3;
583
+ var FULL_MODE_FLAG = "--full";
584
+ function startWarmChild(config, mode = "full") {
585
+ const children = new Set;
586
+ let disposed = false;
587
+ const spawn = () => {
588
+ if (disposed)
589
+ return;
590
+ const child = spawnWarmProcess(config, mode);
591
+ if (!child)
592
+ return;
593
+ children.add(child);
594
+ child.exited.finally(() => children.delete(child));
595
+ forwardWarmStderr(child);
596
+ return child;
597
+ };
598
+ const killOnExit = () => kill();
599
+ const kill = () => {
600
+ if (disposed)
601
+ return;
602
+ disposed = true;
603
+ process.off("exit", killOnExit);
604
+ for (const child of children)
605
+ child.kill();
606
+ children.clear();
607
+ };
608
+ process.once("exit", killOnExit);
609
+ const first = spawn();
610
+ return {
611
+ prewarm(files) {
612
+ if (!first || files.length === 0)
613
+ return;
614
+ try {
615
+ first.stdin.write(`${JSON.stringify({ prewarm: files })}
616
+ `);
617
+ first.stdin.flush();
618
+ } catch {}
619
+ },
620
+ finish: (log, onCompiled, facts = { clientReferences: [] }) => warmWithRestarts(first, spawn, mode, log, facts, onCompiled).finally(kill),
621
+ kill
622
+ };
623
+ }
624
+ async function forwardWarmStderr(child) {
625
+ try {
626
+ const reader = child.stderr.getReader();
627
+ for (;; ) {
628
+ const { done, value } = await reader.read();
629
+ if (done)
630
+ return;
631
+ process.stderr.write(value);
632
+ }
633
+ } catch {}
634
+ }
635
+ function spawnWarmProcess(config, mode) {
636
+ const entry = fileURLToPath(new URL(Bun.pathToFileURL(__PNEXT_PACKAGE_ROOT__ + "/src/cli/adapters/vercel-warm.ts").href));
637
+ const argv = mode === "full" ? [config.root, FULL_MODE_FLAG] : [config.root];
638
+ try {
639
+ return Bun.spawn([namedBunBinary("pnext-warm"), "--conditions=react-server", entry, ...argv], {
640
+ cwd: config.root,
641
+ stdin: "pipe",
642
+ stdout: "pipe",
643
+ stderr: "pipe",
644
+ env: process.env
645
+ });
646
+ } catch {
647
+ return;
648
+ }
1447
649
  }
1448
- function routeSources(patterns, wrap) {
1449
- const sources = [];
1450
- for (const pattern of patterns) {
1451
- const last = sources.length - 1;
1452
- if (last >= 0 && wrap(`${sources[last]}|${pattern}`).length <= maxRouteSourceLength) {
1453
- sources[last] += `|${pattern}`;
1454
- } else {
1455
- sources.push(pattern);
650
+ async function warmWithRestarts(first, spawn, mode, log, facts, onCompiled) {
651
+ const finished = new Map;
652
+ const compiled = () => [...finished.values()].filter((file) => Boolean(file));
653
+ let fired = false;
654
+ const fireOnCompiled = onCompiled ? () => {
655
+ if (fired)
656
+ return;
657
+ fired = true;
658
+ onCompiled(compiled());
659
+ } : undefined;
660
+ let child = first;
661
+ for (let attempt = 1;attempt <= MAX_ATTEMPTS && child; attempt++) {
662
+ const before = finished.size;
663
+ const failure = await runAttempt(child, {
664
+ skip: [...finished.keys()],
665
+ compiled: Object.fromEntries([...finished].filter((entry) => Boolean(entry[1]))),
666
+ ...facts
667
+ }, finished, fireOnCompiled);
668
+ if (!failure) {
669
+ log.log(`warmed ${compiled().length} modules`);
670
+ return compiled();
1456
671
  }
672
+ child = finished.size > before && attempt < MAX_ATTEMPTS ? spawn() : undefined;
673
+ if (child)
674
+ log.log(`warm-up ${failure} after ${finished.size} files; restarting past them`);
675
+ else
676
+ warmIncomplete(failure, finished.size, mode);
1457
677
  }
1458
- return sources.map(wrap);
678
+ fireOnCompiled?.();
679
+ return compiled();
1459
680
  }
1460
- function servedPathPattern(relative) {
1461
- if (relative === "index.html")
1462
- return "(?:index\\.html)?";
1463
- if (!relative.endsWith("/index.html"))
1464
- return escapeRegex(relative);
1465
- return `${escapeRegex(relative.slice(0, -"/index.html".length))}(?:/|/index\\.html)?`;
681
+ async function runAttempt(child, request, finished, onCompiled) {
682
+ try {
683
+ child.stdin.write(`${JSON.stringify(request)}
684
+ `);
685
+ child.stdin.end();
686
+ } catch {}
687
+ const timeout = setTimeout(() => child.kill("SIGKILL"), ATTEMPT_TIMEOUT_MS);
688
+ timeout.unref?.();
689
+ const processLine = (line) => {
690
+ if (!line)
691
+ return;
692
+ if (line === COMPILED_MARKER) {
693
+ onCompiled?.();
694
+ return;
695
+ }
696
+ if (!line.startsWith(DONE_MARKER)) {
697
+ console.log(line);
698
+ return;
699
+ }
700
+ const [source, artifact] = line.slice(DONE_MARKER.length).split("\t");
701
+ if (source)
702
+ finished.set(source, artifact || undefined);
703
+ };
704
+ const reader = child.stdout.getReader();
705
+ const decoder = new TextDecoder;
706
+ let buffer = "";
707
+ for (;; ) {
708
+ const { done, value } = await reader.read();
709
+ if (done)
710
+ break;
711
+ buffer += decoder.decode(value, { stream: true });
712
+ let newline;
713
+ while ((newline = buffer.indexOf(`
714
+ `)) >= 0) {
715
+ processLine(buffer.slice(0, newline));
716
+ buffer = buffer.slice(newline + 1);
717
+ }
718
+ }
719
+ if (buffer)
720
+ processLine(buffer);
721
+ const code = await child.exited.finally(() => clearTimeout(timeout));
722
+ if (code === 0)
723
+ return;
724
+ return child.signalCode ? `was killed by ${child.signalCode}` : `exited with code ${code}`;
725
+ }
726
+ function warmIncomplete(failure, done, mode) {
727
+ console.warn(`pnext build: module warm-up ${failure} after warming ${done} file(s). ` + (mode === "full" ? "The function ships without the rest of its module cache and may fail to render those " + "routes at request time, where Vercel's filesystem is read-only." : "The production server compiles the rest on the first request that needs them."));
1466
728
  }
729
+ if (false) {}
1467
730
 
1468
731
  // src/cli/build.ts
1469
732
  import { runWithCacheScope } from "../../../src/request/cache.ts";
@@ -1471,10 +734,10 @@ import { runWithCacheScope } from "../../../src/request/cache.ts";
1471
734
  // src/cli/build/cache.ts
1472
735
  import { createHash } from "crypto";
1473
736
  import { existsSync as existsSync3 } from "fs";
1474
- import { lstat, mkdir as mkdir2, readFile as readFile2, readdir, readlink } from "fs/promises";
737
+ import { lstat, mkdir as mkdir2, readFile as readFile2, readdir as readdir2, readlink } from "fs/promises";
1475
738
  import path3 from "path";
1476
739
  var CACHE_VERSION = 2;
1477
- var CACHE_SEGMENTS = ["cache", "build"];
740
+ var CACHE_SEGMENTS = ["build"];
1478
741
  var SKIP_INPUT_DIRS = new Set([
1479
742
  ".claude",
1480
743
  ".git",
@@ -1511,7 +774,7 @@ async function lookupBuildCache(config, options) {
1511
774
  return { enabled: true, context, inputs, reason: `output (${changed || "unknown"})` };
1512
775
  }
1513
776
  try {
1514
- const manifest = resolveManifest(JSON.parse(await readFile2(path3.join(config.outPath, "manifest.json"), "utf8")), config.outPath, config.root);
777
+ const manifest = resolveManifest(JSON.parse(await readFile2(buildManifestFile(config.outPath), "utf8")), config.outPath, config.root);
1515
778
  return { enabled: true, context, inputs, manifest, reason: "hit" };
1516
779
  } catch {
1517
780
  return { enabled: true, context, inputs, reason: "manifest" };
@@ -1538,7 +801,7 @@ function cacheEnabled(options) {
1538
801
  return options.adapter === undefined && options.debugBuildPaths === undefined && options.buildMode === undefined && options.debugPrerender !== true;
1539
802
  }
1540
803
  function cacheDir(outPath) {
1541
- return path3.join(outPath, ...CACHE_SEGMENTS);
804
+ return path3.join(outCachePath(outPath), ...CACHE_SEGMENTS);
1542
805
  }
1543
806
  function recordFile(outPath) {
1544
807
  return path3.join(cacheDir(outPath), "result.json");
@@ -1605,7 +868,7 @@ async function inputRecords(config, previous) {
1605
868
  async function collectModuleGraphInputs(config, files) {
1606
869
  let parsed;
1607
870
  try {
1608
- parsed = JSON.parse(await readFile2(path3.join(config.outPath, "cache", "server", "graph.json"), "utf8"));
871
+ parsed = JSON.parse(await readFile2(path3.join(outCachePath(config.outPath), "server", "graph.json"), "utf8"));
1609
872
  } catch {
1610
873
  return;
1611
874
  }
@@ -1618,7 +881,7 @@ async function collectModuleGraphInputs(config, files) {
1618
881
  }
1619
882
  }
1620
883
  async function collectTree(root, prefix, files, outPath, dir = root) {
1621
- const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
884
+ const entries = await readdir2(dir, { withFileTypes: true }).catch(() => []);
1622
885
  await Promise.all(entries.map(async (entry) => {
1623
886
  const file = path3.join(dir, entry.name);
1624
887
  if (file === outPath || file.startsWith(`${outPath}${path3.sep}`))
@@ -1643,7 +906,7 @@ function addFile(files, key, file) {
1643
906
  }
1644
907
  async function outputSnapshot(outPath) {
1645
908
  const files = new Map;
1646
- const entries = await readdir(outPath, { withFileTypes: true }).catch(() => []);
909
+ const entries = await readdir2(outPath, { withFileTypes: true }).catch(() => []);
1647
910
  await Promise.all(entries.map(async (entry) => {
1648
911
  if (entry.name === "cache" || entry.name === "dev")
1649
912
  return;
@@ -1669,7 +932,7 @@ function changedFiles(before, after) {
1669
932
  return [...new Set([...Object.keys(before), ...Object.keys(after)])].filter((file) => before[file] !== after[file]);
1670
933
  }
1671
934
  async function collectOutputTree(root, dir, files) {
1672
- const entries = await readdir(dir, { withFileTypes: true });
935
+ const entries = await readdir2(dir, { withFileTypes: true });
1673
936
  await Promise.all(entries.map(async (entry) => {
1674
937
  const file = path3.join(dir, entry.name);
1675
938
  if (entry.isDirectory())
@@ -1686,32 +949,581 @@ function toPosix(file) {
1686
949
  return path3.sep === "/" ? file : file.split(path3.sep).join("/");
1687
950
  }
1688
951
 
1689
- // src/cli/serve/entry.ts
1690
- import { readFileSync as readFileSync3 } from "fs";
1691
- import { mkdir as mkdir3, writeFile as writeFile2 } from "fs/promises";
952
+ // src/cli/serve/standalone.ts
953
+ import { createHash as createHash2 } from "crypto";
954
+ import { constants as constants2, existsSync as existsSync4, readFileSync as readFileSync2, readdirSync as readdirSync2, realpathSync as realpathSync2, statSync } from "fs";
955
+ import { copyFile as copyFile2, mkdir as mkdir3, readFile as readFile3, rename as rename2, rm as rm2, writeFile } from "fs/promises";
956
+ import { builtinModules } from "module";
1692
957
  import path4 from "path";
1693
- var frameworkRoot2 = path4.resolve(__PNEXT_PACKAGE_ROOT__ + "/src/cli/serve", "..", "..", "..");
1694
- function frameworkVersion() {
958
+ import { fileURLToPath as fileURLToPath2, pathToFileURL } from "url";
959
+ var frameworkRoot2 = realpathSync2(path4.resolve(__PNEXT_PACKAGE_ROOT__ + "/src/cli/serve", "..", "..", ".."));
960
+ var frameworkPackage = JSON.parse(readFileSync2(path4.join(frameworkRoot2, "package.json"), "utf8"));
961
+ var runtimeDependencies = new Set(Object.keys(frameworkPackage.dependencies ?? {}));
962
+ var buildOnlyModule = /^(?:build|modules|loader|compile|esbuild|dev|run|typegen|analyze|create)$/;
963
+ var builtins = new Set(builtinModules);
964
+ var scriptFile = /\.(?:[cm]?[jt]sx?)$/;
965
+ function frameworkStartEntry() {
966
+ return readPrebundleStamp(frameworkRoot2, frameworkFingerprint()) ? path4.join(frameworkRoot2, "dist", "server", "cli", "start.js") : path4.join(frameworkRoot2, "src", "cli", "start.ts");
967
+ }
968
+ function startStandalone(config) {
969
+ const input = {
970
+ outPath: config.outPath,
971
+ root: config.root,
972
+ workspaceRoot: config.workspaceRoot
973
+ };
974
+ const modules = path4.join(config.workspaceRoot, "node_modules");
975
+ const cacheFile = existsSync4(modules) && path4.join(modules, ".cache", "pnext", `standalone-${frameworkTraceKey()}.json`);
976
+ if (cacheFile && existsSync4(cacheFile)) {
977
+ try {
978
+ return Promise.resolve(JSON.parse(readFileSync2(cacheFile, "utf8")));
979
+ } catch {}
980
+ }
981
+ const framework = new Promise((resolve, reject) => {
982
+ const worker = new Worker(new URL("./standalone-worker.ts", Bun.pathToFileURL(__PNEXT_PACKAGE_ROOT__ + "/src/cli/serve/standalone.ts").href));
983
+ worker.unref?.();
984
+ worker.onmessage = (event) => {
985
+ resolve(event.data);
986
+ worker.terminate();
987
+ };
988
+ worker.onerror = (event) => {
989
+ reject(new Error(event.message));
990
+ worker.terminate();
991
+ };
992
+ worker.postMessage(input);
993
+ }).catch(() => traceFramework(input));
994
+ if (cacheFile)
995
+ framework.then(async (snapshot) => {
996
+ await mkdir3(path4.dirname(cacheFile), { recursive: true });
997
+ const temporary = `${cacheFile}.${process.pid}.tmp`;
998
+ await writeFile(temporary, JSON.stringify(snapshot));
999
+ await rename2(temporary, cacheFile);
1000
+ }).catch(() => {
1001
+ return;
1002
+ });
1003
+ return framework;
1004
+ }
1005
+ function frameworkTraceKey() {
1006
+ const startEntry = frameworkStartEntry();
1007
+ const packages = [...runtimeDependencies, ...frameworkRuntimeSpecifiers()].map((specifier) => {
1008
+ const file = resolveEdge(specifier, startEntry);
1009
+ return file ? `${file}\x00${statSync(file).mtimeMs}` : specifier;
1010
+ });
1011
+ return createHash2("sha256").update(JSON.stringify([frameworkFingerprint(), startEntry, packages])).digest("hex").slice(0, 16);
1012
+ }
1013
+ async function traceFramework(config) {
1014
+ const tracer = createTracer(config);
1015
+ const startEntry = frameworkStartEntry();
1016
+ await tracer.add([
1017
+ { file: startEntry, app: false },
1018
+ ...frameworkRuntimeSpecifiers().flatMap((specifier) => {
1019
+ const file = resolveEdge(specifier, startEntry);
1020
+ return file ? [{ file, app: false }] : [];
1021
+ })
1022
+ ]);
1023
+ return tracer.snapshot();
1024
+ }
1025
+ async function writeStandalone(config, framework = startStandalone(config)) {
1026
+ const outPath = config.outPath;
1027
+ const cache = cacheRoot2(outPath);
1028
+ const index = readBuildIndex(outPath);
1029
+ const manifestFile = buildManifestFile(outPath);
1030
+ const manifest = JSON.parse(await readFile3(manifestFile, "utf8"));
1031
+ const startEntry = frameworkStartEntry();
1032
+ const snapshot = await framework;
1033
+ const copier = createCopier(outPath);
1034
+ const rewrittenFramework = new Map(snapshot.rewritten);
1035
+ for (const [dest, source] of snapshot.files)
1036
+ copier.copy(dest, source, rewrittenFramework.get(dest));
1037
+ const tracer = createTracer(config, snapshot, (dest) => copier.copy(dest, tracer.trace.files.get(dest), tracer.trace.rewritten.get(dest)));
1038
+ const { trace, place } = tracer;
1039
+ await tracer.add([
1040
+ ...Object.values(index.modules),
1041
+ ...index.dependencies ?? [],
1042
+ index.nextConfig,
1043
+ index.instrumentation?.file,
1044
+ index.instrumentation?.edge,
1045
+ ...Object.values(index.compat?.cacheHandlers ?? {}),
1046
+ ...Object.values(index.fonts ?? {}).flatMap((font) => font.files),
1047
+ manifest.proxyModule,
1048
+ ...(manifest.actions ?? []).map((action) => action.modulePath)
1049
+ ].flatMap((artifact) => artifact ? [{ file: path4.resolve(outPath, artifact), app: true }] : []));
1050
+ addAppFiles(config, index, trace);
1051
+ tracer.flush();
1052
+ await copier.settle();
1053
+ const cachePrefix = `${toPosixPath(path4.relative(outPath, cache))}/`;
1054
+ const relocate = (value) => {
1055
+ if (typeof value === "string")
1056
+ return value.startsWith(cachePrefix) ? `server/${value.slice(cachePrefix.length)}` : value;
1057
+ if (Array.isArray(value))
1058
+ return value.map(relocate);
1059
+ if (value && typeof value === "object")
1060
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, relocate(item)]));
1061
+ return value;
1062
+ };
1063
+ const indexFile = buildIndexFile(outPath);
1064
+ await writeFile(indexFile, JSON.stringify(relocate(JSON.parse(await readFile3(indexFile, "utf8")))));
1065
+ const shippedManifest = relocate(JSON.parse(await readFile3(manifestFile, "utf8")));
1066
+ for (const route of shippedManifest.routes) {
1067
+ if (route.sourceFiles)
1068
+ route.sourceFiles = route.sourceFiles.filter((file) => !file.startsWith("../"));
1069
+ }
1070
+ await writeFile(manifestFile, `${JSON.stringify(shippedManifest, null, 2)}
1071
+ `);
1072
+ await writeFile(path4.join(outPath, "server", "entry.js"), `export * from ${JSON.stringify(relativeSpecifier("server", place(startEntry)))}
1073
+ `);
1074
+ await writeFile(path4.join(outPath, "package.json"), `{ "type": "module" }
1075
+ `);
1076
+ const origins = Object.fromEntries([...trace.files].filter(([dest]) => dest.startsWith("node_modules/")));
1077
+ const originsFile = standaloneOriginsFile(outPath);
1078
+ await mkdir3(path4.dirname(originsFile), { recursive: true });
1079
+ await writeFile(originsFile, JSON.stringify({ release: outPath, origins }));
1080
+ }
1081
+ function setFile(trace, dest, source) {
1082
+ if (!trace.files.has(dest))
1083
+ trace.fresh.push(dest);
1084
+ trace.files.set(dest, source);
1085
+ }
1086
+ function createTracer(config, from, onReady) {
1087
+ const outPath = config.outPath;
1088
+ const cache = cacheRoot2(outPath);
1089
+ const trace = {
1090
+ files: new Map(from?.files),
1091
+ fresh: [],
1092
+ rewritten: new Map(from?.rewritten)
1093
+ };
1094
+ const claims = new Map(from?.claims);
1095
+ const place = createPlacer(outPath, cache, claims);
1096
+ const standalones = new Set(from?.standalones);
1097
+ const shipped = (file) => installed(file) || isInside(frameworkRoot2, file) && !isInside(config.root, file);
1098
+ const seen = new Set(from?.seen);
1099
+ const reads = new Map;
1100
+ const prefetch = (file) => {
1101
+ if (scriptFile.test(file) && !reads.has(file))
1102
+ reads.set(file, readFile3(file, "utf8").catch(() => {
1103
+ return;
1104
+ }));
1105
+ };
1106
+ const queue = [];
1107
+ const enqueue = (file, app) => {
1108
+ if (seen.has(`${app}\x00${file}`))
1109
+ return;
1110
+ queue.push({ file, app });
1111
+ prefetch(file);
1112
+ };
1113
+ const flush = () => {
1114
+ for (const dest of trace.fresh.splice(0))
1115
+ onReady?.(dest);
1116
+ };
1117
+ const run = async (items) => {
1118
+ for (const item of items)
1119
+ enqueue(item.file, item.app);
1120
+ for (let item = queue.shift();item; item = queue.shift(), flush()) {
1121
+ const { file, app } = item;
1122
+ if (seen.has(`${app}\x00${file}`))
1123
+ continue;
1124
+ seen.add(`${app}\x00${file}`);
1125
+ const nested = enclosingStandalone(file, outPath);
1126
+ if (nested) {
1127
+ if (!standalones.has(nested)) {
1128
+ standalones.add(nested);
1129
+ addTree(nested, path4.posix.dirname(path4.posix.dirname(place(path4.join(nested, "server", "entry.js")))), trace);
1130
+ }
1131
+ continue;
1132
+ }
1133
+ const dest = place(file);
1134
+ setFile(trace, dest, file);
1135
+ if (!isInside(outPath, file) && !isInside(cache, file))
1136
+ addPackageFiles(file, trace, place);
1137
+ if (!scriptFile.test(file))
1138
+ continue;
1139
+ const release = isInside(outPath, file) || isInside(cache, file);
1140
+ const framework = !release && isInside(frameworkRoot2, file) && !installedIn(frameworkRoot2, file);
1141
+ prefetch(file);
1142
+ const source = await reads.get(file);
1143
+ if (source === undefined)
1144
+ continue;
1145
+ const edits = new Map;
1146
+ for (const edge of scanEdges(file, source)) {
1147
+ if (edge.url) {
1148
+ const target2 = urlTarget(edge.specifier, file);
1149
+ if (!target2)
1150
+ continue;
1151
+ const appFile = release && !isInside(outPath, target2) && !isInside(cache, target2) && !shipped(target2);
1152
+ if (appFile && scriptFile.test(target2))
1153
+ continue;
1154
+ const stat = statSync(target2, { throwIfNoEntry: false });
1155
+ if (stat?.isDirectory() && !release && packageDataDir(target2, file))
1156
+ for (const asset of dataFiles(target2))
1157
+ setFile(trace, place(asset), asset);
1158
+ if (!stat?.isFile())
1159
+ continue;
1160
+ const at = appFile ? toPosixPath(path4.join("server", "assets", path4.relative(config.workspaceRoot, target2))) : place(target2);
1161
+ if (appFile)
1162
+ setFile(trace, at, target2);
1163
+ else
1164
+ enqueue(target2, release);
1165
+ if (release) {
1166
+ const relative = relativeSpecifier(path4.dirname(dest), at);
1167
+ if (relative !== edge.specifier)
1168
+ edits.set(edge.specifier, relative);
1169
+ }
1170
+ continue;
1171
+ }
1172
+ const bare = isPackageSpecifier(edge.specifier);
1173
+ const name = bare ? packageName(edge.specifier) : undefined;
1174
+ if (bare && !name && !edge.specifier.startsWith("#"))
1175
+ continue;
1176
+ if (name && framework && !app && (edge.require || !runtimeDependencies.has(name)))
1177
+ continue;
1178
+ const target = resolveEdge(edge.specifier, file, edge.require);
1179
+ if (!target)
1180
+ continue;
1181
+ if (edge.dynamic && framework && buildOnlyModule.test(moduleName(target)))
1182
+ continue;
1183
+ enqueue(target, release);
1184
+ for (const counterpart of frameworkCounterparts(target))
1185
+ enqueue(counterpart, release);
1186
+ if (release || name && !place(target).startsWith(`node_modules/${name}/`)) {
1187
+ const relative = relativeSpecifier(path4.dirname(dest), place(target));
1188
+ if (relative !== edge.specifier)
1189
+ edits.set(edge.specifier, relative);
1190
+ }
1191
+ }
1192
+ if (edits.size > 0)
1193
+ trace.rewritten.set(dest, rewriteSpecifiers(file, source, edits));
1194
+ }
1195
+ flush();
1196
+ };
1197
+ const snapshot = () => ({
1198
+ files: [...trace.files],
1199
+ rewritten: [...trace.rewritten],
1200
+ seen: [...seen],
1201
+ claims: [...claims],
1202
+ standalones: [...standalones]
1203
+ });
1204
+ return { trace, place, add: run, snapshot, flush };
1205
+ }
1206
+ var prunedDirNames = [
1207
+ "node_modules",
1208
+ ".git",
1209
+ ".next",
1210
+ ".pnext",
1211
+ ".turbo",
1212
+ ".cache",
1213
+ ".vercel",
1214
+ ".tmp"
1215
+ ];
1216
+ var standaloneEntries = new Set(["server", "static", "node_modules", "package.json"]);
1217
+ function addAppFiles(config, index, trace) {
1218
+ const { keep = [], exclude = [] } = config.adapter ?? {};
1219
+ const named = (entries, name) => entries.some((entry) => name === entry || entry.startsWith(".") && name.endsWith(entry));
1220
+ for (const dest of trace.files.keys()) {
1221
+ const segments = dest.split("/");
1222
+ if (dest.startsWith("node_modules/") && segments.some((name) => named(exclude, name)))
1223
+ trace.files.delete(dest);
1224
+ }
1225
+ if (keep.length === 0)
1226
+ return;
1227
+ const compiled = compiledSources(config, index);
1228
+ const outTop = path4.relative(config.root, config.outRootPath).split(path4.sep)[0];
1229
+ const visit = (dir, kept) => {
1230
+ for (const entry of readdirSync2(dir, { withFileTypes: true })) {
1231
+ const file = path4.join(dir, entry.name);
1232
+ if (entry.isDirectory()) {
1233
+ const pruned = prunedDirNames.includes(entry.name) && !named(keep, entry.name);
1234
+ if (pruned || dir === config.root && entry.name === outTop)
1235
+ continue;
1236
+ visit(file, kept || named(keep, entry.name));
1237
+ continue;
1238
+ }
1239
+ if (!entry.isFile() || compiled.has(file) && !named(keep, entry.name))
1240
+ continue;
1241
+ const env = entry.name.startsWith(".env");
1242
+ if (env ? !keep.includes(entry.name) : !kept && !named(keep, entry.name))
1243
+ continue;
1244
+ const relative = toPosixPath(path4.relative(config.root, file));
1245
+ if (!standaloneEntries.has(relative.split("/")[0]))
1246
+ setFile(trace, relative, file);
1247
+ }
1248
+ };
1249
+ visit(config.root, false);
1250
+ }
1251
+ function compiledSources(config, index) {
1252
+ flushDevModuleCaches();
1253
+ const graph = compiledSourceGraph(config.outPath, config.workspaceRoot);
1254
+ const queue = Object.keys(index.modules).map((key) => releaseSourceFile(key.slice(key.indexOf(":", key.indexOf(":") + 1) + 1), config.root, config.workspaceRoot));
1255
+ if (index.proxy)
1256
+ queue.push(path4.resolve(config.root, index.proxy.file));
1257
+ for (const name of readdirSync2(config.root))
1258
+ if (/^(?:pnext|next|instrumentation)\.config\.|^instrumentation\./.test(name) && scriptFile.test(name))
1259
+ queue.push(path4.join(config.root, name));
1260
+ const compiled = new Set;
1261
+ for (const file of queue) {
1262
+ if (compiled.has(file))
1263
+ continue;
1264
+ compiled.add(file);
1265
+ queue.push(...graph.get(file) ?? []);
1266
+ }
1267
+ for (const css of index.globalCss)
1268
+ compiled.add(path4.resolve(config.root, css));
1269
+ return compiled;
1270
+ }
1271
+ function createPlacer(outPath, cache, claims = new Map) {
1272
+ const packageDir = (root, name) => {
1273
+ const owner = claims.get(name);
1274
+ if (owner === undefined)
1275
+ claims.set(name, root);
1276
+ if (owner === undefined || owner === root)
1277
+ return `node_modules/${name}`;
1278
+ const key = createHash2("sha256").update(root).digest("hex").slice(0, 12);
1279
+ return `node_modules/.pnext/${key}/node_modules/${name}`;
1280
+ };
1281
+ return (file) => {
1282
+ if (isInside(cache, file))
1283
+ return toPosixPath(path4.join("server", path4.relative(cache, file)));
1284
+ if (isInside(outPath, file))
1285
+ return toPosixPath(path4.relative(outPath, file));
1286
+ const framework = !installed(frameworkRoot2) && isInside(frameworkRoot2, file) && !installedIn(frameworkRoot2, file);
1287
+ if (framework) {
1288
+ const dir = packageDir(frameworkRoot2, frameworkPackage.name);
1289
+ return `${dir}/${toPosixPath(path4.relative(frameworkRoot2, file))}`;
1290
+ }
1291
+ const owner = installedPackage(file);
1292
+ if (owner)
1293
+ return [packageDir(owner.root, owner.name), ...owner.rest].join("/");
1294
+ const root = packageRoot(path4.dirname(file));
1295
+ const name = root && readPackageName(root);
1296
+ if (!root || !name)
1297
+ throw new Error(`pnext build: cannot place ${file} in the standalone output`);
1298
+ return `${packageDir(root, name)}/${toPosixPath(path4.relative(root, file))}`;
1299
+ };
1300
+ }
1301
+ var standaloneDirs = new Map;
1302
+ function enclosingStandalone(file, outPath) {
1303
+ const dir = path4.dirname(file);
1304
+ if (dir === path4.dirname(dir))
1305
+ return;
1306
+ if (standaloneDirs.has(dir))
1307
+ return standaloneDirs.get(dir);
1308
+ const own = dir !== outPath && existsSync4(path4.join(dir, "server", "build-index.json")) && existsSync4(path4.join(dir, "server", "entry.js"));
1309
+ const found = own ? dir : enclosingStandalone(dir, outPath);
1310
+ standaloneDirs.set(dir, found);
1311
+ return found;
1312
+ }
1313
+ function addTree(root, dest, trace) {
1314
+ const visit = (dir, seen) => {
1315
+ const real = realpathSync2(dir);
1316
+ if (seen.has(real))
1317
+ return;
1318
+ seen.add(real);
1319
+ for (const name of readdirSync2(dir)) {
1320
+ const file = path4.join(dir, name);
1321
+ const stat = statSync(file, { throwIfNoEntry: false });
1322
+ if (stat?.isDirectory())
1323
+ visit(file, seen);
1324
+ else if (stat?.isFile())
1325
+ setFile(trace, `${dest}/${toPosixPath(path4.relative(root, file))}`, realpathSync2(file));
1326
+ }
1327
+ };
1328
+ visit(root, new Set);
1329
+ }
1330
+ function installedPackage(file) {
1331
+ const posix = toPosixPath(file);
1332
+ const at = posix.lastIndexOf("/node_modules/");
1333
+ if (at === -1)
1334
+ return;
1335
+ const rest = posix.slice(at + "/node_modules/".length).split("/");
1336
+ const length = rest[0].startsWith("@") ? 2 : 1;
1337
+ const name = rest.slice(0, length).join("/");
1338
+ return { root: `${posix.slice(0, at)}/node_modules/${name}`, name, rest: rest.slice(length) };
1339
+ }
1340
+ function installed(file) {
1341
+ return toPosixPath(file).includes("/node_modules/");
1342
+ }
1343
+ function installedIn(root, file) {
1344
+ return path4.relative(root, file).split(path4.sep).includes("node_modules");
1345
+ }
1346
+ var transpilers = new Map;
1347
+ function scanEdges(file, source) {
1348
+ const ext = path4.extname(file);
1349
+ const loader = ext === ".tsx" || ext === ".jsx" ? "tsx" : /\.[cm]?ts$/.test(ext) ? "ts" : "js";
1350
+ let transpiler = transpilers.get(loader);
1351
+ if (!transpiler) {
1352
+ transpiler = new Bun.Transpiler({
1353
+ loader,
1354
+ tsconfig: { compilerOptions: { jsx: "react-jsx", jsxImportSource: "preact" } }
1355
+ });
1356
+ transpilers.set(loader, transpiler);
1357
+ }
1358
+ let imports;
1359
+ try {
1360
+ imports = transpiler.scanImports(source);
1361
+ } catch {
1362
+ return [];
1363
+ }
1364
+ const edges = imports.map((entry) => ({
1365
+ specifier: entry.path,
1366
+ dynamic: entry.kind === "dynamic-import",
1367
+ require: entry.kind === "require-call"
1368
+ }));
1369
+ const refs = importMetaRefs(file, source);
1370
+ for (const url of refs.urls)
1371
+ edges.push({ specifier: url.specifier, dynamic: false, url: true });
1372
+ for (const ref of refs.resolves)
1373
+ edges.push({ specifier: ref.specifier, dynamic: false });
1374
+ if (loader === "tsx")
1375
+ edges.push({ specifier: "preact/jsx-runtime", dynamic: false }, { specifier: "preact/jsx-dev-runtime", dynamic: false });
1376
+ return edges;
1377
+ }
1378
+ var resolved = new Map;
1379
+ function resolveEdge(specifier, from, require2 = false) {
1380
+ if (/^(?:node:|bun:|data:|https?:)/.test(specifier) || specifier === "bun")
1381
+ return;
1382
+ const bare = require2 ? specifier : splitResourceQuery(specifier).path;
1383
+ if (builtins.has(bare))
1384
+ return;
1385
+ const dir = path4.dirname(from);
1386
+ const key = `${dir}\x00${bare}`;
1387
+ if (resolved.has(key))
1388
+ return resolved.get(key);
1389
+ let target;
1695
1390
  try {
1696
- const pkg = readFileSync3(path4.join(frameworkRoot2, "package.json"), "utf8");
1697
- return JSON.parse(pkg).version ?? "0";
1391
+ const request = bare.startsWith("file:") ? fileURLToPath2(bare) : bare;
1392
+ target = realpathSync2(Bun.resolveSync(request, dir));
1393
+ if (!statSync(target).isFile())
1394
+ target = undefined;
1698
1395
  } catch {
1699
- return "0";
1396
+ target = undefined;
1700
1397
  }
1398
+ resolved.set(key, target);
1399
+ return target;
1400
+ }
1401
+ function frameworkCounterparts(file) {
1402
+ const counterpart = prebundledFile(file);
1403
+ if (counterpart === file)
1404
+ return [];
1405
+ return [counterpart, path4.join(frameworkRoot2, PREBUNDLE_STAMP)];
1701
1406
  }
1702
- function serverEntryDir(outPath) {
1703
- const generation = frameworkFingerprint(path4.join(outPath, "cache", "server"));
1704
- return path4.join(outPath, "server", `bundle-${frameworkVersion()}-${generation}`);
1407
+ function moduleName(file) {
1408
+ const base = path4.basename(file, path4.extname(file));
1409
+ const chunk = path4.basename(path4.dirname(file)) === "_chunks";
1410
+ return chunk && isInside(path4.join(frameworkRoot2, "dist"), file) ? base.replace(/-[a-z0-9]{8}$/, "") : base;
1705
1411
  }
1706
- async function emitServerEntry(outPath) {
1707
- const start = await Bun.file(path4.join(__PNEXT_PACKAGE_ROOT__ + "/src/cli/serve", "..", "start.ts")).text();
1708
- const names = new Bun.Transpiler({ loader: "ts" }).scan(start).exports;
1709
- const dir = serverEntryDir(outPath);
1710
- const target = readPrebundleStamp(frameworkRoot2, frameworkFingerprint()) ? "../dist/server/cli/start.js" : "./cli/start.ts";
1711
- await mkdir3(dir, { recursive: true });
1712
- await writeFile2(path4.join(dir, "entry.js"), `const pnext = await import(new URL('${target}', import.meta.resolve('@wular/pnext')).href)
1713
- ` + `export const { ${names.join(", ")} } = pnext
1714
- `);
1412
+ function packageName(specifier) {
1413
+ if (specifier.startsWith("#"))
1414
+ return;
1415
+ const parts = specifier.split("/");
1416
+ const name = specifier.startsWith("@") ? parts.slice(0, 2).join("/") : parts[0];
1417
+ return name && !builtins.has(name) ? name : undefined;
1418
+ }
1419
+ function addPackageFiles(file, trace, place) {
1420
+ const inStore = installed(file);
1421
+ for (let dir = path4.dirname(file);dir !== path4.dirname(dir); dir = path4.dirname(dir)) {
1422
+ const manifest = path4.join(dir, "package.json");
1423
+ const found = existsSync4(manifest);
1424
+ if (found)
1425
+ setFile(trace, place(manifest), manifest);
1426
+ if (found && dir === frameworkRoot2) {
1427
+ for (const name of ["tsconfig.json", path4.join("config", "ts", "react.json")]) {
1428
+ const extra = path4.join(dir, name);
1429
+ if (existsSync4(extra))
1430
+ setFile(trace, place(extra), extra);
1431
+ }
1432
+ }
1433
+ const parent = path4.basename(path4.dirname(dir));
1434
+ const packageTop = parent === "node_modules" || parent.startsWith("@") && path4.basename(path4.dirname(path4.dirname(dir))) === "node_modules";
1435
+ if (inStore ? packageTop : found && readPackageName(dir))
1436
+ return;
1437
+ }
1438
+ }
1439
+ function packageDataDir(dir, from) {
1440
+ const root = installedPackage(from)?.root ?? packageRoot(path4.dirname(from));
1441
+ if (!root || !isInside(root, dir) || isInside(dir, path4.dirname(from)))
1442
+ return false;
1443
+ return !path4.relative(root, dir).split(path4.sep).includes("node_modules");
1444
+ }
1445
+ function dataFiles(dir) {
1446
+ return readdirSync2(dir, { withFileTypes: true }).flatMap((entry) => {
1447
+ const file = path4.join(dir, entry.name);
1448
+ if (entry.isDirectory())
1449
+ return entry.name === "node_modules" ? [] : dataFiles(file);
1450
+ return entry.isFile() ? [file] : [];
1451
+ });
1452
+ }
1453
+ function packageRoot(dir) {
1454
+ for (;dir !== path4.dirname(dir); dir = path4.dirname(dir)) {
1455
+ if (existsSync4(path4.join(dir, "package.json")))
1456
+ return dir;
1457
+ }
1458
+ return;
1459
+ }
1460
+ function readPackageName(dir) {
1461
+ try {
1462
+ return JSON.parse(readFileSync2(path4.join(dir, "package.json"), "utf8")).name;
1463
+ } catch {
1464
+ return;
1465
+ }
1466
+ }
1467
+ function relativeSpecifier(fromDir, to) {
1468
+ const relative = toPosixPath(path4.relative(fromDir, to));
1469
+ return relative.startsWith(".") ? relative : `./${relative}`;
1470
+ }
1471
+ function rewriteSpecifiers(file, source, edits) {
1472
+ const refs = importMetaRefs(file, source);
1473
+ const spans = [...moduleSpecifierEdges(source, file), ...refs.urls, ...refs.resolves];
1474
+ const changes = spans.flatMap((span) => {
1475
+ const value = edits.get(span.specifier);
1476
+ return value === undefined ? [] : [{ start: span.start, end: span.end, value: JSON.stringify(value) }];
1477
+ });
1478
+ changes.sort((a, b) => a.start - b.start);
1479
+ return changes.length > 0 ? spliceSource(source, changes) : source;
1480
+ }
1481
+ function urlTarget(specifier, from) {
1482
+ try {
1483
+ const url = new URL(specifier, pathToFileURL(from));
1484
+ return url.protocol === "file:" ? path4.resolve(fileURLToPath2(url)) : undefined;
1485
+ } catch {
1486
+ return;
1487
+ }
1488
+ }
1489
+ function isPackageSpecifier(specifier) {
1490
+ if (specifier === "." || specifier === "..")
1491
+ return false;
1492
+ if (specifier.startsWith("./") || specifier.startsWith("../"))
1493
+ return false;
1494
+ return !path4.isAbsolute(specifier) && !specifier.startsWith("file:");
1495
+ }
1496
+ function createCopier(outPath) {
1497
+ const dirs = new Map;
1498
+ const copied = new Set;
1499
+ const pending = [];
1500
+ const ensureDir = (dir) => {
1501
+ let made = dirs.get(dir);
1502
+ if (!made) {
1503
+ made = mkdir3(dir, { recursive: true });
1504
+ dirs.set(dir, made);
1505
+ }
1506
+ return made;
1507
+ };
1508
+ const copy = (dest, source, contents) => {
1509
+ if (copied.has(dest))
1510
+ return;
1511
+ copied.add(dest);
1512
+ const target = path4.join(outPath, dest);
1513
+ pending.push(ensureDir(path4.dirname(target)).then(async () => {
1514
+ if (contents !== undefined) {
1515
+ if (target !== source)
1516
+ await rm2(target, { force: true });
1517
+ return writeFile(target, contents);
1518
+ }
1519
+ if (target !== source)
1520
+ await copyFile2(source, target, constants2.COPYFILE_FICLONE);
1521
+ }));
1522
+ };
1523
+ return { copy, settle: () => Promise.all(pending) };
1524
+ }
1525
+ function isInside(root, file) {
1526
+ return file === root || file.startsWith(`${root}${path4.sep}`);
1715
1527
  }
1716
1528
 
1717
1529
  // src/cli/build.ts
@@ -1765,9 +1577,10 @@ async function runBuild(root, options, lifecycle) {
1765
1577
  const warmMode = options.adapter === "vercel" ? "full" : "compile";
1766
1578
  const warm = startWarmChild(config, warmMode);
1767
1579
  lifecycle.warm = warm;
1580
+ const standalone = startStandalone(config);
1768
1581
  const publicFiles = await log.step("prepare output directory", async () => {
1769
- await ensureEmptyDir(config.outPath, [devOutSegment, "pnext-pages-compat"]);
1770
- return copyPublicDir(config.publicPath, path5.join(config.outPath, "public"));
1582
+ await ensureEmptyDir(config.outRootPath, [devOutSegment, "pnext-pages-compat"]);
1583
+ return copyPublicDir(config.publicPath, path5.join(config.outPath, "static"));
1771
1584
  });
1772
1585
  const documentCss = Promise.resolve().then(() => buildGlobalCss(config, { verbose })).then(() => buildNotFoundCss(config, { verbose }));
1773
1586
  documentCss.catch(() => {
@@ -1851,7 +1664,7 @@ async function runBuild(root, options, lifecycle) {
1851
1664
  const clientBundles = log.step(`client bundles (${clientRoutes.length} route${clientRoutes.length === 1 ? "" : "s"})`, () => buildClientEntries({
1852
1665
  config,
1853
1666
  routes: clientRoutes,
1854
- outDir: path5.join(config.outPath, "public", "assets"),
1667
+ outDir: path5.join(config.outPath, "static", "assets"),
1855
1668
  verbose,
1856
1669
  hasServerActions: actionSources.length > 0,
1857
1670
  pipeline: clientSources
@@ -1879,7 +1692,7 @@ async function runBuild(root, options, lifecycle) {
1879
1692
  await clientBundles;
1880
1693
  const proxyModule = await proxyBuild;
1881
1694
  await partytownLib;
1882
- await emitStaticClientChunks(config, path5.join(config.outPath, "public", "assets"));
1695
+ await emitStaticClientChunks(config, path5.join(config.outPath, "static", "assets"));
1883
1696
  if (verbose) {
1884
1697
  const sources = sourceCacheStats();
1885
1698
  log.log(`source cache \u2014 ${sources.reads} reads, ${sources.hits} shared, ${sources.files} files \xB7 parses ${JSON.stringify(scanFactsStats())}`);
@@ -2054,7 +1867,7 @@ async function runBuild(root, options, lifecycle) {
2054
1867
  html: rendered.value.html,
2055
1868
  status: rendered.value.status
2056
1869
  });
2057
- const relative = toPosixPath(path5.relative(path5.join(config.outPath, "public"), file));
1870
+ const relative = toPosixPath(path5.relative(path5.join(config.outPath, "static"), file));
2058
1871
  const revalidateSeconds = combineRevalidate(segmentConfig?.revalidate, rendered.revalidateSeconds);
2059
1872
  const defaultExpireTime = buildCompat().defaultExpireTimeSeconds();
2060
1873
  const effectiveCacheLife = cacheLife ?? (rendered.expireSeconds !== undefined || rendered.staleSeconds !== undefined ? {
@@ -2116,8 +1929,8 @@ Route (app)`);
2116
1929
  await emitProxyServerArtifacts(config, proxyModule);
2117
1930
  if (config.compat?.next) {
2118
1931
  const sourceApp = path5.join(config.appPath, "..", "source-app");
2119
- const layoutRoot = existsSync4(sourceApp) ? sourceApp : config.appPath;
2120
- const hasTopLevelRootLayout = ["tsx", "ts", "jsx", "js"].some((ext) => existsSync4(path5.join(layoutRoot, `layout.${ext}`)));
1932
+ const layoutRoot = existsSync5(sourceApp) ? sourceApp : config.appPath;
1933
+ const hasTopLevelRootLayout = ["tsx", "ts", "jsx", "js"].some((ext) => existsSync5(path5.join(layoutRoot, `layout.${ext}`)));
2121
1934
  const pseudos = hasTopLevelRootLayout ? ["_not-found.html", "_global-error.html"] : ["_not-found.html"];
2122
1935
  for (const pseudo of pseudos) {
2123
1936
  if (!(pseudo in staticFiles)) {
@@ -2147,21 +1960,19 @@ Route (app)`);
2147
1960
  };
2148
1961
  await writeBuildManifest(config.outPath, manifest);
2149
1962
  log.log(`wrote manifest.json (${routes.length} route${routes.length === 1 ? "" : "s"})`);
2150
- await log.step("server entry", () => emitServerEntry(config.outPath));
2151
1963
  for (const hook of getBuildExtensions().completeHooks) {
2152
1964
  await hook({ config, manifest, log });
2153
1965
  }
2154
- if (options.adapter === "vercel")
2155
- await log.step("vercel adapter output", () => writeVercelOutput(config, manifest, { verbose, warm }));
2156
- else {
2157
- await log.step("warm module cache", () => warm.finish(log, undefined, {
2158
- globalCss: globalCssSources(config),
2159
- clientReferences: [...compiledClientReferenceFiles()]
2160
- }));
2161
- }
2162
- if (!existsSync4(buildIndexFile(config.outPath))) {
1966
+ await log.step("warm module cache", () => warm.finish(log, undefined, {
1967
+ globalCss: globalCssSources(config),
1968
+ clientReferences: [...compiledClientReferenceFiles()]
1969
+ }));
1970
+ if (!existsSync5(buildIndexFile(config.outPath))) {
2163
1971
  throw new Error("pnext build: the server compile did not complete (see the error above).");
2164
1972
  }
1973
+ await log.step("standalone output", () => writeStandalone(config, standalone));
1974
+ if (options.adapter === "vercel")
1975
+ await log.step("vercel adapter output", () => writeVercelOutput(config, manifest, { verbose }));
2165
1976
  throwIfModuleGraphFailed();
2166
1977
  const buildDurationMs = performance.now() - startedAt;
2167
1978
  const phases = await settleBuildParallelPhases();
@@ -2207,7 +2018,7 @@ async function logInterceptionPrerenders(config, routes) {
2207
2018
  return prerenders;
2208
2019
  }
2209
2020
  function routeFileExportsStaticParams(file) {
2210
- if (!existsSync4(file))
2021
+ if (!existsSync5(file))
2211
2022
  return false;
2212
2023
  const source = readTextSync(file);
2213
2024
  return /\bexport\s+(?:async\s+)?function\s+generateStaticParams\b/.test(source) || /\bexport\s+const\s+generateStaticParams\b/.test(source);
@@ -2226,22 +2037,24 @@ function interceptionDisplayRoute(route, filled) {
2226
2037
  }
2227
2038
  async function writeBuildManifest(outPath, manifest) {
2228
2039
  assertManifestServerArtifacts(outPath, manifest);
2229
- const file = path5.join(outPath, "manifest.json");
2230
- const temporary = path5.join(outPath, `.manifest-${process.pid}.tmp`);
2231
- await writeFile3(temporary, serializeBuildManifest(manifest));
2232
- await rename2(temporary, file);
2040
+ const file = buildManifestFile(outPath);
2041
+ const temporary = `${file}.${process.pid}.tmp`;
2042
+ await mkdir4(path5.dirname(file), { recursive: true });
2043
+ await writeFile2(temporary, serializeBuildManifest(manifest));
2044
+ await rename3(temporary, file);
2233
2045
  }
2234
2046
  function assertManifestServerArtifacts(outPath, manifest) {
2235
2047
  const artifacts = [
2236
2048
  ...manifest.proxyModule ? [manifest.proxyModule] : [],
2237
2049
  ...manifest.actions?.map((action) => action.modulePath) ?? []
2238
2050
  ];
2051
+ const outRoot = path5.dirname(outPath);
2239
2052
  for (const artifact of artifacts) {
2240
2053
  const file = path5.resolve(outPath, artifact);
2241
- if (file !== outPath && !file.startsWith(`${outPath}${path5.sep}`)) {
2054
+ if (!file.startsWith(`${outRoot}${path5.sep}`)) {
2242
2055
  throw new Error(`Build manifest server artifact escapes output directory: ${artifact}`);
2243
2056
  }
2244
- if (!existsSync4(file)) {
2057
+ if (!existsSync5(file)) {
2245
2058
  throw new Error(`Build manifest server artifact is missing: ${artifact}`);
2246
2059
  }
2247
2060
  }
@@ -2333,7 +2146,7 @@ async function renderShellWithCacheMeta(config, route, render) {
2333
2146
  var DYNAMIC_EXPIRE_SECONDS = 300;
2334
2147
  function routeDeclaresShortLivedCache(route) {
2335
2148
  for (const file of route.sourceFiles) {
2336
- if (!existsSync4(file))
2149
+ if (!existsSync5(file))
2337
2150
  continue;
2338
2151
  const source = readTextSync(file);
2339
2152
  for (const literal of source.matchAll(/cacheLife\s*\(\s*\{[^}]*\bexpire\s*:\s*([^,}]+)/gs)) {
@@ -2515,7 +2328,7 @@ async function emitConcreteNextPageArtifacts(config, route, routePath, rendered)
2515
2328
  function staleTimeFromRouteSources(route) {
2516
2329
  let found;
2517
2330
  for (const file of route.sourceFiles) {
2518
- if (!existsSync4(file))
2331
+ if (!existsSync5(file))
2519
2332
  continue;
2520
2333
  const source = readTextSync(file);
2521
2334
  for (const literal of source.matchAll(/cacheLife\s*\(\s*\{[^}]*\bstale\s*:\s*([^,}]+)/gs)) {
@@ -2533,7 +2346,7 @@ function staleTimeFromRouteSources(route) {
2533
2346
  }
2534
2347
  function readTextSync(file) {
2535
2348
  try {
2536
- return existsSync4(file) && statSync2(file).isFile() ? readFileSync4(file, "utf8") : "";
2349
+ return existsSync5(file) && statSync2(file).isFile() ? readFileSync3(file, "utf8") : "";
2537
2350
  } catch {
2538
2351
  return "";
2539
2352
  }
@@ -2791,7 +2604,7 @@ function routeSourcesUseHttpFallback(root, route) {
2791
2604
  for (const file of route.sourceFiles) {
2792
2605
  if (!file.startsWith(root) || file.includes(`${path5.sep}node_modules${path5.sep}`))
2793
2606
  continue;
2794
- if (!existsSync4(file))
2607
+ if (!existsSync5(file))
2795
2608
  continue;
2796
2609
  const source = readTextSync(file);
2797
2610
  if (/\b(?:notFound|forbidden|unauthorized)\s*\(\s*\)/.test(source))
@@ -2803,7 +2616,7 @@ function routeSourcesUseRequestApi(root, route) {
2803
2616
  for (const file of route.sourceFiles) {
2804
2617
  if (!file.startsWith(root) || file.includes(`${path5.sep}node_modules${path5.sep}`))
2805
2618
  continue;
2806
- if (!existsSync4(file))
2619
+ if (!existsSync5(file))
2807
2620
  continue;
2808
2621
  const source = readTextSync(file).replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/.*$/gm, "$1");
2809
2622
  if (/\b(?:connection|cookies|headers|draftMode)\s*\(\s*\)/.test(source))
@@ -2813,7 +2626,7 @@ function routeSourcesUseRequestApi(root, route) {
2813
2626
  }
2814
2627
  function routeSourcesHaveDynamicHead(route) {
2815
2628
  for (const file of route.sourceFiles) {
2816
- if (!existsSync4(file))
2629
+ if (!existsSync5(file))
2817
2630
  continue;
2818
2631
  const source = readTextSync(file);
2819
2632
  const match = /export\s+(?:async\s+)?function\s+(?:generateMetadata|generateViewport)\s*\([^)]*\)\s*(?::[^{]+)?\{/.exec(source);
@@ -2890,11 +2703,11 @@ async function renderNotFoundDocuments({
2890
2703
  };
2891
2704
  await documentCss;
2892
2705
  if (await shouldBuildGlobalNotFound(config)) {
2893
- await log.step("global not-found", async () => writeText(path5.join(config.outPath, "public", "404.html"), await render()));
2706
+ await log.step("global not-found", async () => writeText(path5.join(config.outPath, "static", "404.html"), await render()));
2894
2707
  }
2895
2708
  if (!config.compat?.next)
2896
2709
  return;
2897
- if (existsSync4(path5.join(config.outPath, "public", "404.html")))
2710
+ if (existsSync5(path5.join(config.outPath, "static", "404.html")))
2898
2711
  return;
2899
2712
  return defaultNotFoundDocument();
2900
2713
  }
@@ -2902,7 +2715,7 @@ async function shouldBuildGlobalNotFound(config) {
2902
2715
  const file = ["tsx", "ts", "jsx", "js"].flatMap((ext) => [
2903
2716
  path5.join(config.appPath, `global-not-found.${ext}`),
2904
2717
  path5.join(config.appPath, `not-found.${ext}`)
2905
- ]).find((candidate) => existsSync4(candidate));
2718
+ ]).find((candidate) => existsSync5(candidate));
2906
2719
  if (!file)
2907
2720
  return false;
2908
2721
  return !/\bexport\s+const\s+dynamic\s*=\s*['"]force-dynamic['"]/.test(await readText(file));
@@ -2911,21 +2724,21 @@ async function emitProxyServerArtifacts(config, proxyModule) {
2911
2724
  if (!config.compat?.next || !proxyModule)
2912
2725
  return;
2913
2726
  const compiled = path5.resolve(config.outPath, proxyModule);
2914
- if (!existsSync4(compiled))
2727
+ if (!existsSync5(compiled))
2915
2728
  return;
2916
2729
  const serverDir = path5.join(config.root, ".next", "server");
2917
2730
  await mkdir4(serverDir, { recursive: true });
2918
2731
  const middlewareFile = path5.join(serverDir, "middleware.js");
2919
- await copyFile2(compiled, middlewareFile);
2920
- const files = ["middleware.js"].filter((name) => existsSync4(path5.join(serverDir, name)));
2921
- await writeFile3(path5.join(serverDir, "middleware.js.nft.json"), `${JSON.stringify({ version: 1, files })}
2732
+ await copyFile3(compiled, middlewareFile);
2733
+ const files = ["middleware.js"].filter((name) => existsSync5(path5.join(serverDir, name)));
2734
+ await writeFile2(path5.join(serverDir, "middleware.js.nft.json"), `${JSON.stringify({ version: 1, files })}
2922
2735
  `);
2923
2736
  }
2924
2737
  async function emitNextNotFoundArtifacts(config, fallback404) {
2925
2738
  if (!config.compat?.next)
2926
2739
  return;
2927
- const source = path5.join(config.outPath, "public", "404.html");
2928
- const html = existsSync4(source) ? readFileSync4(source, "utf8") : fallback404;
2740
+ const source = path5.join(config.outPath, "static", "404.html");
2741
+ const html = existsSync5(source) ? readFileSync3(source, "utf8") : fallback404;
2929
2742
  if (html === undefined)
2930
2743
  return;
2931
2744
  const serverDir = path5.join(config.root, ".next", "server");
@@ -2933,21 +2746,21 @@ async function emitNextNotFoundArtifacts(config, fallback404) {
2933
2746
  const notFoundDir = path5.join(serverDir, "app", "_not-found");
2934
2747
  await mkdir4(pagesDir, { recursive: true });
2935
2748
  await mkdir4(notFoundDir, { recursive: true });
2936
- await writeFile3(path5.join(pagesDir, "404.html"), html);
2937
- await writeFile3(path5.join(serverDir, "app", "_not-found.html"), html);
2938
- await writeFile3(path5.join(serverDir, "app", "_not-found.rsc"), html);
2749
+ await writeFile2(path5.join(pagesDir, "404.html"), html);
2750
+ await writeFile2(path5.join(serverDir, "app", "_not-found.html"), html);
2751
+ await writeFile2(path5.join(serverDir, "app", "_not-found.rsc"), html);
2939
2752
  const pagesManifestFile = path5.join(serverDir, "pages-manifest.json");
2940
2753
  let pagesManifest = {};
2941
2754
  try {
2942
- pagesManifest = JSON.parse(readFileSync4(pagesManifestFile, "utf8"));
2755
+ pagesManifest = JSON.parse(readFileSync3(pagesManifestFile, "utf8"));
2943
2756
  } catch {}
2944
2757
  pagesManifest["/404"] = "pages/404.html";
2945
- await writeFile3(pagesManifestFile, `${JSON.stringify(pagesManifest, null, 2)}
2758
+ await writeFile2(pagesManifestFile, `${JSON.stringify(pagesManifest, null, 2)}
2946
2759
  `);
2947
2760
  const clientReferenceManifest = "page_client-reference-manifest.js";
2948
- await writeFile3(path5.join(notFoundDir, clientReferenceManifest), `self.__RSC_MANIFEST={}
2761
+ await writeFile2(path5.join(notFoundDir, clientReferenceManifest), `self.__RSC_MANIFEST={}
2949
2762
  `);
2950
- await writeFile3(path5.join(notFoundDir, "page.js.nft.json"), `${JSON.stringify({ version: 1, files: [clientReferenceManifest] }, null, 2)}
2763
+ await writeFile2(path5.join(notFoundDir, "page.js.nft.json"), `${JSON.stringify({ version: 1, files: [clientReferenceManifest] }, null, 2)}
2951
2764
  `);
2952
2765
  }
2953
2766
  async function collectStaticModuleMetadata(config, routes) {
@@ -2959,7 +2772,7 @@ async function collectStaticModuleMetadata(config, routes) {
2959
2772
  if (route.kind !== "page")
2960
2773
  continue;
2961
2774
  for (const file of findLayouts(config.appPath, route.file)) {
2962
- if (existsSync4(file))
2775
+ if (existsSync5(file))
2963
2776
  files.add(file);
2964
2777
  }
2965
2778
  files.add(route.file);
@@ -2994,8 +2807,8 @@ async function collectStaticRouteMetadata(config, routes, staticMetadataFiles) {
2994
2807
  for (const params of paramSets) {
2995
2808
  const routePath = fillRoutePath(route.route, params);
2996
2809
  const base = route.interception ? staticMetadataForRouteFromFiles(staticMetadataFiles, config.appPath, route.file, routePath) : staticMetadataForPathFromFiles(staticMetadataFiles, routePath);
2997
- const resolved = await withDynamicMetadataRoutes(base, config.appPath, route.file, routePath, (file) => importMetadataModule(config, file));
2998
- metadata[staticRouteMetadataKey(routePath)] = resolved;
2810
+ const resolved2 = await withDynamicMetadataRoutes(base, config.appPath, route.file, routePath, (file) => importMetadataModule(config, file));
2811
+ metadata[staticRouteMetadataKey(routePath)] = resolved2;
2999
2812
  }
3000
2813
  }
3001
2814
  return metadata;
@@ -3052,10 +2865,10 @@ async function buildStaticRouteHandler(config, route, options = {}) {
3052
2865
  const body = await settleBeforeNextTask(response.clone().arrayBuffer());
3053
2866
  if (!body)
3054
2867
  continue;
3055
- const relative = toPosixPath(path5.relative(path5.join(config.outPath, "public"), file));
2868
+ const relative = toPosixPath(path5.relative(path5.join(config.outPath, "static"), file));
3056
2869
  if (!skipPhysicalWrite) {
3057
2870
  await mkdir4(path5.dirname(file), { recursive: true });
3058
- await writeFile3(file, new Uint8Array(body));
2871
+ await writeFile2(file, new Uint8Array(body));
3059
2872
  }
3060
2873
  const revalidateSeconds = combineRevalidate(route.segmentConfig?.revalidate, rendered.revalidateSeconds);
3061
2874
  staticFiles[relative] = {
@@ -3087,7 +2900,7 @@ function settleBeforeNextTask(value) {
3087
2900
  });
3088
2901
  }
3089
2902
  async function handlerHasEntirelyCachedIo(route) {
3090
- if (route.synthetic || !existsSync4(route.file))
2903
+ if (route.synthetic || !existsSync5(route.file))
3091
2904
  return false;
3092
2905
  const source = await readText(route.file);
3093
2906
  if (route.metadataRoute && metadataDefaultUsesCache(source))
@@ -3128,7 +2941,7 @@ function metadataDefaultUsesCache(source) {
3128
2941
  return /\bexport\s+default\s+(?:async\s+)?function\b[^(]*\([^)]*\)\s*(?::[^{]*)?\{\s*(?:\/\/[^\n]*\n\s*|\/\*[\s\S]*?\*\/\s*)*['"]use cache['"]/.test(source);
3129
2942
  }
3130
2943
  async function usesUnstableCache(route) {
3131
- if (route.synthetic || !existsSync4(route.file))
2944
+ if (route.synthetic || !existsSync5(route.file))
3132
2945
  return false;
3133
2946
  const source = await readText(route.file);
3134
2947
  const localNames = [];
@@ -3154,7 +2967,7 @@ async function staticHandlerDynamicUsage(route) {
3154
2967
  if (route.segmentConfig?.dynamic === "force-static" || route.segmentConfig?.dynamic === "error") {
3155
2968
  return;
3156
2969
  }
3157
- if (route.synthetic || !existsSync4(route.file))
2970
+ if (route.synthetic || !existsSync5(route.file))
3158
2971
  return;
3159
2972
  const source = await readText(route.file);
3160
2973
  if (/\b(?:request|req)\.url\b/.test(source))
@@ -3262,8 +3075,8 @@ function routeMetadataImageFiles(appPath, routeFile) {
3262
3075
  let dir = path5.dirname(routeFile);
3263
3076
  const root = path5.resolve(appPath);
3264
3077
  while (dir.startsWith(root)) {
3265
- if (existsSync4(dir)) {
3266
- for (const entry of readdirSync2(dir)) {
3078
+ if (existsSync5(dir)) {
3079
+ for (const entry of readdirSync3(dir)) {
3267
3080
  if (/^(opengraph-image|twitter-image)\d*\.(tsx?|jsx?|mjs|png|jpe?g|gif|webp|svg)$/.test(entry)) {
3268
3081
  return true;
3269
3082
  }
@@ -3284,7 +3097,7 @@ async function copyStaticMetadataFiles(config, staticFiles, metadataFiles = disc
3284
3097
  continue;
3285
3098
  }
3286
3099
  await mkdir4(path5.dirname(target), { recursive: true });
3287
- await copyFile2(metadataFile.file, target);
3100
+ await copyFile3(metadataFile.file, target);
3288
3101
  staticFiles[metadataFile.outputPath] = {
3289
3102
  status: 200,
3290
3103
  headers: [
@@ -3296,7 +3109,7 @@ async function copyStaticMetadataFiles(config, staticFiles, metadataFiles = disc
3296
3109
  }
3297
3110
  function staticHtmlPath(outPath, routePath, flatLayout = false) {
3298
3111
  if (routePath === "/")
3299
- return path5.join(outPath, "public", "index.html");
3112
+ return path5.join(outPath, "static", "index.html");
3300
3113
  const normalized = routePath.replace(/^\/|\/$/g, "");
3301
3114
  if (flatLayout)
3302
3115
  return safePublicPath(outPath, `${normalized}.html`);
@@ -3360,13 +3173,13 @@ function staticRouteHandlerPath(outPath, routePath) {
3360
3173
  return safePublicPath(outPath, routePath.replace(/^\/+/, "") || "index");
3361
3174
  }
3362
3175
  function staticOutputCollision(outPath, file) {
3363
- const publicPath = path5.join(outPath, "public");
3364
- if (existsSync4(file) && statSync2(file).isDirectory()) {
3176
+ const publicPath = path5.join(outPath, "static");
3177
+ if (existsSync5(file) && statSync2(file).isDirectory()) {
3365
3178
  return `${toPosixPath(path5.relative(publicPath, file))} already exists as a directory`;
3366
3179
  }
3367
3180
  let dir = path5.dirname(file);
3368
3181
  while (dir !== publicPath && dir !== path5.dirname(dir)) {
3369
- if (existsSync4(dir)) {
3182
+ if (existsSync5(dir)) {
3370
3183
  if (!statSync2(dir).isDirectory()) {
3371
3184
  return `${toPosixPath(path5.relative(publicPath, dir))} already exists as a file`;
3372
3185
  }
@@ -3407,8 +3220,8 @@ async function requestApiBailoutReason(route) {
3407
3220
  function ownSourceFiles(route) {
3408
3221
  const frameworkRoot3 = path5.resolve(fileURLToPath3(Bun.pathToFileURL(__PNEXT_PACKAGE_ROOT__ + "/src/cli/build.ts").href), "..", "..");
3409
3222
  return route.sourceFiles.filter((file) => {
3410
- const resolved = path5.resolve(file);
3411
- return !resolved.includes(`${path5.sep}node_modules${path5.sep}`) && !resolved.startsWith(frameworkRoot3 + path5.sep);
3223
+ const resolved2 = path5.resolve(file);
3224
+ return !resolved2.includes(`${path5.sep}node_modules${path5.sep}`) && !resolved2.startsWith(frameworkRoot3 + path5.sep);
3412
3225
  });
3413
3226
  }
3414
3227
  async function schedulesDeferredWork(route) {
@@ -3501,7 +3314,7 @@ function realFilePath(file) {
3501
3314
  }
3502
3315
  }
3503
3316
  function safePublicPath(outPath, ...segments) {
3504
- const publicPath = path5.join(outPath, "public");
3317
+ const publicPath = path5.join(outPath, "static");
3505
3318
  const file = path5.join(publicPath, ...segments);
3506
3319
  const relative = path5.relative(publicPath, file);
3507
3320
  if (relative.startsWith("..") || path5.isAbsolute(relative)) {
@@ -3519,7 +3332,7 @@ async function copyPartytownLib(config) {
3519
3332
  console.warn("pnext build: experimental.nextScriptWorkers is enabled but no Partytown package was found (@qwik.dev/partytown or @builder.io/partytown); worker scripts will 404 the library until it is installed");
3520
3333
  return;
3521
3334
  }
3522
- const target = path5.join(config.outPath, "public", "_next", "static", "~partytown");
3335
+ const target = path5.join(config.outPath, "static", "_next", "static", "~partytown");
3523
3336
  await mkdir4(target, { recursive: true });
3524
3337
  await copyPublicDir(libDir, target);
3525
3338
  }
@@ -3529,7 +3342,7 @@ function resolvePartytownLibDir(root) {
3529
3342
  try {
3530
3343
  const pkgJson = requireFromRoot.resolve(`${pkg}/package.json`);
3531
3344
  const libDir = path5.join(path5.dirname(pkgJson), "lib");
3532
- if (existsSync4(libDir) && statSync2(libDir).isDirectory())
3345
+ if (existsSync5(libDir) && statSync2(libDir).isDirectory())
3533
3346
  return libDir;
3534
3347
  } catch {}
3535
3348
  }
@@ -3540,7 +3353,7 @@ async function copyPublicDir(from, to) {
3540
3353
  for (const relative of files) {
3541
3354
  const target = path5.join(to, relative);
3542
3355
  await mkdir4(path5.dirname(target), { recursive: true });
3543
- await copyFile2(path5.join(from, relative), target);
3356
+ await copyFile3(path5.join(from, relative), target);
3544
3357
  }
3545
3358
  return files;
3546
3359
  }