@monkeyplus/flow 5.0.0-rc.129 → 5.0.0-rc.13

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