@monkeyplus/flow 5.0.0-rc.139 → 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.139";
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,38 +53,35 @@ const metaModule = defineFlowModule({
50
53
 
51
54
  const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }) => {
52
55
  return {
53
- name: "nuxt:imports-transform",
56
+ name: "flow:auto-imports-transform",
54
57
  enforce: "post",
55
58
  transformInclude(id) {
56
59
  const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
57
- const query = parseQuery(search);
58
- if (options.transform?.include?.some((pattern) => id.match(pattern)))
59
- return true;
60
- if (options.transform?.exclude?.some((pattern) => id.match(pattern)))
60
+ const { type, macro } = parseQuery(search);
61
+ const exclude = options.transform?.exclude || [/[\\/]node_modules[\\/]/];
62
+ const include = options.transform?.include || [];
63
+ if (exclude.some((pattern) => id.match(pattern)))
61
64
  return false;
62
- if (id.endsWith(".vue") || "macro" in query || "vue" in query && (query.type === "template" || query.type === "script" || "setup" in query))
65
+ if (include.some((pattern) => id.match(pattern)))
66
+ return true;
67
+ if (pathname.endsWith(".vue") && (type === "template" || type === "script" || macro || !search))
63
68
  return true;
64
69
  if (pathname.match(/\.((c|m)?j|t)sx?$/g))
65
70
  return true;
66
71
  },
67
- async transform(code, id) {
68
- id = normalize(id);
69
- const isNodeModule = id.match(/[\\/]node_modules[\\/]/) && !options.transform?.include?.some((pattern) => id.match(pattern));
70
- if (isNodeModule && !code.match(/(['"])#imports\1/))
72
+ async transform(_code, id) {
73
+ const { code, s } = await ctx.injectImports(_code);
74
+ if (code === _code)
71
75
  return;
72
- const { s } = await ctx.injectImports(code, id, { autoImport: options.autoImport && !isNodeModule });
73
- if (s.hasChanged()) {
74
- return {
75
- code: s.toString(),
76
- map: sourcemap ? s.generateMap({ source: id, includeContent: true }) : void 0
77
- };
78
- }
76
+ return {
77
+ code,
78
+ map: sourcemap && s.generateMap({ source: id, includeContent: true })
79
+ };
79
80
  }
80
81
  };
81
82
  });
82
83
 
83
84
  const commonPresets = [
84
- // #head
85
85
  defineUnimportPreset({
86
86
  from: "#head",
87
87
  imports: [
@@ -92,8 +92,7 @@ const commonPresets = [
92
92
  from: "#_pages",
93
93
  imports: [
94
94
  "definePage",
95
- "defineDynamicPage",
96
- "defineSharedContext"
95
+ "defineDinamycPage"
97
96
  ]
98
97
  })
99
98
  ];
@@ -112,12 +111,10 @@ const appPreset = defineUnimportPreset({
112
111
  const vuePreset = defineUnimportPreset({
113
112
  from: "vue",
114
113
  imports: [
115
- // Components
116
114
  "defineComponent",
117
115
  "getCurrentInstance",
118
116
  "useSlots",
119
117
  "h",
120
- // Reactivity
121
118
  "computed"
122
119
  ]
123
120
  });
@@ -127,65 +124,50 @@ const defaultPresets = [
127
124
  vuePreset
128
125
  ];
129
126
 
130
- const importsModule = defineNuxtModule({
127
+ const autoImportsModule = defineNuxtModule({
131
128
  meta: {
132
- name: "imports",
133
- configKey: "imports"
129
+ name: "auto-imports",
130
+ configKey: "autoImports"
134
131
  },
135
132
  defaults: {
136
- autoImport: true,
137
133
  presets: defaultPresets,
138
134
  global: false,
139
135
  imports: [],
140
136
  dirs: [],
141
137
  transform: {
142
- include: [],
143
138
  exclude: void 0
144
139
  }
145
140
  },
146
- async setup(options, nuxt) {
147
- if (nuxt.options.autoImports) {
148
- logger.warn("`autoImports` config is deprecated, use `imports` instead.");
149
- options = defu(nuxt.options.autoImports, options);
150
- }
151
- await nuxt.callHook("imports:sources", options.presets);
152
- options.presets?.forEach((_i) => {
153
- const i = _i;
141
+ async setup(options, flow) {
142
+ await flow.callHook("autoImports:sources", options.presets);
143
+ options.presets.forEach((i) => {
154
144
  if (typeof i !== "string" && i.names && !i.imports) {
155
145
  i.imports = i.names;
156
- logger.warn("imports: presets.names is deprecated, use presets.imports instead");
146
+ logger.warn("auto-imports: presets.names is deprecated, use presets.imports instead");
157
147
  }
158
148
  });
159
149
  const ctx = createUnimport({
160
150
  presets: options.presets,
161
- imports: options.imports,
162
- virtualImports: ["#imports"],
163
- addons: {
164
- vueTemplate: options.autoImport
165
- }
151
+ imports: options.imports
166
152
  });
167
153
  let composablesDirs = [];
168
- for (const layer of nuxt.options._layers) {
154
+ for (const layer of flow.options._layers) {
169
155
  composablesDirs.push(resolve(layer.config.srcDir, "composables"));
170
- for (const dir of layer.config.imports?.dirs ?? []) {
171
- if (!dir)
172
- continue;
156
+ for (const dir of layer.config.autoImports?.dirs ?? [])
173
157
  composablesDirs.push(resolve(layer.config.srcDir, dir));
174
- }
175
158
  }
176
- await nuxt.callHook("imports:dirs", composablesDirs);
159
+ await flow.callHook("autoImports:dirs", composablesDirs);
177
160
  composablesDirs = composablesDirs.map((dir) => normalize(dir));
178
161
  addTemplate({
179
162
  filename: "imports.mjs",
180
- getContents: async () => `${await ctx.toExports()}
181
- if (process.dev) { console.warn("[nuxt] \`#imports\` should be transformed with real imports. There seems to be something wrong with the imports plugin.") }`
163
+ getContents: () => ctx.toExports()
182
164
  });
183
- nuxt.options.alias["#imports"] = join(nuxt.options.buildDir, "imports");
184
- if (nuxt.options.dev && options.global) {
165
+ flow.options.alias["#imports"] = join(flow.options.buildDir, "imports");
166
+ if (flow.options.dev && options.global) {
185
167
  addPluginTemplate({
186
- filename: "imports.mjs",
187
- getContents: async () => {
188
- const imports = await ctx.getImports();
168
+ filename: "auto-imports.mjs",
169
+ getContents: () => {
170
+ const imports = ctx.getImports();
189
171
  const importStatement = toImports(imports);
190
172
  const globalThisSet = imports.map((i) => `globalThis.${i.as} = ${i.as};`).join("\n");
191
173
  return `${importStatement}
@@ -196,41 +178,32 @@ export default () => {};`;
196
178
  }
197
179
  });
198
180
  } else {
199
- addVitePlugin(TransformPlugin.vite({ ctx, options, sourcemap: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client }));
200
- addWebpackPlugin(TransformPlugin.webpack({ ctx, options, sourcemap: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client }));
181
+ addVitePlugin(TransformPlugin.vite({ ctx, options, sourcemap: flow.options.sourcemap }));
201
182
  }
202
- const regenerateImports = async () => {
183
+ const regenerateAutoImports = async () => {
203
184
  ctx.clearDynamicImports();
204
185
  await ctx.modifyDynamicImports(async (imports) => {
205
186
  imports.push(...await scanDirExports(composablesDirs));
206
- await nuxt.callHook("imports:extend", imports);
187
+ await flow.callHook("autoImports:extend", imports);
207
188
  });
208
189
  };
209
- await regenerateImports();
210
- addDeclarationTemplates(ctx, options);
211
- nuxt.hook("prepare:types", ({ references }) => {
212
- references.push({ path: resolve(nuxt.options.buildDir, "types/imports.d.ts") });
213
- references.push({ path: resolve(nuxt.options.buildDir, "imports.d.ts") });
190
+ await regenerateAutoImports();
191
+ addDeclarationTemplates(ctx);
192
+ flow.hook("prepare:types", ({ references }) => {
193
+ references.push({ path: resolve(flow.options.buildDir, "types/auto-imports.d.ts") });
194
+ references.push({ path: resolve(flow.options.buildDir, "imports.d.ts") });
214
195
  });
215
- const templates = [
216
- "types/imports.d.ts",
217
- "imports.d.ts",
218
- "imports.mjs"
219
- ];
220
- nuxt.hook("builder:watch", async (_, path) => {
221
- const _resolved = resolve(nuxt.options.srcDir, path);
222
- if (composablesDirs.find((dir) => _resolved.startsWith(dir))) {
223
- await updateTemplates({
224
- filter: (template) => templates.includes(template.filename)
225
- });
226
- }
196
+ flow.hook("builder:watch", async (_, path) => {
197
+ const _resolved = resolve(flow.options.srcDir, path);
198
+ if (composablesDirs.find((dir) => _resolved.startsWith(dir)))
199
+ await flow.callHook("builder:generateApp");
227
200
  });
228
- nuxt.hook("builder:generateApp", async () => {
229
- await regenerateImports();
201
+ flow.hook("builder:generateApp", async () => {
202
+ await regenerateAutoImports();
230
203
  });
231
204
  }
232
205
  });
233
- function addDeclarationTemplates(ctx, options) {
206
+ function addDeclarationTemplates(ctx) {
234
207
  const nuxt = useNuxt();
235
208
  const stripExtension = (path) => path.replace(/\.[a-z]+$/, "");
236
209
  const resolved = {};
@@ -246,64 +219,49 @@ function addDeclarationTemplates(ctx, options) {
246
219
  };
247
220
  addTemplate({
248
221
  filename: "imports.d.ts",
249
- getContents: () => ctx.toExports(nuxt.options.buildDir)
222
+ getContents: () => ctx.toExports()
250
223
  });
251
224
  addTemplate({
252
- filename: "types/imports.d.ts",
253
- getContents: async () => `// Generated by auto imports
254
- ${options.autoImport ? await ctx.generateTypeDeclarations({ resolvePath: r }) : "// Implicit auto importing is disabled, you can use explicitly import from `#imports` instead."}`
225
+ filename: "types/auto-imports.d.ts",
226
+ getContents: () => `// Generated by auto imports
227
+ ${ctx.generateTypeDecarations({ resolvePath: r })}`
255
228
  });
256
229
  }
257
230
 
258
- async function resolveFiles(dir) {
231
+ async function resolvePagesRoutes() {
259
232
  const nuxt = useNuxt();
260
- const dirs = [resolve(nuxt.options.srcDir, dir)];
261
- const allRoutes = (await Promise.all(
262
- dirs.map(async (dir2) => {
263
- const files = await resolveFilesFlow(dir2, `**/*{${nuxt.options.extensions.join(",")}}`);
264
- files.sort();
265
- return files.filter((file) => {
266
- if (file.includes(" copy"))
267
- return false;
268
- if (!fs.readFileSync(file, "utf8").includes("export"))
269
- return false;
270
- return true;
271
- }).map((file) => {
272
- const segments = relative(dir2, file).replace(new RegExp(`${escapeRE(extname(file))}$`), "").split("/").join("_");
273
- return {
274
- file,
275
- name: camelCase(segments)
276
- };
277
- });
278
- })
279
- )).flat();
233
+ const pagesDirs = [resolve(nuxt.options.srcDir, nuxt.options.dir?.pages || "pages")];
234
+ const allRoutes = (await Promise.all(pagesDirs.map(async (dir) => {
235
+ const files = await resolveFilesFlow(dir, `**/*{${nuxt.options.extensions.join(",")}}`);
236
+ files.sort();
237
+ return files.filter((file) => !file.includes(" copy")).map((file) => {
238
+ const segments = relative(dir, file).replace(new RegExp(`${escapeRE(extname(file))}$`), "").split("/").join("_");
239
+ return {
240
+ file,
241
+ name: camelCase(segments)
242
+ };
243
+ });
244
+ }))).flat();
280
245
  return allRoutes;
281
246
  }
282
- function normalizeExports(files) {
283
- const imports = files.map((page) => genImport(page.file, page.name)).join("\n");
284
- const exports = files.reduce((acc, curr) => {
285
- const name = curr.name;
286
- return `${name}:typeof ${name}==='function'?${name}():${name},${acc}`;
287
- }, "");
247
+ function normalizePages(pages) {
248
+ const imports = pages.map((page) => genImport(page.file, [{ name: "pages", as: page.name }])).join("\n");
288
249
  return {
289
250
  imports,
290
- exports
251
+ exports: pages.reduce((acc, curr) => {
252
+ const name = curr.name;
253
+ return `${name}:typeof ${name}==='function'?${name}():${name},${acc}`;
254
+ }, "")
291
255
  };
292
256
  }
293
257
 
294
258
  const pagesTypeTemplate = {
295
- filename: "types/pages.d.ts",
259
+ filename: "pages.d.ts",
296
260
  getContents: ({ options }) => `// Generated by pages discovery
297
261
  export {}
298
262
  declare global {
299
- type ArrElement<ArrType> = ArrType extends readonly (infer ElementType)[]
300
- ? ElementType
301
- : never;
302
263
 
303
- ${options.pages.map((c) => {
304
- const _type = `ArrElement<typeof ${genDynamicImport(isAbsolute(c.file) ? relative(join(options.buildDir, "types"), c.file) : c.file, { wrapper: false })}['default']>`;
305
- return `export type ${pascalCase(c.name)}Context=Awaited<ReturnType<${_type}['locales']['es-ec']['context']>>`;
306
- }).join("\n")}
264
+ ${options.pages.map((c) => `export type ${pascalCase(c.name)}Context=Awaited<ReturnType<typeof ${genDynamicImport(isAbsolute(c.file) ? relative(options.buildDir, c.file) : c.file, { wrapper: false })}['pages']['locales']['es-ec']['context']>>`).join("\n")}
307
265
  }
308
266
  export const pagesNames: string[]
309
267
  `.replaceAll(".ts", "")
@@ -317,44 +275,29 @@ const pagesModule = defineNuxtModule({
317
275
  const runtimeDir = resolve(distDir, "pages/runtime");
318
276
  flow.options.alias["#_pages"] = runtimeDir;
319
277
  const pages = [];
320
- const contexts = [];
321
- const options = { pages, buildDir: flow.options.buildDir, contexts };
278
+ const options = { pages, buildDir: flow.options.buildDir };
322
279
  addTemplate({
323
280
  ...pagesTypeTemplate,
324
281
  options
325
282
  });
326
283
  const pagesDirs = [{ path: resolve(flow.options.srcDir, flow.options.dir.pages) }];
327
284
  flow.options.alias["#pages"] = resolve(flow.options.buildDir, "pages.mjs");
328
- flow.options.alias["#pagesContexts"] = resolve(flow.options.buildDir, "pages.contexts.mjs");
329
285
  addTemplate({
330
286
  filename: "pages.mjs",
331
287
  async getContents({ options: options2 }) {
332
- const { exports, imports } = normalizeExports(options2.pages);
333
- const module = [imports, `export default {${exports}}`].join("\n");
334
- return module;
335
- },
336
- options
337
- });
338
- addTemplate({
339
- filename: "pages.contexts.mjs",
340
- async getContents({ options: options2 }) {
341
- const { exports, imports } = normalizeExports(options2.contexts);
342
- const module = [imports, `export default {${exports}}`].join("\n");
343
- return module;
288
+ const { exports, imports } = normalizePages(options2.pages);
289
+ return [imports, `export default {${exports}}`].join("\n");
344
290
  },
345
291
  options
346
292
  });
347
293
  flow.hook("app:templates", async () => {
348
- options.pages = await resolveFiles(flow.options.dir?.pages || "pages");
349
- });
350
- flow.hook("app:templates", async () => {
351
- options.contexts = await resolveFiles("shared/contexts");
294
+ options.pages = await resolvePagesRoutes();
352
295
  });
353
296
  flow.hook("prepare:types", ({ references }) => {
354
- references.push({ path: resolve(flow.options.buildDir, "types/pages.d.ts") });
297
+ references.push({ path: resolve(flow.options.buildDir, "pages.d.ts") });
355
298
  });
356
299
  flow.hook("builder:watch", async (event, path) => {
357
- if (!["add", "unlink", "change"].includes(event))
300
+ if (!["add", "unlink"].includes(event))
358
301
  return;
359
302
  if (path.includes(" copy"))
360
303
  return;
@@ -362,28 +305,126 @@ const pagesModule = defineNuxtModule({
362
305
  if (pagesDirs.find((dir) => fPath.startsWith(dir.path)))
363
306
  await flow.callHook("builder:generateApp");
364
307
  });
365
- addPlugin(resolve(runtimeDir, "pages"));
308
+ addPlugin({ src: resolve(runtimeDir, "plugin") });
309
+ }
310
+ });
311
+
312
+ const createClient = async (flow) => {
313
+ let vite;
314
+ if (globalThis.viteClient) {
315
+ vite = globalThis.viteClient;
316
+ } else {
317
+ vite = await createServer({
318
+ root: resolve(flow.options.rootDir),
319
+ base: "/_vite/",
320
+ build: {
321
+ manifest: true
322
+ },
323
+ server: {
324
+ watch: {
325
+ ignored: ["**/.env/**", "**/.env*"]
326
+ },
327
+ middlewareMode: "ssr"
328
+ }
329
+ });
330
+ globalThis.viteClient = vite;
331
+ }
332
+ const _doReload = () => {
333
+ if (vite)
334
+ vite?.ws?.send({ type: "full-reload" });
335
+ };
336
+ const doReload = debounce(_doReload, 60);
337
+ flow.hook("bundler:change", () => {
338
+ doReload();
339
+ });
340
+ flow.hook("close", async () => {
341
+ vite.restart();
342
+ });
343
+ return vite;
344
+ };
345
+ const builClient = async (flow) => {
346
+ return await build$1({
347
+ root: flow.options.rootDir,
348
+ mode: "production",
349
+ build: {
350
+ assetsDir: "scripts",
351
+ target: "es2017",
352
+ outDir: ".vite",
353
+ manifest: true
354
+ }
355
+ });
356
+ };
357
+
358
+ const viteModule = defineFlowModule({
359
+ meta: {
360
+ name: "vite-client",
361
+ configKey: "bundle"
362
+ },
363
+ defaults: {
364
+ route: "/_vite/",
365
+ dir: "/client/pages"
366
+ },
367
+ async setup(_options, flow) {
368
+ const runtimeDir = resolve(distDir, "vite-client/runtime");
369
+ flow.options.alias["#viteManifest"] = resolve(flow.options.buildDir, "viteManifest.mjs");
370
+ let vite;
371
+ if (flow.options.dev) {
372
+ flow.hook("nitro:init", async (nitro) => {
373
+ vite = await createClient(flow);
374
+ nitro.options.devHandlers.push({
375
+ handler: vite.middlewares,
376
+ route: _options.route
377
+ });
378
+ });
379
+ addTemplate({
380
+ filename: "viteManifest.mjs",
381
+ async getContents() {
382
+ return [
383
+ "export default {",
384
+ `head:()=>'<script type="module" src="${joinURL("/", _options.route, "/@vite/client")}"><\/script>'`,
385
+ ",",
386
+ `body: (bundle)=>\`<script type="module" src="${joinURL("/", _options.route, _options.dir)}/\${bundle}.ts"><\/script>\``,
387
+ "}"
388
+ ].join("\n");
389
+ }
390
+ });
391
+ } else {
392
+ 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") });
366
416
  }
367
417
  });
368
418
 
369
419
  const _require = createRequire(import.meta.url);
370
420
  const ImportProtectionPlugin = createUnplugin((options) => {
371
421
  const cache = {};
372
- const importersToExclude = options?.exclude || [];
373
422
  return {
374
- name: "nuxt:import-protection",
423
+ name: "flow:import-protection",
375
424
  enforce: "pre",
376
425
  resolveId(id, importer) {
377
- if (!importer)
378
- return;
379
- if (id.startsWith("."))
380
- id = join(importer, "..", id);
381
- if (isAbsolute(id))
382
- id = relative(options.rootDir, id);
383
- if (importersToExclude.some((p) => typeof p === "string" ? importer === p : p.test(importer)))
384
- return;
385
426
  const invalidImports = options.patterns.filter(([pattern]) => pattern instanceof RegExp ? pattern.test(id) : pattern === id);
386
- let matched = false;
427
+ let matched;
387
428
  for (const match of invalidImports) {
388
429
  cache[id] = cache[id] || /* @__PURE__ */ new Map();
389
430
  const [pattern, warning] = match;
@@ -402,38 +443,25 @@ const ImportProtectionPlugin = createUnplugin((options) => {
402
443
  });
403
444
 
404
445
  async function initNitro(flow) {
446
+ const { handlers, devHandlers } = await resolveHandlers(flow);
405
447
  const _nitroConfig = flow.options.nitro || {};
406
448
  globalThis.generate = {};
407
- const scanDirs = flow.options._layers.map((layer) => (layer.config.serverDir || layer.config.srcDir) && resolve(layer.cwd, layer.config.serverDir || resolve(layer.config.srcDir, "server"))).filter(Boolean);
408
449
  const nitroConfig = defu(_nitroConfig, {
409
450
  rootDir: flow.options.rootDir,
410
- workspaceDir: flow.options.workspaceDir,
411
- srcDir: flow.options.serverDir,
451
+ srcDir: join(flow.options.srcDir, "server"),
412
452
  dev: flow.options.dev,
453
+ preset: flow.options.dev ? "nitro-dev" : void 0,
413
454
  buildDir: flow.options.buildDir,
414
- scanDirs,
455
+ scanDirs: flow.options._layers.map((layer) => join(layer.config.srcDir, "server")),
415
456
  renderer: resolve(distDir, "core/runtime/nitro/renderer"),
416
- // errorHandler: resolve(distDir, 'core/runtime/nitro/error'),
417
457
  nodeModulesDirs: flow.options.modulesDir,
418
- handlers: [
419
- //* Important middleware
420
- {
421
- middleware: true,
422
- handler: resolve(distDir, "core/runtime/nitro/flow")
423
- },
424
- ...flow.options.serverHandlers
425
- ],
426
- output: {
427
- dir: resolve(flow.options.buildDir, "output")
428
- },
458
+ handlers,
429
459
  devHandlers: [],
430
460
  baseURL: flow.options.app.baseURL,
431
- virtual: {},
432
461
  runtimeConfig: {
433
462
  ...flow.options.runtimeConfig,
434
463
  app: {
435
464
  ...flow.options.runtimeConfig.app,
436
- baseURL: flow.options.dev ? "/" : flow.options.app.baseURL,
437
465
  rootDir: flow.options.rootDir,
438
466
  locale: flow.options.locale
439
467
  },
@@ -448,81 +476,61 @@ async function initNitro(flow) {
448
476
  },
449
477
  publicAssets: [
450
478
  {
451
- // baseURL: flow.options.app.buildAssetsDir,
479
+ baseURL: flow.options.app.buildAssetsDir,
452
480
  dir: resolve(flow.options.buildDir, "dist/client")
453
481
  },
454
482
  ...flow.options._layers.map((layer) => join(layer.config.srcDir, layer.config.dir?.public || "public")).filter((dir) => existsSync(dir)).map((dir) => ({ dir }))
455
483
  ],
456
484
  prerender: {
457
- crawlLinks: flow.options._generate ?? void 0,
458
- 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] : [])
459
487
  },
460
- sourceMap: flow.options.sourcemap.server,
488
+ sourcemap: flow.options.sourcemap,
461
489
  externals: {
462
490
  inline: [
463
491
  ...flow.options.dev ? [] : ["eta", "@monkeyplus/", "@vue/", "@nuxt/", flow.options.buildDir],
464
- "@monkeyplus/flow/dist",
465
- // Dev windows
466
- "C:/Users/gnu/Documents/GitHub/flow/packages/flow/dist/app",
467
- distDir
492
+ "@monkeyplus/flow/dist"
468
493
  ]
469
494
  },
470
- // preset: flow.options.dev ? 'nitro-dev' : undefined,
471
- // output: {
472
- // dir: resolve(flow.options.buildDir, 'output'),
473
- // },
474
- replace: {
475
- "process.dev": flow.options.dev
476
- },
477
495
  alias: {
478
- // Vue 3 mocks
479
496
  "estree-walker": "unenv/runtime/mock/proxy",
480
497
  "@babel/parser": "unenv/runtime/mock/proxy",
481
- // Paths
482
498
  "#paths": resolve(distDir, "core/runtime/nitro/paths"),
483
- // Shortcut to server main file
484
499
  "#server": "#build/dist/server/server.mjs",
485
- // Nuxt aliases
486
500
  ...flow.options.alias
487
501
  },
488
502
  rollupConfig: {
489
503
  plugins: []
490
- },
491
- // watchOptions:{}
492
- //* Include to refresh server
493
- devServer: {
494
- watch: [resolve(flow.options.buildDir, "dist/server/server.mjs")]
495
504
  }
496
505
  });
497
- nitroConfig.rollupConfig.plugins.push(
498
- ImportProtectionPlugin.rollup({
499
- rootDir: flow.options.rootDir,
500
- patterns: [
501
- ...["#app", /^#build(\/|$)/].map((p) => [p, "Vue app aliases are not allowed in server routes."])
502
- ],
503
- exclude: [/core[\\/]runtime[\\/]nitro[\\/]renderer/]
504
- })
505
- );
506
506
  await flow.callHook("nitro:config", nitroConfig);
507
+ nitroConfig.handlers.unshift({
508
+ middleware: true,
509
+ handler: resolve(distDir, "core/runtime/nitro/flow")
510
+ });
507
511
  const nitro = await createNitro(nitroConfig);
508
- flow._nitro = nitro;
509
- flow.nitro = nitro;
510
512
  await flow.callHook("nitro:init", nitro);
511
513
  nitro.vfs = flow.vfs = nitro.vfs || flow.vfs || {};
512
514
  flow.hook("close", () => nitro.hooks.callHook("close"));
513
- nitro.hooks.hook("prerender:routes", (routes) => {
514
- 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);
515
523
  });
516
- const devMiddlewareHandler = dynamicEventHandler();
517
- nitro.options.devHandlers.unshift({ handler: devMiddlewareHandler });
518
- nitro.options.devHandlers.push(...flow.options.devServerHandlers);
524
+ const devMidlewareHandler = dynamicEventHandler();
525
+ nitro.options.devHandlers.unshift({ handler: devMidlewareHandler });
526
+ nitro.options.devHandlers.push(...devHandlers);
519
527
  nitro.options.handlers.unshift({
520
- route: "/__nuxt_error",
528
+ route: "/__flow_error",
521
529
  lazy: true,
522
530
  handler: resolve(distDir, "core/runtime/nitro/renderer")
523
531
  });
524
532
  flow.hook("prepare:types", async (opts) => {
525
- if (!flow.options.dev) {
533
+ if (flow.options._prepare) {
526
534
  await scanHandlers(nitro);
527
535
  await writeTypes(nitro);
528
536
  }
@@ -531,15 +539,21 @@ async function initNitro(flow) {
531
539
  flow.hook("build:done", async () => {
532
540
  await flow.callHook("nitro:build:before", nitro);
533
541
  if (flow.options.dev) {
534
- await build$1(nitro);
542
+ await build$2(nitro);
535
543
  } else {
536
- console.log("build", flow.options._generate);
537
544
  await prepare(nitro);
538
545
  await copyPublicAssets(nitro);
539
546
  await prerender(nitro);
540
547
  if (!flow.options._generate) {
541
- await build$1(nitro);
548
+ await build$2(nitro);
542
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;
543
557
  const distDir2 = resolve(flow.options.rootDir, "dist");
544
558
  if (!existsSync(distDir2))
545
559
  await promises.symlink(nitro.options.output.publicDir, distDir2, "junction").catch(() => {
@@ -548,27 +562,37 @@ async function initNitro(flow) {
548
562
  }
549
563
  });
550
564
  if (flow.options.dev) {
551
- flow.hook("vite:compiled", () => {
552
- flow.server.reload();
565
+ flow.hook("build:compile", ({ compiler }) => {
566
+ compiler.outputFileSystem = { ...fse, join };
553
567
  });
554
- flow.hook("server:devHandler", (h) => {
555
- devMiddlewareHandler.set(h);
568
+ flow.hook("server:devMiddleware", (m) => {
569
+ devMidlewareHandler.set(toEventHandler(m));
556
570
  });
557
571
  flow.server = createDevServer(nitro);
572
+ flow.hook("build:resources", () => {
573
+ flow.server.reload();
574
+ });
558
575
  const waitUntilCompile = new Promise((resolve2) => nitro.hooks.hook("compiled", () => resolve2()));
559
576
  flow.hook("build:done", () => waitUntilCompile);
560
577
  }
561
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
+ }
562
587
 
563
588
  const addModuleTranspiles = (opts = {}) => {
564
589
  const flow = useNuxt();
565
590
  const modules = [
566
591
  ...opts.additionalModules || [],
567
- // ...flow.options.buildModules,
568
592
  ...flow.options.modules,
569
593
  ...flow.options._modules
570
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());
571
- 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);
572
596
  function isTranspilePresent(mod) {
573
597
  return flow.options.build.transpile.some((t) => !(t instanceof Function) && (t instanceof RegExp ? t.test(mod) : new RegExp(t).test(mod)));
574
598
  }
@@ -581,10 +605,7 @@ const addModuleTranspiles = (opts = {}) => {
581
605
  function createFlow(options) {
582
606
  const hooks = createHooks();
583
607
  const flow = {
584
- //* Include nuxt version
585
- _version: "3.0.0",
586
- //* Include version
587
- // @ts-ignore
608
+ _version: "3.0.0-rc.3",
588
609
  version,
589
610
  options,
590
611
  hooks,
@@ -598,12 +619,10 @@ function createFlow(options) {
598
619
  return flow;
599
620
  }
600
621
  async function initFlow(flow) {
601
- flow.hooks.addHooks(flow.options.hooks);
602
622
  nuxtCtx.set(flow);
603
623
  flow.hook("close", () => nuxtCtx.unset());
604
- await flow.callHook("modules:before");
624
+ await flow.callHook("modules:before", { nuxt: flow });
605
625
  const modulesToInstall = [
606
- // ...flow.options.buildModules,
607
626
  ...flow.options.modules,
608
627
  ...flow.options._modules
609
628
  ];
@@ -613,26 +632,17 @@ async function initFlow(flow) {
613
632
  else
614
633
  await installModule(m, {});
615
634
  }
616
- await flow.callHook("modules:done");
617
- flow.options.build.transpile = flow.options.build.transpile.map((t) => typeof t === "string" ? normalize(t) : t);
618
- addModuleTranspiles();
635
+ await flow.callHook("modules:done", { nuxt: flow });
636
+ await addModuleTranspiles();
619
637
  await initNitro(flow);
620
638
  await flow.callHook("ready", flow);
621
639
  }
622
640
  async function loadFlow(opts) {
623
- const start1 = Date.now();
624
641
  const options = await loadFlowConfig(opts);
625
- logger.info(`Config loading in ${Date.now() - start1}ms`);
626
642
  options.appDir = resolve(distDir, "app");
627
643
  options.alias["#app"] = resolve(distDir, "app/index");
628
644
  options._majorVersion = 3;
629
- options._modules.push(pagesModule, metaModule);
630
- options._modules.push([importsModule, {
631
- transform: {
632
- include: options._layers.filter((i) => i.cwd && i.cwd.includes("node_modules")).map((i) => new RegExp(`(^|\\/)${escapeRE(i.cwd.split("node_modules/").pop())}(\\/|$)(?!node_modules\\/)`))
633
- }
634
- }]);
635
- options.modulesDir.push(resolve(options.workspaceDir, "node_modules"));
645
+ options._modules.push(pagesModule, metaModule, autoImportsModule, viteModule);
636
646
  options.modulesDir.push(resolve(pkgDir, "node_modules"));
637
647
  const flow = createFlow(options);
638
648
  if (opts.ready !== false)
@@ -647,17 +657,11 @@ const serverPluginTemplate = {
647
657
  filename: "plugins/server.mjs",
648
658
  getContents(ctx) {
649
659
  const serverPlugins = ctx.app.plugins;
650
- const exports = [];
651
- const imports = [];
652
- for (const plugin of serverPlugins) {
653
- const path = relative(ctx.nuxt.options.rootDir, plugin.src);
654
- const variable = `${genSafeVariableName(path).replace(/_(45|46|47)/g, "_")}_${hash(path)}`;
655
- exports.push(variable);
656
- imports.push(genImport(plugin.src, variable));
657
- }
658
660
  return [
659
- ...imports,
660
- `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
+ ])}`
661
665
  ].join("\n");
662
666
  }
663
667
  };
@@ -686,52 +690,43 @@ export { }
686
690
  `;
687
691
  }
688
692
  };
689
- const adHocModules = ["imports", "meta", "pages"];
693
+ const adHocModules = ["auto-imports", "meta", "pages", "vite-client"];
690
694
  const schemaTemplate = {
691
695
  filename: "types/schema.d.ts",
692
- getContents: async ({ nuxt }) => {
696
+ getContents: ({ nuxt }) => {
693
697
  const moduleInfo = nuxt.options._installedModules.map((m) => ({
694
698
  ...m.meta || {},
695
699
  importName: m.entryPath || m.meta?.name
696
700
  })).filter((m) => m.configKey && m.name && !adHocModules.includes(m.name));
697
- const relativeRoot = relative(resolve(nuxt.options.buildDir, "types"), nuxt.options.rootDir);
698
701
  return [
699
702
  "import { FlowModule } from '@monkeyplus/flow-schema'",
700
703
  "declare module '@monkeyplus/flow-schema' {",
701
704
  " interface FlowConfig {",
702
- ...moduleInfo.filter(Boolean).map(
703
- (meta) => ` [${genString(meta.configKey)}]?: typeof ${genDynamicImport(meta.importName.startsWith(".") ? `./${join(relativeRoot, meta.importName)}` : meta.importName, { wrapper: false })}.default extends FlowModule<infer O> ? Partial<O> : Record<string, any>`
704
- ),
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>`),
705
706
  " }",
706
- generateTypes(
707
- await resolveSchema(Object.fromEntries(Object.entries(nuxt.options.runtimeConfig).filter(([key]) => key !== "public"))),
708
- {
709
- interfaceName: "RuntimeConfig",
710
- addExport: false,
711
- addDefaults: false,
712
- allowExtraKeys: false,
713
- indentation: 2
714
- }
715
- ),
716
- generateTypes(
717
- await resolveSchema(nuxt.options.runtimeConfig.public),
718
- {
719
- interfaceName: "PublicRuntimeConfig",
720
- addExport: false,
721
- addDefaults: false,
722
- allowExtraKeys: false,
723
- indentation: 2
724
- }
725
- ),
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
+ }),
726
721
  "}"
727
722
  ].join("\n");
728
723
  }
729
724
  };
730
725
  const publicPathTemplate = {
731
726
  filename: "paths.mjs",
732
- async getContents({ nuxt }) {
727
+ getContents({ nuxt }) {
733
728
  return [
734
- `import { joinURL } from '${await _resolveId("ufo")}'`,
729
+ "import { joinURL } from 'ufo'",
735
730
  !nuxt.options.dev && "import { useRuntimeConfig } from '#internal/nitro'",
736
731
  nuxt.options.dev ? `const appConfig = ${JSON.stringify(nuxt.options.app)}` : "const appConfig = useRuntimeConfig().app",
737
732
  "export const baseURL = () => appConfig.baseURL",
@@ -744,39 +739,15 @@ const publicPathTemplate = {
744
739
  ].filter(Boolean).join("\n");
745
740
  }
746
741
  };
747
- function _resolveId(id) {
748
- return resolvePath(id, {
749
- url: [
750
- // @ts-ignore
751
- global.__NUXT_PREPATHS__,
752
- import.meta.url,
753
- process.cwd(),
754
- // @ts-ignore
755
- global.__NUXT_PATHS__
756
- ]
757
- });
758
- }
759
742
 
760
743
  const defaultTemplates = {
761
744
  __proto__: null,
745
+ serverPluginTemplate: serverPluginTemplate,
762
746
  pluginsDeclaration: pluginsDeclaration,
763
- publicPathTemplate: publicPathTemplate,
764
747
  schemaTemplate: schemaTemplate,
765
- serverPluginTemplate: serverPluginTemplate
748
+ publicPathTemplate: publicPathTemplate
766
749
  };
767
750
 
768
- function uniqueBy(arr, key) {
769
- const res = [];
770
- const seen = /* @__PURE__ */ new Set();
771
- for (const item of arr) {
772
- if (seen.has(item[key]))
773
- continue;
774
- seen.add(item[key]);
775
- res.push(item);
776
- }
777
- return res;
778
- }
779
-
780
751
  function createApp(flow, options = {}) {
781
752
  return defu(options, {
782
753
  dir: flow.options.srcDir,
@@ -785,95 +756,51 @@ function createApp(flow, options = {}) {
785
756
  templates: []
786
757
  });
787
758
  }
788
- async function generateApp(flow, app, options) {
759
+ async function generateApp(flow, app) {
789
760
  await resolveApp(flow, app);
790
- app.templates = Object.values(defaultTemplates).concat(
791
- flow.options.build.templates
792
- );
761
+ app.templates = Object.values(defaultTemplates).concat(flow.options.build.templates);
793
762
  await flow.callHook("app:templates", app);
794
763
  app.templates = app.templates.map((tmpl) => normalizeTemplate(tmpl));
795
764
  const templateContext = { utils: templateUtils, nuxt: flow, app };
796
- await Promise.all(
797
- app.templates.map(async (template) => {
798
- const contents = await compileTemplate(template, templateContext);
799
- const fullPath = template.dst || resolve(flow.options.buildDir, template.filename);
800
- flow.vfs[fullPath] = contents;
801
- const aliasPath = `#build/${template.filename.replace(/\.\w+$/, "")}`;
802
- flow.vfs[aliasPath] = contents;
803
- if (process.platform === "win32")
804
- flow.vfs[fullPath.replace(/\//g, "\\")] = contents;
805
- if (template.write) {
806
- await promises.mkdir(dirname(fullPath), { recursive: true });
807
- await promises.writeFile(fullPath, contents, "utf8");
808
- }
809
- })
810
- );
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
+ }));
811
778
  await flow.callHook("app:templatesGenerated", app);
812
779
  }
813
780
  async function resolveApp(flow, app) {
814
- app.plugins = [
815
- ...flow.options.plugins.map(normalizePlugin)
816
- ];
781
+ app.plugins = [...flow.options.plugins.map(normalizePlugin)];
817
782
  for (const config of flow.options._layers.map((layer) => layer.config)) {
818
783
  app.plugins.push(...[
819
784
  ...config.plugins || [],
820
- ...config.srcDir ? await resolveFilesFlow(config.srcDir, [
821
- `${config.dir?.plugins || "plugins"}/*.{ts,js,mjs,cjs,mts,cts}`,
822
- `${config.dir?.plugins || "plugins"}/*/index.*{ts,js,mjs,cjs,mts,cts}`
823
- ]) : []
785
+ ...await resolveFilesFlow(config.srcDir, [
786
+ "plugins/*.{ts,js,mjs,cjs,mts,cts}",
787
+ "plugins/*/index.*{ts,js,mjs,cjs,mts,cts}"
788
+ ])
824
789
  ].map((plugin) => normalizePlugin(plugin)));
825
790
  }
826
- app.configs = [];
827
- for (const config of flow.options._layers.map((layer) => layer.config)) {
828
- const appConfigPath = await findPath(resolve(config.srcDir, "app.config"));
829
- if (appConfigPath)
830
- app.configs.push(appConfigPath);
831
- }
832
- await flow.callHook("app:resolve", app);
833
791
  app.plugins = uniqueBy(app.plugins, "src");
792
+ await flow.callHook("app:resolve", app);
834
793
  }
835
-
836
- const PREFIX = "virtual:nuxt:";
837
- function virtual(vfs) {
838
- const extensions = ["", ".ts", ".vue", ".mjs", ".cjs", ".js", ".json"];
839
- const resolveWithExt = (id) => {
840
- for (const ext of extensions) {
841
- const rId = id + ext;
842
- if (rId in vfs)
843
- return rId;
844
- }
845
- return null;
846
- };
847
- return {
848
- name: "virtual",
849
- resolveId(id, importer) {
850
- if (process.platform === "win32" && isAbsolute(id)) {
851
- id = resolve(id);
852
- }
853
- const resolvedId = resolveWithExt(id);
854
- if (resolvedId)
855
- return PREFIX + resolvedId;
856
- if (importer && !isAbsolute(id)) {
857
- const importerNoPrefix = importer.startsWith(PREFIX) ? importer.slice(PREFIX.length) : importer;
858
- const importedDir = dirname(importerNoPrefix);
859
- const resolved = resolveWithExt(join(importedDir, id));
860
- if (resolved)
861
- return PREFIX + resolved;
862
- }
863
- return null;
864
- },
865
- load(id) {
866
- if (!id.startsWith(PREFIX))
867
- return null;
868
- const idNoPrefix = id.slice(PREFIX.length);
869
- if (idNoPrefix in vfs) {
870
- return {
871
- code: vfs[idNoPrefix],
872
- map: null
873
- };
874
- }
875
- }
876
- };
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;
877
804
  }
878
805
 
879
806
  async function warmupViteServer(server, entries) {
@@ -894,11 +821,6 @@ async function warmupViteServer(server, entries) {
894
821
  await Promise.all(entries.map((entry) => warmup(entry)));
895
822
  }
896
823
 
897
- const wpfs = {
898
- ...fse,
899
- join
900
- };
901
-
902
824
  function cacheDirPlugin(rootDir, name) {
903
825
  const optimizeCacheDir = resolve(rootDir, "node_modules/.cache/vite", name);
904
826
  return {
@@ -909,63 +831,279 @@ function cacheDirPlugin(rootDir, name) {
909
831
  };
910
832
  }
911
833
 
912
- 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) => {
913
1077
  const serverConfig = vite.mergeConfig(ctx.config, {
914
- base: ctx.nuxt.options.dev ? joinURL(ctx.nuxt.options.app.baseURL.replace(/^\.\//, "/") || "/", ctx.nuxt.options.app.buildAssetsDir) : void 0,
915
- // experimental: {
916
- // renderBuiltUrl: (filename, { type, hostType }) => {
917
- // if (hostType !== 'js') {
918
- // // In CSS we only use relative paths until we craft a clever runtime CSS hack
919
- // return { relative: true };
920
- // }
921
- // if (type === 'public')
922
- // return { runtime: `globalThis.__publicAssetsURL(${JSON.stringify(filename)})` };
923
- // if (type === 'asset') {
924
- // const relativeFilename = filename.replace(withTrailingSlash(withoutLeadingSlash(ctx.nuxt.options.app.buildAssetsDir)), '');
925
- // return { runtime: `globalThis.__buildAssetsURL(${JSON.stringify(relativeFilename)})` };
926
- // }
927
- // },
928
- // },
1078
+ configFile: false,
929
1079
  define: {
930
1080
  "process.server": true,
931
- "process.client": false,
932
1081
  "typeof window": '"undefined"',
933
1082
  "typeof document": '"undefined"',
934
1083
  "typeof navigator": '"undefined"',
935
1084
  "typeof location": '"undefined"',
936
1085
  "typeof XMLHttpRequest": '"undefined"'
937
1086
  },
938
- resolve: {
939
- alias: {
940
- "#build/plugins": resolve(ctx.nuxt.options.buildDir, "plugins/server")
941
- }
942
- },
943
1087
  ssr: {
944
- external: ["#internal/nitro", "#internal/nitro/utils"],
945
1088
  noExternal: [
946
- ...ctx.nuxt.options.build.transpile,
947
- // TODO: Use externality for production (rollup) build
1089
+ ...ctx.flow.options.build.transpile,
948
1090
  /\/esm\/.*\.js$/,
949
1091
  /\.(es|esm|esm-browser|esm-bundler).js$/,
950
1092
  "/__vue-jsx",
951
1093
  "#app",
952
1094
  /(nuxt|nuxt3)\/(dist|src|app)/,
953
- /flow\/(dist|src|app)/,
954
- /flow\/modules\/(content|icons|images|netlify|netlify-cms|seo|sitemap|vue)/,
955
1095
  /@monkeyplus\/flow\/(dist|src|app)/,
956
1096
  /@nuxt\/nitro\/(dist|src)/
957
1097
  ]
958
1098
  },
959
1099
  build: {
960
- outDir: resolve(ctx.nuxt.options.buildDir, "dist/server"),
961
- ssr: true,
1100
+ outDir: resolve(ctx.flow.options.buildDir, "dist/server"),
1101
+ manifest: true,
962
1102
  rollupOptions: {
963
1103
  external: ["#internal/nitro"],
964
1104
  output: {
965
1105
  entryFileNames: "server.mjs",
966
1106
  preferConst: true,
967
- // TODO: https://github.com/vitejs/vite/pull/8641
968
- inlineDynamicImports: !ctx.nuxt.options.experimental.viteServerDynamicImports,
969
1107
  format: "module"
970
1108
  },
971
1109
  onwarn(warning, rollupWarn) {
@@ -975,31 +1113,39 @@ async function buildServer(ctx) {
975
1113
  }
976
1114
  },
977
1115
  server: {
978
- // https://github.com/vitest-dev/vitest/issues/229#issuecomment-1002685027
979
1116
  preTransformRequests: false,
980
- hmr: false
1117
+ cors: true
981
1118
  },
982
1119
  plugins: [
983
- cacheDirPlugin(ctx.nuxt.options.rootDir, "server"),
984
- replace({
985
- ...Object.fromEntries([";", "(", "{", "}", " ", " ", "\n"].map((d) => [`${d}global.`, `${d}globalThis.`])),
986
- preventAssignment: true
987
- })
988
- // vuePlugin(ctx.config.vue),
989
- // viteJsxPlugin(),
1120
+ cacheDirPlugin(ctx.flow.options.rootDir, "server")
990
1121
  ]
991
1122
  });
992
- if (ctx.nuxt.options.typescript.typeCheck === true || ctx.nuxt.options.typescript.typeCheck === "build" && !ctx.nuxt.options.dev) {
993
- const checker = await import('vite-plugin-checker').then((r) => r.default);
994
- serverConfig.plugins.push(checker({
995
- vueTsc: {
996
- tsconfigPath: await resolveTSConfig(ctx.nuxt.options.rootDir)
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
+ }
997
1137
  }
998
- }));
999
- }
1000
- await ctx.nuxt.callHook("vite:extendConfig", serverConfig, { isClient: false, isServer: true });
1001
- const onBuild = () => ctx.nuxt.callHook("build:resources", wpfs);
1002
- if (!ctx.nuxt.options.dev) {
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) {
1003
1149
  const start = Date.now();
1004
1150
  logger.info("Building server...");
1005
1151
  await vite.build(serverConfig);
@@ -1009,87 +1155,184 @@ async function buildServer(ctx) {
1009
1155
  }
1010
1156
  const viteServer = await vite.createServer(serverConfig);
1011
1157
  ctx.ssrServer = viteServer;
1012
- await ctx.nuxt.callHook("vite:serverCreated", viteServer, { isClient: false, isServer: true });
1013
- 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());
1014
1160
  await viteServer.pluginContainer.buildStart({});
1015
- 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
+ };
1016
1222
  }
1017
1223
 
1018
- async function bundle$1(nuxt) {
1019
- 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
+ });
1020
1273
  const ctx = {
1021
- nuxt,
1022
- entry,
1023
- config: vite.mergeConfig(
1024
- {
1025
- configFile: false,
1026
- resolve: {
1027
- alias: {
1028
- ...nuxt.options.alias,
1029
- "#app": nuxt.options.appDir,
1030
- // We need this resolution to be present before the following entry, but it
1031
- // will be filled in client/server configs
1032
- "#build/plugins": "",
1033
- "#build": nuxt.options.buildDir,
1034
- "web-streams-polyfill/ponyfill/es2018": "unenv/runtime/mock/empty",
1035
- // Cannot destructure property 'AbortController' of ..
1036
- "abort-controller": "unenv/runtime/mock/empty"
1037
- }
1038
- },
1039
- optimizeDeps: {
1040
- entries: [entry],
1041
- include: []
1042
- },
1043
- // css: resolveCSSOptions(nuxt),
1044
- build: {
1045
- rollupOptions: {
1046
- output: { sanitizeFileName: sanitizeFilePath },
1047
- input: resolve(nuxt.options.appDir, "entry")
1048
- },
1049
- watch: {
1050
- exclude: nuxt.options.ignore
1051
- }
1052
- },
1053
- plugins: [
1054
- // composableKeysPlugin.vite({ sourcemap: nuxt.options.sourcemap, rootDir: nuxt.options.rootDir }),
1055
- replace({
1056
- ...Object.fromEntries([";", "(", "{", "}", " ", " ", "\n"].map((d) => [`${d}global.`, `${d}globalThis.`])),
1057
- preventAssignment: true
1058
- }),
1059
- virtual(nuxt.vfs)
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")
1060
1290
  ],
1061
- vue: {
1062
- reactivityTransform: nuxt.options.experimental.reactivityTransform
1063
- },
1064
- server: {
1065
- watch: { ignored: isIgnoredFlow },
1066
- fs: {
1067
- allow: [
1068
- nuxt.options.appDir
1069
- ]
1070
- },
1071
- hmr: false
1291
+ include: []
1292
+ },
1293
+ build: {
1294
+ rollupOptions: {
1295
+ output: { sanitizeFileName: sanitizeFilePath },
1296
+ input: resolve(flow.options.appDir, "entry")
1072
1297
  }
1073
1298
  },
1074
- nuxt.options.vite
1075
- )
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)
1076
1323
  };
1077
- if (!nuxt.options.dev) {
1078
- ctx.config.server.watch = void 0;
1079
- ctx.config.build.watch = void 0;
1080
- }
1081
- await nuxt.callHook("vite:extend", ctx);
1082
- nuxt.hook("vite:serverCreated", (server, env) => {
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) => {
1083
1328
  ctx.nuxt.hook("app:templatesGenerated", () => {
1084
1329
  for (const [id, mod] of server.moduleGraph.idToModuleMap) {
1085
- if (id.includes("pages."))
1086
- server.moduleGraph.invalidateModule(mod);
1087
- if (id.startsWith("\virtual:"))
1330
+ if (id.startsWith("\0virtual:"))
1088
1331
  server.moduleGraph.invalidateModule(mod);
1089
1332
  }
1090
1333
  });
1091
1334
  const start = Date.now();
1092
- warmupViteServer(server, [join("/@fs/", ctx.entry)]).then(() => logger.info(`Vite ${env.isClient ? "client" : "server"} warmed up in ${Date.now() - start}ms`)).catch(logger.error);
1335
+ warmupViteServer(server, ["/entry.mjs"]).then(() => logger.info(`Vite server warmed up in ${Date.now() - start}ms`)).catch(logger.error);
1093
1336
  });
1094
1337
  await buildServer(ctx);
1095
1338
  }
@@ -1104,16 +1347,12 @@ async function build(flow) {
1104
1347
  if (event !== "change" && /app|error|plugins/i.test(path))
1105
1348
  await generateApp$1();
1106
1349
  });
1107
- flow.hook("builder:generateApp", (options) => {
1108
- if (options)
1109
- return generateApp(flow, app);
1110
- return generateApp$1();
1111
- });
1350
+ flow.hook("builder:generateApp", generateApp$1);
1112
1351
  }
1113
- await flow.callHook("build:before");
1352
+ await flow.callHook("build:before", { flow }, flow.options.build);
1114
1353
  if (!flow.options._prepare) {
1115
1354
  await bundle(flow);
1116
- await flow.callHook("build:done");
1355
+ await flow.callHook("build:done", { flow });
1117
1356
  }
1118
1357
  if (!flow.options.dev)
1119
1358
  await flow.callHook("close", flow);
@@ -1129,13 +1368,14 @@ function watch(flow) {
1129
1368
  "node_modules"
1130
1369
  ]
1131
1370
  });
1132
- 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);
1133
1373
  flow.hook("close", () => watcher.close());
1134
1374
  return watcher;
1135
1375
  }
1136
1376
  async function bundle(nuxt) {
1137
1377
  try {
1138
- return bundle$1(nuxt);
1378
+ return bundleVite(nuxt);
1139
1379
  } catch (error) {
1140
1380
  await nuxt.callHook("build:error", error);
1141
1381
  throw error;