@monkeyplus/flow 4.0.0-beta.1 → 4.0.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +200 -9
- package/dist/index.d.ts +9 -2
- package/dist/index.mjs +200 -10
- package/package.json +8 -3
- package/resources/client +1 -0
- package/resources/ws.js +15 -0
- package/types/flow.d.ts +5 -0
package/dist/index.cjs
CHANGED
|
@@ -10,6 +10,9 @@ const boom = require('@hapi/boom');
|
|
|
10
10
|
const os = require('os');
|
|
11
11
|
const chalk = require('chalk');
|
|
12
12
|
const fs = require('fs-extra');
|
|
13
|
+
const fs$1 = require('fs');
|
|
14
|
+
const hookable = require('hookable');
|
|
15
|
+
const chokidar = require('chokidar');
|
|
13
16
|
|
|
14
17
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }
|
|
15
18
|
|
|
@@ -31,9 +34,11 @@ const R__namespace = /*#__PURE__*/_interopNamespace(R);
|
|
|
31
34
|
const os__default = /*#__PURE__*/_interopDefaultLegacy(os);
|
|
32
35
|
const chalk__default = /*#__PURE__*/_interopDefaultLegacy(chalk);
|
|
33
36
|
const fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
|
|
37
|
+
const fs__default$1 = /*#__PURE__*/_interopDefaultLegacy(fs$1);
|
|
38
|
+
const chokidar__default = /*#__PURE__*/_interopDefaultLegacy(chokidar);
|
|
34
39
|
|
|
35
40
|
const name = "@monkeyplus/flow";
|
|
36
|
-
const version = "4.0.0-beta.
|
|
41
|
+
const version = "4.0.0-beta.11";
|
|
37
42
|
const description = "Utils hapi";
|
|
38
43
|
const author = "Andres Navarrete";
|
|
39
44
|
const license = "MIT";
|
|
@@ -42,7 +47,8 @@ const module$1 = "./dist/index.mjs";
|
|
|
42
47
|
const types = "./dist/index.d.ts";
|
|
43
48
|
const files = [
|
|
44
49
|
"dist/",
|
|
45
|
-
"types/"
|
|
50
|
+
"types/",
|
|
51
|
+
"resources/"
|
|
46
52
|
];
|
|
47
53
|
const exports$1 = {
|
|
48
54
|
".": {
|
|
@@ -58,21 +64,24 @@ const scripts = {
|
|
|
58
64
|
lint: "eslint --ext .js,.ts .",
|
|
59
65
|
fix: "eslint --fix --ext .ts .",
|
|
60
66
|
prepublishOnly: "pnpm run build",
|
|
61
|
-
publish: "pnpm publish",
|
|
62
67
|
start: "esno src/index.ts",
|
|
63
68
|
test: "vitest"
|
|
64
69
|
};
|
|
65
70
|
const dependencies$1 = {
|
|
66
71
|
"@hapi/boom": "9.x.x",
|
|
67
72
|
"@hapi/hoek": "9.x.x",
|
|
68
|
-
chalk: "^5.0.0",
|
|
69
73
|
consola: "^2.15.3",
|
|
74
|
+
chalk: "^4.1.2",
|
|
75
|
+
chokidar: "^3.5.3",
|
|
76
|
+
hookable: "^5.1.1",
|
|
70
77
|
"fs-extra": "^10.0.0",
|
|
71
78
|
ramda: "^0.28.0"
|
|
72
79
|
};
|
|
73
80
|
const devDependencies = {
|
|
74
81
|
"@types/fs-extra": "^9.0.13",
|
|
75
82
|
"@types/hapi__hapi": "^20.0.10",
|
|
83
|
+
"@types/hapi__nes": "^11.0.5",
|
|
84
|
+
"@types/hapi__vision": "^5.5.3",
|
|
76
85
|
"@types/ramda": "^0.27.64"
|
|
77
86
|
};
|
|
78
87
|
const peerDependencies = {
|
|
@@ -99,8 +108,13 @@ const pkg = {
|
|
|
99
108
|
|
|
100
109
|
const logger$1 = consola__default.withScope(pkg.name);
|
|
101
110
|
const dependencies = {
|
|
102
|
-
"@hapi/vision": "6.x.x"
|
|
111
|
+
"@hapi/vision": "6.x.x",
|
|
112
|
+
"@hapi/inert": "6.x.x",
|
|
113
|
+
"@hapi/h2o2": "9.x.x",
|
|
114
|
+
"@hapi/nes": "12.x.x"
|
|
103
115
|
};
|
|
116
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
117
|
+
const isGenerate = process.env.GENERATE;
|
|
104
118
|
|
|
105
119
|
const LifeCircle = {
|
|
106
120
|
register: (server) => {
|
|
@@ -314,7 +328,7 @@ const handlerPage = async (req, h) => {
|
|
|
314
328
|
return context;
|
|
315
329
|
}
|
|
316
330
|
context.utils = utils;
|
|
317
|
-
return h.view(`${configs.dirTemplates}${flow.view.
|
|
331
|
+
return h.view(`${configs.dirTemplates}${flow.view.layout || "default"}`, context);
|
|
318
332
|
};
|
|
319
333
|
|
|
320
334
|
const logger = consola__default.withScope("@monkeyplus/flow");
|
|
@@ -322,6 +336,10 @@ const defaults = {
|
|
|
322
336
|
locales: ["es-ec"],
|
|
323
337
|
defaultUbication: "ec",
|
|
324
338
|
defaultLanguage: "es",
|
|
339
|
+
staticDir: "static",
|
|
340
|
+
hmr: {
|
|
341
|
+
dirs: ["views"]
|
|
342
|
+
},
|
|
325
343
|
publicPath: "/",
|
|
326
344
|
locale: "es-ec",
|
|
327
345
|
relativeTo: "",
|
|
@@ -693,6 +711,47 @@ const definePage = (pageOptions) => (levelOptions) => (configs) => {
|
|
|
693
711
|
return routes;
|
|
694
712
|
};
|
|
695
713
|
|
|
714
|
+
const readPagesDir = (pathDir, folder) => {
|
|
715
|
+
const p = fs__default$1.readdirSync(pathDir);
|
|
716
|
+
return R.flatten(p.filter((f) => !f.includes(".js.map") && !f.includes(" copy.js.map") && !f.includes(" copy.js") && !f.includes(".model")).map((e) => {
|
|
717
|
+
if (e.includes(".js") || e.includes(".ts")) {
|
|
718
|
+
return {
|
|
719
|
+
path: path__default.join(pathDir, e),
|
|
720
|
+
prefix: folder
|
|
721
|
+
};
|
|
722
|
+
} else {
|
|
723
|
+
return readPagesDir(path__default.join(pathDir, e), e);
|
|
724
|
+
}
|
|
725
|
+
}));
|
|
726
|
+
};
|
|
727
|
+
const registerPages = async (server, dir) => {
|
|
728
|
+
const dirPages = path__default.resolve(dir || "./pages");
|
|
729
|
+
const listFiles = readPagesDir(dirPages);
|
|
730
|
+
const listPrePages = [];
|
|
731
|
+
for (const item of listFiles) {
|
|
732
|
+
try {
|
|
733
|
+
const module = require(item.path)?.default;
|
|
734
|
+
if (typeof module === "function") {
|
|
735
|
+
listPrePages.push(module());
|
|
736
|
+
} else if (typeof module === "object") {
|
|
737
|
+
if (Array.isArray(module)) {
|
|
738
|
+
module.forEach((el) => listPrePages.push(el()));
|
|
739
|
+
} else {
|
|
740
|
+
const _pages = await module.pages({ server });
|
|
741
|
+
if (Array.isArray(_pages))
|
|
742
|
+
_pages.forEach((page) => listPrePages.push(definePage(page)()));
|
|
743
|
+
else
|
|
744
|
+
listPrePages.push(definePage(_pages)());
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
} catch (details) {
|
|
748
|
+
logger$1.error(details);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
for (const page of listPrePages)
|
|
752
|
+
await server.flow.addPage(page);
|
|
753
|
+
};
|
|
754
|
+
|
|
696
755
|
const RunMethods = {
|
|
697
756
|
register: (server) => {
|
|
698
757
|
const { flow: state } = server.app;
|
|
@@ -706,7 +765,7 @@ const RunMethods = {
|
|
|
706
765
|
server.route(route);
|
|
707
766
|
};
|
|
708
767
|
const addPage = (_page, extra) => {
|
|
709
|
-
const
|
|
768
|
+
const registerPages2 = (_pages2) => {
|
|
710
769
|
for (const _route of _pages2) {
|
|
711
770
|
if (state.routes[_route.path])
|
|
712
771
|
logger$1.warn("The route %s alredy exist", _route.path);
|
|
@@ -717,13 +776,14 @@ const RunMethods = {
|
|
|
717
776
|
let _pages;
|
|
718
777
|
if (typeof _page === "function") {
|
|
719
778
|
_pages = _page(config);
|
|
720
|
-
|
|
779
|
+
registerPages2(_pages);
|
|
721
780
|
} else {
|
|
722
781
|
_pages = definePage(_page)()(config);
|
|
723
|
-
|
|
782
|
+
registerPages2(_pages);
|
|
724
783
|
}
|
|
725
784
|
};
|
|
726
785
|
const init = async () => {
|
|
786
|
+
await registerPages(server);
|
|
727
787
|
const pages = server.app.flow.routes;
|
|
728
788
|
for (const key in pages) {
|
|
729
789
|
const page = pages[key];
|
|
@@ -740,6 +800,136 @@ const RunMethods = {
|
|
|
740
800
|
}
|
|
741
801
|
};
|
|
742
802
|
|
|
803
|
+
const createHmr = (options) => {
|
|
804
|
+
const state = {
|
|
805
|
+
dir: options.relativeTo || "",
|
|
806
|
+
dirs: options.dirs || [],
|
|
807
|
+
extensions: options.extensions || ["eta"]
|
|
808
|
+
};
|
|
809
|
+
let watcher;
|
|
810
|
+
const hooks = hookable.createHooks();
|
|
811
|
+
const watch = () => {
|
|
812
|
+
watcher = chokidar__default.watch(state.dirs.map((d) => path__default.join(d, `**/*.(${state.extensions.join("|")})`)), {
|
|
813
|
+
cwd: state.dir,
|
|
814
|
+
ignoreInitial: true,
|
|
815
|
+
ignored: "node_modules/**/*"
|
|
816
|
+
}).on("change", (path2) => {
|
|
817
|
+
logger$1.info("Changed file", path2);
|
|
818
|
+
hooks.callHook("page:refresh");
|
|
819
|
+
});
|
|
820
|
+
};
|
|
821
|
+
watch();
|
|
822
|
+
return { watcher, hooks };
|
|
823
|
+
};
|
|
824
|
+
|
|
825
|
+
const RegisterCommon = async (server, configs) => {
|
|
826
|
+
server.route({
|
|
827
|
+
method: "GET",
|
|
828
|
+
path: "/{param*}",
|
|
829
|
+
options: {
|
|
830
|
+
ext: {
|
|
831
|
+
onPreResponse: {
|
|
832
|
+
method: (req, h) => {
|
|
833
|
+
return h.continue;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
},
|
|
838
|
+
handler: {
|
|
839
|
+
directory: {
|
|
840
|
+
path: configs.staticDir,
|
|
841
|
+
listing: true
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
});
|
|
845
|
+
if (!isGenerate) {
|
|
846
|
+
const hmr = createHmr({
|
|
847
|
+
dirs: configs.hmr.dirs,
|
|
848
|
+
relativeTo: configs.relativeTo
|
|
849
|
+
});
|
|
850
|
+
hmr.hooks.hook("page:refresh", () => {
|
|
851
|
+
setTimeout(() => {
|
|
852
|
+
logger$1.info("Refresh page");
|
|
853
|
+
server.publish("/_flow/hmr", { reload: true });
|
|
854
|
+
}, 40);
|
|
855
|
+
});
|
|
856
|
+
server.subscription("/_flow/hmr");
|
|
857
|
+
server.route({
|
|
858
|
+
path: "/_flow/hmr/client.js",
|
|
859
|
+
method: "get",
|
|
860
|
+
handler: {
|
|
861
|
+
file: {
|
|
862
|
+
path: path.join(__dirname, "../resources/client"),
|
|
863
|
+
confine: false
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
});
|
|
867
|
+
server.route({
|
|
868
|
+
path: "/_flow/hmr/connect.js",
|
|
869
|
+
method: "get",
|
|
870
|
+
handler: {
|
|
871
|
+
file: {
|
|
872
|
+
path: path.join(__dirname, "../resources/ws.js"),
|
|
873
|
+
confine: false
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
});
|
|
877
|
+
logger$1.debug("Enable development routes");
|
|
878
|
+
server.route({
|
|
879
|
+
path: "/_flow/sitemap",
|
|
880
|
+
method: "get",
|
|
881
|
+
handler: async () => {
|
|
882
|
+
const { pages: getPages } = server.methods.flow;
|
|
883
|
+
const urls = await getPages();
|
|
884
|
+
const pages = Object.values(urls).map((p) => R.dissoc("context", p));
|
|
885
|
+
return {
|
|
886
|
+
total: pages.length,
|
|
887
|
+
pages
|
|
888
|
+
};
|
|
889
|
+
}
|
|
890
|
+
});
|
|
891
|
+
server.route({
|
|
892
|
+
path: "/_flow/locales",
|
|
893
|
+
method: "get",
|
|
894
|
+
handler: async (req) => {
|
|
895
|
+
const { pages: getPages } = server.methods.flow;
|
|
896
|
+
const urls = await getPages();
|
|
897
|
+
const pages = Object.values(urls).map((p) => R.dissoc("context", p));
|
|
898
|
+
const locales = R.groupBy((page) => page.locale, pages);
|
|
899
|
+
return {
|
|
900
|
+
locales: req.server.plugins.flow.configs.locales,
|
|
901
|
+
all: R.mapObjIndexed((l) => {
|
|
902
|
+
return {
|
|
903
|
+
total: l.length,
|
|
904
|
+
pages: l
|
|
905
|
+
};
|
|
906
|
+
}, locales)
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
});
|
|
910
|
+
server.route({
|
|
911
|
+
path: "/_flow/configs",
|
|
912
|
+
method: "get",
|
|
913
|
+
handler: (req) => {
|
|
914
|
+
return req.server.plugins.flow.configs;
|
|
915
|
+
}
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
const HMR = {
|
|
919
|
+
head: ' <script src="/_flow/hmr/client.js"><\/script>',
|
|
920
|
+
body: ' <script src="/_flow/hmr/connect.js"><\/script>'
|
|
921
|
+
};
|
|
922
|
+
server.ext("onPreHandler", async (req, h) => {
|
|
923
|
+
if (req.route.settings.plugins?.generate === ".html") {
|
|
924
|
+
const { global } = req.plugins.flow;
|
|
925
|
+
Object.assign(global, {
|
|
926
|
+
hmr: isProduction || isGenerate ? { head: "", body: "" } : HMR
|
|
927
|
+
});
|
|
928
|
+
}
|
|
929
|
+
return h.continue;
|
|
930
|
+
});
|
|
931
|
+
};
|
|
932
|
+
|
|
743
933
|
const plugin = {
|
|
744
934
|
pkg,
|
|
745
935
|
dependencies,
|
|
@@ -864,6 +1054,7 @@ const plugin = {
|
|
|
864
1054
|
return baseOptions;
|
|
865
1055
|
}
|
|
866
1056
|
};
|
|
1057
|
+
await RegisterCommon(server, config);
|
|
867
1058
|
}
|
|
868
1059
|
};
|
|
869
1060
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Plugin } from '@hapi/hapi';
|
|
1
|
+
import { Server, Plugin } from '@hapi/hapi';
|
|
2
2
|
import { PageInfo } from '../types/core';
|
|
3
3
|
import { OptionsHapiPage, RunPreDefinePage, Flow, FlowExtensions, OptionDynamicLocalePages, GenerateOptions, FlowServerMethods, FlowOptions } from '../types';
|
|
4
4
|
export { ContextHandler, Contexts, Extension, Flow, FlowContextPage, FlowContextSeo, FlowContextView, FlowEngines, FlowExtensions, FlowOptionPlugins, FlowOptions, FlowPluginExtension, FlowPluginGlobal, FlowPluginLocal, FlowPluginUtils, FlowServerMethods, FlowStatePlugins, GenerateFolder, OptionDynamicLocalePages, OptionsDynamicPages, OptionsHapiPage, RunDefinePage, RunPreDefinePage } from '../types';
|
|
@@ -6,7 +6,14 @@ export { ContextHandler, Contexts, Extension, Flow, FlowContextPage, FlowContext
|
|
|
6
6
|
declare type DefinePage = (page: OptionsHapiPage) => RunPreDefinePage;
|
|
7
7
|
declare const definePage: DefinePage;
|
|
8
8
|
|
|
9
|
+
declare type HapiPages = OptionsHapiPage | OptionsHapiPage[];
|
|
10
|
+
interface Context {
|
|
11
|
+
server: Server;
|
|
12
|
+
}
|
|
13
|
+
declare type Pages = (ctx: Context) => Promise<HapiPages>;
|
|
14
|
+
|
|
9
15
|
declare const plugin: Plugin<FlowOptions>;
|
|
16
|
+
|
|
10
17
|
declare module '@hapi/hapi' {
|
|
11
18
|
interface ServerApplicationState {
|
|
12
19
|
flow: Flow.AppState;
|
|
@@ -54,4 +61,4 @@ declare module '@hapi/hapi' {
|
|
|
54
61
|
}
|
|
55
62
|
}
|
|
56
63
|
|
|
57
|
-
export { definePage, plugin };
|
|
64
|
+
export { Pages, definePage, plugin };
|
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import path from 'path';
|
|
1
|
+
import path, { join } from 'path';
|
|
2
2
|
import { applyToDefaults } from '@hapi/hoek';
|
|
3
3
|
import consola from 'consola';
|
|
4
4
|
import * as R from 'ramda';
|
|
5
|
+
import { flatten, dissoc, groupBy, mapObjIndexed } from 'ramda';
|
|
5
6
|
import { notFound } from '@hapi/boom';
|
|
6
7
|
import os from 'os';
|
|
7
8
|
import chalk from 'chalk';
|
|
8
9
|
import fs from 'fs-extra';
|
|
10
|
+
import fs$1 from 'fs';
|
|
11
|
+
import { createHooks } from 'hookable';
|
|
12
|
+
import chokidar from 'chokidar';
|
|
9
13
|
|
|
10
14
|
const name = "@monkeyplus/flow";
|
|
11
|
-
const version = "4.0.0-beta.
|
|
15
|
+
const version = "4.0.0-beta.11";
|
|
12
16
|
const description = "Utils hapi";
|
|
13
17
|
const author = "Andres Navarrete";
|
|
14
18
|
const license = "MIT";
|
|
@@ -17,7 +21,8 @@ const module = "./dist/index.mjs";
|
|
|
17
21
|
const types = "./dist/index.d.ts";
|
|
18
22
|
const files = [
|
|
19
23
|
"dist/",
|
|
20
|
-
"types/"
|
|
24
|
+
"types/",
|
|
25
|
+
"resources/"
|
|
21
26
|
];
|
|
22
27
|
const exports = {
|
|
23
28
|
".": {
|
|
@@ -33,21 +38,24 @@ const scripts = {
|
|
|
33
38
|
lint: "eslint --ext .js,.ts .",
|
|
34
39
|
fix: "eslint --fix --ext .ts .",
|
|
35
40
|
prepublishOnly: "pnpm run build",
|
|
36
|
-
publish: "pnpm publish",
|
|
37
41
|
start: "esno src/index.ts",
|
|
38
42
|
test: "vitest"
|
|
39
43
|
};
|
|
40
44
|
const dependencies$1 = {
|
|
41
45
|
"@hapi/boom": "9.x.x",
|
|
42
46
|
"@hapi/hoek": "9.x.x",
|
|
43
|
-
chalk: "^5.0.0",
|
|
44
47
|
consola: "^2.15.3",
|
|
48
|
+
chalk: "^4.1.2",
|
|
49
|
+
chokidar: "^3.5.3",
|
|
50
|
+
hookable: "^5.1.1",
|
|
45
51
|
"fs-extra": "^10.0.0",
|
|
46
52
|
ramda: "^0.28.0"
|
|
47
53
|
};
|
|
48
54
|
const devDependencies = {
|
|
49
55
|
"@types/fs-extra": "^9.0.13",
|
|
50
56
|
"@types/hapi__hapi": "^20.0.10",
|
|
57
|
+
"@types/hapi__nes": "^11.0.5",
|
|
58
|
+
"@types/hapi__vision": "^5.5.3",
|
|
51
59
|
"@types/ramda": "^0.27.64"
|
|
52
60
|
};
|
|
53
61
|
const peerDependencies = {
|
|
@@ -74,8 +82,13 @@ const pkg = {
|
|
|
74
82
|
|
|
75
83
|
const logger$1 = consola.withScope(pkg.name);
|
|
76
84
|
const dependencies = {
|
|
77
|
-
"@hapi/vision": "6.x.x"
|
|
85
|
+
"@hapi/vision": "6.x.x",
|
|
86
|
+
"@hapi/inert": "6.x.x",
|
|
87
|
+
"@hapi/h2o2": "9.x.x",
|
|
88
|
+
"@hapi/nes": "12.x.x"
|
|
78
89
|
};
|
|
90
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
91
|
+
const isGenerate = process.env.GENERATE;
|
|
79
92
|
|
|
80
93
|
const LifeCircle = {
|
|
81
94
|
register: (server) => {
|
|
@@ -289,7 +302,7 @@ const handlerPage = async (req, h) => {
|
|
|
289
302
|
return context;
|
|
290
303
|
}
|
|
291
304
|
context.utils = utils;
|
|
292
|
-
return h.view(`${configs.dirTemplates}${flow.view.
|
|
305
|
+
return h.view(`${configs.dirTemplates}${flow.view.layout || "default"}`, context);
|
|
293
306
|
};
|
|
294
307
|
|
|
295
308
|
const logger = consola.withScope("@monkeyplus/flow");
|
|
@@ -297,6 +310,10 @@ const defaults = {
|
|
|
297
310
|
locales: ["es-ec"],
|
|
298
311
|
defaultUbication: "ec",
|
|
299
312
|
defaultLanguage: "es",
|
|
313
|
+
staticDir: "static",
|
|
314
|
+
hmr: {
|
|
315
|
+
dirs: ["views"]
|
|
316
|
+
},
|
|
300
317
|
publicPath: "/",
|
|
301
318
|
locale: "es-ec",
|
|
302
319
|
relativeTo: "",
|
|
@@ -668,6 +685,47 @@ const definePage = (pageOptions) => (levelOptions) => (configs) => {
|
|
|
668
685
|
return routes;
|
|
669
686
|
};
|
|
670
687
|
|
|
688
|
+
const readPagesDir = (pathDir, folder) => {
|
|
689
|
+
const p = fs$1.readdirSync(pathDir);
|
|
690
|
+
return flatten(p.filter((f) => !f.includes(".js.map") && !f.includes(" copy.js.map") && !f.includes(" copy.js") && !f.includes(".model")).map((e) => {
|
|
691
|
+
if (e.includes(".js") || e.includes(".ts")) {
|
|
692
|
+
return {
|
|
693
|
+
path: path.join(pathDir, e),
|
|
694
|
+
prefix: folder
|
|
695
|
+
};
|
|
696
|
+
} else {
|
|
697
|
+
return readPagesDir(path.join(pathDir, e), e);
|
|
698
|
+
}
|
|
699
|
+
}));
|
|
700
|
+
};
|
|
701
|
+
const registerPages = async (server, dir) => {
|
|
702
|
+
const dirPages = path.resolve(dir || "./pages");
|
|
703
|
+
const listFiles = readPagesDir(dirPages);
|
|
704
|
+
const listPrePages = [];
|
|
705
|
+
for (const item of listFiles) {
|
|
706
|
+
try {
|
|
707
|
+
const module = require(item.path)?.default;
|
|
708
|
+
if (typeof module === "function") {
|
|
709
|
+
listPrePages.push(module());
|
|
710
|
+
} else if (typeof module === "object") {
|
|
711
|
+
if (Array.isArray(module)) {
|
|
712
|
+
module.forEach((el) => listPrePages.push(el()));
|
|
713
|
+
} else {
|
|
714
|
+
const _pages = await module.pages({ server });
|
|
715
|
+
if (Array.isArray(_pages))
|
|
716
|
+
_pages.forEach((page) => listPrePages.push(definePage(page)()));
|
|
717
|
+
else
|
|
718
|
+
listPrePages.push(definePage(_pages)());
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
} catch (details) {
|
|
722
|
+
logger$1.error(details);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
for (const page of listPrePages)
|
|
726
|
+
await server.flow.addPage(page);
|
|
727
|
+
};
|
|
728
|
+
|
|
671
729
|
const RunMethods = {
|
|
672
730
|
register: (server) => {
|
|
673
731
|
const { flow: state } = server.app;
|
|
@@ -681,7 +739,7 @@ const RunMethods = {
|
|
|
681
739
|
server.route(route);
|
|
682
740
|
};
|
|
683
741
|
const addPage = (_page, extra) => {
|
|
684
|
-
const
|
|
742
|
+
const registerPages2 = (_pages2) => {
|
|
685
743
|
for (const _route of _pages2) {
|
|
686
744
|
if (state.routes[_route.path])
|
|
687
745
|
logger$1.warn("The route %s alredy exist", _route.path);
|
|
@@ -692,13 +750,14 @@ const RunMethods = {
|
|
|
692
750
|
let _pages;
|
|
693
751
|
if (typeof _page === "function") {
|
|
694
752
|
_pages = _page(config);
|
|
695
|
-
|
|
753
|
+
registerPages2(_pages);
|
|
696
754
|
} else {
|
|
697
755
|
_pages = definePage(_page)()(config);
|
|
698
|
-
|
|
756
|
+
registerPages2(_pages);
|
|
699
757
|
}
|
|
700
758
|
};
|
|
701
759
|
const init = async () => {
|
|
760
|
+
await registerPages(server);
|
|
702
761
|
const pages = server.app.flow.routes;
|
|
703
762
|
for (const key in pages) {
|
|
704
763
|
const page = pages[key];
|
|
@@ -715,6 +774,136 @@ const RunMethods = {
|
|
|
715
774
|
}
|
|
716
775
|
};
|
|
717
776
|
|
|
777
|
+
const createHmr = (options) => {
|
|
778
|
+
const state = {
|
|
779
|
+
dir: options.relativeTo || "",
|
|
780
|
+
dirs: options.dirs || [],
|
|
781
|
+
extensions: options.extensions || ["eta"]
|
|
782
|
+
};
|
|
783
|
+
let watcher;
|
|
784
|
+
const hooks = createHooks();
|
|
785
|
+
const watch = () => {
|
|
786
|
+
watcher = chokidar.watch(state.dirs.map((d) => path.join(d, `**/*.(${state.extensions.join("|")})`)), {
|
|
787
|
+
cwd: state.dir,
|
|
788
|
+
ignoreInitial: true,
|
|
789
|
+
ignored: "node_modules/**/*"
|
|
790
|
+
}).on("change", (path2) => {
|
|
791
|
+
logger$1.info("Changed file", path2);
|
|
792
|
+
hooks.callHook("page:refresh");
|
|
793
|
+
});
|
|
794
|
+
};
|
|
795
|
+
watch();
|
|
796
|
+
return { watcher, hooks };
|
|
797
|
+
};
|
|
798
|
+
|
|
799
|
+
const RegisterCommon = async (server, configs) => {
|
|
800
|
+
server.route({
|
|
801
|
+
method: "GET",
|
|
802
|
+
path: "/{param*}",
|
|
803
|
+
options: {
|
|
804
|
+
ext: {
|
|
805
|
+
onPreResponse: {
|
|
806
|
+
method: (req, h) => {
|
|
807
|
+
return h.continue;
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
},
|
|
812
|
+
handler: {
|
|
813
|
+
directory: {
|
|
814
|
+
path: configs.staticDir,
|
|
815
|
+
listing: true
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
});
|
|
819
|
+
if (!isGenerate) {
|
|
820
|
+
const hmr = createHmr({
|
|
821
|
+
dirs: configs.hmr.dirs,
|
|
822
|
+
relativeTo: configs.relativeTo
|
|
823
|
+
});
|
|
824
|
+
hmr.hooks.hook("page:refresh", () => {
|
|
825
|
+
setTimeout(() => {
|
|
826
|
+
logger$1.info("Refresh page");
|
|
827
|
+
server.publish("/_flow/hmr", { reload: true });
|
|
828
|
+
}, 40);
|
|
829
|
+
});
|
|
830
|
+
server.subscription("/_flow/hmr");
|
|
831
|
+
server.route({
|
|
832
|
+
path: "/_flow/hmr/client.js",
|
|
833
|
+
method: "get",
|
|
834
|
+
handler: {
|
|
835
|
+
file: {
|
|
836
|
+
path: join(__dirname, "../resources/client"),
|
|
837
|
+
confine: false
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
});
|
|
841
|
+
server.route({
|
|
842
|
+
path: "/_flow/hmr/connect.js",
|
|
843
|
+
method: "get",
|
|
844
|
+
handler: {
|
|
845
|
+
file: {
|
|
846
|
+
path: join(__dirname, "../resources/ws.js"),
|
|
847
|
+
confine: false
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
});
|
|
851
|
+
logger$1.debug("Enable development routes");
|
|
852
|
+
server.route({
|
|
853
|
+
path: "/_flow/sitemap",
|
|
854
|
+
method: "get",
|
|
855
|
+
handler: async () => {
|
|
856
|
+
const { pages: getPages } = server.methods.flow;
|
|
857
|
+
const urls = await getPages();
|
|
858
|
+
const pages = Object.values(urls).map((p) => dissoc("context", p));
|
|
859
|
+
return {
|
|
860
|
+
total: pages.length,
|
|
861
|
+
pages
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
});
|
|
865
|
+
server.route({
|
|
866
|
+
path: "/_flow/locales",
|
|
867
|
+
method: "get",
|
|
868
|
+
handler: async (req) => {
|
|
869
|
+
const { pages: getPages } = server.methods.flow;
|
|
870
|
+
const urls = await getPages();
|
|
871
|
+
const pages = Object.values(urls).map((p) => dissoc("context", p));
|
|
872
|
+
const locales = groupBy((page) => page.locale, pages);
|
|
873
|
+
return {
|
|
874
|
+
locales: req.server.plugins.flow.configs.locales,
|
|
875
|
+
all: mapObjIndexed((l) => {
|
|
876
|
+
return {
|
|
877
|
+
total: l.length,
|
|
878
|
+
pages: l
|
|
879
|
+
};
|
|
880
|
+
}, locales)
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
});
|
|
884
|
+
server.route({
|
|
885
|
+
path: "/_flow/configs",
|
|
886
|
+
method: "get",
|
|
887
|
+
handler: (req) => {
|
|
888
|
+
return req.server.plugins.flow.configs;
|
|
889
|
+
}
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
const HMR = {
|
|
893
|
+
head: ' <script src="/_flow/hmr/client.js"><\/script>',
|
|
894
|
+
body: ' <script src="/_flow/hmr/connect.js"><\/script>'
|
|
895
|
+
};
|
|
896
|
+
server.ext("onPreHandler", async (req, h) => {
|
|
897
|
+
if (req.route.settings.plugins?.generate === ".html") {
|
|
898
|
+
const { global } = req.plugins.flow;
|
|
899
|
+
Object.assign(global, {
|
|
900
|
+
hmr: isProduction || isGenerate ? { head: "", body: "" } : HMR
|
|
901
|
+
});
|
|
902
|
+
}
|
|
903
|
+
return h.continue;
|
|
904
|
+
});
|
|
905
|
+
};
|
|
906
|
+
|
|
718
907
|
const plugin = {
|
|
719
908
|
pkg,
|
|
720
909
|
dependencies,
|
|
@@ -839,6 +1028,7 @@ const plugin = {
|
|
|
839
1028
|
return baseOptions;
|
|
840
1029
|
}
|
|
841
1030
|
};
|
|
1031
|
+
await RegisterCommon(server, config);
|
|
842
1032
|
}
|
|
843
1033
|
};
|
|
844
1034
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monkeyplus/flow",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.11",
|
|
4
4
|
"description": "Utils hapi",
|
|
5
5
|
"author": "Andres Navarrete",
|
|
6
6
|
"license": "MIT",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"types": "./dist/index.d.ts",
|
|
10
10
|
"files": [
|
|
11
11
|
"dist/",
|
|
12
|
-
"types/"
|
|
12
|
+
"types/",
|
|
13
|
+
"resources/"
|
|
13
14
|
],
|
|
14
15
|
"exports": {
|
|
15
16
|
".": {
|
|
@@ -20,14 +21,18 @@
|
|
|
20
21
|
"dependencies": {
|
|
21
22
|
"@hapi/boom": "9.x.x",
|
|
22
23
|
"@hapi/hoek": "9.x.x",
|
|
23
|
-
"chalk": "^5.0.0",
|
|
24
24
|
"consola": "^2.15.3",
|
|
25
|
+
"chalk": "^4.1.2",
|
|
26
|
+
"chokidar": "^3.5.3",
|
|
27
|
+
"hookable": "^5.1.1",
|
|
25
28
|
"fs-extra": "^10.0.0",
|
|
26
29
|
"ramda": "^0.28.0"
|
|
27
30
|
},
|
|
28
31
|
"devDependencies": {
|
|
29
32
|
"@types/fs-extra": "^9.0.13",
|
|
30
33
|
"@types/hapi__hapi": "^20.0.10",
|
|
34
|
+
"@types/hapi__nes": "^11.0.5",
|
|
35
|
+
"@types/hapi__vision": "^5.5.3",
|
|
31
36
|
"@types/ramda": "^0.27.64"
|
|
32
37
|
},
|
|
33
38
|
"peerDependencies": {
|
package/resources/client
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';var _typeof='function'==typeof Symbol&&'symbol'==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&'function'==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?'symbol':typeof a};(function(a,b){'object'===('undefined'==typeof exports?'undefined':_typeof(exports))&&'object'===('undefined'==typeof module?'undefined':_typeof(module))?module.exports=b():'function'==typeof define&&define.amd?define(b):'object'===('undefined'==typeof exports?'undefined':_typeof(exports))?exports.nes=b():a.nes=b()})('undefined'==typeof window?global:window,function(){var a=function(){},b=function(a){try{return JSON.stringify(a)}catch(a){throw new e(a,d.USER)}},c=function(a){return function(b){setTimeout(function(){return a(b)},0)}},d={TIMEOUT:'timeout',DISCONNECT:'disconnect',SERVER:'server',PROTOCOL:'protocol',WS:'ws',USER:'user'},e=function(a,b){'string'==typeof a&&(a=new Error(a)),a.type=b,a.isNes=!0;try{throw a}catch(a){return a}},f={1000:'Normal closure',1001:'Going away',1002:'Protocol error',1003:'Unsupported data',1004:'Reserved',1005:'No status received',1006:'Abnormal closure',1007:'Invalid frame payload data',1008:'Policy violation',1009:'Message too big',1010:'Mandatory extension',1011:'Internal server error',1015:'TLS handshake'},g=function(b,c){c=c||{},this._isBrowser='undefined'!=typeof WebSocket,this._isBrowser||(c.ws=c.ws||{},void 0===c.ws.maxPayload&&(c.ws.maxPayload=0)),this._url=b,this._settings=c,this._heartbeatTimeout=!1,this._ws=null,this._reconnection=null,this._reconnectionTimer=null,this._ids=0,this._requests={},this._subscriptions={},this._heartbeat=null,this._packets=[],this._disconnectListeners=null,this._disconnectRequested=!1,this.onError=function(a){return console.error(a)},this.onConnect=a,this.onDisconnect=a,this.onHeartbeatTimeout=a,this.onUpdate=a,this.id=null};return g.WebSocket='undefined'==typeof WebSocket?null:WebSocket,g.prototype.connect=function(a){var b=this;return(a=a||{},this._reconnection)?Promise.reject(new e('Cannot connect while client attempts to reconnect',d.USER)):this._ws?Promise.reject(new e('Already connected',d.USER)):(this._reconnection=!1===a.reconnect?null:{wait:0,delay:a.delay||1e3,maxDelay:a.maxDelay||5e3,retries:a.retries||Infinity,settings:{auth:a.auth,timeout:a.timeout}},new Promise(function(c,d){b._connect(a,!0,function(a){return a?d(a):c()})}))},g.prototype._connect=function(a,b,h){var i=this,j=this._isBrowser?new g.WebSocket(this._url):new g.WebSocket(this._url,this._settings.ws);this._ws=j,clearTimeout(this._reconnectionTimer),this._reconnectionTimer=null;var k=function(a){j.onopen&&l(new e('Connection terminated while waiting to connect',d.WS));var b=i._disconnectRequested;i._cleanup();var c={code:a.code,explanation:f[a.code]||'Unknown',reason:a.reason,wasClean:a.wasClean,willReconnect:i._willReconnect(),wasRequested:b};i.onDisconnect(c.willReconnect,c),i._reconnect()},l=function(a){if(h){var b=h;return h=null,b(a)}return i.onError(a)},m=a.timeout?setTimeout(function timeoutHandler(){if(i._cleanup(),l(new e('Connection timed out',d.TIMEOUT)),b)return i._reconnect()},a.timeout):null;j.onopen=function(){clearTimeout(m),j.onopen=null,i._hello(a.auth).then(function(){i.onConnect(),l()}).catch(function(a){a.path&&delete i._subscriptions[a.path],i._disconnect(function(){return c(l)(a)},!0)})},j.onerror=function(a){if(clearTimeout(m),i._willReconnect())return k(a);i._cleanup();var b=new e('Socket error',d.WS);return l(b)},j.onclose=k,j.onmessage=function(a){return i._onMessage(a)}},g.prototype.overrideReconnectionAuth=function(a){return!!this._reconnection&&(this._reconnection.settings.auth=a,!0)},g.prototype.reauthenticate=function(a){this.overrideReconnectionAuth(a);return this._send({type:'reauth',auth:a},!0)},g.prototype.disconnect=function(){var a=this;return new Promise(function(b){return a._disconnect(b,!1)})},g.prototype._disconnect=function(a,b){this._reconnection=null,clearTimeout(this._reconnectionTimer),this._reconnectionTimer=null;var c=this._disconnectRequested||!b;return this._disconnectListeners?(this._disconnectRequested=c,void this._disconnectListeners.push(a)):this._ws&&(this._ws.readyState===g.WebSocket.OPEN||this._ws.readyState===g.WebSocket.CONNECTING)?void(this._disconnectRequested=c,this._disconnectListeners=[a],this._ws.close()):a()},g.prototype._cleanup=function(){if(this._ws){var k=this._ws;this._ws=null,k.readyState!==g.WebSocket.CLOSED&&k.readyState!==g.WebSocket.CLOSING&&k.close(),k.onopen=null,k.onclose=null,k.onerror=a,k.onmessage=null}this._packets=[],this.id=null,clearTimeout(this._heartbeat),this._heartbeat=null;var b=new e('Request failed - server disconnected',d.DISCONNECT),c=this._requests;this._requests={};for(var f=Object.keys(c),h=0;h<f.length;++h){var i=f[h],j=c[i];clearTimeout(j.timeout),j.reject(b)}if(this._disconnectListeners){var l=this._disconnectListeners;this._disconnectListeners=null,this._disconnectRequested=!1,l.forEach(function(a){return a()})}},g.prototype._reconnect=function(){var b=this,c=this._reconnection;if(c){if(1>c.retries)return this._disconnect(a,!0);--c.retries,c.wait+=c.delay;var d=Math.min(c.wait,c.maxDelay);this._reconnectionTimer=setTimeout(function(){b._connect(c.settings,!1,function(a){if(a)return b.onError(a),b._reconnect()})},d)}},g.prototype.request=function(a){'string'==typeof a&&(a={method:'GET',path:a});var b={type:'request',method:a.method||'GET',path:a.path,headers:a.headers,payload:a.payload};return this._send(b,!0)},g.prototype.message=function(a){return this._send({type:'message',message:a},!0)},g.prototype._isReady=function(){return this._ws&&this._ws.readyState===g.WebSocket.OPEN},g.prototype._send=function(a,c){if(!this._isReady())return Promise.reject(new e('Failed to send message - server disconnected',d.DISCONNECT));a.id=++this._ids;try{var f=b(a)}catch(a){return Promise.reject(a)}if(!c)try{return this._ws.send(f),Promise.resolve()}catch(a){return Promise.reject(new e(a,d.WS))}var g={resolve:null,reject:null,timeout:null},h=new Promise(function(a,b){g.resolve=a,g.reject=b});this._settings.timeout&&(g.timeout=setTimeout(function(){return g.timeout=null,g.reject(new e('Request timed out',d.TIMEOUT))},this._settings.timeout)),this._requests[a.id]=g;try{this._ws.send(f)}catch(b){return clearTimeout(this._requests[a.id].timeout),delete this._requests[a.id],Promise.reject(new e(b,d.WS))}return h},g.prototype._hello=function(a){var b={type:'hello',version:'2'};a&&(b.auth=a);var c=this.subscriptions();return c.length&&(b.subs=c),this._send(b,!0)},g.prototype.subscriptions=function(){return Object.keys(this._subscriptions)},g.prototype.subscribe=function(a,b){var c=this;if(!a||'/'!==a[0])return Promise.reject(new e('Invalid path',d.USER));var f=this._subscriptions[a];if(f)return-1===f.indexOf(b)&&f.push(b),Promise.resolve();if(this._subscriptions[a]=[b],!this._isReady())return Promise.resolve();var g=this._send({type:'sub',path:a},!0);return g.catch(function(){delete c._subscriptions[a]}),g},g.prototype.unsubscribe=function(b,c){if(!b||'/'!==b[0])return Promise.reject(new e('Invalid path',d.USER));var f=this._subscriptions[b];if(!f)return Promise.resolve();var g=!1;if(!c)delete this._subscriptions[b],g=!0;else{var i=f.indexOf(c);if(-1===i)return Promise.resolve();f.splice(i,1),f.length||(delete this._subscriptions[b],g=!0)}if(!g||!this._isReady())return Promise.resolve();var h=this._send({type:'unsub',path:b},!0);return h.catch(a),h},g.prototype._onMessage=function(b){this._beat();var c=b.data,f=c[0];if('{'!==f){if(this._packets.push(c.slice(1)),'!'!==f)return;c=this._packets.join(''),this._packets=[]}this._packets.length&&(this._packets=[],this.onError(new e('Received an incomplete message',d.PROTOCOL)));try{var g=JSON.parse(c)}catch(a){return this.onError(new e(a,d.PROTOCOL))}var h=null;if(g.statusCode&&400<=g.statusCode&&(h=new e(g.payload.message||g.payload.error||'Error',d.SERVER),h.statusCode=g.statusCode,h.data=g.payload,h.headers=g.headers,h.path=g.path),'ping'===g.type)return this._send({type:'ping'},!1).catch(a);if('update'===g.type)return this.onUpdate(g.message);if('pub'===g.type||'revoke'===g.type){var l=this._subscriptions[g.path];if('revoke'===g.type&&delete this._subscriptions[g.path],l&&void 0!==g.message){var m={};'revoke'===g.type&&(m.revoked=!0);for(var n=0;n<l.length;++n)l[n](g.message,m)}return}var j=this._requests[g.id];if(!j)return this.onError(new e('Received response for unknown request',d.PROTOCOL));clearTimeout(j.timeout),delete this._requests[g.id];var k=function(a,b){return a?j.reject(a):j.resolve(b)};return'request'===g.type?k(h,{payload:g.payload,statusCode:g.statusCode,headers:g.headers}):'message'===g.type?k(h,{payload:g.message}):'hello'===g.type?(this.id=g.socket,g.heartbeat&&(this._heartbeatTimeout=g.heartbeat.interval+g.heartbeat.timeout,this._beat()),k(h)):'reauth'===g.type?k(h,!0):'sub'===g.type||'unsub'===g.type?k(h):(k(new e('Received invalid response',d.PROTOCOL)),this.onError(new e('Received unknown response type: '+g.type,d.PROTOCOL)))},g.prototype._beat=function(){var a=this;this._heartbeatTimeout&&(clearTimeout(this._heartbeat),this._heartbeat=setTimeout(function(){a.onError(new e('Disconnecting due to heartbeat timeout',d.TIMEOUT)),a.onHeartbeatTimeout(a._willReconnect()),a._ws.close()},this._heartbeatTimeout))},g.prototype._willReconnect=function(){return!!(this._reconnection&&1<=this._reconnection.retries)},{Client:g}});
|
package/resources/ws.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/* eslint-disable no-undef */
|
|
2
|
+
const client = new nes.Client("ws://" + location.host, {
|
|
3
|
+
timeout: 5000,
|
|
4
|
+
});
|
|
5
|
+
console.log("[flow] connecting...");
|
|
6
|
+
const start = async () => {
|
|
7
|
+
await client.connect({ delay: 5000 });
|
|
8
|
+
console.log("[flow] connected.");
|
|
9
|
+
const handler = (update, flags) => {
|
|
10
|
+
location.reload();
|
|
11
|
+
};
|
|
12
|
+
client.subscribe("/_flow/hmr", handler);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
start();
|
package/types/flow.d.ts
CHANGED
|
@@ -33,6 +33,10 @@ export interface FlowOptions {
|
|
|
33
33
|
routeOptions?: RouteOptions
|
|
34
34
|
dirTemplates?: string
|
|
35
35
|
plugins: FlowOptionPlugins
|
|
36
|
+
staticDir: string
|
|
37
|
+
hmr: {
|
|
38
|
+
dirs: string[]
|
|
39
|
+
}
|
|
36
40
|
engines?: ('eta' | 'nunjucks')[]
|
|
37
41
|
}
|
|
38
42
|
|
|
@@ -118,6 +122,7 @@ export namespace Flow {
|
|
|
118
122
|
}
|
|
119
123
|
export interface Configs extends FlowOptions {
|
|
120
124
|
relativeTo: string
|
|
125
|
+
|
|
121
126
|
locales: string[]
|
|
122
127
|
defaultUbication: string
|
|
123
128
|
defaultLanguage: string
|