@monkeyplus/flow 5.0.0-rc.108 → 5.0.0-rc.11

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,31 +1,33 @@
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';
5
- import { fileURLToPath } from 'url';
3
+ import { defineFlowModule, addPlugin, defineNuxtModule, logger, addTemplate, addPluginTemplate, addVitePlugin, useNuxt, resolveAlias, resolveFilesFlow, nuxtCtx, installModule, loadFlowConfig, templateUtils, normalizeTemplate, compileTemplate, normalizePlugin, isIgnoredFlow } from '@monkeyplus/flow-kit';
4
+ import { fileURLToPath, pathToFileURL } from 'node:url';
6
5
  import { defineUnimportPreset, createUnimport, toImports, scanDirExports } from 'unimport';
7
- import defu from 'defu';
8
- import { pathToFileURL } from 'node:url';
9
6
  import { createUnplugin } from 'unplugin';
10
- import { parseURL, parseQuery, joinURL } from 'ufo';
11
- import fs from 'fs';
7
+ import { parseURL, parseQuery, joinURL, withoutTrailingSlash } from 'ufo';
8
+ import escapeRE from 'escape-string-regexp';
12
9
  import { camelCase, pascalCase } from 'scule';
13
- import { genImport, genDynamicImport, genSafeVariableName, genArrayFromRaw, genString } from 'knitwork';
14
- import { existsSync, promises } from 'node:fs';
15
- import { createNitro, scanHandlers, writeTypes, build as build$1, prepare, copyPublicAssets, prerender, createDevServer } from 'nitropack';
16
- import { dynamicEventHandler } from 'h3';
17
- import { createRequire } from 'node:module';
18
- 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';
19
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';
20
22
  import { generateTypes, resolveSchema } from 'untyped';
21
- import { hash } from 'ohash';
22
- import { resolvePath, sanitizeFilePath } from 'mlly';
23
- import * as vite from 'vite';
23
+ import { getPort } from 'get-port-please';
24
+ import { sanitizeFilePath } from 'mlly';
24
25
  import replace from '@rollup/plugin-replace';
25
- import { resolveTSConfig } from 'pkg-types';
26
- 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';
27
29
 
28
- const version = "5.0.0-rc.108";
30
+ const version = "5.0.0-rc.11";
29
31
 
30
32
  let _distDir = dirname(fileURLToPath(import.meta.url));
31
33
  if (_distDir.endsWith("chunks"))
@@ -51,32 +53,30 @@ const metaModule = defineFlowModule({
51
53
 
52
54
  const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }) => {
53
55
  return {
54
- name: "nuxt:imports-transform",
56
+ name: "flow:auto-imports-transform",
55
57
  enforce: "post",
56
58
  transformInclude(id) {
57
59
  const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
58
- const query = parseQuery(search);
59
- if (options.transform?.include?.some((pattern) => id.match(pattern)))
60
- return true;
61
- 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)))
62
64
  return false;
63
- 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))
64
68
  return true;
65
69
  if (pathname.match(/\.((c|m)?j|t)sx?$/g))
66
70
  return true;
67
71
  },
68
- async transform(code, id) {
69
- id = normalize(id);
70
- const isNodeModule = id.match(/[\\/]node_modules[\\/]/) && !options.transform?.include?.some((pattern) => id.match(pattern));
71
- if (isNodeModule && !code.match(/(['"])#imports\1/))
72
+ async transform(_code, id) {
73
+ const { code, s } = await ctx.injectImports(_code);
74
+ if (code === _code)
72
75
  return;
73
- const { s } = await ctx.injectImports(code, id, { autoImport: options.autoImport && !isNodeModule });
74
- if (s.hasChanged()) {
75
- return {
76
- code: s.toString(),
77
- map: sourcemap ? s.generateMap({ source: id, includeContent: true }) : void 0
78
- };
79
- }
76
+ return {
77
+ code,
78
+ map: sourcemap && s.generateMap({ source: id, includeContent: true })
79
+ };
80
80
  }
81
81
  };
82
82
  });
@@ -92,8 +92,7 @@ const commonPresets = [
92
92
  from: "#_pages",
93
93
  imports: [
94
94
  "definePage",
95
- "defineDynamicPage",
96
- "defineSharedContext"
95
+ "defineDinamycPage"
97
96
  ]
98
97
  })
99
98
  ];
@@ -125,65 +124,50 @@ const defaultPresets = [
125
124
  vuePreset
126
125
  ];
127
126
 
128
- const importsModule = defineNuxtModule({
127
+ const autoImportsModule = defineNuxtModule({
129
128
  meta: {
130
- name: "imports",
131
- configKey: "imports"
129
+ name: "auto-imports",
130
+ configKey: "autoImports"
132
131
  },
133
132
  defaults: {
134
- autoImport: true,
135
133
  presets: defaultPresets,
136
134
  global: false,
137
135
  imports: [],
138
136
  dirs: [],
139
137
  transform: {
140
- include: [],
141
138
  exclude: void 0
142
139
  }
143
140
  },
144
- async setup(options, nuxt) {
145
- if (nuxt.options.autoImports) {
146
- logger.warn("`autoImports` config is deprecated, use `imports` instead.");
147
- options = defu(nuxt.options.autoImports, options);
148
- }
149
- await nuxt.callHook("imports:sources", options.presets);
150
- options.presets?.forEach((_i) => {
151
- const i = _i;
141
+ async setup(options, flow) {
142
+ await flow.callHook("autoImports:sources", options.presets);
143
+ options.presets.forEach((i) => {
152
144
  if (typeof i !== "string" && i.names && !i.imports) {
153
145
  i.imports = i.names;
154
- logger.warn("imports: presets.names is deprecated, use presets.imports instead");
146
+ logger.warn("auto-imports: presets.names is deprecated, use presets.imports instead");
155
147
  }
156
148
  });
157
149
  const ctx = createUnimport({
158
150
  presets: options.presets,
159
- imports: options.imports,
160
- virtualImports: ["#imports"],
161
- addons: {
162
- vueTemplate: options.autoImport
163
- }
151
+ imports: options.imports
164
152
  });
165
153
  let composablesDirs = [];
166
- for (const layer of nuxt.options._layers) {
154
+ for (const layer of flow.options._layers) {
167
155
  composablesDirs.push(resolve(layer.config.srcDir, "composables"));
168
- for (const dir of layer.config.imports?.dirs ?? []) {
169
- if (!dir)
170
- continue;
156
+ for (const dir of layer.config.autoImports?.dirs ?? [])
171
157
  composablesDirs.push(resolve(layer.config.srcDir, dir));
172
- }
173
158
  }
174
- await nuxt.callHook("imports:dirs", composablesDirs);
159
+ await flow.callHook("autoImports:dirs", composablesDirs);
175
160
  composablesDirs = composablesDirs.map((dir) => normalize(dir));
176
161
  addTemplate({
177
162
  filename: "imports.mjs",
178
- getContents: async () => `${await ctx.toExports()}
179
- 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()
180
164
  });
181
- nuxt.options.alias["#imports"] = join(nuxt.options.buildDir, "imports");
182
- if (nuxt.options.dev && options.global) {
165
+ flow.options.alias["#imports"] = join(flow.options.buildDir, "imports");
166
+ if (flow.options.dev && options.global) {
183
167
  addPluginTemplate({
184
- filename: "imports.mjs",
185
- getContents: async () => {
186
- const imports = await ctx.getImports();
168
+ filename: "auto-imports.mjs",
169
+ getContents: () => {
170
+ const imports = ctx.getImports();
187
171
  const importStatement = toImports(imports);
188
172
  const globalThisSet = imports.map((i) => `globalThis.${i.as} = ${i.as};`).join("\n");
189
173
  return `${importStatement}
@@ -194,41 +178,32 @@ export default () => {};`;
194
178
  }
195
179
  });
196
180
  } else {
197
- addVitePlugin(TransformPlugin.vite({ ctx, options, sourcemap: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client }));
198
- addWebpackPlugin(TransformPlugin.webpack({ ctx, options, sourcemap: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client }));
181
+ addVitePlugin(TransformPlugin.vite({ ctx, options, sourcemap: flow.options.sourcemap }));
199
182
  }
200
- const regenerateImports = async () => {
183
+ const regenerateAutoImports = async () => {
201
184
  ctx.clearDynamicImports();
202
185
  await ctx.modifyDynamicImports(async (imports) => {
203
186
  imports.push(...await scanDirExports(composablesDirs));
204
- await nuxt.callHook("imports:extend", imports);
187
+ await flow.callHook("autoImports:extend", imports);
205
188
  });
206
189
  };
207
- await regenerateImports();
208
- addDeclarationTemplates(ctx, options);
209
- nuxt.hook("prepare:types", ({ references }) => {
210
- references.push({ path: resolve(nuxt.options.buildDir, "types/imports.d.ts") });
211
- 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") });
212
195
  });
213
- const templates = [
214
- "types/imports.d.ts",
215
- "imports.d.ts",
216
- "imports.mjs"
217
- ];
218
- nuxt.hook("builder:watch", async (_, path) => {
219
- const _resolved = resolve(nuxt.options.srcDir, path);
220
- if (composablesDirs.find((dir) => _resolved.startsWith(dir))) {
221
- await updateTemplates({
222
- filter: (template) => templates.includes(template.filename)
223
- });
224
- }
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");
225
200
  });
226
- nuxt.hook("builder:generateApp", async () => {
227
- await regenerateImports();
201
+ flow.hook("builder:generateApp", async () => {
202
+ await regenerateAutoImports();
228
203
  });
229
204
  }
230
205
  });
231
- function addDeclarationTemplates(ctx, options) {
206
+ function addDeclarationTemplates(ctx) {
232
207
  const nuxt = useNuxt();
233
208
  const stripExtension = (path) => path.replace(/\.[a-z]+$/, "");
234
209
  const resolved = {};
@@ -244,64 +219,49 @@ function addDeclarationTemplates(ctx, options) {
244
219
  };
245
220
  addTemplate({
246
221
  filename: "imports.d.ts",
247
- getContents: () => ctx.toExports(nuxt.options.buildDir)
222
+ getContents: () => ctx.toExports()
248
223
  });
249
224
  addTemplate({
250
- filename: "types/imports.d.ts",
251
- getContents: async () => `// Generated by auto imports
252
- ${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 })}`
253
228
  });
254
229
  }
255
230
 
256
- async function resolveFiles(dir) {
231
+ async function resolvePagesRoutes() {
257
232
  const nuxt = useNuxt();
258
- const dirs = [resolve(nuxt.options.srcDir, dir)];
259
- const allRoutes = (await Promise.all(
260
- dirs.map(async (dir2) => {
261
- const files = await resolveFilesFlow(dir2, `**/*{${nuxt.options.extensions.join(",")}}`);
262
- files.sort();
263
- return files.filter((file) => {
264
- if (file.includes(" copy"))
265
- return false;
266
- if (!fs.readFileSync(file, "utf8").includes("export"))
267
- return false;
268
- return true;
269
- }).map((file) => {
270
- const segments = relative(dir2, file).replace(new RegExp(`${escapeRE(extname(file))}$`), "").split("/").join("_");
271
- return {
272
- file,
273
- name: camelCase(segments)
274
- };
275
- });
276
- })
277
- )).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();
278
245
  return allRoutes;
279
246
  }
280
- function normalizeExports(files) {
281
- const imports = files.map((page) => genImport(page.file, page.name)).join("\n");
282
- const exports = files.reduce((acc, curr) => {
283
- const name = curr.name;
284
- return `${name}:typeof ${name}==='function'?${name}():${name},${acc}`;
285
- }, "");
247
+ function normalizePages(pages) {
248
+ const imports = pages.map((page) => genImport(page.file, [{ name: "pages", as: page.name }])).join("\n");
286
249
  return {
287
250
  imports,
288
- exports
251
+ exports: pages.reduce((acc, curr) => {
252
+ const name = curr.name;
253
+ return `${name}:typeof ${name}==='function'?${name}():${name},${acc}`;
254
+ }, "")
289
255
  };
290
256
  }
291
257
 
292
258
  const pagesTypeTemplate = {
293
- filename: "types/pages.d.ts",
259
+ filename: "pages.d.ts",
294
260
  getContents: ({ options }) => `// Generated by pages discovery
295
261
  export {}
296
262
  declare global {
297
- type ArrElement<ArrType> = ArrType extends readonly (infer ElementType)[]
298
- ? ElementType
299
- : never;
300
263
 
301
- ${options.pages.map((c) => {
302
- const _type = `ArrElement<typeof ${genDynamicImport(isAbsolute(c.file) ? relative(join(options.buildDir, "types"), c.file) : c.file, { wrapper: false })}['default']>`;
303
- return `export type ${pascalCase(c.name)}Context=Awaited<ReturnType<${_type}['locales']['es-ec']['context']>>`;
304
- }).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")}
305
265
  }
306
266
  export const pagesNames: string[]
307
267
  `.replaceAll(".ts", "")
@@ -315,73 +275,164 @@ const pagesModule = defineNuxtModule({
315
275
  const runtimeDir = resolve(distDir, "pages/runtime");
316
276
  flow.options.alias["#_pages"] = runtimeDir;
317
277
  const pages = [];
318
- const contexts = [];
319
- 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 };
320
289
  addTemplate({
321
290
  ...pagesTypeTemplate,
322
291
  options
323
292
  });
324
293
  const pagesDirs = [{ path: resolve(flow.options.srcDir, flow.options.dir.pages) }];
325
294
  flow.options.alias["#pages"] = resolve(flow.options.buildDir, "pages.mjs");
326
- flow.options.alias["#pagesContexts"] = resolve(flow.options.buildDir, "pages.contexts.mjs");
327
295
  addTemplate({
328
296
  filename: "pages.mjs",
329
297
  async getContents({ options: options2 }) {
330
- const { exports, imports } = normalizeExports(options2.pages);
331
- const module = [imports, `export default {${exports}}`].join("\n");
332
- return module;
333
- },
334
- options
335
- });
336
- addTemplate({
337
- filename: "pages.contexts.mjs",
338
- async getContents({ options: options2 }) {
339
- const { exports, imports } = normalizeExports(options2.contexts);
340
- const module = [imports, `export default {${exports}}`].join("\n");
341
- return module;
298
+ const { exports, imports } = normalizePages(options2.pages);
299
+ return [imports, `export default {${exports}}`].join("\n");
342
300
  },
343
301
  options
344
302
  });
345
303
  flow.hook("app:templates", async () => {
346
- options.pages = await resolveFiles(flow.options.dir?.pages || "pages");
347
- });
348
- flow.hook("app:templates", async () => {
349
- options.contexts = await resolveFiles("shared/contexts");
304
+ options.pages = await resolvePagesRoutes();
350
305
  });
351
306
  flow.hook("prepare:types", ({ references }) => {
352
- references.push({ path: resolve(flow.options.buildDir, "types/pages.d.ts") });
307
+ references.push({ path: resolve(flow.options.buildDir, "pages.d.ts") });
353
308
  });
354
309
  flow.hook("builder:watch", async (event, path) => {
355
- if (!["add", "unlink", "change"].includes(event))
356
- return;
357
- if (path.includes(" copy"))
310
+ if (!["add", "unlink"].includes(event))
358
311
  return;
359
312
  const fPath = resolve(flow.options.rootDir, path);
360
313
  if (pagesDirs.find((dir) => fPath.startsWith(dir.path)))
361
314
  await flow.callHook("builder:generateApp");
362
315
  });
363
- 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") });
364
424
  }
365
425
  });
366
426
 
367
427
  const _require = createRequire(import.meta.url);
368
428
  const ImportProtectionPlugin = createUnplugin((options) => {
369
429
  const cache = {};
370
- const importersToExclude = options?.exclude || [];
371
430
  return {
372
- name: "nuxt:import-protection",
431
+ name: "flow:import-protection",
373
432
  enforce: "pre",
374
433
  resolveId(id, importer) {
375
- if (!importer)
376
- return;
377
- if (id.startsWith("."))
378
- id = join(importer, "..", id);
379
- if (isAbsolute(id))
380
- id = relative(options.rootDir, id);
381
- if (importersToExclude.some((p) => typeof p === "string" ? importer === p : p.test(importer)))
382
- return;
383
434
  const invalidImports = options.patterns.filter(([pattern]) => pattern instanceof RegExp ? pattern.test(id) : pattern === id);
384
- let matched = false;
435
+ let matched;
385
436
  for (const match of invalidImports) {
386
437
  cache[id] = cache[id] || /* @__PURE__ */ new Map();
387
438
  const [pattern, warning] = match;
@@ -400,35 +451,25 @@ const ImportProtectionPlugin = createUnplugin((options) => {
400
451
  });
401
452
 
402
453
  async function initNitro(flow) {
454
+ const { handlers, devHandlers } = await resolveHandlers(flow);
403
455
  const _nitroConfig = flow.options.nitro || {};
404
456
  globalThis.generate = {};
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: flow.options._layers.map((layer) => (layer.config.serverDir || layer.config.srcDir) && resolve(layer.cwd, layer.config.serverDir || resolve(layer.config.srcDir, "server"))).filter(Boolean),
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,20 +484,20 @@ 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"
500
+ "@monkeyplus/flow/dist"
460
501
  ]
461
502
  },
462
503
  alias: {
@@ -467,39 +508,37 @@ async function initNitro(flow) {
467
508
  ...flow.options.alias
468
509
  },
469
510
  rollupConfig: {
470
- plugins: [],
471
- external: [""]
511
+ plugins: []
472
512
  }
473
513
  });
474
- nitroConfig.rollupConfig.plugins.push(
475
- ImportProtectionPlugin.rollup({
476
- rootDir: flow.options.rootDir,
477
- patterns: [
478
- ...["#app", /^#build(\/|$)/].map((p) => [p, "Vue app aliases are not allowed in server routes."])
479
- ],
480
- exclude: [/core[\\/]runtime[\\/]nitro[\\/]renderer/]
481
- })
482
- );
483
514
  await flow.callHook("nitro:config", nitroConfig);
515
+ nitroConfig.handlers.unshift({
516
+ middleware: true,
517
+ handler: resolve(distDir, "core/runtime/nitro/flow")
518
+ });
484
519
  const nitro = await createNitro(nitroConfig);
485
- flow._nitro = nitro;
486
- flow.nitro = nitro;
487
520
  await flow.callHook("nitro:init", nitro);
488
521
  nitro.vfs = flow.vfs = nitro.vfs || flow.vfs || {};
489
522
  flow.hook("close", () => nitro.hooks.callHook("close"));
490
- nitro.hooks.hook("prerender:routes", (routes) => {
491
- 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);
492
531
  });
493
- const devMiddlewareHandler = dynamicEventHandler();
494
- nitro.options.devHandlers.unshift({ handler: devMiddlewareHandler });
495
- nitro.options.devHandlers.push(...flow.options.devServerHandlers);
532
+ const devMidlewareHandler = dynamicEventHandler();
533
+ nitro.options.devHandlers.unshift({ handler: devMidlewareHandler });
534
+ nitro.options.devHandlers.push(...devHandlers);
496
535
  nitro.options.handlers.unshift({
497
- route: "/__nuxt_error",
536
+ route: "/__flow_error",
498
537
  lazy: true,
499
538
  handler: resolve(distDir, "core/runtime/nitro/renderer")
500
539
  });
501
540
  flow.hook("prepare:types", async (opts) => {
502
- if (!flow.options.dev) {
541
+ if (flow.options._prepare) {
503
542
  await scanHandlers(nitro);
504
543
  await writeTypes(nitro);
505
544
  }
@@ -508,14 +547,21 @@ async function initNitro(flow) {
508
547
  flow.hook("build:done", async () => {
509
548
  await flow.callHook("nitro:build:before", nitro);
510
549
  if (flow.options.dev) {
511
- await build$1(nitro);
550
+ await build$2(nitro);
512
551
  } else {
513
552
  await prepare(nitro);
514
553
  await copyPublicAssets(nitro);
515
554
  await prerender(nitro);
516
555
  if (!flow.options._generate) {
517
- await build$1(nitro);
556
+ await build$2(nitro);
518
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;
519
565
  const distDir2 = resolve(flow.options.rootDir, "dist");
520
566
  if (!existsSync(distDir2))
521
567
  await promises.symlink(nitro.options.output.publicDir, distDir2, "junction").catch(() => {
@@ -524,17 +570,28 @@ async function initNitro(flow) {
524
570
  }
525
571
  });
526
572
  if (flow.options.dev) {
527
- flow.hook("vite:compiled", () => {
528
- flow.server.reload();
573
+ flow.hook("build:compile", ({ compiler }) => {
574
+ compiler.outputFileSystem = { ...fse, join };
529
575
  });
530
- flow.hook("server:devHandler", (h) => {
531
- devMiddlewareHandler.set(h);
576
+ flow.hook("server:devMiddleware", (m) => {
577
+ devMidlewareHandler.set(toEventHandler(m));
532
578
  });
533
579
  flow.server = createDevServer(nitro);
580
+ flow.hook("build:resources", () => {
581
+ flow.server.reload();
582
+ });
534
583
  const waitUntilCompile = new Promise((resolve2) => nitro.hooks.hook("compiled", () => resolve2()));
535
584
  flow.hook("build:done", () => waitUntilCompile);
536
585
  }
537
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
+ }
538
595
 
539
596
  const addModuleTranspiles = (opts = {}) => {
540
597
  const flow = useNuxt();
@@ -543,7 +600,7 @@ const addModuleTranspiles = (opts = {}) => {
543
600
  ...flow.options.modules,
544
601
  ...flow.options._modules
545
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());
546
- 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);
547
604
  function isTranspilePresent(mod) {
548
605
  return flow.options.build.transpile.some((t) => !(t instanceof Function) && (t instanceof RegExp ? t.test(mod) : new RegExp(t).test(mod)));
549
606
  }
@@ -556,7 +613,7 @@ const addModuleTranspiles = (opts = {}) => {
556
613
  function createFlow(options) {
557
614
  const hooks = createHooks();
558
615
  const flow = {
559
- _version: "3.0.0",
616
+ _version: "3.0.0-rc.3",
560
617
  version,
561
618
  options,
562
619
  hooks,
@@ -570,10 +627,9 @@ function createFlow(options) {
570
627
  return flow;
571
628
  }
572
629
  async function initFlow(flow) {
573
- flow.hooks.addHooks(flow.options.hooks);
574
630
  nuxtCtx.set(flow);
575
631
  flow.hook("close", () => nuxtCtx.unset());
576
- await flow.callHook("modules:before");
632
+ await flow.callHook("modules:before", { nuxt: flow });
577
633
  const modulesToInstall = [
578
634
  ...flow.options.modules,
579
635
  ...flow.options._modules
@@ -584,26 +640,17 @@ async function initFlow(flow) {
584
640
  else
585
641
  await installModule(m, {});
586
642
  }
587
- await flow.callHook("modules:done");
588
- flow.options.build.transpile = flow.options.build.transpile.map((t) => typeof t === "string" ? normalize(t) : t);
589
- addModuleTranspiles();
643
+ await flow.callHook("modules:done", { nuxt: flow });
644
+ await addModuleTranspiles();
590
645
  await initNitro(flow);
591
646
  await flow.callHook("ready", flow);
592
647
  }
593
648
  async function loadFlow(opts) {
594
- const start1 = Date.now();
595
649
  const options = await loadFlowConfig(opts);
596
- logger.info(`Config loading in ${Date.now() - start1}ms`);
597
650
  options.appDir = resolve(distDir, "app");
598
651
  options.alias["#app"] = resolve(distDir, "app/index");
599
652
  options._majorVersion = 3;
600
- options._modules.push(pagesModule, metaModule);
601
- options._modules.push([importsModule, {
602
- transform: {
603
- 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\\/)`))
604
- }
605
- }]);
606
- options.modulesDir.push(resolve(options.workspaceDir, "node_modules"));
653
+ options._modules.push(pagesModule, metaModule, autoImportsModule, viteModule);
607
654
  options.modulesDir.push(resolve(pkgDir, "node_modules"));
608
655
  const flow = createFlow(options);
609
656
  if (opts.ready !== false)
@@ -618,17 +665,11 @@ const serverPluginTemplate = {
618
665
  filename: "plugins/server.mjs",
619
666
  getContents(ctx) {
620
667
  const serverPlugins = ctx.app.plugins;
621
- const exports = [];
622
- const imports = [];
623
- for (const plugin of serverPlugins) {
624
- const path = relative(ctx.nuxt.options.rootDir, plugin.src);
625
- const variable = `${genSafeVariableName(path).replace(/_(45|46|47)/g, "_")}_${hash(path)}`;
626
- exports.push(variable);
627
- imports.push(genImport(plugin.src, variable));
628
- }
629
668
  return [
630
- ...imports,
631
- `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
+ ])}`
632
673
  ].join("\n");
633
674
  }
634
675
  };
@@ -657,52 +698,43 @@ export { }
657
698
  `;
658
699
  }
659
700
  };
660
- const adHocModules = ["imports", "meta", "pages"];
701
+ const adHocModules = ["auto-imports", "meta", "pages", "vite-client"];
661
702
  const schemaTemplate = {
662
703
  filename: "types/schema.d.ts",
663
- getContents: async ({ nuxt }) => {
704
+ getContents: ({ nuxt }) => {
664
705
  const moduleInfo = nuxt.options._installedModules.map((m) => ({
665
706
  ...m.meta || {},
666
707
  importName: m.entryPath || m.meta?.name
667
708
  })).filter((m) => m.configKey && m.name && !adHocModules.includes(m.name));
668
- const relativeRoot = relative(resolve(nuxt.options.buildDir, "types"), nuxt.options.rootDir);
669
709
  return [
670
710
  "import { FlowModule } from '@monkeyplus/flow-schema'",
671
711
  "declare module '@monkeyplus/flow-schema' {",
672
712
  " interface FlowConfig {",
673
- ...moduleInfo.filter(Boolean).map(
674
- (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>`
675
- ),
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>`),
676
714
  " }",
677
- generateTypes(
678
- await resolveSchema(Object.fromEntries(Object.entries(nuxt.options.runtimeConfig).filter(([key]) => key !== "public"))),
679
- {
680
- interfaceName: "RuntimeConfig",
681
- addExport: false,
682
- addDefaults: false,
683
- allowExtraKeys: false,
684
- indentation: 2
685
- }
686
- ),
687
- generateTypes(
688
- await resolveSchema(nuxt.options.runtimeConfig.public),
689
- {
690
- interfaceName: "PublicRuntimeConfig",
691
- addExport: false,
692
- addDefaults: false,
693
- allowExtraKeys: false,
694
- indentation: 2
695
- }
696
- ),
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
+ }),
697
729
  "}"
698
730
  ].join("\n");
699
731
  }
700
732
  };
701
733
  const publicPathTemplate = {
702
734
  filename: "paths.mjs",
703
- async getContents({ nuxt }) {
735
+ getContents({ nuxt }) {
704
736
  return [
705
- `import { joinURL } from '${await _resolveId("ufo")}'`,
737
+ "import { joinURL } from 'ufo'",
706
738
  !nuxt.options.dev && "import { useRuntimeConfig } from '#internal/nitro'",
707
739
  nuxt.options.dev ? `const appConfig = ${JSON.stringify(nuxt.options.app)}` : "const appConfig = useRuntimeConfig().app",
708
740
  "export const baseURL = () => appConfig.baseURL",
@@ -715,16 +747,6 @@ const publicPathTemplate = {
715
747
  ].filter(Boolean).join("\n");
716
748
  }
717
749
  };
718
- function _resolveId(id) {
719
- return resolvePath(id, {
720
- url: [
721
- global.__NUXT_PREPATHS__,
722
- import.meta.url,
723
- process.cwd(),
724
- global.__NUXT_PATHS__
725
- ]
726
- });
727
- }
728
750
 
729
751
  const defaultTemplates = {
730
752
  __proto__: null,
@@ -734,18 +756,6 @@ const defaultTemplates = {
734
756
  publicPathTemplate: publicPathTemplate
735
757
  };
736
758
 
737
- function uniqueBy(arr, key) {
738
- const res = [];
739
- const seen = /* @__PURE__ */ new Set();
740
- for (const item of arr) {
741
- if (seen.has(item[key]))
742
- continue;
743
- seen.add(item[key]);
744
- res.push(item);
745
- }
746
- return res;
747
- }
748
-
749
759
  function createApp(flow, options = {}) {
750
760
  return defu(options, {
751
761
  dir: flow.options.srcDir,
@@ -754,95 +764,51 @@ function createApp(flow, options = {}) {
754
764
  templates: []
755
765
  });
756
766
  }
757
- async function generateApp(flow, app, options) {
767
+ async function generateApp(flow, app) {
758
768
  await resolveApp(flow, app);
759
- app.templates = Object.values(defaultTemplates).concat(
760
- flow.options.build.templates
761
- );
769
+ app.templates = Object.values(defaultTemplates).concat(flow.options.build.templates);
762
770
  await flow.callHook("app:templates", app);
763
771
  app.templates = app.templates.map((tmpl) => normalizeTemplate(tmpl));
764
772
  const templateContext = { utils: templateUtils, nuxt: flow, app };
765
- await Promise.all(
766
- app.templates.map(async (template) => {
767
- const contents = await compileTemplate(template, templateContext);
768
- const fullPath = template.dst || resolve(flow.options.buildDir, template.filename);
769
- flow.vfs[fullPath] = contents;
770
- const aliasPath = `#build/${template.filename.replace(/\.\w+$/, "")}`;
771
- flow.vfs[aliasPath] = contents;
772
- if (process.platform === "win32")
773
- flow.vfs[fullPath.replace(/\//g, "\\")] = contents;
774
- if (template.write) {
775
- await promises.mkdir(dirname(fullPath), { recursive: true });
776
- await promises.writeFile(fullPath, contents, "utf8");
777
- }
778
- })
779
- );
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
+ }));
780
786
  await flow.callHook("app:templatesGenerated", app);
781
787
  }
782
788
  async function resolveApp(flow, app) {
783
- app.plugins = [
784
- ...flow.options.plugins.map(normalizePlugin)
785
- ];
789
+ app.plugins = [...flow.options.plugins.map(normalizePlugin)];
786
790
  for (const config of flow.options._layers.map((layer) => layer.config)) {
787
791
  app.plugins.push(...[
788
792
  ...config.plugins || [],
789
- ...config.srcDir ? await resolveFilesFlow(config.srcDir, [
790
- `${config.dir?.plugins || "plugins"}/*.{ts,js,mjs,cjs,mts,cts}`,
791
- `${config.dir?.plugins || "plugins"}/*/index.*{ts,js,mjs,cjs,mts,cts}`
792
- ]) : []
793
+ ...await resolveFilesFlow(config.srcDir, [
794
+ "plugins/*.{ts,js,mjs,cjs,mts,cts}",
795
+ "plugins/*/index.*{ts,js,mjs,cjs,mts,cts}"
796
+ ])
793
797
  ].map((plugin) => normalizePlugin(plugin)));
794
798
  }
795
- app.configs = [];
796
- for (const config of flow.options._layers.map((layer) => layer.config)) {
797
- const appConfigPath = await findPath(resolve(config.srcDir, "app.config"));
798
- if (appConfigPath)
799
- app.configs.push(appConfigPath);
800
- }
801
- await flow.callHook("app:resolve", app);
802
799
  app.plugins = uniqueBy(app.plugins, "src");
800
+ await flow.callHook("app:resolve", app);
803
801
  }
804
-
805
- const PREFIX = "virtual:nuxt:";
806
- function virtual(vfs) {
807
- const extensions = ["", ".ts", ".vue", ".mjs", ".cjs", ".js", ".json"];
808
- const resolveWithExt = (id) => {
809
- for (const ext of extensions) {
810
- const rId = id + ext;
811
- if (rId in vfs)
812
- return rId;
813
- }
814
- return null;
815
- };
816
- return {
817
- name: "virtual",
818
- resolveId(id, importer) {
819
- if (process.platform === "win32" && isAbsolute(id)) {
820
- id = resolve(id);
821
- }
822
- const resolvedId = resolveWithExt(id);
823
- if (resolvedId)
824
- return PREFIX + resolvedId;
825
- if (importer && !isAbsolute(id)) {
826
- const importerNoPrefix = importer.startsWith(PREFIX) ? importer.slice(PREFIX.length) : importer;
827
- const importedDir = dirname(importerNoPrefix);
828
- const resolved = resolveWithExt(join(importedDir, id));
829
- if (resolved)
830
- return PREFIX + resolved;
831
- }
832
- return null;
833
- },
834
- load(id) {
835
- if (!id.startsWith(PREFIX))
836
- return null;
837
- const idNoPrefix = id.slice(PREFIX.length);
838
- if (idNoPrefix in vfs) {
839
- return {
840
- code: vfs[idNoPrefix],
841
- map: null
842
- };
843
- }
844
- }
845
- };
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;
846
812
  }
847
813
 
848
814
  async function warmupViteServer(server, entries) {
@@ -863,11 +829,6 @@ async function warmupViteServer(server, entries) {
863
829
  await Promise.all(entries.map((entry) => warmup(entry)));
864
830
  }
865
831
 
866
- const wpfs = {
867
- ...fse,
868
- join
869
- };
870
-
871
832
  function cacheDirPlugin(rootDir, name) {
872
833
  const optimizeCacheDir = resolve(rootDir, "node_modules/.cache/vite", name);
873
834
  return {
@@ -878,47 +839,279 @@ function cacheDirPlugin(rootDir, name) {
878
839
  };
879
840
  }
880
841
 
881
- 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) => {
882
1085
  const serverConfig = vite.mergeConfig(ctx.config, {
883
- base: ctx.nuxt.options.dev ? joinURL(ctx.nuxt.options.app.baseURL.replace(/^\.\//, "/") || "/", ctx.nuxt.options.app.buildAssetsDir) : void 0,
1086
+ configFile: false,
884
1087
  define: {
885
1088
  "process.server": true,
886
- "process.client": false,
887
1089
  "typeof window": '"undefined"',
888
1090
  "typeof document": '"undefined"',
889
1091
  "typeof navigator": '"undefined"',
890
1092
  "typeof location": '"undefined"',
891
1093
  "typeof XMLHttpRequest": '"undefined"'
892
1094
  },
893
- resolve: {
894
- alias: {
895
- "#build/plugins": resolve(ctx.nuxt.options.buildDir, "plugins/server")
896
- }
897
- },
898
1095
  ssr: {
899
- external: ["#internal/nitro", "#internal/nitro/utils"],
900
1096
  noExternal: [
901
- ...ctx.nuxt.options.build.transpile,
1097
+ ...ctx.flow.options.build.transpile,
902
1098
  /\/esm\/.*\.js$/,
903
1099
  /\.(es|esm|esm-browser|esm-bundler).js$/,
904
1100
  "/__vue-jsx",
905
1101
  "#app",
906
1102
  /(nuxt|nuxt3)\/(dist|src|app)/,
907
- /flow\/(dist|src|app)/,
908
- /flow\/modules\/(content|icons|images|netlify|netlify-cms|seo|sitemap|vue)/,
909
1103
  /@monkeyplus\/flow\/(dist|src|app)/,
910
1104
  /@nuxt\/nitro\/(dist|src)/
911
1105
  ]
912
1106
  },
913
1107
  build: {
914
- outDir: resolve(ctx.nuxt.options.buildDir, "dist/server"),
915
- ssr: true,
1108
+ outDir: resolve(ctx.flow.options.buildDir, "dist/server"),
1109
+ manifest: true,
916
1110
  rollupOptions: {
917
1111
  external: ["#internal/nitro"],
918
1112
  output: {
919
1113
  entryFileNames: "server.mjs",
920
1114
  preferConst: true,
921
- inlineDynamicImports: !ctx.nuxt.options.experimental.viteServerDynamicImports,
922
1115
  format: "module"
923
1116
  },
924
1117
  onwarn(warning, rollupWarn) {
@@ -929,27 +1122,38 @@ async function buildServer(ctx) {
929
1122
  },
930
1123
  server: {
931
1124
  preTransformRequests: false,
932
- hmr: false
1125
+ cors: true
933
1126
  },
934
1127
  plugins: [
935
- cacheDirPlugin(ctx.nuxt.options.rootDir, "server"),
936
- replace({
937
- ...Object.fromEntries([";", "(", "{", "}", " ", " ", "\n"].map((d) => [`${d}global.`, `${d}globalThis.`])),
938
- preventAssignment: true
939
- })
1128
+ cacheDirPlugin(ctx.flow.options.rootDir, "server")
940
1129
  ]
941
1130
  });
942
- if (ctx.nuxt.options.typescript.typeCheck === true || ctx.nuxt.options.typescript.typeCheck === "build" && !ctx.nuxt.options.dev) {
943
- const checker = await import('vite-plugin-checker').then((r) => r.default);
944
- serverConfig.plugins.push(checker({
945
- vueTsc: {
946
- 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
+ }
947
1145
  }
948
- }));
949
- }
950
- await ctx.nuxt.callHook("vite:extendConfig", serverConfig, { isClient: false, isServer: true });
951
- const onBuild = () => ctx.nuxt.callHook("build:resources", wpfs);
952
- 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) {
953
1157
  const start = Date.now();
954
1158
  logger.info("Building server...");
955
1159
  await vite.build(serverConfig);
@@ -959,82 +1163,184 @@ async function buildServer(ctx) {
959
1163
  }
960
1164
  const viteServer = await vite.createServer(serverConfig);
961
1165
  ctx.ssrServer = viteServer;
962
- await ctx.nuxt.callHook("vite:serverCreated", viteServer, { isClient: false, isServer: true });
963
- 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());
964
1168
  await viteServer.pluginContainer.buildStart({});
965
- 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
+ };
966
1230
  }
967
1231
 
968
- async function bundle$1(nuxt) {
969
- 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
+ });
970
1281
  const ctx = {
971
- nuxt,
972
- entry,
973
- config: vite.mergeConfig(
974
- {
975
- configFile: false,
976
- resolve: {
977
- alias: {
978
- ...nuxt.options.alias,
979
- "#app": nuxt.options.appDir,
980
- "#build/plugins": "",
981
- "#build": nuxt.options.buildDir,
982
- "web-streams-polyfill/ponyfill/es2018": "unenv/runtime/mock/empty",
983
- "abort-controller": "unenv/runtime/mock/empty"
984
- }
985
- },
986
- optimizeDeps: {
987
- entries: [entry],
988
- include: []
989
- },
990
- build: {
991
- rollupOptions: {
992
- output: { sanitizeFileName: sanitizeFilePath },
993
- input: resolve(nuxt.options.appDir, "entry")
994
- },
995
- watch: {
996
- exclude: nuxt.options.ignore
997
- }
998
- },
999
- plugins: [
1000
- replace({
1001
- ...Object.fromEntries([";", "(", "{", "}", " ", " ", "\n"].map((d) => [`${d}global.`, `${d}globalThis.`])),
1002
- preventAssignment: true
1003
- }),
1004
- 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")
1005
1298
  ],
1006
- vue: {
1007
- reactivityTransform: nuxt.options.experimental.reactivityTransform
1008
- },
1009
- server: {
1010
- watch: { ignored: isIgnoredFlow },
1011
- fs: {
1012
- allow: [
1013
- nuxt.options.appDir
1014
- ]
1015
- },
1016
- hmr: false
1299
+ include: []
1300
+ },
1301
+ build: {
1302
+ rollupOptions: {
1303
+ output: { sanitizeFileName: sanitizeFilePath },
1304
+ input: resolve(flow.options.appDir, "entry")
1017
1305
  }
1018
1306
  },
1019
- nuxt.options.vite
1020
- )
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)
1021
1331
  };
1022
- if (!nuxt.options.dev) {
1023
- ctx.config.server.watch = void 0;
1024
- ctx.config.build.watch = void 0;
1025
- }
1026
- await nuxt.callHook("vite:extend", ctx);
1027
- 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) => {
1028
1336
  ctx.nuxt.hook("app:templatesGenerated", () => {
1029
1337
  for (const [id, mod] of server.moduleGraph.idToModuleMap) {
1030
- if (id.includes("pages."))
1031
- server.moduleGraph.invalidateModule(mod);
1032
- if (id.startsWith("\virtual:"))
1338
+ if (id.startsWith("\0virtual:"))
1033
1339
  server.moduleGraph.invalidateModule(mod);
1034
1340
  }
1035
1341
  });
1036
1342
  const start = Date.now();
1037
- 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);
1038
1344
  });
1039
1345
  await buildServer(ctx);
1040
1346
  }
@@ -1049,16 +1355,12 @@ async function build(flow) {
1049
1355
  if (event !== "change" && /app|error|plugins/i.test(path))
1050
1356
  await generateApp$1();
1051
1357
  });
1052
- flow.hook("builder:generateApp", (options) => {
1053
- if (options)
1054
- return generateApp(flow, app);
1055
- return generateApp$1();
1056
- });
1358
+ flow.hook("builder:generateApp", generateApp$1);
1057
1359
  }
1058
- await flow.callHook("build:before");
1360
+ await flow.callHook("build:before", { flow }, flow.options.build);
1059
1361
  if (!flow.options._prepare) {
1060
1362
  await bundle(flow);
1061
- await flow.callHook("build:done");
1363
+ await flow.callHook("build:done", { flow });
1062
1364
  }
1063
1365
  if (!flow.options.dev)
1064
1366
  await flow.callHook("close", flow);
@@ -1074,13 +1376,14 @@ function watch(flow) {
1074
1376
  "node_modules"
1075
1377
  ]
1076
1378
  });
1077
- 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);
1078
1381
  flow.hook("close", () => watcher.close());
1079
1382
  return watcher;
1080
1383
  }
1081
1384
  async function bundle(nuxt) {
1082
1385
  try {
1083
- return bundle$1(nuxt);
1386
+ return bundleVite(nuxt);
1084
1387
  } catch (error) {
1085
1388
  await nuxt.callHook("build:error", error);
1086
1389
  throw error;