@monkeyplus/flow 5.0.0-rc.209 → 5.0.0-rc.21

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