@monkeyplus/flow 5.0.0-rc.138 → 5.0.0-rc.14

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