@monkeyplus/flow 5.0.0-rc.199 → 5.0.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/build.config.ts +25 -0
  2. package/dist/app/entry.d.ts +2 -2
  3. package/dist/app/entry.mjs +2 -3
  4. package/dist/app/flow.d.ts +3 -12
  5. package/dist/app/flow.mjs +0 -3
  6. package/dist/core/runtime/nitro/flow.d.ts +0 -1
  7. package/dist/core/runtime/nitro/flow.mjs +14 -9
  8. package/dist/core/runtime/nitro/renderer.mjs +18 -82
  9. package/dist/head/runtime/plugin.mjs +1 -0
  10. package/dist/index.mjs +772 -543
  11. package/dist/pages/runtime/helpers/index.d.ts +1 -1
  12. package/dist/pages/runtime/helpers/index.mjs +3 -14
  13. package/dist/pages/runtime/index.d.ts +3 -10
  14. package/dist/pages/runtime/index.mjs +4 -12
  15. package/dist/pages/runtime/plugin.mjs +53 -0
  16. package/dist/vite-client/runtime/injectManifest.d.ts +26 -0
  17. package/dist/vite-client/runtime/injectManifest.mjs +104 -0
  18. package/dist/vite-client/runtime/plugin.d.ts +2 -0
  19. package/dist/vite-client/runtime/plugin.mjs +27 -0
  20. package/package.json +40 -55
  21. package/src/app/composables/index.ts +20 -0
  22. package/src/app/entry.ts +36 -0
  23. package/src/app/flow.ts +157 -0
  24. package/src/app/index.ts +5 -0
  25. package/src/auto-imports/module.ts +143 -0
  26. package/src/auto-imports/presets.ts +49 -0
  27. package/src/auto-imports/transform.ts +48 -0
  28. package/src/core/app.ts +90 -0
  29. package/src/core/builder.ts +60 -0
  30. package/src/core/flow.ts +93 -0
  31. package/src/core/modules.ts +32 -0
  32. package/src/core/nitro.ts +206 -0
  33. package/src/core/plugins/import-protection.ts +49 -0
  34. package/src/core/plugins/unctx.ts +31 -0
  35. package/src/core/runtime/nitro/flow.ts +43 -0
  36. package/src/core/runtime/nitro/paths.ts +20 -0
  37. package/src/core/runtime/nitro/renderer.ts +74 -0
  38. package/src/core/templates.ts +119 -0
  39. package/src/core/vite/builder/css.ts +28 -0
  40. package/src/core/vite/builder/dev-bundler.ts +248 -0
  41. package/src/core/vite/builder/index.ts +96 -0
  42. package/src/core/vite/builder/manifest.ts +33 -0
  43. package/src/core/vite/builder/plugins/analyze.ts +32 -0
  44. package/src/core/vite/builder/plugins/cache-dir.ts +13 -0
  45. package/src/core/vite/builder/plugins/dynamic-base.ts +64 -0
  46. package/src/core/vite/builder/plugins/virtual.ts +45 -0
  47. package/src/core/vite/builder/server.ts +164 -0
  48. package/src/core/vite/builder/types/index.ts +13 -0
  49. package/src/core/vite/builder/utils/index.ts +53 -0
  50. package/src/core/vite/builder/utils/warmup.ts +27 -0
  51. package/src/core/vite/builder/utils/wpfs.ts +7 -0
  52. package/src/core/vite/builder/vite-node.ts +110 -0
  53. package/src/core/vite/client/index.ts +63 -0
  54. package/src/dirs.ts +8 -0
  55. package/src/head/module.ts +37 -0
  56. package/src/head/runtime/composables.ts +16 -0
  57. package/src/head/runtime/index.ts +1 -0
  58. package/src/head/runtime/plugin.ts +12 -0
  59. package/src/index.ts +2 -0
  60. package/src/pages/module.ts +55 -0
  61. package/src/pages/runtime/helpers/chunks.ts +0 -0
  62. package/src/pages/runtime/helpers/index.ts +33 -0
  63. package/src/pages/runtime/index.ts +9 -0
  64. package/src/pages/runtime/plugin.ts +65 -0
  65. package/src/pages/templates.ts +20 -0
  66. package/src/pages/utils.ts +49 -0
  67. package/src/vite-client/module.ts +84 -0
  68. package/src/vite-client/runtime/injectManifest.ts +188 -0
  69. package/src/vite-client/runtime/plugin.ts +33 -0
  70. package/dist/app/entry.async.d.ts +0 -3
  71. package/dist/app/entry.async.mjs +0 -1
  72. package/dist/chunks/dev-bundler.mjs +0 -277
  73. package/dist/core/runtime/client.manifest.d.mts +0 -2
  74. package/dist/core/runtime/client.manifest.mjs +0 -6
  75. package/dist/core/runtime/vite-node-shared.d.mts +0 -1
  76. package/dist/core/runtime/vite-node-shared.d.ts +0 -8
  77. package/dist/core/runtime/vite-node-shared.mjs +0 -3
  78. package/dist/core/runtime/vite-node.d.mts +0 -2
  79. package/dist/core/runtime/vite-node.mjs +0 -41
  80. package/dist/pages/runtime/pages.mjs +0 -123
  81. /package/dist/pages/runtime/{pages.d.ts → plugin.d.ts} +0 -0
package/dist/index.mjs CHANGED
@@ -1,33 +1,36 @@
1
1
  import { createHooks } from 'hookable';
2
2
  import { dirname, resolve, normalize, join, isAbsolute, relative, extname } from 'pathe';
3
- import { defineFlowModule, addPlugin, defineNuxtModule, logger, addTemplate, addPluginTemplate, addVitePlugin, addWebpackPlugin, updateTemplates, useNuxt, resolveAlias, resolveFilesFlow, nuxtCtx, installModule, loadFlowConfig, normalizeTemplate, compileTemplate, normalizePlugin, findPath, templateUtils, isIgnoredFlow } from '@monkeyplus/flow-kit';
4
- import escapeRE from 'escape-string-regexp';
3
+ import { defineFlowModule, addPlugin, defineNuxtModule, logger, addTemplate, addPluginTemplate, addVitePlugin, useNuxt, resolveAlias, resolveFilesFlow, nuxtCtx, installModule, loadFlowConfig, templateUtils, normalizeTemplate, compileTemplate, normalizePlugin, isIgnoredFlow } from '@monkeyplus/flow-kit';
5
4
  import { fileURLToPath, pathToFileURL } from 'node:url';
6
5
  import { defineUnimportPreset, createUnimport, toImports, scanDirExports } from 'unimport';
7
- import defu from 'defu';
8
6
  import { createUnplugin } from 'unplugin';
9
- import { parseURL, parseQuery, joinURL } from 'ufo';
10
- import fs from 'fs';
7
+ import { parseURL, parseQuery, joinURL, withoutTrailingSlash } from 'ufo';
8
+ import escapeRE from 'escape-string-regexp';
11
9
  import { camelCase, pascalCase } from 'scule';
12
- import { genImport, genDynamicImport, genSafeVariableName, genArrayFromRaw, genString } from 'knitwork';
13
- import { existsSync, promises } from 'node:fs';
14
- import { createNitro, scanHandlers, writeTypes, build as build$1, prepare, copyPublicAssets, prerender, createDevServer } from 'nitropack';
15
- import { dynamicEventHandler } from 'h3';
16
- import { createRequire } from 'node:module';
17
- import chokidar from 'chokidar';
10
+ import { genImport, genDynamicImport, genArrayFromRaw, genString, genObjectFromRawEntries } from 'knitwork';
11
+ import fse from 'fs-extra';
12
+ import logger$1 from 'consola';
13
+ import * as vite from 'vite';
14
+ import { createServer, build as build$1 } from 'vite';
18
15
  import { debounce } from 'perfect-debounce';
16
+ import { existsSync, promises, readdirSync, statSync } from 'node:fs';
17
+ import { createNitro, scanHandlers, writeTypes, build as build$2, prepare, copyPublicAssets, prerender, createDevServer } from 'nitropack';
18
+ import defu from 'defu';
19
+ import { dynamicEventHandler, toEventHandler } from 'h3';
20
+ import { createRequire, builtinModules } from 'node:module';
21
+ import chokidar from 'chokidar';
19
22
  import { generateTypes, resolveSchema } from 'untyped';
20
- import { hash } from 'ohash';
21
- import { resolvePath, sanitizeFilePath } from 'mlly';
22
- import * as vite from 'vite';
23
+ import { getPort } from 'get-port-please';
24
+ import { sanitizeFilePath } from 'mlly';
23
25
  import replace from '@rollup/plugin-replace';
24
- import { resolveTSConfig } from 'pkg-types';
25
- import fse from 'fs-extra';
26
+ import { isExternal as isExternal$1, ExternalsDefaults } from 'externality';
27
+ import { createHash } from 'node:crypto';
28
+ import MagicString from 'magic-string';
26
29
 
27
- const version = "5.0.0-rc.199";
30
+ const version = "5.0.0-rc.2";
28
31
 
29
32
  let _distDir = dirname(fileURLToPath(import.meta.url));
30
- if (_distDir.match(/(chunks|shared)$/))
33
+ if (_distDir.endsWith("chunks"))
31
34
  _distDir = dirname(_distDir);
32
35
  const distDir = _distDir;
33
36
  const pkgDir = resolve(distDir, "..");
@@ -50,51 +53,40 @@ const metaModule = defineFlowModule({
50
53
 
51
54
  const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }) => {
52
55
  return {
53
- name: "nuxt:imports-transform",
56
+ name: "flow:auto-imports-transform",
54
57
  enforce: "post",
55
58
  transformInclude(id) {
56
59
  const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
57
- const query = parseQuery(search);
58
- if (options.transform?.include?.some((pattern) => id.match(pattern)))
59
- return true;
60
- if (options.transform?.exclude?.some((pattern) => id.match(pattern)))
60
+ const { type, macro } = parseQuery(search);
61
+ const exclude = options.transform?.exclude || [/[\\/]node_modules[\\/]/];
62
+ const include = options.transform?.include || [];
63
+ if (exclude.some((pattern) => id.match(pattern)))
61
64
  return false;
62
- if (id.endsWith(".vue") || "macro" in query || "vue" in query && (query.type === "template" || query.type === "script" || "setup" in query))
65
+ if (include.some((pattern) => id.match(pattern)))
66
+ return true;
67
+ if (pathname.endsWith(".vue") && (type === "template" || type === "script" || macro || !search))
63
68
  return true;
64
69
  if (pathname.match(/\.((c|m)?j|t)sx?$/g))
65
70
  return true;
66
71
  },
67
- async transform(code, id) {
68
- id = normalize(id);
69
- const isNodeModule = id.match(/[\\/]node_modules[\\/]/) && !options.transform?.include?.some((pattern) => id.match(pattern));
70
- if (isNodeModule && !code.match(/(['"])#imports\1/))
72
+ async transform(_code, id) {
73
+ const { code, s } = await ctx.injectImports(_code);
74
+ if (code === _code)
71
75
  return;
72
- const { s } = await ctx.injectImports(code, id, { autoImport: options.autoImport && !isNodeModule });
73
- if (s.hasChanged()) {
74
- return {
75
- code: s.toString(),
76
- map: sourcemap ? s.generateMap({ source: id, includeContent: true }) : void 0
77
- };
78
- }
76
+ return {
77
+ code,
78
+ map: sourcemap && s.generateMap({ source: id, includeContent: true })
79
+ };
79
80
  }
80
81
  };
81
82
  });
82
83
 
83
84
  const commonPresets = [
84
- // #head
85
85
  defineUnimportPreset({
86
86
  from: "#head",
87
87
  imports: [
88
88
  "useHead"
89
89
  ]
90
- }),
91
- defineUnimportPreset({
92
- from: "#_pages",
93
- imports: [
94
- "definePage",
95
- "defineDynamicPage",
96
- "defineSharedContext"
97
- ]
98
90
  })
99
91
  ];
100
92
  const appPreset = defineUnimportPreset({
@@ -112,12 +104,10 @@ const appPreset = defineUnimportPreset({
112
104
  const vuePreset = defineUnimportPreset({
113
105
  from: "vue",
114
106
  imports: [
115
- // Components
116
107
  "defineComponent",
117
108
  "getCurrentInstance",
118
109
  "useSlots",
119
110
  "h",
120
- // Reactivity
121
111
  "computed"
122
112
  ]
123
113
  });
@@ -127,65 +117,50 @@ const defaultPresets = [
127
117
  vuePreset
128
118
  ];
129
119
 
130
- const importsModule = defineNuxtModule({
120
+ const autoImportsModule = defineNuxtModule({
131
121
  meta: {
132
- name: "imports",
133
- configKey: "imports"
122
+ name: "auto-imports",
123
+ configKey: "autoImports"
134
124
  },
135
125
  defaults: {
136
- autoImport: true,
137
126
  presets: defaultPresets,
138
127
  global: false,
139
128
  imports: [],
140
129
  dirs: [],
141
130
  transform: {
142
- include: [],
143
131
  exclude: void 0
144
132
  }
145
133
  },
146
- async setup(options, nuxt) {
147
- if (nuxt.options.autoImports) {
148
- logger.warn("`autoImports` config is deprecated, use `imports` instead.");
149
- options = defu(nuxt.options.autoImports, options);
150
- }
151
- await nuxt.callHook("imports:sources", options.presets);
152
- options.presets?.forEach((_i) => {
153
- const i = _i;
134
+ async setup(options, flow) {
135
+ await flow.callHook("autoImports:sources", options.presets);
136
+ options.presets.forEach((i) => {
154
137
  if (typeof i !== "string" && i.names && !i.imports) {
155
138
  i.imports = i.names;
156
- logger.warn("imports: presets.names is deprecated, use presets.imports instead");
139
+ logger.warn("auto-imports: presets.names is deprecated, use presets.imports instead");
157
140
  }
158
141
  });
159
142
  const ctx = createUnimport({
160
143
  presets: options.presets,
161
- imports: options.imports,
162
- virtualImports: ["#imports"],
163
- addons: {
164
- vueTemplate: options.autoImport
165
- }
144
+ imports: options.imports
166
145
  });
167
146
  let composablesDirs = [];
168
- for (const layer of nuxt.options._layers) {
147
+ for (const layer of flow.options._layers) {
169
148
  composablesDirs.push(resolve(layer.config.srcDir, "composables"));
170
- for (const dir of layer.config.imports?.dirs ?? []) {
171
- if (!dir)
172
- continue;
149
+ for (const dir of layer.config.autoImports?.dirs ?? [])
173
150
  composablesDirs.push(resolve(layer.config.srcDir, dir));
174
- }
175
151
  }
176
- await nuxt.callHook("imports:dirs", composablesDirs);
152
+ await flow.callHook("autoImports:dirs", composablesDirs);
177
153
  composablesDirs = composablesDirs.map((dir) => normalize(dir));
178
154
  addTemplate({
179
155
  filename: "imports.mjs",
180
- getContents: async () => `${await ctx.toExports()}
181
- if (process.dev) { console.warn("[nuxt] \`#imports\` should be transformed with real imports. There seems to be something wrong with the imports plugin.") }`
156
+ getContents: () => ctx.toExports()
182
157
  });
183
- nuxt.options.alias["#imports"] = join(nuxt.options.buildDir, "imports");
184
- if (nuxt.options.dev && options.global) {
158
+ flow.options.alias["#imports"] = join(flow.options.buildDir, "imports");
159
+ if (flow.options.dev && options.global) {
185
160
  addPluginTemplate({
186
- filename: "imports.mjs",
187
- getContents: async () => {
188
- const imports = await ctx.getImports();
161
+ filename: "auto-imports.mjs",
162
+ getContents: () => {
163
+ const imports = ctx.getImports();
189
164
  const importStatement = toImports(imports);
190
165
  const globalThisSet = imports.map((i) => `globalThis.${i.as} = ${i.as};`).join("\n");
191
166
  return `${importStatement}
@@ -196,41 +171,32 @@ export default () => {};`;
196
171
  }
197
172
  });
198
173
  } else {
199
- addVitePlugin(TransformPlugin.vite({ ctx, options, sourcemap: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client }));
200
- addWebpackPlugin(TransformPlugin.webpack({ ctx, options, sourcemap: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client }));
174
+ addVitePlugin(TransformPlugin.vite({ ctx, options, sourcemap: flow.options.sourcemap }));
201
175
  }
202
- const regenerateImports = async () => {
176
+ const regenerateAutoImports = async () => {
203
177
  ctx.clearDynamicImports();
204
178
  await ctx.modifyDynamicImports(async (imports) => {
205
179
  imports.push(...await scanDirExports(composablesDirs));
206
- await nuxt.callHook("imports:extend", imports);
180
+ await flow.callHook("autoImports:extend", imports);
207
181
  });
208
182
  };
209
- await regenerateImports();
210
- addDeclarationTemplates(ctx, options);
211
- nuxt.hook("prepare:types", ({ references }) => {
212
- references.push({ path: resolve(nuxt.options.buildDir, "types/imports.d.ts") });
213
- references.push({ path: resolve(nuxt.options.buildDir, "imports.d.ts") });
183
+ await regenerateAutoImports();
184
+ addDeclarationTemplates(ctx);
185
+ flow.hook("prepare:types", ({ references }) => {
186
+ references.push({ path: resolve(flow.options.buildDir, "types/auto-imports.d.ts") });
187
+ references.push({ path: resolve(flow.options.buildDir, "imports.d.ts") });
214
188
  });
215
- const templates = [
216
- "types/imports.d.ts",
217
- "imports.d.ts",
218
- "imports.mjs"
219
- ];
220
- nuxt.hook("builder:watch", async (_, path) => {
221
- const _resolved = resolve(nuxt.options.srcDir, path);
222
- if (composablesDirs.find((dir) => _resolved.startsWith(dir))) {
223
- await updateTemplates({
224
- filter: (template) => templates.includes(template.filename)
225
- });
226
- }
189
+ flow.hook("builder:watch", async (_, path) => {
190
+ const _resolved = resolve(flow.options.srcDir, path);
191
+ if (composablesDirs.find((dir) => _resolved.startsWith(dir)))
192
+ await flow.callHook("builder:generateApp");
227
193
  });
228
- nuxt.hook("builder:generateApp", async () => {
229
- await regenerateImports();
194
+ flow.hook("builder:generateApp", async () => {
195
+ await regenerateAutoImports();
230
196
  });
231
197
  }
232
198
  });
233
- function addDeclarationTemplates(ctx, options) {
199
+ function addDeclarationTemplates(ctx) {
234
200
  const nuxt = useNuxt();
235
201
  const stripExtension = (path) => path.replace(/\.[a-z]+$/, "");
236
202
  const resolved = {};
@@ -246,64 +212,46 @@ function addDeclarationTemplates(ctx, options) {
246
212
  };
247
213
  addTemplate({
248
214
  filename: "imports.d.ts",
249
- getContents: () => ctx.toExports(nuxt.options.buildDir)
215
+ getContents: () => ctx.toExports()
250
216
  });
251
217
  addTemplate({
252
- filename: "types/imports.d.ts",
253
- getContents: async () => `// Generated by auto imports
254
- ${options.autoImport ? await ctx.generateTypeDeclarations({ resolvePath: r }) : "// Implicit auto importing is disabled, you can use explicitly import from `#imports` instead."}`
218
+ filename: "types/auto-imports.d.ts",
219
+ getContents: () => `// Generated by auto imports
220
+ ${ctx.generateTypeDecarations({ resolvePath: r })}`
255
221
  });
256
222
  }
257
223
 
258
- async function resolveFiles(dir) {
224
+ async function resolvePagesRoutes() {
259
225
  const nuxt = useNuxt();
260
- const dirs = [resolve(nuxt.options.srcDir, dir)];
261
- const allRoutes = (await Promise.all(
262
- dirs.map(async (dir2) => {
263
- const files = await resolveFilesFlow(dir2, `**/*{${nuxt.options.extensions.join(",")}}`);
264
- files.sort();
265
- return files.filter((file) => {
266
- if (file.includes(" copy"))
267
- return false;
268
- if (!fs.readFileSync(file, "utf8").includes("export"))
269
- return false;
270
- return true;
271
- }).map((file) => {
272
- const segments = relative(dir2, file).replace(new RegExp(`${escapeRE(extname(file))}$`), "").split("/").join("_");
273
- return {
274
- file,
275
- name: camelCase(segments)
276
- };
277
- });
278
- })
279
- )).flat();
226
+ const pagesDirs = [...new Set(nuxt.options._layers.map((layer) => resolve(layer.config.srcDir, layer.config.dir?.pages || "pages")))];
227
+ const allRoutes = (await Promise.all(pagesDirs.map(async (dir) => {
228
+ const files = await resolveFilesFlow(dir, `**/*{${nuxt.options.extensions.join(",")}}`);
229
+ files.sort();
230
+ return files.map((file) => {
231
+ const segments = relative(dir, file).replace(new RegExp(`${escapeRE(extname(file))}$`), "").split("/").join("_");
232
+ return {
233
+ file,
234
+ name: camelCase(segments)
235
+ };
236
+ });
237
+ }))).flat();
280
238
  return allRoutes;
281
239
  }
282
- function normalizeExports(files) {
283
- const imports = files.map((page) => genImport(page.file, page.name)).join("\n");
284
- const exports = files.reduce((acc, curr) => {
285
- const name = curr.name;
286
- return `${name}:typeof ${name}==='function'?${name}():${name},${acc}`;
287
- }, "");
240
+ function normalizePages(pages) {
241
+ const imports = pages.map((page) => genImport(page.file, [{ name: "pages", as: page.name }])).join("\n");
288
242
  return {
289
243
  imports,
290
- exports
244
+ exports: pages.reduce((acc, curr) => `${curr.name || ""},${acc}`, "")
291
245
  };
292
246
  }
293
247
 
294
248
  const pagesTypeTemplate = {
295
- filename: "types/pages.d.ts",
249
+ filename: "pages.d.ts",
296
250
  getContents: ({ options }) => `// Generated by pages discovery
297
251
  export {}
298
252
  declare global {
299
- type ArrElement<ArrType> = ArrType extends readonly (infer ElementType)[]
300
- ? ElementType
301
- : never;
302
253
 
303
- ${options.pages.map((c) => {
304
- const _type = `ArrElement<typeof ${genDynamicImport(isAbsolute(c.file) ? relative(join(options.buildDir, "types"), c.file) : c.file, { wrapper: false })}['default']>`;
305
- return `export type ${pascalCase(c.name)}Context=Awaited<ReturnType<${_type}['locales']['es-ec']['context']>>`;
306
- }).join("\n")}
254
+ ${options.pages.map((c) => `export type ${pascalCase(c.name)}Context=Awaited<ReturnType<typeof ${genDynamicImport(isAbsolute(c.file) ? relative(options.buildDir, c.file) : c.file, { wrapper: false })}['pages']['locales']['es-ec']['context']>>`).join("\n")}
307
255
  }
308
256
  export const pagesNames: string[]
309
257
  `.replaceAll(".ts", "")
@@ -315,75 +263,157 @@ const pagesModule = defineNuxtModule({
315
263
  },
316
264
  async setup(_options, flow) {
317
265
  const runtimeDir = resolve(distDir, "pages/runtime");
318
- flow.options.alias["#_pages"] = runtimeDir;
319
266
  const pages = [];
320
- const contexts = [];
321
- const options = { pages, buildDir: flow.options.buildDir, contexts };
267
+ flow.hook("builder:watch", async (event, path) => {
268
+ const dirs = [
269
+ flow.options.dir.pages,
270
+ flow.options.dir.layouts,
271
+ flow.options.dir.middleware
272
+ ].filter(Boolean);
273
+ const pathPattern = new RegExp(`^(${dirs.map(escapeRE).join("|")})/`);
274
+ if (event !== "change" && path.match(pathPattern))
275
+ await flow.callHook("builder:generateApp");
276
+ });
277
+ const options = { pages, buildDir: flow.options.buildDir };
322
278
  addTemplate({
323
279
  ...pagesTypeTemplate,
324
280
  options
325
281
  });
326
- const pagesDirs = [{ path: resolve(flow.options.srcDir, flow.options.dir.pages) }];
327
282
  flow.options.alias["#pages"] = resolve(flow.options.buildDir, "pages.mjs");
328
- flow.options.alias["#pagesContexts"] = resolve(flow.options.buildDir, "pages.contexts.mjs");
329
283
  addTemplate({
330
284
  filename: "pages.mjs",
331
285
  async getContents({ options: options2 }) {
332
- const { exports, imports } = normalizeExports(options2.pages);
333
- const module = [imports, `export default {${exports}}`].join("\n");
334
- return module;
335
- },
336
- options
337
- });
338
- addTemplate({
339
- filename: "pages.contexts.mjs",
340
- async getContents({ options: options2 }) {
341
- const { exports, imports } = normalizeExports(options2.contexts);
342
- const module = [imports, `export default {${exports}}`].join("\n");
343
- return module;
286
+ const { exports, imports } = normalizePages(options2.pages);
287
+ return [imports, `export default {${exports}}`].join("\n");
344
288
  },
345
289
  options
346
290
  });
347
291
  flow.hook("app:templates", async () => {
348
- options.pages = await resolveFiles(flow.options.dir?.pages || "pages");
349
- });
350
- flow.hook("app:templates", async () => {
351
- options.contexts = await resolveFiles("shared/contexts");
292
+ options.pages = await resolvePagesRoutes();
352
293
  });
353
294
  flow.hook("prepare:types", ({ references }) => {
354
- references.push({ path: resolve(flow.options.buildDir, "types/pages.d.ts") });
295
+ references.push({ path: resolve(flow.options.buildDir, "pages.d.ts") });
355
296
  });
356
- flow.hook("builder:watch", async (event, path) => {
357
- if (!["add", "unlink", "change"].includes(event))
358
- return;
359
- if (path.includes(" copy"))
360
- return;
361
- const fPath = resolve(flow.options.rootDir, path);
362
- if (pagesDirs.find((dir) => fPath.startsWith(dir.path)))
363
- await flow.callHook("builder:generateApp");
297
+ addPlugin({ src: resolve(runtimeDir, "plugin") });
298
+ }
299
+ });
300
+
301
+ const createClient = async (flow) => {
302
+ let vite;
303
+ if (globalThis.viteClient) {
304
+ vite = globalThis.viteClient;
305
+ } else {
306
+ vite = await createServer({
307
+ root: resolve(flow.options.rootDir),
308
+ base: "/_vite/",
309
+ build: {
310
+ manifest: true
311
+ },
312
+ server: {
313
+ watch: {
314
+ ignored: ["**/.env/**", "**/.env*"]
315
+ },
316
+ middlewareMode: "ssr"
317
+ }
364
318
  });
365
- addPlugin(resolve(runtimeDir, "pages"));
319
+ globalThis.viteClient = vite;
320
+ }
321
+ const _doReload = () => {
322
+ if (vite)
323
+ vite?.ws?.send({ type: "full-reload" });
324
+ };
325
+ const doReload = debounce(_doReload, 60);
326
+ flow.hook("bundler:change", () => {
327
+ doReload();
328
+ });
329
+ flow.hook("close", async () => {
330
+ vite.restart();
331
+ });
332
+ return vite;
333
+ };
334
+ const builClient = async (flow) => {
335
+ return await build$1({
336
+ root: flow.options.rootDir,
337
+ mode: "production",
338
+ build: {
339
+ assetsDir: "scripts",
340
+ target: "es2017",
341
+ outDir: ".vite",
342
+ manifest: true
343
+ }
344
+ });
345
+ };
346
+
347
+ const viteModule = defineFlowModule({
348
+ meta: {
349
+ name: "vite-client",
350
+ configKey: "bundle"
351
+ },
352
+ defaults: {
353
+ route: "/_vite/",
354
+ dir: "/client/pages"
355
+ },
356
+ async setup(_options, flow) {
357
+ const runtimeDir = resolve(distDir, "vite-client/runtime");
358
+ flow.options.alias["#viteManifest"] = resolve(flow.options.buildDir, "viteManifest.mjs");
359
+ let vite;
360
+ if (flow.options.dev) {
361
+ flow.hook("nitro:init", async (nitro) => {
362
+ vite = await createClient(flow);
363
+ nitro.options.devHandlers.push({
364
+ handler: vite.middlewares,
365
+ route: _options.route
366
+ });
367
+ });
368
+ addTemplate({
369
+ filename: "viteManifest.mjs",
370
+ async getContents() {
371
+ return [
372
+ "export default {",
373
+ `head:()=>'<script type="module" src="${joinURL("/", _options.route, "/@vite/client")}"><\/script>'`,
374
+ ",",
375
+ `body: (bundle)=>\`<script type="module" src="${joinURL("/", _options.route, _options.dir)}/\${bundle}.ts"><\/script>\``,
376
+ "}"
377
+ ].join("\n");
378
+ }
379
+ });
380
+ } else {
381
+ flow.hook("modules:done", async () => {
382
+ const start = Date.now();
383
+ logger$1.info("Building client...");
384
+ await builClient(flow);
385
+ const file = resolve(flow.options.rootDir, ".vite/manifest.json");
386
+ const manifest = await fse.readFile(file, "utf8");
387
+ logger$1.success(`Client build in ${Date.now() - start}ms`);
388
+ addTemplate({
389
+ filename: "viteManifest.mjs",
390
+ async getContents() {
391
+ return [
392
+ "export default ()=>(",
393
+ manifest,
394
+ ")"
395
+ ].join("\n");
396
+ }
397
+ });
398
+ });
399
+ flow.hook("generate:before", async () => {
400
+ const files = resolve(flow.options.rootDir, ".vite/scripts");
401
+ await fse.copy(files, resolve(flow.options.generate.dir, "assets"));
402
+ });
403
+ }
404
+ addPlugin({ src: resolve(runtimeDir, "plugin") });
366
405
  }
367
406
  });
368
407
 
369
408
  const _require = createRequire(import.meta.url);
370
409
  const ImportProtectionPlugin = createUnplugin((options) => {
371
410
  const cache = {};
372
- const importersToExclude = options?.exclude || [];
373
411
  return {
374
- name: "nuxt:import-protection",
412
+ name: "flow:import-protection",
375
413
  enforce: "pre",
376
414
  resolveId(id, importer) {
377
- if (!importer)
378
- return;
379
- if (id.startsWith("."))
380
- id = join(importer, "..", id);
381
- if (isAbsolute(id))
382
- id = relative(options.rootDir, id);
383
- if (importersToExclude.some((p) => typeof p === "string" ? importer === p : p.test(importer)))
384
- return;
385
415
  const invalidImports = options.patterns.filter(([pattern]) => pattern instanceof RegExp ? pattern.test(id) : pattern === id);
386
- let matched = false;
416
+ let matched;
387
417
  for (const match of invalidImports) {
388
418
  cache[id] = cache[id] || /* @__PURE__ */ new Map();
389
419
  const [pattern, warning] = match;
@@ -402,38 +432,25 @@ const ImportProtectionPlugin = createUnplugin((options) => {
402
432
  });
403
433
 
404
434
  async function initNitro(flow) {
435
+ const { handlers, devHandlers } = await resolveHandlers(flow);
405
436
  const _nitroConfig = flow.options.nitro || {};
406
437
  globalThis.generate = {};
407
- const scanDirs = flow.options._layers.map((layer) => (layer.config.serverDir || layer.config.srcDir) && resolve(layer.cwd, layer.config.serverDir || resolve(layer.config.srcDir, "server"))).filter(Boolean);
408
438
  const nitroConfig = defu(_nitroConfig, {
409
439
  rootDir: flow.options.rootDir,
410
- workspaceDir: flow.options.workspaceDir,
411
- srcDir: flow.options.serverDir,
440
+ srcDir: join(flow.options.srcDir, "server"),
412
441
  dev: flow.options.dev,
442
+ preset: flow.options.dev ? "nitro-dev" : void 0,
413
443
  buildDir: flow.options.buildDir,
414
- scanDirs,
444
+ scanDirs: flow.options._layers.map((layer) => join(layer.config.srcDir, "server")),
415
445
  renderer: resolve(distDir, "core/runtime/nitro/renderer"),
416
- // errorHandler: resolve(distDir, 'core/runtime/nitro/error'),
417
446
  nodeModulesDirs: flow.options.modulesDir,
418
- handlers: [
419
- //* Important middleware
420
- {
421
- middleware: true,
422
- handler: resolve(distDir, "core/runtime/nitro/flow")
423
- },
424
- ...flow.options.serverHandlers
425
- ],
426
- output: {
427
- dir: resolve(flow.options.buildDir, "output")
428
- },
447
+ handlers,
429
448
  devHandlers: [],
430
449
  baseURL: flow.options.app.baseURL,
431
- virtual: {},
432
450
  runtimeConfig: {
433
451
  ...flow.options.runtimeConfig,
434
452
  app: {
435
453
  ...flow.options.runtimeConfig.app,
436
- baseURL: flow.options.dev ? "/" : flow.options.app.baseURL,
437
454
  rootDir: flow.options.rootDir,
438
455
  locale: flow.options.locale
439
456
  },
@@ -448,81 +465,62 @@ async function initNitro(flow) {
448
465
  },
449
466
  publicAssets: [
450
467
  {
451
- // baseURL: flow.options.app.buildAssetsDir,
468
+ baseURL: flow.options.app.buildAssetsDir,
452
469
  dir: resolve(flow.options.buildDir, "dist/client")
453
470
  },
454
471
  ...flow.options._layers.map((layer) => join(layer.config.srcDir, layer.config.dir?.public || "public")).filter((dir) => existsSync(dir)).map((dir) => ({ dir }))
455
472
  ],
456
473
  prerender: {
457
- crawlLinks: flow.options._generate ?? void 0,
458
- routes: [].concat(flow.options.generate.routes).concat(flow.options._generate ? ["/_urls", ...flow.options.generate.routes] : [])
474
+ crawlLinks: flow.options._generate ? flow.options.generate.crawler : false,
475
+ routes: [].concat(flow.options._generate ? ["/_urls", ...flow.options.generate.routes] : [])
459
476
  },
460
- sourceMap: flow.options.sourcemap.server,
477
+ sourcemap: flow.options.sourcemap,
461
478
  externals: {
462
479
  inline: [
463
480
  ...flow.options.dev ? [] : ["eta", "@monkeyplus/", "@vue/", "@nuxt/", flow.options.buildDir],
464
- "@monkeyplus/flow/dist",
465
- // Dev windows
466
- "C:/Users/gnu/Documents/GitHub/flow/packages/flow/dist/app",
467
- distDir
481
+ "@monkeyplus/flow/dist"
468
482
  ]
469
483
  },
470
- // preset: flow.options.dev ? 'nitro-dev' : undefined,
471
- // output: {
472
- // dir: resolve(flow.options.buildDir, 'output'),
473
- // },
474
- replace: {
475
- "process.dev": flow.options.dev
476
- },
477
484
  alias: {
478
- // Vue 3 mocks
479
485
  "estree-walker": "unenv/runtime/mock/proxy",
480
486
  "@babel/parser": "unenv/runtime/mock/proxy",
481
- // Paths
482
487
  "#paths": resolve(distDir, "core/runtime/nitro/paths"),
483
- // Shortcut to server main file
484
488
  "#server": "#build/dist/server/server.mjs",
485
- // Nuxt aliases
489
+ "#app": flow.options.appDir,
486
490
  ...flow.options.alias
487
491
  },
488
492
  rollupConfig: {
489
493
  plugins: []
490
- },
491
- // watchOptions:{}
492
- //* Include to refresh server
493
- devServer: {
494
- watch: [resolve(flow.options.buildDir, "dist/server/server.mjs")]
495
494
  }
496
495
  });
497
- nitroConfig.rollupConfig.plugins.push(
498
- ImportProtectionPlugin.rollup({
499
- rootDir: flow.options.rootDir,
500
- patterns: [
501
- ...["#app", /^#build(\/|$)/].map((p) => [p, "Vue app aliases are not allowed in server routes."])
502
- ],
503
- exclude: [/core[\\/]runtime[\\/]nitro[\\/]renderer/]
504
- })
505
- );
506
496
  await flow.callHook("nitro:config", nitroConfig);
497
+ nitroConfig.handlers.unshift({
498
+ middleware: true,
499
+ handler: resolve(distDir, "core/runtime/nitro/flow")
500
+ });
507
501
  const nitro = await createNitro(nitroConfig);
508
- flow._nitro = nitro;
509
- flow.nitro = nitro;
510
502
  await flow.callHook("nitro:init", nitro);
511
503
  nitro.vfs = flow.vfs = nitro.vfs || flow.vfs || {};
512
504
  flow.hook("close", () => nitro.hooks.callHook("close"));
513
- nitro.hooks.hook("prerender:routes", (routes) => {
514
- flow.callHook("prerender:routes", { routes });
505
+ nitro.hooks.hook("rollup:before", (nitro2) => {
506
+ const plugin = ImportProtectionPlugin.rollup({
507
+ rootDir: flow.options.rootDir,
508
+ patterns: [
509
+ ...["#app", /^#build(\/|$)/].map((p) => [p, "Flow app aliases are not allowed in server routes."])
510
+ ]
511
+ });
512
+ nitro2.options.rollupConfig.plugins.push(plugin);
515
513
  });
516
- const devMiddlewareHandler = dynamicEventHandler();
517
- nitro.options.devHandlers.unshift({ handler: devMiddlewareHandler });
518
- nitro.options.devHandlers.push(...flow.options.devServerHandlers);
514
+ const devMidlewareHandler = dynamicEventHandler();
515
+ nitro.options.devHandlers.unshift({ handler: devMidlewareHandler });
516
+ nitro.options.devHandlers.push(...devHandlers);
519
517
  nitro.options.handlers.unshift({
520
- route: "/__nuxt_error",
518
+ route: "/__flow_error",
521
519
  lazy: true,
522
520
  handler: resolve(distDir, "core/runtime/nitro/renderer")
523
521
  });
524
522
  flow.hook("prepare:types", async (opts) => {
525
- if (!flow.options.dev) {
523
+ if (flow.options._prepare) {
526
524
  await scanHandlers(nitro);
527
525
  await writeTypes(nitro);
528
526
  }
@@ -531,15 +529,21 @@ async function initNitro(flow) {
531
529
  flow.hook("build:done", async () => {
532
530
  await flow.callHook("nitro:build:before", nitro);
533
531
  if (flow.options.dev) {
534
- await build$1(nitro);
532
+ await build$2(nitro);
535
533
  } else {
536
- console.log("build", flow.options._generate);
537
534
  await prepare(nitro);
538
535
  await copyPublicAssets(nitro);
539
536
  await prerender(nitro);
540
537
  if (!flow.options._generate) {
541
- await build$1(nitro);
538
+ await build$2(nitro);
542
539
  } else {
540
+ const nitroDev = await createNitro({
541
+ ...nitro.options._config,
542
+ rootDir: nitro.options.rootDir,
543
+ logLevel: 0,
544
+ preset: "nitro-prerender"
545
+ });
546
+ flow.server = nitroDev;
543
547
  const distDir2 = resolve(flow.options.rootDir, "dist");
544
548
  if (!existsSync(distDir2))
545
549
  await promises.symlink(nitro.options.output.publicDir, distDir2, "junction").catch(() => {
@@ -548,27 +552,37 @@ async function initNitro(flow) {
548
552
  }
549
553
  });
550
554
  if (flow.options.dev) {
551
- flow.hook("vite:compiled", () => {
552
- flow.server.reload();
555
+ flow.hook("build:compile", ({ compiler }) => {
556
+ compiler.outputFileSystem = { ...fse, join };
553
557
  });
554
- flow.hook("server:devHandler", (h) => {
555
- devMiddlewareHandler.set(h);
558
+ flow.hook("server:devMiddleware", (m) => {
559
+ devMidlewareHandler.set(toEventHandler(m));
556
560
  });
557
561
  flow.server = createDevServer(nitro);
562
+ flow.hook("build:resources", () => {
563
+ flow.server.reload();
564
+ });
558
565
  const waitUntilCompile = new Promise((resolve2) => nitro.hooks.hook("compiled", () => resolve2()));
559
566
  flow.hook("build:done", () => waitUntilCompile);
560
567
  }
561
568
  }
569
+ async function resolveHandlers(flow) {
570
+ const handlers = [...flow.options.serverHandlers];
571
+ const devHandlers = [...flow.options.devServerHandlers];
572
+ return {
573
+ handlers,
574
+ devHandlers
575
+ };
576
+ }
562
577
 
563
578
  const addModuleTranspiles = (opts = {}) => {
564
579
  const flow = useNuxt();
565
580
  const modules = [
566
581
  ...opts.additionalModules || [],
567
- // ...flow.options.buildModules,
568
582
  ...flow.options.modules,
569
583
  ...flow.options._modules
570
584
  ].map((m) => typeof m === "string" ? m : Array.isArray(m) ? m[0] : m.src).filter((m) => typeof m === "string").map((m) => m.split("node_modules/").pop());
571
- flow.options.build.transpile = flow.options.build.transpile.map((m) => typeof m === "string" ? m.split("node_modules/").pop() : m).filter((x) => !!x);
585
+ flow.options.build.transpile = flow.options.build.transpile.map((m) => typeof m === "string" ? m.split("node_modules/").pop() : m);
572
586
  function isTranspilePresent(mod) {
573
587
  return flow.options.build.transpile.some((t) => !(t instanceof Function) && (t instanceof RegExp ? t.test(mod) : new RegExp(t).test(mod)));
574
588
  }
@@ -581,10 +595,7 @@ const addModuleTranspiles = (opts = {}) => {
581
595
  function createFlow(options) {
582
596
  const hooks = createHooks();
583
597
  const flow = {
584
- //* Include nuxt version
585
- _version: "3.0.0",
586
- //* Include version
587
- // @ts-ignore
598
+ _version: "3.0.0-rc.3",
588
599
  version,
589
600
  options,
590
601
  hooks,
@@ -598,12 +609,10 @@ function createFlow(options) {
598
609
  return flow;
599
610
  }
600
611
  async function initFlow(flow) {
601
- flow.hooks.addHooks(flow.options.hooks);
602
612
  nuxtCtx.set(flow);
603
613
  flow.hook("close", () => nuxtCtx.unset());
604
- await flow.callHook("modules:before");
614
+ await flow.callHook("modules:before", { nuxt: flow });
605
615
  const modulesToInstall = [
606
- // ...flow.options.buildModules,
607
616
  ...flow.options.modules,
608
617
  ...flow.options._modules
609
618
  ];
@@ -613,26 +622,16 @@ async function initFlow(flow) {
613
622
  else
614
623
  await installModule(m, {});
615
624
  }
616
- await flow.callHook("modules:done");
617
- flow.options.build.transpile = flow.options.build.transpile.map((t) => typeof t === "string" ? normalize(t) : t);
618
- addModuleTranspiles();
625
+ await flow.callHook("modules:done", { nuxt: flow });
626
+ await addModuleTranspiles();
619
627
  await initNitro(flow);
620
628
  await flow.callHook("ready", flow);
621
629
  }
622
630
  async function loadFlow(opts) {
623
- const start1 = Date.now();
624
631
  const options = await loadFlowConfig(opts);
625
- logger.info(`Config loading in ${Date.now() - start1}ms`);
626
632
  options.appDir = resolve(distDir, "app");
627
- options.alias["#app"] = resolve(distDir, "app/index");
628
633
  options._majorVersion = 3;
629
- options._modules.push(pagesModule, metaModule);
630
- options._modules.push([importsModule, {
631
- transform: {
632
- include: options._layers.filter((i) => i.cwd && i.cwd.includes("node_modules")).map((i) => new RegExp(`(^|\\/)${escapeRE(i.cwd.split("node_modules/").pop())}(\\/|$)(?!node_modules\\/)`))
633
- }
634
- }]);
635
- options.modulesDir.push(resolve(options.workspaceDir, "node_modules"));
634
+ options._modules.push(pagesModule, metaModule, autoImportsModule, viteModule);
636
635
  options.modulesDir.push(resolve(pkgDir, "node_modules"));
637
636
  const flow = createFlow(options);
638
637
  if (opts.ready !== false)
@@ -647,17 +646,11 @@ const serverPluginTemplate = {
647
646
  filename: "plugins/server.mjs",
648
647
  getContents(ctx) {
649
648
  const serverPlugins = ctx.app.plugins;
650
- const exports = [];
651
- const imports = [];
652
- for (const plugin of serverPlugins) {
653
- const path = relative(ctx.nuxt.options.rootDir, plugin.src);
654
- const variable = `${genSafeVariableName(path).replace(/_(45|46|47)/g, "_")}_${hash(path)}`;
655
- exports.push(variable);
656
- imports.push(genImport(plugin.src, variable));
657
- }
658
649
  return [
659
- ...imports,
660
- `export default ${genArrayFromRaw(exports)}`
650
+ templateUtils.importSources(serverPlugins.map((p) => p.src)),
651
+ `export default ${genArrayFromRaw([
652
+ ...serverPlugins.map((p) => templateUtils.importName(p.src))
653
+ ])}`
661
654
  ].join("\n");
662
655
  }
663
656
  };
@@ -686,52 +679,43 @@ export { }
686
679
  `;
687
680
  }
688
681
  };
689
- const adHocModules = ["imports", "meta", "pages"];
682
+ const adHocModules = ["auto-imports", "meta", "pages", "vite-client"];
690
683
  const schemaTemplate = {
691
684
  filename: "types/schema.d.ts",
692
- getContents: async ({ nuxt }) => {
685
+ getContents: ({ nuxt }) => {
693
686
  const moduleInfo = nuxt.options._installedModules.map((m) => ({
694
687
  ...m.meta || {},
695
688
  importName: m.entryPath || m.meta?.name
696
689
  })).filter((m) => m.configKey && m.name && !adHocModules.includes(m.name));
697
- const relativeRoot = relative(resolve(nuxt.options.buildDir, "types"), nuxt.options.rootDir);
698
690
  return [
699
691
  "import { FlowModule } from '@monkeyplus/flow-schema'",
700
692
  "declare module '@monkeyplus/flow-schema' {",
701
693
  " interface FlowConfig {",
702
- ...moduleInfo.filter(Boolean).map(
703
- (meta) => ` [${genString(meta.configKey)}]?: typeof ${genDynamicImport(meta.importName.startsWith(".") ? `./${join(relativeRoot, meta.importName)}` : meta.importName, { wrapper: false })}.default extends FlowModule<infer O> ? Partial<O> : Record<string, any>`
704
- ),
694
+ ...moduleInfo.filter(Boolean).map((meta) => ` [${genString(meta.configKey)}]?: typeof ${genDynamicImport(meta.importName, { wrapper: false })}.default extends FlowModule<infer O> ? Partial<O> : Record<string, any>`),
705
695
  " }",
706
- generateTypes(
707
- await resolveSchema(Object.fromEntries(Object.entries(nuxt.options.runtimeConfig).filter(([key]) => key !== "public"))),
708
- {
709
- interfaceName: "RuntimeConfig",
710
- addExport: false,
711
- addDefaults: false,
712
- allowExtraKeys: false,
713
- indentation: 2
714
- }
715
- ),
716
- generateTypes(
717
- await resolveSchema(nuxt.options.runtimeConfig.public),
718
- {
719
- interfaceName: "PublicRuntimeConfig",
720
- addExport: false,
721
- addDefaults: false,
722
- allowExtraKeys: false,
723
- indentation: 2
724
- }
725
- ),
696
+ generateTypes(resolveSchema(Object.fromEntries(Object.entries(nuxt.options.runtimeConfig).filter(([key]) => key !== "public"))), {
697
+ interfaceName: "RuntimeConfig",
698
+ addExport: false,
699
+ addDefaults: false,
700
+ allowExtraKeys: false,
701
+ indentation: 2
702
+ }),
703
+ generateTypes(resolveSchema(nuxt.options.runtimeConfig.public), {
704
+ interfaceName: "PublicRuntimeConfig",
705
+ addExport: false,
706
+ addDefaults: false,
707
+ allowExtraKeys: false,
708
+ indentation: 2
709
+ }),
726
710
  "}"
727
711
  ].join("\n");
728
712
  }
729
713
  };
730
714
  const publicPathTemplate = {
731
715
  filename: "paths.mjs",
732
- async getContents({ nuxt }) {
716
+ getContents({ nuxt }) {
733
717
  return [
734
- `import { joinURL } from '${await _resolveId("ufo")}'`,
718
+ "import { joinURL } from 'ufo'",
735
719
  !nuxt.options.dev && "import { useRuntimeConfig } from '#internal/nitro'",
736
720
  nuxt.options.dev ? `const appConfig = ${JSON.stringify(nuxt.options.app)}` : "const appConfig = useRuntimeConfig().app",
737
721
  "export const baseURL = () => appConfig.baseURL",
@@ -744,39 +728,15 @@ const publicPathTemplate = {
744
728
  ].filter(Boolean).join("\n");
745
729
  }
746
730
  };
747
- function _resolveId(id) {
748
- return resolvePath(id, {
749
- url: [
750
- // @ts-ignore
751
- global.__NUXT_PREPATHS__,
752
- import.meta.url,
753
- process.cwd(),
754
- // @ts-ignore
755
- global.__NUXT_PATHS__
756
- ]
757
- });
758
- }
759
731
 
760
732
  const defaultTemplates = {
761
733
  __proto__: null,
734
+ serverPluginTemplate: serverPluginTemplate,
762
735
  pluginsDeclaration: pluginsDeclaration,
763
- publicPathTemplate: publicPathTemplate,
764
736
  schemaTemplate: schemaTemplate,
765
- serverPluginTemplate: serverPluginTemplate
737
+ publicPathTemplate: publicPathTemplate
766
738
  };
767
739
 
768
- function uniqueBy(arr, key) {
769
- const res = [];
770
- const seen = /* @__PURE__ */ new Set();
771
- for (const item of arr) {
772
- if (seen.has(item[key]))
773
- continue;
774
- seen.add(item[key]);
775
- res.push(item);
776
- }
777
- return res;
778
- }
779
-
780
740
  function createApp(flow, options = {}) {
781
741
  return defu(options, {
782
742
  dir: flow.options.srcDir,
@@ -785,95 +745,51 @@ function createApp(flow, options = {}) {
785
745
  templates: []
786
746
  });
787
747
  }
788
- async function generateApp(flow, app, options) {
748
+ async function generateApp(flow, app) {
789
749
  await resolveApp(flow, app);
790
- app.templates = Object.values(defaultTemplates).concat(
791
- flow.options.build.templates
792
- );
750
+ app.templates = Object.values(defaultTemplates).concat(flow.options.build.templates);
793
751
  await flow.callHook("app:templates", app);
794
752
  app.templates = app.templates.map((tmpl) => normalizeTemplate(tmpl));
795
753
  const templateContext = { utils: templateUtils, nuxt: flow, app };
796
- await Promise.all(
797
- app.templates.map(async (template) => {
798
- const contents = await compileTemplate(template, templateContext);
799
- const fullPath = template.dst || resolve(flow.options.buildDir, template.filename);
800
- flow.vfs[fullPath] = contents;
801
- const aliasPath = `#build/${template.filename.replace(/\.\w+$/, "")}`;
802
- flow.vfs[aliasPath] = contents;
803
- if (process.platform === "win32")
804
- flow.vfs[fullPath.replace(/\//g, "\\")] = contents;
805
- if (template.write) {
806
- await promises.mkdir(dirname(fullPath), { recursive: true });
807
- await promises.writeFile(fullPath, contents, "utf8");
808
- }
809
- })
810
- );
754
+ await Promise.all(app.templates.map(async (template) => {
755
+ const contents = await compileTemplate(template, templateContext);
756
+ const fullPath = template.dst || resolve(flow.options.buildDir, template.filename);
757
+ flow.vfs[fullPath] = contents;
758
+ const aliasPath = `#build/${template.filename.replace(/\.\w+$/, "")}`;
759
+ flow.vfs[aliasPath] = contents;
760
+ if (process.platform === "win32")
761
+ flow.vfs[fullPath.replace(/\//g, "\\")] = contents;
762
+ if (template.write) {
763
+ await promises.mkdir(dirname(fullPath), { recursive: true });
764
+ await promises.writeFile(fullPath, contents, "utf8");
765
+ }
766
+ }));
811
767
  await flow.callHook("app:templatesGenerated", app);
812
768
  }
813
769
  async function resolveApp(flow, app) {
814
- app.plugins = [
815
- ...flow.options.plugins.map(normalizePlugin)
816
- ];
770
+ app.plugins = [...flow.options.plugins.map(normalizePlugin)];
817
771
  for (const config of flow.options._layers.map((layer) => layer.config)) {
818
772
  app.plugins.push(...[
819
773
  ...config.plugins || [],
820
- ...config.srcDir ? await resolveFilesFlow(config.srcDir, [
821
- `${config.dir?.plugins || "plugins"}/*.{ts,js,mjs,cjs,mts,cts}`,
822
- `${config.dir?.plugins || "plugins"}/*/index.*{ts,js,mjs,cjs,mts,cts}`
823
- ]) : []
774
+ ...await resolveFilesFlow(config.srcDir, [
775
+ "plugins/*.{ts,js,mjs,cjs,mts,cts}",
776
+ "plugins/*/index.*{ts,js,mjs,cjs,mts,cts}"
777
+ ])
824
778
  ].map((plugin) => normalizePlugin(plugin)));
825
779
  }
826
- app.configs = [];
827
- for (const config of flow.options._layers.map((layer) => layer.config)) {
828
- const appConfigPath = await findPath(resolve(config.srcDir, "app.config"));
829
- if (appConfigPath)
830
- app.configs.push(appConfigPath);
831
- }
832
- await flow.callHook("app:resolve", app);
833
780
  app.plugins = uniqueBy(app.plugins, "src");
781
+ await flow.callHook("app:resolve", app);
834
782
  }
835
-
836
- const PREFIX = "virtual:nuxt:";
837
- function virtual(vfs) {
838
- const extensions = ["", ".ts", ".vue", ".mjs", ".cjs", ".js", ".json"];
839
- const resolveWithExt = (id) => {
840
- for (const ext of extensions) {
841
- const rId = id + ext;
842
- if (rId in vfs)
843
- return rId;
844
- }
845
- return null;
846
- };
847
- return {
848
- name: "virtual",
849
- resolveId(id, importer) {
850
- if (process.platform === "win32" && isAbsolute(id)) {
851
- id = resolve(id);
852
- }
853
- const resolvedId = resolveWithExt(id);
854
- if (resolvedId)
855
- return PREFIX + resolvedId;
856
- if (importer && !isAbsolute(id)) {
857
- const importerNoPrefix = importer.startsWith(PREFIX) ? importer.slice(PREFIX.length) : importer;
858
- const importedDir = dirname(importerNoPrefix);
859
- const resolved = resolveWithExt(join(importedDir, id));
860
- if (resolved)
861
- return PREFIX + resolved;
862
- }
863
- return null;
864
- },
865
- load(id) {
866
- if (!id.startsWith(PREFIX))
867
- return null;
868
- const idNoPrefix = id.slice(PREFIX.length);
869
- if (idNoPrefix in vfs) {
870
- return {
871
- code: vfs[idNoPrefix],
872
- map: null
873
- };
874
- }
875
- }
876
- };
783
+ function uniqueBy(arr, key) {
784
+ const res = [];
785
+ const seen = /* @__PURE__ */ new Set();
786
+ for (const item of arr) {
787
+ if (seen.has(item[key]))
788
+ continue;
789
+ seen.add(item[key]);
790
+ res.push(item);
791
+ }
792
+ return res;
877
793
  }
878
794
 
879
795
  async function warmupViteServer(server, entries) {
@@ -894,11 +810,6 @@ async function warmupViteServer(server, entries) {
894
810
  await Promise.all(entries.map((entry) => warmup(entry)));
895
811
  }
896
812
 
897
- const wpfs = {
898
- ...fse,
899
- join
900
- };
901
-
902
813
  function cacheDirPlugin(rootDir, name) {
903
814
  const optimizeCacheDir = resolve(rootDir, "node_modules/.cache/vite", name);
904
815
  return {
@@ -909,63 +820,279 @@ function cacheDirPlugin(rootDir, name) {
909
820
  };
910
821
  }
911
822
 
912
- async function buildServer(ctx) {
823
+ const wpfs = {
824
+ ...fse,
825
+ join
826
+ };
827
+
828
+ function uniq(arr) {
829
+ return Array.from(new Set(arr));
830
+ }
831
+ const IS_CSS_RE = /\.(?:css|scss|sass|postcss|less|stylus|styl)(\?[^.]+)?$/;
832
+ function isCSS(file) {
833
+ return IS_CSS_RE.test(file);
834
+ }
835
+ function hashId(id) {
836
+ return `$id_${hash(id)}`;
837
+ }
838
+ function hash(input, length = 8) {
839
+ return createHash("sha256").update(input).digest("hex").slice(0, length);
840
+ }
841
+ function readDirRecursively(dir) {
842
+ return readdirSync(dir).reduce((files, file) => {
843
+ const name = join(dir, file);
844
+ const isDirectory2 = statSync(name).isDirectory();
845
+ return isDirectory2 ? [...files, ...readDirRecursively(name)] : [...files, name];
846
+ }, []);
847
+ }
848
+ async function isDirectory(path) {
849
+ try {
850
+ return (await promises.stat(path)).isDirectory();
851
+ } catch (_err) {
852
+ return false;
853
+ }
854
+ }
855
+
856
+ function isExternal(opts, id) {
857
+ const ssrConfig = opts.viteServer.config.ssr;
858
+ const externalOpts = {
859
+ inline: [
860
+ /virtual:/,
861
+ /\.ts$/,
862
+ ...ExternalsDefaults.inline,
863
+ ...ssrConfig.noExternal
864
+ ],
865
+ external: [
866
+ /node_modules/
867
+ ],
868
+ resolve: {
869
+ type: "module",
870
+ extensions: [".ts", ".js", ".json", ".vue", ".mjs", ".jsx", ".tsx", ".wasm"]
871
+ }
872
+ };
873
+ return isExternal$1(id, opts.viteServer.config.root, externalOpts);
874
+ }
875
+ async function transformRequest(opts, id) {
876
+ if (id && id.startsWith("/@id/__x00__"))
877
+ id = `\0${id.slice("/@id/__x00__".length)}`;
878
+ if (id && id.startsWith("/@id/"))
879
+ id = id.slice("/@id/".length);
880
+ if (id && id.startsWith("/@fs/")) {
881
+ id = id.slice("/@fs".length);
882
+ if (id.match(/^\/\w:/))
883
+ id = id.slice(1);
884
+ } else if (!id.includes("entry") && id.startsWith("/")) {
885
+ const resolvedPath = resolve(opts.viteServer.config.root, `.${id}`);
886
+ if (existsSync(resolvedPath))
887
+ id = resolvedPath;
888
+ }
889
+ const withoutVersionQuery = id.replace(/\?v=\w+$/, "");
890
+ if (await isExternal(opts, withoutVersionQuery)) {
891
+ const path = builtinModules.includes(withoutVersionQuery.split("node:").pop()) ? withoutVersionQuery : pathToFileURL(withoutVersionQuery).href;
892
+ return {
893
+ code: `(global, module, _, exports, importMeta, ssrImport, ssrDynamicImport, ssrExportAll) =>
894
+ ${genDynamicImport(path, { wrapper: false })}
895
+ .then(r => {
896
+ if (r.default && r.default.__esModule)
897
+ r = r.default
898
+ exports.default = r.default
899
+ ssrExportAll(r)
900
+ })
901
+ .catch(e => {
902
+ console.error(e)
903
+ throw new Error(${JSON.stringify(`[vite dev] Error loading external "${id}".`)})
904
+ })`,
905
+ deps: [],
906
+ dynamicDeps: []
907
+ };
908
+ }
909
+ const res = await opts.viteServer.transformRequest(id, { ssr: true }).catch((err) => {
910
+ console.warn(`[SSR] Error transforming ${id}:`, err);
911
+ }) || { code: "", map: {}, deps: [], dynamicDeps: [] };
912
+ const code = `async function (global, module, exports, __vite_ssr_exports__, __vite_ssr_import_meta__, __vite_ssr_import__, __vite_ssr_dynamic_import__, __vite_ssr_exportAll__) {
913
+ ${res.code || "/* empty */"};
914
+ }`;
915
+ return { code, deps: res.deps || [], dynamicDeps: res.dynamicDeps || [] };
916
+ }
917
+ async function transformRequestRecursive(opts, id, parent = "<entry>", chunks = {}) {
918
+ if (chunks[id]) {
919
+ chunks[id].parents.push(parent);
920
+ return;
921
+ }
922
+ const res = await transformRequest(opts, id);
923
+ const deps = uniq([...res.deps, ...res.dynamicDeps]);
924
+ chunks[id] = {
925
+ id,
926
+ code: res.code,
927
+ deps,
928
+ parents: [parent]
929
+ };
930
+ for (const dep of deps)
931
+ await transformRequestRecursive(opts, dep, id, chunks);
932
+ return Object.values(chunks);
933
+ }
934
+ async function bundleRequest(opts, entryURL) {
935
+ const chunks = await transformRequestRecursive(opts, entryURL);
936
+ const listIds = (ids) => ids.map((id) => `// - ${id} (${hashId(id)})`).join("\n");
937
+ const chunksCode = chunks.map((chunk) => `
938
+ // --------------------
939
+ // Request: ${chunk.id}
940
+ // Parents:
941
+ ${listIds(chunk.parents)}
942
+ // Dependencies:
943
+ ${listIds(chunk.deps)}
944
+ // --------------------
945
+ const ${hashId(chunk.id)} = ${chunk.code}
946
+ `).join("\n");
947
+ const manifestCode = `const __modules__ = ${genObjectFromRawEntries(chunks.map((chunk) => [chunk.id, hashId(chunk.id)]))}`;
948
+ const ssrModuleLoader = `
949
+ const __pendingModules__ = new Map()
950
+ const __pendingImports__ = new Map()
951
+ const __ssrContext__ = { global: globalThis }
952
+
953
+ function __ssrLoadModule__(url, urlStack = []) {
954
+ const pendingModule = __pendingModules__.get(url)
955
+ if (pendingModule) { return pendingModule }
956
+ const modulePromise = __instantiateModule__(url, urlStack)
957
+ __pendingModules__.set(url, modulePromise)
958
+ modulePromise.catch(() => { __pendingModules__.delete(url) })
959
+ .finally(() => { __pendingModules__.delete(url) })
960
+ return modulePromise
961
+ }
962
+
963
+ async function __instantiateModule__(url, urlStack) {
964
+ const mod = __modules__[url]
965
+ if (mod.stubModule) { return mod.stubModule }
966
+ const stubModule = { [Symbol.toStringTag]: 'Module' }
967
+ Object.defineProperty(stubModule, '__esModule', { value: true })
968
+ mod.stubModule = stubModule
969
+ // https://vitejs.dev/guide/api-hmr.html
970
+ const importMeta = { url, hot: { accept() {}, prune() {}, dispose() {}, invalidate() {}, decline() {}, on() {} } }
971
+ urlStack = urlStack.concat(url)
972
+ const isCircular = url => urlStack.includes(url)
973
+ const pendingDeps = []
974
+ const ssrImport = async (dep) => {
975
+ // TODO: Handle externals if dep[0] !== '.' | '/'
976
+ if (!isCircular(dep) && !__pendingImports__.get(dep)?.some(isCircular)) {
977
+ pendingDeps.push(dep)
978
+ if (pendingDeps.length === 1) {
979
+ __pendingImports__.set(url, pendingDeps)
980
+ }
981
+ await __ssrLoadModule__(dep, urlStack)
982
+ if (pendingDeps.length === 1) {
983
+ __pendingImports__.delete(url)
984
+ } else {
985
+ pendingDeps.splice(pendingDeps.indexOf(dep), 1)
986
+ }
987
+ }
988
+ return __modules__[dep].stubModule
989
+ }
990
+ function ssrDynamicImport (dep) {
991
+ // TODO: Handle dynamic import starting with . relative to url
992
+ return ssrImport(dep)
993
+ }
994
+
995
+ function ssrExportAll(sourceModule) {
996
+ for (const key in sourceModule) {
997
+ if (key !== 'default') {
998
+ try {
999
+ Object.defineProperty(stubModule, key, {
1000
+ enumerable: true,
1001
+ configurable: true,
1002
+ get() { return sourceModule[key] }
1003
+ })
1004
+ } catch (_err) { }
1005
+ }
1006
+ }
1007
+ }
1008
+
1009
+ const cjsModule = {
1010
+ get exports () {
1011
+ return stubModule.default
1012
+ },
1013
+ set exports (v) {
1014
+ stubModule.default = v
1015
+ },
1016
+ }
1017
+
1018
+ await mod(
1019
+ __ssrContext__.global,
1020
+ cjsModule,
1021
+ stubModule.default,
1022
+ stubModule,
1023
+ importMeta,
1024
+ ssrImport,
1025
+ ssrDynamicImport,
1026
+ ssrExportAll
1027
+ )
1028
+
1029
+ return stubModule
1030
+ }
1031
+ `;
1032
+ const code = [
1033
+ chunksCode,
1034
+ manifestCode,
1035
+ ssrModuleLoader,
1036
+ `export default await __ssrLoadModule__(${JSON.stringify(entryURL)})`
1037
+ ].join("\n\n");
1038
+ return {
1039
+ code,
1040
+ ids: chunks.map((i) => i.id)
1041
+ };
1042
+ }
1043
+
1044
+ async function writeManifest(ctx, extraEntries = []) {
1045
+ const clientDist = resolve(ctx.flow.options.buildDir, "dist/client");
1046
+ const serverDist = resolve(ctx.flow.options.buildDir, "dist/server");
1047
+ const entries = [
1048
+ "@vite/client",
1049
+ "entry.mjs",
1050
+ ...extraEntries
1051
+ ];
1052
+ const devClientManifest = {
1053
+ publicPath: joinURL(ctx.flow.options.app.baseURL, ctx.flow.options.app.buildAssetsDir),
1054
+ all: entries,
1055
+ initial: entries,
1056
+ async: [],
1057
+ modules: {}
1058
+ };
1059
+ const clientManifest = ctx.flow.options.dev ? devClientManifest : await fse.readJSON(resolve(clientDist, "manifest.json"));
1060
+ await fse.mkdirp(serverDist);
1061
+ await fse.writeFile(resolve(serverDist, "client.manifest.json"), JSON.stringify(clientManifest, null, 2), "utf8");
1062
+ await fse.writeFile(resolve(serverDist, "client.manifest.mjs"), `export default ${JSON.stringify(clientManifest, null, 2)}`, "utf8");
1063
+ }
1064
+
1065
+ const buildServer = async (ctx) => {
913
1066
  const serverConfig = vite.mergeConfig(ctx.config, {
914
- base: ctx.nuxt.options.dev ? joinURL(ctx.nuxt.options.app.baseURL.replace(/^\.\//, "/") || "/", ctx.nuxt.options.app.buildAssetsDir) : void 0,
915
- // experimental: {
916
- // renderBuiltUrl: (filename, { type, hostType }) => {
917
- // if (hostType !== 'js') {
918
- // // In CSS we only use relative paths until we craft a clever runtime CSS hack
919
- // return { relative: true };
920
- // }
921
- // if (type === 'public')
922
- // return { runtime: `globalThis.__publicAssetsURL(${JSON.stringify(filename)})` };
923
- // if (type === 'asset') {
924
- // const relativeFilename = filename.replace(withTrailingSlash(withoutLeadingSlash(ctx.nuxt.options.app.buildAssetsDir)), '');
925
- // return { runtime: `globalThis.__buildAssetsURL(${JSON.stringify(relativeFilename)})` };
926
- // }
927
- // },
928
- // },
1067
+ configFile: false,
929
1068
  define: {
930
1069
  "process.server": true,
931
- "process.client": false,
932
1070
  "typeof window": '"undefined"',
933
1071
  "typeof document": '"undefined"',
934
1072
  "typeof navigator": '"undefined"',
935
1073
  "typeof location": '"undefined"',
936
1074
  "typeof XMLHttpRequest": '"undefined"'
937
1075
  },
938
- resolve: {
939
- alias: {
940
- "#build/plugins": resolve(ctx.nuxt.options.buildDir, "plugins/server")
941
- }
942
- },
943
1076
  ssr: {
944
- external: ["#internal/nitro", "#internal/nitro/utils"],
945
1077
  noExternal: [
946
- ...ctx.nuxt.options.build.transpile,
947
- // TODO: Use externality for production (rollup) build
1078
+ ...ctx.flow.options.build.transpile,
948
1079
  /\/esm\/.*\.js$/,
949
1080
  /\.(es|esm|esm-browser|esm-bundler).js$/,
950
1081
  "/__vue-jsx",
951
1082
  "#app",
952
1083
  /(nuxt|nuxt3)\/(dist|src|app)/,
953
- /flow\/(dist|src|app)/,
954
- /flow\/modules\/(content|icons|images|netlify|netlify-cms|seo|sitemap|vue)/,
955
1084
  /@monkeyplus\/flow\/(dist|src|app)/,
956
1085
  /@nuxt\/nitro\/(dist|src)/
957
1086
  ]
958
1087
  },
959
1088
  build: {
960
- outDir: resolve(ctx.nuxt.options.buildDir, "dist/server"),
961
- ssr: true,
1089
+ outDir: resolve(ctx.flow.options.buildDir, "dist/server"),
1090
+ manifest: true,
962
1091
  rollupOptions: {
963
1092
  external: ["#internal/nitro"],
964
1093
  output: {
965
1094
  entryFileNames: "server.mjs",
966
1095
  preferConst: true,
967
- // TODO: https://github.com/vitejs/vite/pull/8641
968
- inlineDynamicImports: !ctx.nuxt.options.experimental.viteServerDynamicImports,
969
1096
  format: "module"
970
1097
  },
971
1098
  onwarn(warning, rollupWarn) {
@@ -975,31 +1102,39 @@ async function buildServer(ctx) {
975
1102
  }
976
1103
  },
977
1104
  server: {
978
- // https://github.com/vitest-dev/vitest/issues/229#issuecomment-1002685027
979
1105
  preTransformRequests: false,
980
- hmr: false
1106
+ cors: true
981
1107
  },
982
1108
  plugins: [
983
- cacheDirPlugin(ctx.nuxt.options.rootDir, "server"),
984
- replace({
985
- ...Object.fromEntries([";", "(", "{", "}", " ", " ", "\n"].map((d) => [`${d}global.`, `${d}globalThis.`])),
986
- preventAssignment: true
987
- })
988
- // vuePlugin(ctx.config.vue),
989
- // viteJsxPlugin(),
1109
+ cacheDirPlugin(ctx.flow.options.rootDir, "server")
990
1110
  ]
991
1111
  });
992
- if (ctx.nuxt.options.typescript.typeCheck === true || ctx.nuxt.options.typescript.typeCheck === "build" && !ctx.nuxt.options.dev) {
993
- const checker = await import('vite-plugin-checker').then((r) => r.default);
994
- serverConfig.plugins.push(checker({
995
- vueTsc: {
996
- tsconfigPath: await resolveTSConfig(ctx.nuxt.options.rootDir)
1112
+ await ctx.flow.callHook("vite:extendConfig", serverConfig, { isClient: false, isServer: true });
1113
+ ctx.flow.hook("nitro:build:before", async () => {
1114
+ if (ctx.flow.options.dev)
1115
+ return;
1116
+ const clientDist = resolve(ctx.flow.options.buildDir, "dist/client");
1117
+ const publicDir = join(ctx.flow.options.srcDir, ctx.flow.options.dir.public);
1118
+ let publicFiles = [];
1119
+ if (await isDirectory(publicDir)) {
1120
+ publicFiles = readDirRecursively(publicDir).map((r) => r.replace(publicDir, ""));
1121
+ for (const file of publicFiles) {
1122
+ try {
1123
+ fse.rmSync(join(clientDist, file));
1124
+ } catch {
1125
+ }
997
1126
  }
998
- }));
999
- }
1000
- await ctx.nuxt.callHook("vite:extendConfig", serverConfig, { isClient: false, isServer: true });
1001
- const onBuild = () => ctx.nuxt.callHook("build:resources", wpfs);
1002
- if (!ctx.nuxt.options.dev) {
1127
+ }
1128
+ if (await isDirectory(clientDist)) {
1129
+ const nestedAssetsPath = withoutTrailingSlash(join(clientDist, ctx.flow.options.app.buildAssetsDir));
1130
+ if (await isDirectory(nestedAssetsPath)) {
1131
+ await fse.copy(nestedAssetsPath, clientDist, { recursive: true });
1132
+ await fse.remove(nestedAssetsPath);
1133
+ }
1134
+ }
1135
+ });
1136
+ const onBuild = () => ctx.flow.callHook("build:resources", wpfs);
1137
+ if (!ctx.flow.options.dev) {
1003
1138
  const start = Date.now();
1004
1139
  logger.info("Building server...");
1005
1140
  await vite.build(serverConfig);
@@ -1009,87 +1144,184 @@ async function buildServer(ctx) {
1009
1144
  }
1010
1145
  const viteServer = await vite.createServer(serverConfig);
1011
1146
  ctx.ssrServer = viteServer;
1012
- await ctx.nuxt.callHook("vite:serverCreated", viteServer, { isClient: false, isServer: true });
1013
- ctx.nuxt.hook("close", () => viteServer.close());
1147
+ await ctx.flow.callHook("vite:serverCreated", viteServer, { isClient: false, isServer: true });
1148
+ ctx.flow.hook("close", () => viteServer.close());
1014
1149
  await viteServer.pluginContainer.buildStart({});
1015
- await import('./chunks/dev-bundler.mjs').then((r) => r.initViteDevBundler(ctx, onBuild));
1150
+ const _doBuild = async () => {
1151
+ const start = Date.now();
1152
+ const { code, ids } = await bundleRequest({ viteServer }, resolve(ctx.flow.options.appDir, "entry"));
1153
+ await fse.ensureFile(resolve(ctx.flow.options.buildDir, "dist/server/server.mjs"));
1154
+ await fse.writeFile(resolve(ctx.flow.options.buildDir, "dist/server/server.mjs"), code, "utf-8");
1155
+ await writeManifest(ctx, ids.filter(isCSS).map((i) => i.slice(1)));
1156
+ const time = Date.now() - start;
1157
+ logger.success(`Vite server built in ${time}ms`);
1158
+ await onBuild();
1159
+ ctx.flow.callHook("bundler:change", {});
1160
+ };
1161
+ const doBuild = debounce(_doBuild);
1162
+ await _doBuild();
1163
+ viteServer.watcher.on("all", (_event, file) => {
1164
+ file = normalize(file);
1165
+ if (file.indexOf(ctx.flow.options.buildDir) === 0)
1166
+ return;
1167
+ doBuild();
1168
+ });
1169
+ ctx.flow.hook("app:templatesGenerated", () => doBuild());
1170
+ };
1171
+
1172
+ const PREFIX = "virtual:";
1173
+ function virtual(vfs) {
1174
+ const extensions = ["", ".ts", ".vue", ".mjs", ".cjs", ".js", ".json"];
1175
+ const resolveWithExt = (id) => {
1176
+ for (const ext of extensions) {
1177
+ const rId = id + ext;
1178
+ if (rId in vfs)
1179
+ return rId;
1180
+ }
1181
+ return null;
1182
+ };
1183
+ return {
1184
+ name: "virtual",
1185
+ resolveId(id, importer) {
1186
+ if (process.platform === "win32" && isAbsolute(id)) {
1187
+ id = resolve(id);
1188
+ }
1189
+ const resolvedId = resolveWithExt(id);
1190
+ if (resolvedId)
1191
+ return PREFIX + resolvedId;
1192
+ if (importer && !isAbsolute(id)) {
1193
+ const importerNoPrefix = importer.startsWith(PREFIX) ? importer.slice(PREFIX.length) : importer;
1194
+ const importedDir = dirname(importerNoPrefix);
1195
+ const resolved = resolveWithExt(join(importedDir, id));
1196
+ if (resolved)
1197
+ return PREFIX + resolved;
1198
+ }
1199
+ return null;
1200
+ },
1201
+ load(id) {
1202
+ if (!id.startsWith(PREFIX))
1203
+ return null;
1204
+ const idNoPrefix = id.slice(PREFIX.length);
1205
+ return {
1206
+ code: vfs[idNoPrefix],
1207
+ map: null
1208
+ };
1209
+ }
1210
+ };
1016
1211
  }
1017
1212
 
1018
- async function bundle$1(nuxt) {
1019
- const entry = resolve(nuxt.options.appDir, nuxt.options.experimental.asyncEntry ? "entry.async" : "entry");
1213
+ const VITE_ASSET_RE = /^export default ["'](__VITE_ASSET.*)["']$/;
1214
+ const DynamicBasePlugin = createUnplugin((options = {}) => {
1215
+ return {
1216
+ name: "nuxt:dynamic-base-path",
1217
+ resolveId(id) {
1218
+ if (id.startsWith("/__NUXT_BASE__"))
1219
+ return id.replace("/__NUXT_BASE__", "");
1220
+ if (id === "#internal/nitro")
1221
+ return "#internal/nitro";
1222
+ return null;
1223
+ },
1224
+ enforce: "post",
1225
+ transform(code, id) {
1226
+ const s = new MagicString(code);
1227
+ if (options.globalPublicPath && id.includes("paths.mjs") && code.includes("const appConfig = "))
1228
+ s.append(`${options.globalPublicPath} = buildAssetsURL();
1229
+ `);
1230
+ const assetId = code.match(VITE_ASSET_RE);
1231
+ if (assetId) {
1232
+ s.overwrite(0, code.length, [
1233
+ "import { buildAssetsURL } from '#build/paths.mjs';",
1234
+ `export default buildAssetsURL("${assetId[1]}".replace("/__NUXT_BASE__", ""));`
1235
+ ].join("\n"));
1236
+ }
1237
+ if (!id.includes("paths.mjs") && code.includes("NUXT_BASE") && !code.includes("import { publicAssetsURL as __publicAssetsURL }"))
1238
+ s.prepend("import { publicAssetsURL as __publicAssetsURL } from '#build/paths.mjs';\n");
1239
+ if (id === "vite/preload-helper") {
1240
+ s.prepend("import { buildAssetsDir } from '#build/paths.mjs';\n");
1241
+ s.replace(/const base = ['"]\/__NUXT_BASE__\/['"]/, "const base = buildAssetsDir()");
1242
+ }
1243
+ s.replace(/from *['"]\/__NUXT_BASE__(\/[^'"]*)['"]/g, 'from "$1"');
1244
+ const delimiterRE = /(?<!(const base = |from *))(`([^`]*)\/__NUXT_BASE__\/([^`]*)`|'([^']*)\/__NUXT_BASE__\/([^']*)'|"([^"]*)\/__NUXT_BASE__\/([^"]*)")/g;
1245
+ s.replace(delimiterRE, (r) => `\`${r.replace(/\/__NUXT_BASE__\//g, "${__publicAssetsURL()}").slice(1, -1)}\``);
1246
+ if (s.hasChanged()) {
1247
+ return {
1248
+ code: s.toString(),
1249
+ map: options.sourcemap && s.generateMap({ source: id, includeContent: true })
1250
+ };
1251
+ }
1252
+ }
1253
+ };
1254
+ });
1255
+
1256
+ async function bundleVite(flow) {
1257
+ const hmrPortDefault = 24678;
1258
+ const hmrPort = await getPort({
1259
+ port: hmrPortDefault,
1260
+ ports: Array.from({ length: 20 }, (_, i) => hmrPortDefault + 1 + i)
1261
+ });
1020
1262
  const ctx = {
1021
- nuxt,
1022
- entry,
1023
- config: vite.mergeConfig(
1024
- {
1025
- configFile: false,
1026
- resolve: {
1027
- alias: {
1028
- ...nuxt.options.alias,
1029
- "#app": nuxt.options.appDir,
1030
- // We need this resolution to be present before the following entry, but it
1031
- // will be filled in client/server configs
1032
- "#build/plugins": "",
1033
- "#build": nuxt.options.buildDir,
1034
- "web-streams-polyfill/ponyfill/es2018": "unenv/runtime/mock/empty",
1035
- // Cannot destructure property 'AbortController' of ..
1036
- "abort-controller": "unenv/runtime/mock/empty"
1037
- }
1038
- },
1039
- optimizeDeps: {
1040
- entries: [entry],
1041
- include: []
1042
- },
1043
- // css: resolveCSSOptions(nuxt),
1044
- build: {
1045
- rollupOptions: {
1046
- output: { sanitizeFileName: sanitizeFilePath },
1047
- input: resolve(nuxt.options.appDir, "entry")
1048
- },
1049
- watch: {
1050
- exclude: nuxt.options.ignore
1051
- }
1052
- },
1053
- plugins: [
1054
- // composableKeysPlugin.vite({ sourcemap: nuxt.options.sourcemap, rootDir: nuxt.options.rootDir }),
1055
- replace({
1056
- ...Object.fromEntries([";", "(", "{", "}", " ", " ", "\n"].map((d) => [`${d}global.`, `${d}globalThis.`])),
1057
- preventAssignment: true
1058
- }),
1059
- virtual(nuxt.vfs)
1263
+ nuxt: flow,
1264
+ flow,
1265
+ config: vite.mergeConfig({
1266
+ mode: flow.options.dev ? "development" : void 0,
1267
+ resolve: {
1268
+ alias: {
1269
+ ...flow.options.alias,
1270
+ "#app": flow.options.appDir,
1271
+ "#build/plugins": resolve(flow.options.buildDir, "plugins/server"),
1272
+ "#build": flow.options.buildDir,
1273
+ "/entry.mjs": resolve(flow.options.appDir, "entry")
1274
+ }
1275
+ },
1276
+ optimizeDeps: {
1277
+ entries: [
1278
+ resolve(flow.options.appDir, "entry.ts")
1060
1279
  ],
1061
- vue: {
1062
- reactivityTransform: nuxt.options.experimental.reactivityTransform
1063
- },
1064
- server: {
1065
- watch: { ignored: isIgnoredFlow },
1066
- fs: {
1067
- allow: [
1068
- nuxt.options.appDir
1069
- ]
1070
- },
1071
- hmr: false
1280
+ include: []
1281
+ },
1282
+ build: {
1283
+ rollupOptions: {
1284
+ output: { sanitizeFileName: sanitizeFilePath },
1285
+ input: resolve(flow.options.appDir, "entry")
1072
1286
  }
1073
1287
  },
1074
- nuxt.options.vite
1075
- )
1288
+ plugins: [
1289
+ replace({
1290
+ ...Object.fromEntries([";", "(", "{", "}", " ", " ", "\n"].map((d) => [`${d}global.`, `${d}globalThis.`])),
1291
+ preventAssignment: true
1292
+ }),
1293
+ virtual(flow.vfs),
1294
+ DynamicBasePlugin.vite({ sourcemap: flow.options.sourcemap })
1295
+ ],
1296
+ server: {
1297
+ watch: {
1298
+ ignored: isIgnoredFlow
1299
+ },
1300
+ hmr: {
1301
+ protocol: "ws",
1302
+ clientPort: hmrPort,
1303
+ port: hmrPort
1304
+ },
1305
+ fs: {
1306
+ allow: [
1307
+ flow.options.appDir
1308
+ ]
1309
+ }
1310
+ }
1311
+ }, flow.options.vite)
1076
1312
  };
1077
- if (!nuxt.options.dev) {
1078
- ctx.config.server.watch = void 0;
1079
- ctx.config.build.watch = void 0;
1080
- }
1081
- await nuxt.callHook("vite:extend", ctx);
1082
- nuxt.hook("vite:serverCreated", (server, env) => {
1313
+ if (flow.options.dev)
1314
+ ctx.config.mode = process.env.NODE_ENV || "development";
1315
+ await flow.callHook("vite:extend", ctx);
1316
+ flow.hook("vite:serverCreated", (server) => {
1083
1317
  ctx.nuxt.hook("app:templatesGenerated", () => {
1084
1318
  for (const [id, mod] of server.moduleGraph.idToModuleMap) {
1085
- if (id.includes("pages."))
1086
- server.moduleGraph.invalidateModule(mod);
1087
- if (id.startsWith("\virtual:"))
1319
+ if (id.startsWith("\0virtual:"))
1088
1320
  server.moduleGraph.invalidateModule(mod);
1089
1321
  }
1090
1322
  });
1091
1323
  const start = Date.now();
1092
- warmupViteServer(server, [join("/@fs/", ctx.entry)]).then(() => logger.info(`Vite ${env.isClient ? "client" : "server"} warmed up in ${Date.now() - start}ms`)).catch(logger.error);
1324
+ warmupViteServer(server, ["/entry.mjs"]).then(() => logger.info(`Vite server warmed up in ${Date.now() - start}ms`)).catch(logger.error);
1093
1325
  });
1094
1326
  await buildServer(ctx);
1095
1327
  }
@@ -1104,16 +1336,12 @@ async function build(flow) {
1104
1336
  if (event !== "change" && /app|error|plugins/i.test(path))
1105
1337
  await generateApp$1();
1106
1338
  });
1107
- flow.hook("builder:generateApp", (options) => {
1108
- if (options)
1109
- return generateApp(flow, app);
1110
- return generateApp$1();
1111
- });
1339
+ flow.hook("builder:generateApp", generateApp$1);
1112
1340
  }
1113
- await flow.callHook("build:before");
1341
+ await flow.callHook("build:before", { flow }, flow.options.build);
1114
1342
  if (!flow.options._prepare) {
1115
1343
  await bundle(flow);
1116
- await flow.callHook("build:done");
1344
+ await flow.callHook("build:done", { flow });
1117
1345
  }
1118
1346
  if (!flow.options.dev)
1119
1347
  await flow.callHook("close", flow);
@@ -1129,13 +1357,14 @@ function watch(flow) {
1129
1357
  "node_modules"
1130
1358
  ]
1131
1359
  });
1132
- watcher.on("all", (event, path) => flow.callHook("builder:watch", event, normalize(path)));
1360
+ const watchHook = debounce((event, path) => flow.callHook("builder:watch", event, normalize(path)));
1361
+ watcher.on("all", watchHook);
1133
1362
  flow.hook("close", () => watcher.close());
1134
1363
  return watcher;
1135
1364
  }
1136
1365
  async function bundle(nuxt) {
1137
1366
  try {
1138
- return bundle$1(nuxt);
1367
+ return bundleVite(nuxt);
1139
1368
  } catch (error) {
1140
1369
  await nuxt.callHook("build:error", error);
1141
1370
  throw error;