@monkeyplus/flow 5.0.0-rc.6 → 5.0.0-rc.61
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/app/flow.d.ts +9 -2
- package/dist/app/flow.mjs +3 -0
- package/dist/core/runtime/nitro/flow.mjs +3 -2
- package/dist/core/runtime/nitro/renderer.mjs +51 -13
- package/dist/index.mjs +94 -53
- package/dist/pages/runtime/index.d.ts +9 -3
- package/dist/pages/runtime/index.mjs +11 -4
- package/dist/pages/runtime/pages.mjs +90 -0
- package/dist/vite-client/runtime/injectManifest.mjs +3 -2
- package/dist/vite-client/runtime/plugin.mjs +3 -2
- package/package.json +5 -5
- package/dist/pages/runtime/plugin.mjs +0 -53
- /package/dist/pages/runtime/{plugin.d.ts → pages.d.ts} +0 -0
package/dist/app/flow.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { RadixRouter } from 'radix3';
|
|
2
2
|
import type { Hookable } from 'hookable';
|
|
3
|
-
import type { FlowPage, RuntimeConfig } from '@monkeyplus/flow-schema';
|
|
3
|
+
import type { FlowAppUtils, FlowPage, RuntimeConfig } from '@monkeyplus/flow-schema';
|
|
4
4
|
declare type HookResult = Promise<void> | void;
|
|
5
5
|
export interface FlowAppHooks {
|
|
6
6
|
'flow:pages': (page: FlowPage[]) => HookResult;
|
|
@@ -11,6 +11,10 @@ export interface FlowAppHooks {
|
|
|
11
11
|
bodyStart: string[];
|
|
12
12
|
}) => HookResult;
|
|
13
13
|
'page:links': (links: string[]) => HookResult;
|
|
14
|
+
'page:context': (ctx: {
|
|
15
|
+
page: string;
|
|
16
|
+
localeCode: string;
|
|
17
|
+
}, utils: any, data: Record<string, any>) => HookResult;
|
|
14
18
|
'page:chunks': (bundle: string, scripts: {
|
|
15
19
|
head: string[];
|
|
16
20
|
body: string[];
|
|
@@ -27,11 +31,14 @@ export interface FlowApp {
|
|
|
27
31
|
callHook: FlowApp['hooks']['callHook'];
|
|
28
32
|
eta: any;
|
|
29
33
|
app: {
|
|
30
|
-
utils:
|
|
34
|
+
utils: FlowAppUtils;
|
|
31
35
|
plugins: Record<string, any>;
|
|
32
36
|
globals: Record<string, any>;
|
|
33
37
|
};
|
|
34
38
|
engine: string;
|
|
39
|
+
site: {
|
|
40
|
+
origin: string;
|
|
41
|
+
};
|
|
35
42
|
engines: Record<string, (template: string) => string>;
|
|
36
43
|
generate: boolean;
|
|
37
44
|
render: (view: Record<string, string>, data: any) => Promise<string> | void | string;
|
package/dist/app/flow.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { defineEventHandler } from "h3";
|
|
2
1
|
import "node-fetch-native/polyfill";
|
|
3
|
-
import {
|
|
2
|
+
import { defineEventHandler } from "h3";
|
|
3
|
+
import { defineCachedFunction, useRuntimeConfig } from "#internal/nitro";
|
|
4
4
|
const getServerApp = cachedImport(() => import("#server"));
|
|
5
5
|
const getFlowRenderer = cachedResult(async () => {
|
|
6
6
|
const createFlowApp = await getServerApp();
|
|
@@ -12,6 +12,7 @@ export default defineEventHandler(async ({ context }) => {
|
|
|
12
12
|
const flow = await getFlowRenderer();
|
|
13
13
|
context.flow = flow;
|
|
14
14
|
context.render = flow.render;
|
|
15
|
+
context.defineCachedFunction = defineCachedFunction;
|
|
15
16
|
});
|
|
16
17
|
function _interopDefault(e) {
|
|
17
18
|
return e && typeof e === "object" && "default" in e ? e.default : e;
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { eventHandler, useQuery } from "h3";
|
|
2
|
+
import { joinURL } from "ufo";
|
|
3
|
+
const normalizeCall = async (seo, ctx) => {
|
|
4
|
+
if (typeof seo === "function")
|
|
5
|
+
return await seo(ctx);
|
|
6
|
+
return seo || {};
|
|
7
|
+
};
|
|
2
8
|
export default eventHandler(async (event) => {
|
|
3
9
|
const url = event.req.url?.split("?")[0];
|
|
4
10
|
const flow = event.context.flow;
|
|
@@ -9,34 +15,57 @@ export default eventHandler(async (event) => {
|
|
|
9
15
|
const scripts = { head: [], bodyStart: [], bodyEnd: [] };
|
|
10
16
|
const chunks = { head: [], body: [] };
|
|
11
17
|
const generate = {};
|
|
12
|
-
const { page, locale, params, view } = flow.router.byUrl.lookup(url) || {};
|
|
18
|
+
const { page, locale, params, view, name: pageName } = flow.router.byUrl.lookup(url) || {};
|
|
13
19
|
if (!page)
|
|
14
20
|
return;
|
|
15
21
|
await flow.callHook("page:scripts", scripts);
|
|
16
22
|
if (view.bundle)
|
|
17
23
|
await flow.callHook("page:chunks", view.bundle, chunks);
|
|
18
24
|
const templateContext = {};
|
|
19
|
-
const
|
|
20
|
-
const contextPage = {
|
|
21
|
-
|
|
25
|
+
const dynamic = params?._;
|
|
26
|
+
const contextPage = {
|
|
27
|
+
chunks,
|
|
28
|
+
locale
|
|
29
|
+
};
|
|
30
|
+
const contextInject = {};
|
|
31
|
+
const utils = Object.assign({ getLocale: () => locale, injectContext: (key, value) => contextInject[key] = value, defineCachedFunction: event.context.defineCachedFunction }, flow.app.utils);
|
|
32
|
+
const contextHooks = {};
|
|
33
|
+
await flow.callHook("page:context", { localeCode: locale.code, page: pageName }, utils, contextHooks);
|
|
22
34
|
templateContext.url = url;
|
|
35
|
+
const pageObject = {
|
|
36
|
+
name: pageName,
|
|
37
|
+
pathname: url,
|
|
38
|
+
url: joinURL(flow.site.origin, `${url}`),
|
|
39
|
+
origin: flow.site.origin,
|
|
40
|
+
joinOrigin: (_url) => joinURL(flow.site.origin, _url)
|
|
41
|
+
};
|
|
42
|
+
templateContext.page = pageObject;
|
|
43
|
+
contextPage.page = pageObject;
|
|
23
44
|
templateContext.locale = locale;
|
|
24
45
|
templateContext.view = view;
|
|
25
|
-
if (
|
|
46
|
+
if (dynamic && page.dynamic) {
|
|
26
47
|
const pages = await page.dynamic.method({ locale, utils });
|
|
27
|
-
const dynamicPage = pages.find((_page) => _page.url ===
|
|
48
|
+
const dynamicPage = pages.find((_page) => _page.url === dynamic);
|
|
28
49
|
if (!dynamicPage)
|
|
29
50
|
return;
|
|
30
51
|
if (page.dynamic.assign)
|
|
31
52
|
templateContext[page.dynamic.assign] = dynamicPage.context;
|
|
32
|
-
contextPage.
|
|
53
|
+
contextPage.dynamic = dynamicPage;
|
|
33
54
|
}
|
|
34
55
|
templateContext.seo = {};
|
|
35
|
-
|
|
36
|
-
|
|
56
|
+
const sharedContext = await utils.getSharedContext({
|
|
57
|
+
...contextHooks,
|
|
58
|
+
...contextPage,
|
|
59
|
+
utils
|
|
60
|
+
});
|
|
61
|
+
templateContext.sharedContext = sharedContext || {};
|
|
37
62
|
templateContext.utils = utils;
|
|
38
|
-
templateContext.seo = await page
|
|
39
|
-
|
|
63
|
+
templateContext.seo = await normalizeCall(page?.seo, { ...contextHooks, ...contextPage, utils, sharedContext });
|
|
64
|
+
const contexData = await page.context?.({ ...contextHooks, ...contextPage, utils, sharedContext }) || {};
|
|
65
|
+
templateContext.context = {
|
|
66
|
+
...contextHooks,
|
|
67
|
+
...contexData
|
|
68
|
+
};
|
|
40
69
|
templateContext.getHeadScripts = () => {
|
|
41
70
|
return scripts.head.join("\n");
|
|
42
71
|
};
|
|
@@ -46,11 +75,20 @@ export default eventHandler(async (event) => {
|
|
|
46
75
|
templateContext.getBodyChunks = () => {
|
|
47
76
|
return chunks.body.join("\n");
|
|
48
77
|
};
|
|
78
|
+
templateContext.getInjectContext = () => {
|
|
79
|
+
return `<script id="__FLOW_DATA__" type="application/json">${JSON.stringify(contextInject)}<\/script>`;
|
|
80
|
+
};
|
|
49
81
|
const query = useQuery(event);
|
|
50
82
|
if (query?.context)
|
|
51
83
|
return { ...templateContext, utils: Object.keys(utils) };
|
|
52
|
-
|
|
53
|
-
|
|
84
|
+
let html;
|
|
85
|
+
if (view.render)
|
|
86
|
+
html = await view.render(templateContext, event);
|
|
87
|
+
else
|
|
88
|
+
html = await flow.render(view, templateContext);
|
|
89
|
+
event.res.setHeader("Content-Type", view.contentType || "text/html;charset=UTF-8");
|
|
90
|
+
if (view.postRender)
|
|
91
|
+
html = await view.postRender(html, event);
|
|
54
92
|
if (flow.generate) {
|
|
55
93
|
await flow.callHook("page:generate", generate);
|
|
56
94
|
globalThis.generate = generate;
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { createHooks } from 'hookable';
|
|
2
2
|
import { dirname, resolve, normalize, join, isAbsolute, relative, extname } from 'pathe';
|
|
3
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
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
5
|
import { defineUnimportPreset, createUnimport, toImports, scanDirExports } from 'unimport';
|
|
6
|
+
import { pathToFileURL } from 'node:url';
|
|
6
7
|
import { createUnplugin } from 'unplugin';
|
|
7
8
|
import { parseURL, parseQuery, joinURL, withoutTrailingSlash } from 'ufo';
|
|
9
|
+
import fs from 'fs';
|
|
8
10
|
import escapeRE from 'escape-string-regexp';
|
|
9
11
|
import { camelCase, pascalCase } from 'scule';
|
|
10
12
|
import { genImport, genDynamicImport, genArrayFromRaw, genString, genObjectFromRawEntries } from 'knitwork';
|
|
@@ -27,7 +29,7 @@ import { isExternal as isExternal$1, ExternalsDefaults } from 'externality';
|
|
|
27
29
|
import { createHash } from 'node:crypto';
|
|
28
30
|
import MagicString from 'magic-string';
|
|
29
31
|
|
|
30
|
-
const version = "5.0.0-rc.
|
|
32
|
+
const version = "5.0.0-rc.61";
|
|
31
33
|
|
|
32
34
|
let _distDir = dirname(fileURLToPath(import.meta.url));
|
|
33
35
|
if (_distDir.endsWith("chunks"))
|
|
@@ -92,7 +94,8 @@ const commonPresets = [
|
|
|
92
94
|
from: "#_pages",
|
|
93
95
|
imports: [
|
|
94
96
|
"definePage",
|
|
95
|
-
"
|
|
97
|
+
"defineDynamicPage",
|
|
98
|
+
"defineSharedContext"
|
|
96
99
|
]
|
|
97
100
|
})
|
|
98
101
|
];
|
|
@@ -228,14 +231,20 @@ ${ctx.generateTypeDecarations({ resolvePath: r })}`
|
|
|
228
231
|
});
|
|
229
232
|
}
|
|
230
233
|
|
|
231
|
-
async function
|
|
234
|
+
async function resolveFiles(dir) {
|
|
232
235
|
const nuxt = useNuxt();
|
|
233
|
-
const
|
|
234
|
-
const allRoutes = (await Promise.all(
|
|
235
|
-
const files = await resolveFilesFlow(
|
|
236
|
+
const dirs = [resolve(nuxt.options.srcDir, dir)];
|
|
237
|
+
const allRoutes = (await Promise.all(dirs.map(async (dir2) => {
|
|
238
|
+
const files = await resolveFilesFlow(dir2, `**/*{${nuxt.options.extensions.join(",")}}`);
|
|
236
239
|
files.sort();
|
|
237
|
-
return files.
|
|
238
|
-
|
|
240
|
+
return files.filter((file) => {
|
|
241
|
+
if (file.includes(" copy"))
|
|
242
|
+
return false;
|
|
243
|
+
if (!fs.readFileSync(file, "utf8").includes("export"))
|
|
244
|
+
return false;
|
|
245
|
+
return true;
|
|
246
|
+
}).map((file) => {
|
|
247
|
+
const segments = relative(dir2, file).replace(new RegExp(`${escapeRE(extname(file))}$`), "").split("/").join("_");
|
|
239
248
|
return {
|
|
240
249
|
file,
|
|
241
250
|
name: camelCase(segments)
|
|
@@ -244,24 +253,31 @@ async function resolvePagesRoutes() {
|
|
|
244
253
|
}))).flat();
|
|
245
254
|
return allRoutes;
|
|
246
255
|
}
|
|
247
|
-
function
|
|
248
|
-
const imports =
|
|
256
|
+
function normalizeExports(files) {
|
|
257
|
+
const imports = files.map((page) => genImport(page.file, page.name)).join("\n");
|
|
258
|
+
const exports = files.reduce((acc, curr) => {
|
|
259
|
+
const name = curr.name;
|
|
260
|
+
return `${name}:typeof ${name}==='function'?${name}():${name},${acc}`;
|
|
261
|
+
}, "");
|
|
249
262
|
return {
|
|
250
263
|
imports,
|
|
251
|
-
exports
|
|
252
|
-
const name = curr.name;
|
|
253
|
-
return `${name}:typeof ${name}==='function'?${name}():${name},${acc}`;
|
|
254
|
-
}, "")
|
|
264
|
+
exports
|
|
255
265
|
};
|
|
256
266
|
}
|
|
257
267
|
|
|
258
268
|
const pagesTypeTemplate = {
|
|
259
|
-
filename: "pages.d.ts",
|
|
269
|
+
filename: "types/pages.d.ts",
|
|
260
270
|
getContents: ({ options }) => `// Generated by pages discovery
|
|
261
271
|
export {}
|
|
262
272
|
declare global {
|
|
273
|
+
type ArrElement<ArrType> = ArrType extends readonly (infer ElementType)[]
|
|
274
|
+
? ElementType
|
|
275
|
+
: never;
|
|
263
276
|
|
|
264
|
-
${options.pages.map((c) =>
|
|
277
|
+
${options.pages.map((c) => {
|
|
278
|
+
const _type = `ArrElement<typeof ${genDynamicImport(isAbsolute(c.file) ? relative(join(options.buildDir, "types"), c.file) : c.file, { wrapper: false })}['default']>`;
|
|
279
|
+
return `export type ${pascalCase(c.name)}Context=Awaited<ReturnType<${_type}['locales']['es-ec']['context']>>`;
|
|
280
|
+
}).join("\n")}
|
|
265
281
|
}
|
|
266
282
|
export const pagesNames: string[]
|
|
267
283
|
`.replaceAll(".ts", "")
|
|
@@ -273,38 +289,54 @@ const pagesModule = defineNuxtModule({
|
|
|
273
289
|
},
|
|
274
290
|
async setup(_options, flow) {
|
|
275
291
|
const runtimeDir = resolve(distDir, "pages/runtime");
|
|
292
|
+
flow.options.alias["#_pages"] = runtimeDir;
|
|
276
293
|
const pages = [];
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
flow.options.dir.pages,
|
|
280
|
-
flow.options.dir.layouts,
|
|
281
|
-
flow.options.dir.middleware
|
|
282
|
-
].filter(Boolean);
|
|
283
|
-
const pathPattern = new RegExp(`^(${dirs.map(escapeRE).join("|")})/`);
|
|
284
|
-
if (event !== "change" && path.match(pathPattern))
|
|
285
|
-
await flow.callHook("builder:generateApp");
|
|
286
|
-
});
|
|
287
|
-
const options = { pages, buildDir: flow.options.buildDir };
|
|
294
|
+
const contexts = [];
|
|
295
|
+
const options = { pages, buildDir: flow.options.buildDir, contexts };
|
|
288
296
|
addTemplate({
|
|
289
297
|
...pagesTypeTemplate,
|
|
290
298
|
options
|
|
291
299
|
});
|
|
300
|
+
const pagesDirs = [{ path: resolve(flow.options.srcDir, flow.options.dir.pages) }];
|
|
292
301
|
flow.options.alias["#pages"] = resolve(flow.options.buildDir, "pages.mjs");
|
|
302
|
+
flow.options.alias["#pagesContexts"] = resolve(flow.options.buildDir, "pages.contexts.mjs");
|
|
293
303
|
addTemplate({
|
|
294
304
|
filename: "pages.mjs",
|
|
295
305
|
async getContents({ options: options2 }) {
|
|
296
|
-
const { exports, imports } =
|
|
297
|
-
|
|
306
|
+
const { exports, imports } = normalizeExports(options2.pages);
|
|
307
|
+
const module = [imports, `export default {${exports}}`].join("\n");
|
|
308
|
+
return module;
|
|
309
|
+
},
|
|
310
|
+
options
|
|
311
|
+
});
|
|
312
|
+
addTemplate({
|
|
313
|
+
filename: "pages.contexts.mjs",
|
|
314
|
+
async getContents({ options: options2 }) {
|
|
315
|
+
const { exports, imports } = normalizeExports(options2.contexts);
|
|
316
|
+
const module = [imports, `export default {${exports}}`].join("\n");
|
|
317
|
+
return module;
|
|
298
318
|
},
|
|
299
319
|
options
|
|
300
320
|
});
|
|
301
321
|
flow.hook("app:templates", async () => {
|
|
302
|
-
options.pages = await
|
|
322
|
+
options.pages = await resolveFiles(flow.options.dir?.pages || "pages");
|
|
323
|
+
});
|
|
324
|
+
flow.hook("app:templates", async () => {
|
|
325
|
+
options.contexts = await resolveFiles("shared/contexts");
|
|
303
326
|
});
|
|
304
327
|
flow.hook("prepare:types", ({ references }) => {
|
|
305
|
-
references.push({ path: resolve(flow.options.buildDir, "pages.d.ts") });
|
|
328
|
+
references.push({ path: resolve(flow.options.buildDir, "types/pages.d.ts") });
|
|
306
329
|
});
|
|
307
|
-
|
|
330
|
+
flow.hook("builder:watch", async (event, path) => {
|
|
331
|
+
if (!["add", "unlink", "change"].includes(event))
|
|
332
|
+
return;
|
|
333
|
+
if (path.includes(" copy"))
|
|
334
|
+
return;
|
|
335
|
+
const fPath = resolve(flow.options.rootDir, path);
|
|
336
|
+
if (pagesDirs.find((dir) => fPath.startsWith(dir.path)))
|
|
337
|
+
await flow.callHook("builder:generateApp");
|
|
338
|
+
});
|
|
339
|
+
addPlugin(resolve(runtimeDir, "pages"));
|
|
308
340
|
}
|
|
309
341
|
});
|
|
310
342
|
|
|
@@ -332,7 +364,7 @@ const createClient = async (flow) => {
|
|
|
332
364
|
if (vite)
|
|
333
365
|
vite?.ws?.send({ type: "full-reload" });
|
|
334
366
|
};
|
|
335
|
-
const doReload = debounce(_doReload,
|
|
367
|
+
const doReload = debounce(_doReload, 75);
|
|
336
368
|
flow.hook("bundler:change", () => {
|
|
337
369
|
doReload();
|
|
338
370
|
});
|
|
@@ -347,7 +379,7 @@ const builClient = async (flow) => {
|
|
|
347
379
|
mode: "production",
|
|
348
380
|
build: {
|
|
349
381
|
assetsDir: "scripts",
|
|
350
|
-
target: "
|
|
382
|
+
target: "es2015",
|
|
351
383
|
outDir: ".vite",
|
|
352
384
|
manifest: true
|
|
353
385
|
}
|
|
@@ -388,23 +420,24 @@ const viteModule = defineFlowModule({
|
|
|
388
420
|
}
|
|
389
421
|
});
|
|
390
422
|
} else {
|
|
391
|
-
flow.
|
|
423
|
+
const file = resolve(flow.options.rootDir, ".vite/manifest.json");
|
|
424
|
+
addTemplate({
|
|
425
|
+
filename: "viteManifest.mjs",
|
|
426
|
+
async getContents() {
|
|
427
|
+
return [
|
|
428
|
+
"import fs from 'fs';",
|
|
429
|
+
`export default ()=>{
|
|
430
|
+
const manifest =JSON.parse(fs.readFileSync("${file}", 'utf8'));
|
|
431
|
+
return {manifest,base:'${_options.dir}'}
|
|
432
|
+
}`
|
|
433
|
+
].join("\n");
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
flow.hook("build:before", async () => {
|
|
392
437
|
const start = Date.now();
|
|
393
438
|
logger$1.info("Building client...");
|
|
394
439
|
await builClient(flow);
|
|
395
|
-
const file = resolve(flow.options.rootDir, ".vite/manifest.json");
|
|
396
|
-
const manifest = await fse.readFile(file, "utf8");
|
|
397
440
|
logger$1.success(`Client build in ${Date.now() - start}ms`);
|
|
398
|
-
addTemplate({
|
|
399
|
-
filename: "viteManifest.mjs",
|
|
400
|
-
async getContents() {
|
|
401
|
-
return [
|
|
402
|
-
"export default ()=>(",
|
|
403
|
-
manifest,
|
|
404
|
-
")"
|
|
405
|
-
].join("\n");
|
|
406
|
-
}
|
|
407
|
-
});
|
|
408
441
|
});
|
|
409
442
|
flow.hook("generate:before", async () => {
|
|
410
443
|
const files = resolve(flow.options.rootDir, ".vite/scripts");
|
|
@@ -488,7 +521,8 @@ async function initNitro(flow) {
|
|
|
488
521
|
externals: {
|
|
489
522
|
inline: [
|
|
490
523
|
...flow.options.dev ? [] : ["eta", "@monkeyplus/", "@vue/", "@nuxt/", flow.options.buildDir],
|
|
491
|
-
"@monkeyplus/flow/dist"
|
|
524
|
+
"@monkeyplus/flow/dist",
|
|
525
|
+
"C:/Users/gnu/Documents/GitHub/flow/packages/flow/dist/app"
|
|
492
526
|
]
|
|
493
527
|
},
|
|
494
528
|
alias: {
|
|
@@ -499,7 +533,8 @@ async function initNitro(flow) {
|
|
|
499
533
|
...flow.options.alias
|
|
500
534
|
},
|
|
501
535
|
rollupConfig: {
|
|
502
|
-
plugins: []
|
|
536
|
+
plugins: [],
|
|
537
|
+
external: [""]
|
|
503
538
|
}
|
|
504
539
|
});
|
|
505
540
|
await flow.callHook("nitro:config", nitroConfig);
|
|
@@ -1091,6 +1126,8 @@ const buildServer = async (ctx) => {
|
|
|
1091
1126
|
"/__vue-jsx",
|
|
1092
1127
|
"#app",
|
|
1093
1128
|
/(nuxt|nuxt3)\/(dist|src|app)/,
|
|
1129
|
+
/flow\/(dist|src|app)/,
|
|
1130
|
+
/flow\/modules\/(content|icons|images|netlify|netlify-cms|seo|sitemap|vue)/,
|
|
1094
1131
|
/@monkeyplus\/flow\/(dist|src|app)/,
|
|
1095
1132
|
/@nuxt\/nitro\/(dist|src)/
|
|
1096
1133
|
]
|
|
@@ -1168,9 +1205,11 @@ const buildServer = async (ctx) => {
|
|
|
1168
1205
|
await onBuild();
|
|
1169
1206
|
ctx.flow.callHook("bundler:change", {});
|
|
1170
1207
|
};
|
|
1171
|
-
const doBuild = debounce(_doBuild);
|
|
1208
|
+
const doBuild = debounce(_doBuild, 50);
|
|
1172
1209
|
await _doBuild();
|
|
1173
1210
|
viteServer.watcher.on("all", (_event, file) => {
|
|
1211
|
+
if (file.includes("/pages/"))
|
|
1212
|
+
return;
|
|
1174
1213
|
file = normalize(file);
|
|
1175
1214
|
if (file.indexOf(ctx.flow.options.buildDir) === 0)
|
|
1176
1215
|
return;
|
|
@@ -1290,6 +1329,7 @@ async function bundleVite(flow) {
|
|
|
1290
1329
|
include: []
|
|
1291
1330
|
},
|
|
1292
1331
|
build: {
|
|
1332
|
+
ssr: true,
|
|
1293
1333
|
rollupOptions: {
|
|
1294
1334
|
output: { sanitizeFileName: sanitizeFilePath },
|
|
1295
1335
|
input: resolve(flow.options.appDir, "entry")
|
|
@@ -1326,6 +1366,8 @@ async function bundleVite(flow) {
|
|
|
1326
1366
|
flow.hook("vite:serverCreated", (server) => {
|
|
1327
1367
|
ctx.nuxt.hook("app:templatesGenerated", () => {
|
|
1328
1368
|
for (const [id, mod] of server.moduleGraph.idToModuleMap) {
|
|
1369
|
+
if (id.includes("pages.mjs"))
|
|
1370
|
+
server.moduleGraph.invalidateModule(mod);
|
|
1329
1371
|
if (id.startsWith("\0virtual:"))
|
|
1330
1372
|
server.moduleGraph.invalidateModule(mod);
|
|
1331
1373
|
}
|
|
@@ -1367,8 +1409,7 @@ function watch(flow) {
|
|
|
1367
1409
|
"node_modules"
|
|
1368
1410
|
]
|
|
1369
1411
|
});
|
|
1370
|
-
|
|
1371
|
-
watcher.on("all", watchHook);
|
|
1412
|
+
watcher.on("all", (event, path) => flow.callHook("builder:watch", event, normalize(path)));
|
|
1372
1413
|
flow.hook("close", () => watcher.close());
|
|
1373
1414
|
return watcher;
|
|
1374
1415
|
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
import type { DynamicPage, SimplePage } from '@monkeyplus/flow-schema';
|
|
2
|
-
export declare function definePage(
|
|
3
|
-
export declare function
|
|
1
|
+
import type { DynamicPage, PageCtx, SimplePage } from '@monkeyplus/flow-schema';
|
|
2
|
+
export declare function definePage<T>(...pages: SimplePage<T>[]): SimplePage<T>[];
|
|
3
|
+
export declare function defineDynamicPage<T>(...pages: DynamicPage<T>[]): DynamicPage<T>[];
|
|
4
|
+
interface SharedContext {
|
|
5
|
+
assign?: 'global' | 'local';
|
|
6
|
+
setup: (cxt: PageCtx) => any;
|
|
7
|
+
}
|
|
8
|
+
export declare function defineSharedContext(shared: SharedContext): SharedContext;
|
|
9
|
+
export {};
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
export function definePage(
|
|
2
|
-
return
|
|
1
|
+
export function definePage(...pages) {
|
|
2
|
+
return pages;
|
|
3
3
|
}
|
|
4
|
-
export function
|
|
5
|
-
return page
|
|
4
|
+
export function defineDynamicPage(...pages) {
|
|
5
|
+
return pages.map((page) => {
|
|
6
|
+
if (!page.name.endsWith("/**"))
|
|
7
|
+
page.name = `${page.name}/**`;
|
|
8
|
+
return page;
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
export function defineSharedContext(shared) {
|
|
12
|
+
return shared;
|
|
6
13
|
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { joinURL } from "ufo";
|
|
2
|
+
import consola from "consola";
|
|
3
|
+
import { definePage } from "./helpers/index.mjs";
|
|
4
|
+
import { defineFlowPlugin, useRuntimeConfig } from "#app";
|
|
5
|
+
import pages from "#build/pages";
|
|
6
|
+
import contexts from "#build/pages.contexts";
|
|
7
|
+
export default defineFlowPlugin(async (flow) => {
|
|
8
|
+
const { app } = useRuntimeConfig();
|
|
9
|
+
const allPages = [];
|
|
10
|
+
const basePages = Object.entries(pages);
|
|
11
|
+
consola.success("Parsed %i pages files", basePages.length);
|
|
12
|
+
basePages.forEach(([name, _pages]) => {
|
|
13
|
+
const __pages = Array.isArray(_pages) ? _pages : [_pages];
|
|
14
|
+
__pages.forEach((page) => {
|
|
15
|
+
const { getPages } = definePage({
|
|
16
|
+
name,
|
|
17
|
+
...page
|
|
18
|
+
});
|
|
19
|
+
const _pages2 = getPages(app.locale.location, app.locale.language);
|
|
20
|
+
_pages2.forEach((page2) => {
|
|
21
|
+
flow.router.byUrl.insert(page2.url, page2.context);
|
|
22
|
+
flow.router.byName.insert(page2.name, page2.context);
|
|
23
|
+
allPages.push(page2.context);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
const cache = {};
|
|
28
|
+
async function getUrl(namePage, localeCode) {
|
|
29
|
+
const code = localeCode || this?.getLocale()?.code;
|
|
30
|
+
const [lang, loc] = code.split("-");
|
|
31
|
+
const name = joinURL("/", loc, lang, namePage);
|
|
32
|
+
const { path, params, page } = flow.router.byName.lookup(name) || {};
|
|
33
|
+
if (params?._ && page.dynamic) {
|
|
34
|
+
if (!cache[path]) {
|
|
35
|
+
cache[path] = this.defineCachedFunction(async (_ctx) => {
|
|
36
|
+
return await page.dynamic.method(_ctx);
|
|
37
|
+
}, { maxAge: 8, getKey: () => path, swr: false });
|
|
38
|
+
}
|
|
39
|
+
const fn = cache[path];
|
|
40
|
+
const list = await fn({ utils: this, locale: this.getLocale() });
|
|
41
|
+
const dPage = list.find((el) => el.name === params._);
|
|
42
|
+
return dPage ? path.replace("**", dPage.url) : "/404";
|
|
43
|
+
}
|
|
44
|
+
return path || "/404";
|
|
45
|
+
}
|
|
46
|
+
async function getUrls(withLocale = false) {
|
|
47
|
+
const urls = [];
|
|
48
|
+
for (const page of allPages) {
|
|
49
|
+
if (page.path.includes("/**") && page.page.dynamic) {
|
|
50
|
+
const dPages = await page.page.dynamic.method({
|
|
51
|
+
locale: page.locale,
|
|
52
|
+
utils: Object.assign({ getLocale: () => page.locale }, flow.app.utils),
|
|
53
|
+
chunks: {}
|
|
54
|
+
});
|
|
55
|
+
dPages.forEach((dPage) => {
|
|
56
|
+
const _path = joinURL(page.path.replace("/**", ""), dPage.url);
|
|
57
|
+
urls.push(withLocale ? { url: _path, locale: page.locale.code, name: joinURL(page.name, dPage.name) } : _path);
|
|
58
|
+
});
|
|
59
|
+
} else {
|
|
60
|
+
const url = page.path.replaceAll("*", "");
|
|
61
|
+
urls.push(withLocale ? { url, locale: page.locale.code, name: page.name } : url);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return urls.sort();
|
|
65
|
+
}
|
|
66
|
+
async function getSharedContext(ctx) {
|
|
67
|
+
const entries = Object.entries(contexts);
|
|
68
|
+
if (!entries.length)
|
|
69
|
+
return {};
|
|
70
|
+
const _contexts = await Promise.all(entries.map(async ([key, method]) => {
|
|
71
|
+
const data = await method.setup(ctx);
|
|
72
|
+
return { [key]: data };
|
|
73
|
+
}));
|
|
74
|
+
return _contexts.reduce((acc, curr) => {
|
|
75
|
+
return {
|
|
76
|
+
...acc,
|
|
77
|
+
...curr
|
|
78
|
+
};
|
|
79
|
+
}, {});
|
|
80
|
+
}
|
|
81
|
+
flow.setUtil("getUrl", getUrl);
|
|
82
|
+
flow.setUtil("getUrls", getUrls);
|
|
83
|
+
flow.setUtil("getPages", () => allPages);
|
|
84
|
+
flow.setUtil("getSharedContext", getSharedContext);
|
|
85
|
+
return {
|
|
86
|
+
provide: {
|
|
87
|
+
pages: { allPages }
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
});
|
|
@@ -5,7 +5,8 @@ export const generateBundle = (config, bundle, _id) => {
|
|
|
5
5
|
const chunks = [];
|
|
6
6
|
chunk2.imports?.forEach((file) => {
|
|
7
7
|
const importee = bundle[file];
|
|
8
|
-
|
|
8
|
+
const isChunk = file.startsWith("_") || importee.isEntry;
|
|
9
|
+
if (isChunk && !seen.has(file)) {
|
|
9
10
|
seen.add(file);
|
|
10
11
|
chunks.push(...getImportedChunks(importee, seen));
|
|
11
12
|
chunks.push(importee);
|
|
@@ -36,7 +37,7 @@ export const generateBundle = (config, bundle, _id) => {
|
|
|
36
37
|
analyzedChunk.set(chunk2, 1);
|
|
37
38
|
chunk2.imports?.forEach((file) => {
|
|
38
39
|
const importee = bundle[file];
|
|
39
|
-
if (file.startsWith("_"))
|
|
40
|
+
if (file.startsWith("_") || importee.isEntry)
|
|
40
41
|
tags.push(...getCssTagsForChunk(importee, publicBase2, seen));
|
|
41
42
|
});
|
|
42
43
|
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import logger from "consola";
|
|
2
|
+
import { joinURL } from "ufo";
|
|
2
3
|
import { generateBundle } from "./injectManifest.mjs";
|
|
3
4
|
import { defineFlowPlugin } from "#app";
|
|
4
5
|
import manifest from "#viteManifest";
|
|
5
6
|
export default defineFlowPlugin((flow) => {
|
|
6
7
|
if (typeof manifest === "function") {
|
|
7
|
-
const _manifest = manifest();
|
|
8
8
|
flow.hook("page:chunks", (bundle, chunks) => {
|
|
9
9
|
try {
|
|
10
|
-
const
|
|
10
|
+
const data = manifest();
|
|
11
|
+
const chunk = generateBundle(flow.$config.app || {}, data.manifest, joinURL("/", data.base, `${bundle}.ts`).replace("/", ""));
|
|
11
12
|
if (chunk) {
|
|
12
13
|
chunks.head.push(chunk.head);
|
|
13
14
|
chunks.body.push(chunk.body);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monkeyplus/flow",
|
|
3
|
-
"version": "5.0.0-rc.
|
|
3
|
+
"version": "5.0.0-rc.61",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.mjs",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"dist"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@monkeyplus/flow-cli": "5.0.0-rc.
|
|
29
|
-
"@monkeyplus/flow-kit": "5.0.0-rc.
|
|
30
|
-
"@monkeyplus/flow-schema": "5.0.0-rc.
|
|
28
|
+
"@monkeyplus/flow-cli": "5.0.0-rc.61",
|
|
29
|
+
"@monkeyplus/flow-kit": "5.0.0-rc.61",
|
|
30
|
+
"@monkeyplus/flow-schema": "5.0.0-rc.61",
|
|
31
31
|
"@rollup/plugin-replace": "^4.0.0",
|
|
32
32
|
"@vueuse/head": "^0.7.6",
|
|
33
33
|
"c12": "^0.2.7",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"magic-string": "^0.26.2",
|
|
51
51
|
"mlly": "^0.5.2",
|
|
52
52
|
"mri": "^1.2.0",
|
|
53
|
-
"nitropack": "^0.4.
|
|
53
|
+
"nitropack": "^0.4.8",
|
|
54
54
|
"pathe": "^0.2.0",
|
|
55
55
|
"perfect-debounce": "^0.1.3",
|
|
56
56
|
"radix3": "^0.1.2",
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { joinURL } from "ufo";
|
|
2
|
-
import { definePage } from "./helpers/index.mjs";
|
|
3
|
-
import { defineFlowPlugin, useRuntimeConfig } from "#app";
|
|
4
|
-
import pages from "#pages";
|
|
5
|
-
export default defineFlowPlugin(async (flow) => {
|
|
6
|
-
const { app } = useRuntimeConfig();
|
|
7
|
-
const allPages = [];
|
|
8
|
-
Object.entries(pages).forEach(([name, page]) => {
|
|
9
|
-
const { getPages } = definePage({
|
|
10
|
-
name,
|
|
11
|
-
...page
|
|
12
|
-
});
|
|
13
|
-
const _pages = getPages(app.locale.location, app.locale.language);
|
|
14
|
-
_pages.forEach((page2) => {
|
|
15
|
-
flow.router.byUrl.insert(page2.url, page2.context);
|
|
16
|
-
flow.router.byName.insert(page2.name, page2.context);
|
|
17
|
-
allPages.push(page2.context);
|
|
18
|
-
});
|
|
19
|
-
});
|
|
20
|
-
function getUrl(namePage, localeCode) {
|
|
21
|
-
const code = localeCode || this?.getLocale()?.code;
|
|
22
|
-
const [lang, loc] = code.split("-");
|
|
23
|
-
const name = joinURL("/", loc, lang, namePage);
|
|
24
|
-
const { path } = flow.router.byName.lookup(name) || {};
|
|
25
|
-
return path || "/404";
|
|
26
|
-
}
|
|
27
|
-
async function getUrls(withLocale = false) {
|
|
28
|
-
const urls = [];
|
|
29
|
-
for (const page of allPages) {
|
|
30
|
-
if (!page.path.includes("/**")) {
|
|
31
|
-
urls.push(withLocale ? { url: page.path, locale: page.locale.code, name: page.name } : page.path);
|
|
32
|
-
} else {
|
|
33
|
-
const dPages = await page.page.dynamic.method({
|
|
34
|
-
locale: page.locale,
|
|
35
|
-
utils: Object.assign({ getLocale: () => page.locale }, flow.app.utils)
|
|
36
|
-
});
|
|
37
|
-
dPages.forEach((dPage) => {
|
|
38
|
-
const _path = joinURL(page.path.replace("/**", ""), dPage.url);
|
|
39
|
-
urls.push(withLocale ? { url: _path, locale: page.locale.code, name: joinURL(page.name, dPage.name) } : _path);
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return urls.sort();
|
|
44
|
-
}
|
|
45
|
-
flow.setUtil("getUrl", getUrl);
|
|
46
|
-
flow.setUtil("getUrls", getUrls);
|
|
47
|
-
flow.setUtil("getPages", () => allPages);
|
|
48
|
-
return {
|
|
49
|
-
provide: {
|
|
50
|
-
pages: { allPages }
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
});
|
|
File without changes
|