@monkeyplus/flow 5.0.0-rc.8 → 5.0.0-rc.80
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 +48 -13
- package/dist/index.mjs +97 -56
- package/dist/pages/runtime/helpers/index.mjs +5 -2
- package/dist/pages/runtime/index.d.ts +10 -3
- package/dist/pages/runtime/index.mjs +11 -4
- package/dist/pages/runtime/pages.mjs +96 -0
- package/dist/vite-client/runtime/injectManifest.mjs +4 -3
- package/dist/vite-client/runtime/plugin.mjs +3 -2
- package/package.json +24 -24
- package/dist/pages/runtime/plugin.mjs +0 -56
- /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,35 +15,58 @@ 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 = {
|
|
25
|
+
const dynamic = params?._;
|
|
26
|
+
const contextPage = {
|
|
27
|
+
chunks,
|
|
28
|
+
locale
|
|
29
|
+
};
|
|
21
30
|
const contextInject = {};
|
|
22
|
-
const utils = Object.assign({ getLocale: () => locale, injectContext: (key, value) => contextInject[key] = value }, flow.app.utils);
|
|
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);
|
|
23
34
|
templateContext.url = url;
|
|
35
|
+
templateContext.baseURL = flow.$config.app.baseURL;
|
|
36
|
+
const pageObject = {
|
|
37
|
+
name: pageName,
|
|
38
|
+
pathname: url,
|
|
39
|
+
url: joinURL(flow.site.origin, templateContext.baseURL, `${url}`),
|
|
40
|
+
origin: flow.site.origin,
|
|
41
|
+
joinOrigin: (_url, includeBase) => joinURL(flow.site.origin, includeBase ? templateContext.baseURL : "/", _url)
|
|
42
|
+
};
|
|
43
|
+
templateContext.page = pageObject;
|
|
44
|
+
contextPage.page = pageObject;
|
|
24
45
|
templateContext.locale = locale;
|
|
25
46
|
templateContext.view = view;
|
|
26
|
-
if (
|
|
47
|
+
if (dynamic && page.dynamic) {
|
|
27
48
|
const pages = await page.dynamic.method({ locale, utils });
|
|
28
|
-
const dynamicPage = pages.find((_page) => _page.url ===
|
|
49
|
+
const dynamicPage = pages.find((_page) => _page.url === dynamic);
|
|
29
50
|
if (!dynamicPage)
|
|
30
51
|
return;
|
|
31
52
|
if (page.dynamic.assign)
|
|
32
53
|
templateContext[page.dynamic.assign] = dynamicPage.context;
|
|
33
|
-
contextPage.
|
|
54
|
+
contextPage.dynamic = dynamicPage;
|
|
34
55
|
}
|
|
35
56
|
templateContext.seo = {};
|
|
36
|
-
|
|
37
|
-
|
|
57
|
+
const sharedContext = await utils.getSharedContext({
|
|
58
|
+
...contextHooks,
|
|
59
|
+
...contextPage,
|
|
60
|
+
utils
|
|
61
|
+
});
|
|
62
|
+
templateContext.sharedContext = sharedContext || {};
|
|
38
63
|
templateContext.utils = utils;
|
|
39
|
-
templateContext.seo = await page
|
|
40
|
-
|
|
64
|
+
templateContext.seo = await normalizeCall(page?.seo, { ...contextHooks, ...contextPage, utils, sharedContext });
|
|
65
|
+
const contexData = await page.context?.({ ...contextHooks, ...contextPage, utils, sharedContext }) || {};
|
|
66
|
+
templateContext.context = {
|
|
67
|
+
...contextHooks,
|
|
68
|
+
...contexData
|
|
69
|
+
};
|
|
41
70
|
templateContext.getHeadScripts = () => {
|
|
42
71
|
return scripts.head.join("\n");
|
|
43
72
|
};
|
|
@@ -53,8 +82,14 @@ export default eventHandler(async (event) => {
|
|
|
53
82
|
const query = useQuery(event);
|
|
54
83
|
if (query?.context)
|
|
55
84
|
return { ...templateContext, utils: Object.keys(utils) };
|
|
56
|
-
|
|
57
|
-
|
|
85
|
+
let html;
|
|
86
|
+
if (view.render)
|
|
87
|
+
html = await view.render(templateContext, event);
|
|
88
|
+
else
|
|
89
|
+
html = await flow.render(view, templateContext);
|
|
90
|
+
event.res.setHeader("Content-Type", view.contentType || "text/html;charset=UTF-8");
|
|
91
|
+
if (view.postRender)
|
|
92
|
+
html = await view.postRender(html, event);
|
|
58
93
|
if (flow.generate) {
|
|
59
94
|
await flow.callHook("page:generate", generate);
|
|
60
95
|
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.80";
|
|
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
|
];
|
|
@@ -224,18 +227,24 @@ function addDeclarationTemplates(ctx) {
|
|
|
224
227
|
addTemplate({
|
|
225
228
|
filename: "types/auto-imports.d.ts",
|
|
226
229
|
getContents: () => `// Generated by auto imports
|
|
227
|
-
${ctx.
|
|
230
|
+
${ctx.generateTypeDeclarations({ 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", "")
|
|
@@ -275,37 +291,52 @@ const pagesModule = defineNuxtModule({
|
|
|
275
291
|
const runtimeDir = resolve(distDir, "pages/runtime");
|
|
276
292
|
flow.options.alias["#_pages"] = runtimeDir;
|
|
277
293
|
const pages = [];
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
flow.options.dir.pages,
|
|
281
|
-
flow.options.dir.layouts,
|
|
282
|
-
flow.options.dir.middleware
|
|
283
|
-
].filter(Boolean);
|
|
284
|
-
const pathPattern = new RegExp(`^(${dirs.map(escapeRE).join("|")})/`);
|
|
285
|
-
if (event !== "change" && path.match(pathPattern))
|
|
286
|
-
await flow.callHook("builder:generateApp");
|
|
287
|
-
});
|
|
288
|
-
const options = { pages, buildDir: flow.options.buildDir };
|
|
294
|
+
const contexts = [];
|
|
295
|
+
const options = { pages, buildDir: flow.options.buildDir, contexts };
|
|
289
296
|
addTemplate({
|
|
290
297
|
...pagesTypeTemplate,
|
|
291
298
|
options
|
|
292
299
|
});
|
|
300
|
+
const pagesDirs = [{ path: resolve(flow.options.srcDir, flow.options.dir.pages) }];
|
|
293
301
|
flow.options.alias["#pages"] = resolve(flow.options.buildDir, "pages.mjs");
|
|
302
|
+
flow.options.alias["#pagesContexts"] = resolve(flow.options.buildDir, "pages.contexts.mjs");
|
|
294
303
|
addTemplate({
|
|
295
304
|
filename: "pages.mjs",
|
|
296
305
|
async getContents({ options: options2 }) {
|
|
297
|
-
const { exports, imports } =
|
|
298
|
-
|
|
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;
|
|
299
318
|
},
|
|
300
319
|
options
|
|
301
320
|
});
|
|
302
321
|
flow.hook("app:templates", async () => {
|
|
303
|
-
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");
|
|
304
326
|
});
|
|
305
327
|
flow.hook("prepare:types", ({ references }) => {
|
|
306
|
-
references.push({ path: resolve(flow.options.buildDir, "pages.d.ts") });
|
|
328
|
+
references.push({ path: resolve(flow.options.buildDir, "types/pages.d.ts") });
|
|
307
329
|
});
|
|
308
|
-
|
|
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"));
|
|
309
340
|
}
|
|
310
341
|
});
|
|
311
342
|
|
|
@@ -333,7 +364,7 @@ const createClient = async (flow) => {
|
|
|
333
364
|
if (vite)
|
|
334
365
|
vite?.ws?.send({ type: "full-reload" });
|
|
335
366
|
};
|
|
336
|
-
const doReload = debounce(_doReload,
|
|
367
|
+
const doReload = debounce(_doReload, 75);
|
|
337
368
|
flow.hook("bundler:change", () => {
|
|
338
369
|
doReload();
|
|
339
370
|
});
|
|
@@ -344,11 +375,11 @@ const createClient = async (flow) => {
|
|
|
344
375
|
};
|
|
345
376
|
const builClient = async (flow) => {
|
|
346
377
|
return await build$1({
|
|
378
|
+
base: flow.options.dev ? "/" : flow.options.app.baseURL,
|
|
347
379
|
root: flow.options.rootDir,
|
|
348
380
|
mode: "production",
|
|
349
381
|
build: {
|
|
350
|
-
|
|
351
|
-
target: "es2017",
|
|
382
|
+
target: "es2015",
|
|
352
383
|
outDir: ".vite",
|
|
353
384
|
manifest: true
|
|
354
385
|
}
|
|
@@ -389,26 +420,27 @@ const viteModule = defineFlowModule({
|
|
|
389
420
|
}
|
|
390
421
|
});
|
|
391
422
|
} else {
|
|
392
|
-
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 () => {
|
|
393
437
|
const start = Date.now();
|
|
394
438
|
logger$1.info("Building client...");
|
|
395
439
|
await builClient(flow);
|
|
396
|
-
const file = resolve(flow.options.rootDir, ".vite/manifest.json");
|
|
397
|
-
const manifest = await fse.readFile(file, "utf8");
|
|
398
440
|
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
441
|
});
|
|
410
442
|
flow.hook("generate:before", async () => {
|
|
411
|
-
const files = resolve(flow.options.rootDir, ".vite/
|
|
443
|
+
const files = resolve(flow.options.rootDir, ".vite/assets");
|
|
412
444
|
await fse.copy(files, resolve(flow.options.generate.dir, "assets"));
|
|
413
445
|
});
|
|
414
446
|
}
|
|
@@ -462,6 +494,7 @@ async function initNitro(flow) {
|
|
|
462
494
|
...flow.options.runtimeConfig,
|
|
463
495
|
app: {
|
|
464
496
|
...flow.options.runtimeConfig.app,
|
|
497
|
+
baseURL: flow.options.dev ? "/" : flow.options.app.baseURL,
|
|
465
498
|
rootDir: flow.options.rootDir,
|
|
466
499
|
locale: flow.options.locale
|
|
467
500
|
},
|
|
@@ -489,7 +522,8 @@ async function initNitro(flow) {
|
|
|
489
522
|
externals: {
|
|
490
523
|
inline: [
|
|
491
524
|
...flow.options.dev ? [] : ["eta", "@monkeyplus/", "@vue/", "@nuxt/", flow.options.buildDir],
|
|
492
|
-
"@monkeyplus/flow/dist"
|
|
525
|
+
"@monkeyplus/flow/dist",
|
|
526
|
+
"C:/Users/gnu/Documents/GitHub/flow/packages/flow/dist/app"
|
|
493
527
|
]
|
|
494
528
|
},
|
|
495
529
|
alias: {
|
|
@@ -500,7 +534,8 @@ async function initNitro(flow) {
|
|
|
500
534
|
...flow.options.alias
|
|
501
535
|
},
|
|
502
536
|
rollupConfig: {
|
|
503
|
-
plugins: []
|
|
537
|
+
plugins: [],
|
|
538
|
+
external: [""]
|
|
504
539
|
}
|
|
505
540
|
});
|
|
506
541
|
await flow.callHook("nitro:config", nitroConfig);
|
|
@@ -1092,6 +1127,8 @@ const buildServer = async (ctx) => {
|
|
|
1092
1127
|
"/__vue-jsx",
|
|
1093
1128
|
"#app",
|
|
1094
1129
|
/(nuxt|nuxt3)\/(dist|src|app)/,
|
|
1130
|
+
/flow\/(dist|src|app)/,
|
|
1131
|
+
/flow\/modules\/(content|icons|images|netlify|netlify-cms|seo|sitemap|vue)/,
|
|
1095
1132
|
/@monkeyplus\/flow\/(dist|src|app)/,
|
|
1096
1133
|
/@nuxt\/nitro\/(dist|src)/
|
|
1097
1134
|
]
|
|
@@ -1169,9 +1206,11 @@ const buildServer = async (ctx) => {
|
|
|
1169
1206
|
await onBuild();
|
|
1170
1207
|
ctx.flow.callHook("bundler:change", {});
|
|
1171
1208
|
};
|
|
1172
|
-
const doBuild = debounce(_doBuild);
|
|
1209
|
+
const doBuild = debounce(_doBuild, 50);
|
|
1173
1210
|
await _doBuild();
|
|
1174
1211
|
viteServer.watcher.on("all", (_event, file) => {
|
|
1212
|
+
if (file.includes("/pages/"))
|
|
1213
|
+
return;
|
|
1175
1214
|
file = normalize(file);
|
|
1176
1215
|
if (file.indexOf(ctx.flow.options.buildDir) === 0)
|
|
1177
1216
|
return;
|
|
@@ -1291,6 +1330,7 @@ async function bundleVite(flow) {
|
|
|
1291
1330
|
include: []
|
|
1292
1331
|
},
|
|
1293
1332
|
build: {
|
|
1333
|
+
ssr: true,
|
|
1294
1334
|
rollupOptions: {
|
|
1295
1335
|
output: { sanitizeFileName: sanitizeFilePath },
|
|
1296
1336
|
input: resolve(flow.options.appDir, "entry")
|
|
@@ -1327,6 +1367,8 @@ async function bundleVite(flow) {
|
|
|
1327
1367
|
flow.hook("vite:serverCreated", (server) => {
|
|
1328
1368
|
ctx.nuxt.hook("app:templatesGenerated", () => {
|
|
1329
1369
|
for (const [id, mod] of server.moduleGraph.idToModuleMap) {
|
|
1370
|
+
if (id.includes("pages."))
|
|
1371
|
+
server.moduleGraph.invalidateModule(mod);
|
|
1330
1372
|
if (id.startsWith("\0virtual:"))
|
|
1331
1373
|
server.moduleGraph.invalidateModule(mod);
|
|
1332
1374
|
}
|
|
@@ -1368,8 +1410,7 @@ function watch(flow) {
|
|
|
1368
1410
|
"node_modules"
|
|
1369
1411
|
]
|
|
1370
1412
|
});
|
|
1371
|
-
|
|
1372
|
-
watcher.on("all", watchHook);
|
|
1413
|
+
watcher.on("all", (event, path) => flow.callHook("builder:watch", event, normalize(path)));
|
|
1373
1414
|
flow.hook("close", () => watcher.close());
|
|
1374
1415
|
return watcher;
|
|
1375
1416
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { joinURL, withTrailingSlash } from "ufo";
|
|
2
|
-
const buildPages = (page) => (location, language) => {
|
|
3
|
-
const locales =
|
|
2
|
+
const buildPages = (page) => (location, language, _locales) => {
|
|
3
|
+
const locales = _locales.map((key) => {
|
|
4
|
+
const _page = page.locales[key];
|
|
5
|
+
return [key, _page];
|
|
6
|
+
}).filter((el) => !!el[1]);
|
|
4
7
|
return locales.map(([locale, localePage]) => {
|
|
5
8
|
const [_language, _location] = locale.split("-");
|
|
6
9
|
const name = joinURL("/", _location, _language, page.name);
|
|
@@ -1,3 +1,10 @@
|
|
|
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
|
+
export interface SharedContext {
|
|
5
|
+
assign?: 'global' | 'local';
|
|
6
|
+
merge?: boolean;
|
|
7
|
+
setup: (cxt: PageCtx) => any;
|
|
8
|
+
locales?: Record<string, (ctx: PageCtx) => any>;
|
|
9
|
+
}
|
|
10
|
+
export declare function defineSharedContext(shared: SharedContext): SharedContext;
|
|
@@ -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,96 @@
|
|
|
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, app.locale.locales);
|
|
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
|
+
page: {}
|
|
55
|
+
});
|
|
56
|
+
dPages.forEach((dPage) => {
|
|
57
|
+
const _path = joinURL(page.path.replace("/**", ""), dPage.url);
|
|
58
|
+
urls.push(withLocale ? { url: _path, locale: page.locale.code, name: joinURL(page.name, dPage.name) } : _path);
|
|
59
|
+
});
|
|
60
|
+
} else {
|
|
61
|
+
const url = page.path.replaceAll("*", "");
|
|
62
|
+
urls.push(withLocale ? { url, locale: page.locale.code, name: page.name } : url);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return urls.sort();
|
|
66
|
+
}
|
|
67
|
+
async function getSharedContext(ctx) {
|
|
68
|
+
const entries = Object.entries(contexts);
|
|
69
|
+
if (!entries.length)
|
|
70
|
+
return {};
|
|
71
|
+
const _contexts = await Promise.all(entries.map(async ([key, method]) => {
|
|
72
|
+
const data = await method.setup(ctx);
|
|
73
|
+
const setupLocal = method?.locales?.[ctx.locale.code];
|
|
74
|
+
let dataLocal = {};
|
|
75
|
+
if (setupLocal)
|
|
76
|
+
dataLocal = await setupLocal(ctx);
|
|
77
|
+
const obj = method.merge ? { ...data, ...dataLocal } : { [key]: { ...data, ...dataLocal } };
|
|
78
|
+
return obj;
|
|
79
|
+
}));
|
|
80
|
+
return _contexts.reduce((acc, curr) => {
|
|
81
|
+
return {
|
|
82
|
+
...acc,
|
|
83
|
+
...curr
|
|
84
|
+
};
|
|
85
|
+
}, {});
|
|
86
|
+
}
|
|
87
|
+
flow.setUtil("getUrl", getUrl);
|
|
88
|
+
flow.setUtil("getUrls", getUrls);
|
|
89
|
+
flow.setUtil("getPages", () => allPages);
|
|
90
|
+
flow.setUtil("getSharedContext", getSharedContext);
|
|
91
|
+
return {
|
|
92
|
+
provide: {
|
|
93
|
+
pages: { allPages }
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
});
|
|
@@ -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
|
}
|
|
@@ -71,7 +72,7 @@ export const generateBundle = (config, bundle, _id) => {
|
|
|
71
72
|
export const externalRE = /^(https?:)?\/\//;
|
|
72
73
|
export const isExternalUrl = (url) => externalRE.test(url);
|
|
73
74
|
function toPublicPath(filename, publicBase) {
|
|
74
|
-
return isExternalUrl(filename) ? filename : joinURL(publicBase, filename
|
|
75
|
+
return isExternalUrl(filename) ? filename : joinURL(publicBase, filename);
|
|
75
76
|
}
|
|
76
77
|
const unaryTags = new Set(["link", "meta", "base"]);
|
|
77
78
|
function serializeTag({ tag, attrs, children }, indent = "") {
|
|
@@ -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.80",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.mjs",
|
|
@@ -25,52 +25,52 @@
|
|
|
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.80",
|
|
29
|
+
"@monkeyplus/flow-kit": "5.0.0-rc.80",
|
|
30
|
+
"@monkeyplus/flow-schema": "5.0.0-rc.80",
|
|
31
31
|
"@rollup/plugin-replace": "^4.0.0",
|
|
32
32
|
"@vueuse/head": "^0.7.6",
|
|
33
|
-
"c12": "^0.2.
|
|
33
|
+
"c12": "^0.2.8",
|
|
34
34
|
"chokidar": "^3.5.3",
|
|
35
35
|
"consola": "^2.15.3",
|
|
36
36
|
"defu": "^6.0.0",
|
|
37
|
-
"esbuild": "^0.14.
|
|
37
|
+
"esbuild": "^0.14.49",
|
|
38
38
|
"escape-string-regexp": "^5.0.0",
|
|
39
|
-
"esno": "^0.
|
|
39
|
+
"esno": "^0.16.3",
|
|
40
40
|
"eta": "^1.12.3",
|
|
41
|
-
"externality": "^0.2.
|
|
41
|
+
"externality": "^0.2.2",
|
|
42
42
|
"fs-extra": "^10.1.0",
|
|
43
43
|
"get-port-please": "^2.5.0",
|
|
44
|
-
"globby": "^13.1.
|
|
45
|
-
"h3": "^0.7.
|
|
44
|
+
"globby": "^13.1.2",
|
|
45
|
+
"h3": "^0.7.10",
|
|
46
46
|
"hookable": "^5.1.1",
|
|
47
|
-
"jiti": "^1.
|
|
48
|
-
"knitwork": "^0.1.
|
|
49
|
-
"listhen": "^0.2.
|
|
47
|
+
"jiti": "^1.14.0",
|
|
48
|
+
"knitwork": "^0.1.2",
|
|
49
|
+
"listhen": "^0.2.13",
|
|
50
50
|
"magic-string": "^0.26.2",
|
|
51
|
-
"mlly": "^0.5.
|
|
51
|
+
"mlly": "^0.5.4",
|
|
52
52
|
"mri": "^1.2.0",
|
|
53
|
-
"nitropack": "^0.4.
|
|
54
|
-
"pathe": "^0.2
|
|
53
|
+
"nitropack": "^0.4.12",
|
|
54
|
+
"pathe": "^0.3.2",
|
|
55
55
|
"perfect-debounce": "^0.1.3",
|
|
56
56
|
"radix3": "^0.1.2",
|
|
57
57
|
"unenv": "^0.5.2",
|
|
58
58
|
"ohmyfetch": "^0.4.18",
|
|
59
|
-
"node-fetch-native": "^0.1.
|
|
60
|
-
"rollup": "^2.
|
|
61
|
-
"rollup-plugin-visualizer": "^5.
|
|
59
|
+
"node-fetch-native": "^0.1.4",
|
|
60
|
+
"rollup": "^2.77.0",
|
|
61
|
+
"rollup-plugin-visualizer": "^5.7.1",
|
|
62
62
|
"scule": "^0.2.1",
|
|
63
|
-
"ufo": "^0.8.
|
|
63
|
+
"ufo": "^0.8.5",
|
|
64
64
|
"unctx": "^1.1.4",
|
|
65
|
-
"unimport": "^0.
|
|
66
|
-
"unplugin": "^0.
|
|
65
|
+
"unimport": "^0.4.5",
|
|
66
|
+
"unplugin": "^0.7.2",
|
|
67
67
|
"untyped": "^0.4.4",
|
|
68
68
|
"vite": "^2.9.9",
|
|
69
|
-
"vue": "^3.2.
|
|
69
|
+
"vue": "^3.2.37"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/fs-extra": "^9.0.13",
|
|
73
|
-
"vue-router": "^4.
|
|
73
|
+
"vue-router": "^4.1.2"
|
|
74
74
|
},
|
|
75
75
|
"engines": {
|
|
76
76
|
"node": "^16.11.0 || ^17.0.0 || ^18.0.0"
|
|
@@ -1,56 +0,0 @@
|
|
|
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 "#pages";
|
|
6
|
-
export default defineFlowPlugin(async (flow) => {
|
|
7
|
-
const { app } = useRuntimeConfig();
|
|
8
|
-
const allPages = [];
|
|
9
|
-
const basePages = Object.entries(pages);
|
|
10
|
-
consola.success("Parsed %i pages", basePages.length);
|
|
11
|
-
basePages.forEach(([name, page]) => {
|
|
12
|
-
const { getPages } = definePage({
|
|
13
|
-
name,
|
|
14
|
-
...page
|
|
15
|
-
});
|
|
16
|
-
const _pages = getPages(app.locale.location, app.locale.language);
|
|
17
|
-
_pages.forEach((page2) => {
|
|
18
|
-
flow.router.byUrl.insert(page2.url, page2.context);
|
|
19
|
-
flow.router.byName.insert(page2.name, page2.context);
|
|
20
|
-
allPages.push(page2.context);
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
function getUrl(namePage, localeCode) {
|
|
24
|
-
const code = localeCode || this?.getLocale()?.code;
|
|
25
|
-
const [lang, loc] = code.split("-");
|
|
26
|
-
const name = joinURL("/", loc, lang, namePage);
|
|
27
|
-
const { path } = flow.router.byName.lookup(name) || {};
|
|
28
|
-
return path || "/404";
|
|
29
|
-
}
|
|
30
|
-
async function getUrls(withLocale = false) {
|
|
31
|
-
const urls = [];
|
|
32
|
-
for (const page of allPages) {
|
|
33
|
-
if (!page.path.includes("/**")) {
|
|
34
|
-
urls.push(withLocale ? { url: page.path, locale: page.locale.code, name: page.name } : page.path);
|
|
35
|
-
} else {
|
|
36
|
-
const dPages = await page.page.dynamic.method({
|
|
37
|
-
locale: page.locale,
|
|
38
|
-
utils: Object.assign({ getLocale: () => page.locale }, flow.app.utils)
|
|
39
|
-
});
|
|
40
|
-
dPages.forEach((dPage) => {
|
|
41
|
-
const _path = joinURL(page.path.replace("/**", ""), dPage.url);
|
|
42
|
-
urls.push(withLocale ? { url: _path, locale: page.locale.code, name: joinURL(page.name, dPage.name) } : _path);
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return urls.sort();
|
|
47
|
-
}
|
|
48
|
-
flow.setUtil("getUrl", getUrl);
|
|
49
|
-
flow.setUtil("getUrls", getUrls);
|
|
50
|
-
flow.setUtil("getPages", () => allPages);
|
|
51
|
-
return {
|
|
52
|
-
provide: {
|
|
53
|
-
pages: { allPages }
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
});
|
|
File without changes
|