dtwo 2.17.0 → 3.0.0-rc.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +2 -41
  3. package/app.d.ts +1 -0
  4. package/bin/dtwo.mjs +2 -0
  5. package/config.cjs +7 -0
  6. package/config.d.ts +4 -0
  7. package/config.mjs +5 -0
  8. package/dist/app/compat/capi.d.ts +4 -0
  9. package/dist/app/compat/capi.mjs +19 -0
  10. package/dist/app/compat/kdu-demi.d.ts +4 -0
  11. package/dist/app/compat/kdu-demi.mjs +4 -0
  12. package/dist/app/components/client-only.d.mts +22 -0
  13. package/dist/app/components/client-only.mjs +75 -0
  14. package/dist/app/components/dev-only.d.mts +4 -0
  15. package/dist/app/components/dev-only.mjs +11 -0
  16. package/dist/app/components/dtwo-error-boundary.d.ts +8 -0
  17. package/dist/app/components/dtwo-error-boundary.mjs +21 -0
  18. package/dist/app/components/dtwo-error-page.kdu +46 -0
  19. package/dist/app/components/dtwo-link.d.ts +33 -0
  20. package/dist/app/components/dtwo-link.mjs +248 -0
  21. package/dist/app/components/dtwo-loading-indicator.d.ts +43 -0
  22. package/dist/app/components/dtwo-loading-indicator.mjs +107 -0
  23. package/dist/app/components/dtwo-root.kdu +35 -0
  24. package/dist/app/components/index.d.ts +2 -0
  25. package/dist/app/components/index.mjs +1 -0
  26. package/dist/app/components/layout.d.ts +17 -0
  27. package/dist/app/components/layout.mjs +66 -0
  28. package/dist/app/components/server-placeholder.d.ts +2 -0
  29. package/dist/app/components/server-placeholder.mjs +7 -0
  30. package/dist/app/components/utils.d.ts +11 -0
  31. package/dist/app/components/utils.mjs +9 -0
  32. package/dist/app/composables/asyncData.d.ts +40 -0
  33. package/dist/app/composables/asyncData.mjs +169 -0
  34. package/dist/app/composables/component.d.ts +3 -0
  35. package/dist/app/composables/component.mjs +46 -0
  36. package/dist/app/composables/cookie.d.ts +12 -0
  37. package/dist/app/composables/cookie.mjs +58 -0
  38. package/dist/app/composables/error.d.ts +17 -0
  39. package/dist/app/composables/error.mjs +31 -0
  40. package/dist/app/composables/fetch.d.ts +15 -0
  41. package/dist/app/composables/fetch.mjs +66 -0
  42. package/dist/app/composables/hydrate.d.ts +8 -0
  43. package/dist/app/composables/hydrate.mjs +14 -0
  44. package/dist/app/composables/index.d.ts +16 -0
  45. package/dist/app/composables/index.mjs +11 -0
  46. package/dist/app/composables/payload.d.ts +8 -0
  47. package/dist/app/composables/payload.mjs +58 -0
  48. package/dist/app/composables/preload.d.ts +17 -0
  49. package/dist/app/composables/preload.mjs +41 -0
  50. package/dist/app/composables/router.d.ts +28 -0
  51. package/dist/app/composables/router.mjs +111 -0
  52. package/dist/app/composables/ssr.d.ts +6 -0
  53. package/dist/app/composables/ssr.mjs +23 -0
  54. package/dist/app/composables/state.d.ts +9 -0
  55. package/dist/app/composables/state.mjs +27 -0
  56. package/dist/app/config.d.ts +13 -0
  57. package/dist/app/config.mjs +56 -0
  58. package/dist/app/dtwo.d.ts +122 -0
  59. package/dist/app/dtwo.mjs +168 -0
  60. package/dist/app/entry.async.d.ts +2 -0
  61. package/dist/app/entry.async.mjs +5 -0
  62. package/dist/app/entry.d.ts +3 -0
  63. package/dist/app/entry.mjs +59 -0
  64. package/dist/app/index.d.ts +10 -0
  65. package/dist/app/index.mjs +7 -0
  66. package/dist/app/plugins/cross-origin-prefetch.client.d.ts +2 -0
  67. package/dist/app/plugins/cross-origin-prefetch.client.mjs +28 -0
  68. package/dist/app/plugins/debug.d.ts +2 -0
  69. package/dist/app/plugins/debug.mjs +5 -0
  70. package/dist/app/plugins/payload.client.d.ts +2 -0
  71. package/dist/app/plugins/payload.client.mjs +22 -0
  72. package/dist/app/plugins/preload.server.d.ts +2 -0
  73. package/dist/app/plugins/preload.server.mjs +10 -0
  74. package/dist/app/plugins/router.d.ts +53 -0
  75. package/dist/app/plugins/router.mjs +176 -0
  76. package/dist/app/types/augments.d.ts +28 -0
  77. package/dist/core/runtime/hole/error.d.ts +3 -0
  78. package/dist/core/runtime/hole/error.mjs +58 -0
  79. package/dist/core/runtime/hole/paths.d.ts +4 -0
  80. package/dist/core/runtime/hole/paths.mjs +15 -0
  81. package/dist/core/runtime/hole/renderer.d.ts +16 -0
  82. package/dist/core/runtime/hole/renderer.mjs +219 -0
  83. package/dist/head/runtime/components.d.ts +796 -0
  84. package/dist/head/runtime/components.mjs +209 -0
  85. package/dist/head/runtime/composables.d.ts +10 -0
  86. package/dist/head/runtime/composables.mjs +4 -0
  87. package/dist/head/runtime/index.d.ts +4 -0
  88. package/dist/head/runtime/index.mjs +1 -0
  89. package/dist/head/runtime/lib/kdu-meta.plugin.d.ts +2 -0
  90. package/dist/head/runtime/lib/kdu-meta.plugin.mjs +31 -0
  91. package/dist/head/runtime/lib/kduse-head.plugin.d.ts +2 -0
  92. package/dist/head/runtime/lib/kduse-head.plugin.mjs +35 -0
  93. package/dist/head/runtime/types.d.ts +7 -0
  94. package/dist/head/runtime/types.mjs +0 -0
  95. package/dist/index.d.ts +9 -0
  96. package/dist/index.mjs +2274 -0
  97. package/dist/pages/runtime/app.kdu +5 -0
  98. package/dist/pages/runtime/composables.d.ts +42 -0
  99. package/dist/pages/runtime/composables.mjs +8 -0
  100. package/dist/pages/runtime/index.d.ts +1 -0
  101. package/dist/pages/runtime/index.mjs +1 -0
  102. package/dist/pages/runtime/page-placeholder.d.ts +4 -0
  103. package/dist/pages/runtime/page-placeholder.mjs +10 -0
  104. package/dist/pages/runtime/page.d.ts +15 -0
  105. package/dist/pages/runtime/page.mjs +107 -0
  106. package/dist/pages/runtime/router.d.ts +8 -0
  107. package/dist/pages/runtime/router.mjs +152 -0
  108. package/dist/pages/runtime/router.options.d.ts +2 -0
  109. package/dist/pages/runtime/router.options.mjs +51 -0
  110. package/dist/pages/runtime/utils.d.ts +9 -0
  111. package/dist/pages/runtime/utils.mjs +12 -0
  112. package/dist/pages/runtime/validate.d.ts +2 -0
  113. package/dist/pages/runtime/validate.mjs +11 -0
  114. package/package.json +79 -42
  115. package/types.d.ts +15 -0
  116. package/bin/dtwo.js +0 -10
  117. package/dist/dtwo.js +0 -37
  118. package/webpack.config.js +0 -4
@@ -0,0 +1,168 @@
1
+ import { getCurrentInstance, reactive } from "kdu";
2
+ import { createHooks } from "hookable";
3
+ import { getContext } from "unctx";
4
+ const dtwoAppCtx = getContext("dtwo-app");
5
+ export const DtwoPluginIndicator = "__dtwo_plugin";
6
+ export function createDtwoApp(options) {
7
+ let hydratingCount = 0;
8
+ const dtwoApp = {
9
+ provide: void 0,
10
+ globalName: "dtwo",
11
+ payload: reactive({
12
+ data: {},
13
+ state: {},
14
+ _errors: {},
15
+ ...process.client ? window.__DTWO__ : { serverRendered: true }
16
+ }),
17
+ static: {
18
+ data: {}
19
+ },
20
+ isHydrating: process.client,
21
+ deferHydration() {
22
+ if (!dtwoApp.isHydrating) {
23
+ return () => {
24
+ };
25
+ }
26
+ hydratingCount++;
27
+ let called = false;
28
+ return () => {
29
+ if (called) {
30
+ return;
31
+ }
32
+ called = true;
33
+ hydratingCount--;
34
+ if (hydratingCount === 0) {
35
+ dtwoApp.isHydrating = false;
36
+ return dtwoApp.callHook("app:suspense:resolve");
37
+ }
38
+ };
39
+ },
40
+ _asyncDataPromises: {},
41
+ _asyncData: {},
42
+ ...options
43
+ };
44
+ dtwoApp.hooks = createHooks();
45
+ dtwoApp.hook = dtwoApp.hooks.hook;
46
+ dtwoApp.callHook = dtwoApp.hooks.callHook;
47
+ dtwoApp.provide = (name, value) => {
48
+ const $name = "$" + name;
49
+ defineGetter(dtwoApp, $name, value);
50
+ defineGetter(dtwoApp.kduApp.config.globalProperties, $name, value);
51
+ };
52
+ defineGetter(dtwoApp.kduApp, "$dtwo", dtwoApp);
53
+ defineGetter(dtwoApp.kduApp.config.globalProperties, "$dtwo", dtwoApp);
54
+ if (process.server) {
55
+ if (dtwoApp.ssrContext) {
56
+ dtwoApp.ssrContext.dtwo = dtwoApp;
57
+ }
58
+ dtwoApp.ssrContext = dtwoApp.ssrContext || {};
59
+ if (dtwoApp.ssrContext.payload) {
60
+ Object.assign(dtwoApp.payload, dtwoApp.ssrContext.payload);
61
+ }
62
+ dtwoApp.ssrContext.payload = dtwoApp.payload;
63
+ dtwoApp.payload.config = {
64
+ public: options.ssrContext.runtimeConfig.public,
65
+ app: options.ssrContext.runtimeConfig.app
66
+ };
67
+ }
68
+ const runtimeConfig = process.server ? options.ssrContext.runtimeConfig : reactive(dtwoApp.payload.config);
69
+ const compatibilityConfig = new Proxy(runtimeConfig, {
70
+ get(target, prop) {
71
+ if (prop === "public") {
72
+ return target.public;
73
+ }
74
+ return target[prop] ?? target.public[prop];
75
+ },
76
+ set(target, prop, value) {
77
+ if (process.server || prop === "public" || prop === "app") {
78
+ return false;
79
+ }
80
+ target[prop] = value;
81
+ target.public[prop] = value;
82
+ return true;
83
+ }
84
+ });
85
+ dtwoApp.provide("config", compatibilityConfig);
86
+ return dtwoApp;
87
+ }
88
+ export async function applyPlugin(dtwoApp, plugin) {
89
+ if (typeof plugin !== "function") {
90
+ return;
91
+ }
92
+ const { provide } = await callWithDtwo(dtwoApp, plugin, [dtwoApp]) || {};
93
+ if (provide && typeof provide === "object") {
94
+ for (const key in provide) {
95
+ dtwoApp.provide(key, provide[key]);
96
+ }
97
+ }
98
+ }
99
+ export async function applyPlugins(dtwoApp, plugins) {
100
+ for (const plugin of plugins) {
101
+ await applyPlugin(dtwoApp, plugin);
102
+ }
103
+ }
104
+ export function normalizePlugins(_plugins) {
105
+ const unwrappedPlugins = [];
106
+ const legacyInjectPlugins = [];
107
+ const invalidPlugins = [];
108
+ const plugins = _plugins.map((plugin) => {
109
+ if (typeof plugin !== "function") {
110
+ invalidPlugins.push(plugin);
111
+ return null;
112
+ }
113
+ if (plugin.length > 1) {
114
+ legacyInjectPlugins.push(plugin);
115
+ return (dtwoApp) => plugin(dtwoApp, dtwoApp.provide);
116
+ }
117
+ if (!isDtwoPlugin(plugin)) {
118
+ unwrappedPlugins.push(plugin);
119
+ }
120
+ return plugin;
121
+ }).filter(Boolean);
122
+ if (process.dev && legacyInjectPlugins.length) {
123
+ console.warn("[warn] [dtwo] You are using a plugin with legacy Dtwo 2 format (context, inject) which is likely to be broken. In the future they will be ignored:", legacyInjectPlugins.map((p) => p.name || p).join(","));
124
+ }
125
+ if (process.dev && invalidPlugins.length) {
126
+ console.warn("[warn] [dtwo] Some plugins are not exposing a function and skipped:", invalidPlugins);
127
+ }
128
+ if (process.dev && unwrappedPlugins.length) {
129
+ console.warn("[warn] [dtwo] You are using a plugin that has not been wrapped in `defineDtwoPlugin`. It is advised to wrap your plugins as in the future this may enable enhancements:", unwrappedPlugins.map((p) => p.name || p).join(","));
130
+ }
131
+ return plugins;
132
+ }
133
+ export function defineDtwoPlugin(plugin) {
134
+ plugin[DtwoPluginIndicator] = true;
135
+ return plugin;
136
+ }
137
+ export function isDtwoPlugin(plugin) {
138
+ return typeof plugin === "function" && DtwoPluginIndicator in plugin;
139
+ }
140
+ export function callWithDtwo(dtwo, setup, args) {
141
+ const fn = () => args ? setup(...args) : setup();
142
+ if (process.server) {
143
+ return dtwoAppCtx.callAsync(dtwo, fn);
144
+ } else {
145
+ dtwoAppCtx.set(dtwo);
146
+ return fn();
147
+ }
148
+ }
149
+ export function useDtwoApp() {
150
+ const dtwoAppInstance = dtwoAppCtx.tryUse();
151
+ if (!dtwoAppInstance) {
152
+ const vm = getCurrentInstance();
153
+ if (!vm) {
154
+ throw new Error("dtwo instance unavailable");
155
+ }
156
+ return vm.appContext.app.$dtwo;
157
+ }
158
+ return dtwoAppInstance;
159
+ }
160
+ export function useRuntimeConfig() {
161
+ return useDtwoApp().$config;
162
+ }
163
+ function defineGetter(obj, key, val) {
164
+ Object.defineProperty(obj, key, { get: () => val });
165
+ }
166
+ export function defineAppConfig(config) {
167
+ return config;
168
+ }
@@ -0,0 +1,2 @@
1
+ declare const entry: (ctx?: any) => Promise<any>;
2
+ export default entry;
@@ -0,0 +1,5 @@
1
+ const entry = process.server ? (ctx) => import("#app/entry").then((m) => m.default(ctx)) : () => import("#app/entry").then((m) => m.default);
2
+ if (process.client) {
3
+ entry();
4
+ }
5
+ export default entry;
@@ -0,0 +1,3 @@
1
+ import '#build/css';
2
+ declare const _default: (ctx?: any) => any;
3
+ export default _default;
@@ -0,0 +1,59 @@
1
+ import { createSSRApp, createApp, nextTick } from "kdu";
2
+ import { $fetch } from "ofetch";
3
+ import { baseURL } from "#build/paths.mjs";
4
+ import { createDtwoApp, applyPlugins, normalizePlugins } from "#app";
5
+ import "#build/css";
6
+ import _plugins from "#build/plugins";
7
+ import RootComponent from "#build/root-component.mjs";
8
+ import { appRootId } from "#build/dtwo.config.mjs";
9
+ if (!globalThis.$fetch) {
10
+ globalThis.$fetch = $fetch.create({
11
+ baseURL: baseURL()
12
+ });
13
+ }
14
+ let entry;
15
+ const plugins = normalizePlugins(_plugins);
16
+ if (process.server) {
17
+ entry = async function createDtwoAppServer(ssrContext) {
18
+ const kduApp = createApp(RootComponent);
19
+ const dtwo = createDtwoApp({ kduApp, ssrContext });
20
+ try {
21
+ await applyPlugins(dtwo, plugins);
22
+ await dtwo.hooks.callHook("app:created", kduApp);
23
+ } catch (err) {
24
+ await dtwo.callHook("app:error", err);
25
+ dtwo.payload.error = dtwo.payload.error || err;
26
+ }
27
+ return kduApp;
28
+ };
29
+ }
30
+ if (process.client) {
31
+ if (process.dev && import.meta.webpackHot) {
32
+ import.meta.webpackHot.accept();
33
+ }
34
+ entry = async function initApp() {
35
+ const isSSR = Boolean(window.__DTWO__?.serverRendered);
36
+ const kduApp = isSSR ? createSSRApp(RootComponent) : createApp(RootComponent);
37
+ const dtwo = createDtwoApp({ kduApp });
38
+ try {
39
+ await applyPlugins(dtwo, plugins);
40
+ } catch (err) {
41
+ await dtwo.callHook("app:error", err);
42
+ dtwo.payload.error = dtwo.payload.error || err;
43
+ }
44
+ try {
45
+ await dtwo.hooks.callHook("app:created", kduApp);
46
+ await dtwo.hooks.callHook("app:beforeMount", kduApp);
47
+ kduApp.mount("#" + appRootId);
48
+ await dtwo.hooks.callHook("app:mounted", kduApp);
49
+ await nextTick();
50
+ } catch (err) {
51
+ await dtwo.callHook("app:error", err);
52
+ dtwo.payload.error = dtwo.payload.error || err;
53
+ }
54
+ };
55
+ entry().catch((error) => {
56
+ console.error("Error while mounting app:", error);
57
+ });
58
+ }
59
+ export default (ctx) => entry(ctx);
@@ -0,0 +1,10 @@
1
+ /// <reference path="types/augments.d.ts" />
2
+ export * from './dtwo';
3
+ export * from './composables';
4
+ export * from './components';
5
+ export * from './config';
6
+ export type { PageMeta } from '../pages/runtime';
7
+ export type { MetaObject } from '../head/runtime';
8
+ export { useHead } from '#head';
9
+ export declare const isKdu2 = false;
10
+ export declare const isKdu3 = true;
@@ -0,0 +1,7 @@
1
+ export * from "./dtwo.mjs";
2
+ export * from "./composables/index.mjs";
3
+ export * from "./components/index.mjs";
4
+ export * from "./config.mjs";
5
+ export { useHead } from "#head";
6
+ export const isKdu2 = false;
7
+ export const isKdu3 = true;
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,28 @@
1
+ import { ref } from "kdu";
2
+ import { parseURL } from "ufo";
3
+ import { defineDtwoPlugin, useHead } from "#app";
4
+ export default defineDtwoPlugin((dtwoApp) => {
5
+ const externalURLs = ref(/* @__PURE__ */ new Set());
6
+ useHead({
7
+ script: [
8
+ () => ({
9
+ type: "speculationrules",
10
+ innerHTML: JSON.stringify({
11
+ prefetch: [
12
+ {
13
+ source: "list",
14
+ urls: [...externalURLs.value],
15
+ requires: ["anonymous-client-ip-when-cross-origin"]
16
+ }
17
+ ]
18
+ })
19
+ })
20
+ ]
21
+ });
22
+ dtwoApp.hook("link:prefetch", (url) => {
23
+ const { protocol } = parseURL(url);
24
+ if (protocol && ["http:", "https:"].includes(protocol)) {
25
+ externalURLs.value.add(url);
26
+ }
27
+ });
28
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,5 @@
1
+ import { createDebugger } from "hookable";
2
+ import { defineDtwoPlugin } from "#app";
3
+ export default defineDtwoPlugin((dtwoApp) => {
4
+ createDebugger(dtwoApp.hooks, { tag: "dtwo-app" });
5
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,22 @@
1
+ import { parseURL } from "ufo";
2
+ import { defineDtwoPlugin, loadPayload, isPrerendered, useRouter } from "#app";
3
+ export default defineDtwoPlugin((dtwoApp) => {
4
+ if (!isPrerendered()) {
5
+ return;
6
+ }
7
+ dtwoApp.hooks.hook("link:prefetch", (url) => {
8
+ if (!parseURL(url).protocol) {
9
+ return loadPayload(url);
10
+ }
11
+ });
12
+ useRouter().beforeResolve(async (to, from) => {
13
+ if (to.path === from.path) {
14
+ return;
15
+ }
16
+ const payload = await loadPayload(to.path);
17
+ if (!payload) {
18
+ return;
19
+ }
20
+ Object.assign(dtwoApp.static.data, payload.data);
21
+ });
22
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,10 @@
1
+ import { defineDtwoPlugin } from "#app";
2
+ export default defineDtwoPlugin((dtwoApp) => {
3
+ dtwoApp.kduApp.mixin({
4
+ beforeCreate() {
5
+ const { _registeredComponents } = this.$dtwo.ssrContext;
6
+ const { __moduleIdentifier } = this.$options;
7
+ _registeredComponents.add(__moduleIdentifier);
8
+ }
9
+ });
10
+ });
@@ -0,0 +1,53 @@
1
+ interface Route {
2
+ /** Percentage encoded pathname section of the URL. */
3
+ path: string;
4
+ /** The whole location including the `search` and `hash`. */
5
+ fullPath: string;
6
+ /** Object representation of the `search` property of the current location. */
7
+ query: Record<string, any>;
8
+ /** Hash of the current location. If present, starts with a `#`. */
9
+ hash: string;
10
+ /** Name of the matched record */
11
+ name: string | null | undefined;
12
+ /** Object of decoded params extracted from the `path`. */
13
+ params: Record<string, any>;
14
+ /**
15
+ * The location we were initially trying to access before ending up
16
+ * on the current location.
17
+ */
18
+ redirectedFrom: Route | undefined;
19
+ /** Merged `meta` properties from all of the matched route records. */
20
+ meta: Record<string, any>;
21
+ }
22
+ type RouteGuardReturn = void | Error | string | false;
23
+ interface RouterHooks {
24
+ 'resolve:before': (to: Route, from: Route) => RouteGuardReturn | Promise<RouteGuardReturn>;
25
+ 'navigate:before': (to: Route, from: Route) => RouteGuardReturn | Promise<RouteGuardReturn>;
26
+ 'navigate:after': (to: Route, from: Route) => void | Promise<void>;
27
+ 'error': (err: any) => void | Promise<void>;
28
+ }
29
+ interface Router {
30
+ currentRoute: Route;
31
+ isReady: () => Promise<void>;
32
+ options: {};
33
+ install: () => Promise<void>;
34
+ push: (url: string) => Promise<void>;
35
+ replace: (url: string) => Promise<void>;
36
+ back: () => void;
37
+ go: (delta: number) => void;
38
+ forward: () => void;
39
+ beforeResolve: (guard: RouterHooks['resolve:before']) => () => void;
40
+ beforeEach: (guard: RouterHooks['navigate:before']) => () => void;
41
+ afterEach: (guard: RouterHooks['navigate:after']) => () => void;
42
+ onError: (handler: RouterHooks['error']) => () => void;
43
+ resolve: (url: string | Partial<Route>) => Route;
44
+ addRoute: (parentName: string, route: Route) => void;
45
+ getRoutes: () => any[];
46
+ hasRoute: (name: string) => boolean;
47
+ removeRoute: (name: string) => void;
48
+ }
49
+ declare const _default: import("..").Plugin<{
50
+ route: Route;
51
+ router: Router;
52
+ }>;
53
+ export default _default;
@@ -0,0 +1,176 @@
1
+ import { reactive, h } from "kdu";
2
+ import { parseURL, stringifyParsedURL, parseQuery, stringifyQuery, withoutBase, isEqual, joinURL } from "ufo";
3
+ import { createError } from "h3";
4
+ import { defineDtwoPlugin, clearError, navigateTo, showError, useRuntimeConfig, useState } from "../index.mjs";
5
+ import { callWithDtwo } from "../dtwo.mjs";
6
+ import { globalMiddleware } from "#build/middleware";
7
+ function getRouteFromPath(fullPath) {
8
+ if (typeof fullPath === "object") {
9
+ fullPath = stringifyParsedURL({
10
+ pathname: fullPath.path || "",
11
+ search: stringifyQuery(fullPath.query || {}),
12
+ hash: fullPath.hash || ""
13
+ });
14
+ }
15
+ const url = parseURL(fullPath.toString());
16
+ return {
17
+ path: url.pathname,
18
+ fullPath,
19
+ query: parseQuery(url.search),
20
+ hash: url.hash,
21
+ params: {},
22
+ name: void 0,
23
+ matched: [],
24
+ redirectedFrom: void 0,
25
+ meta: {},
26
+ href: fullPath
27
+ };
28
+ }
29
+ export default defineDtwoPlugin((dtwoApp) => {
30
+ const initialURL = process.client ? withoutBase(window.location.pathname, useRuntimeConfig().app.baseURL) + window.location.search + window.location.hash : dtwoApp.ssrContext.url;
31
+ const routes = [];
32
+ const hooks = {
33
+ "navigate:before": [],
34
+ "resolve:before": [],
35
+ "navigate:after": [],
36
+ error: []
37
+ };
38
+ const registerHook = (hook, guard) => {
39
+ hooks[hook].push(guard);
40
+ return () => hooks[hook].splice(hooks[hook].indexOf(guard), 1);
41
+ };
42
+ const baseURL = useRuntimeConfig().app.baseURL;
43
+ const route = reactive(getRouteFromPath(initialURL));
44
+ async function handleNavigation(url, replace) {
45
+ try {
46
+ const to = getRouteFromPath(url);
47
+ for (const middleware of hooks["navigate:before"]) {
48
+ const result = await middleware(to, route);
49
+ if (result === false || result instanceof Error) {
50
+ return;
51
+ }
52
+ if (result) {
53
+ return handleNavigation(result, true);
54
+ }
55
+ }
56
+ for (const handler of hooks["resolve:before"]) {
57
+ await handler(to, route);
58
+ }
59
+ Object.assign(route, to);
60
+ if (process.client) {
61
+ window.history[replace ? "replaceState" : "pushState"]({}, "", joinURL(baseURL, to.fullPath));
62
+ if (!dtwoApp.isHydrating) {
63
+ await callWithDtwo(dtwoApp, clearError);
64
+ }
65
+ }
66
+ for (const middleware of hooks["navigate:after"]) {
67
+ await middleware(to, route);
68
+ }
69
+ } catch (err) {
70
+ if (process.dev && !hooks.error.length) {
71
+ console.warn("No error handlers registered to handle middleware errors. You can register an error handler with `router.onError()`", err);
72
+ }
73
+ for (const handler of hooks.error) {
74
+ await handler(err);
75
+ }
76
+ }
77
+ }
78
+ const router = {
79
+ currentRoute: route,
80
+ isReady: () => Promise.resolve(),
81
+ options: {},
82
+ install: () => Promise.resolve(),
83
+ push: (url) => handleNavigation(url, false),
84
+ replace: (url) => handleNavigation(url, true),
85
+ back: () => window.history.go(-1),
86
+ go: (delta) => window.history.go(delta),
87
+ forward: () => window.history.go(1),
88
+ beforeResolve: (guard) => registerHook("resolve:before", guard),
89
+ beforeEach: (guard) => registerHook("navigate:before", guard),
90
+ afterEach: (guard) => registerHook("navigate:after", guard),
91
+ onError: (handler) => registerHook("error", handler),
92
+ resolve: getRouteFromPath,
93
+ addRoute: (parentName, route2) => {
94
+ routes.push(route2);
95
+ },
96
+ getRoutes: () => routes,
97
+ hasRoute: (name) => routes.some((route2) => route2.name === name),
98
+ removeRoute: (name) => {
99
+ const index = routes.findIndex((route2) => route2.name === name);
100
+ if (index !== -1) {
101
+ routes.splice(index, 1);
102
+ }
103
+ }
104
+ };
105
+ dtwoApp.kduApp.component("RouterLink", {
106
+ functional: true,
107
+ props: {
108
+ to: String,
109
+ custom: Boolean,
110
+ replace: Boolean,
111
+ activeClass: String,
112
+ exactActiveClass: String,
113
+ ariaCurrentValue: String
114
+ },
115
+ setup: (props, { slots }) => {
116
+ const navigate = () => handleNavigation(props.to, props.replace);
117
+ return () => {
118
+ const route2 = router.resolve(props.to);
119
+ return props.custom ? slots.default?.({ href: props.to, navigate, route: route2 }) : h("a", { href: props.to, onClick: (e) => {
120
+ e.preventDefault();
121
+ return navigate();
122
+ } }, slots);
123
+ };
124
+ }
125
+ });
126
+ if (process.client) {
127
+ window.addEventListener("popstate", (event) => {
128
+ const location = event.target.location;
129
+ router.replace(location.href.replace(location.origin, ""));
130
+ });
131
+ }
132
+ dtwoApp._route = route;
133
+ dtwoApp._middleware = dtwoApp._middleware || {
134
+ global: [],
135
+ named: {}
136
+ };
137
+ const initialLayout = useState("_layout");
138
+ dtwoApp.hooks.hookOnce("app:created", async () => {
139
+ router.beforeEach(async (to, from) => {
140
+ to.meta = reactive(to.meta || {});
141
+ if (dtwoApp.isHydrating) {
142
+ to.meta.layout = initialLayout.value ?? to.meta.layout;
143
+ }
144
+ dtwoApp._processingMiddleware = true;
145
+ const middlewareEntries = /* @__PURE__ */ new Set([...globalMiddleware, ...dtwoApp._middleware.global]);
146
+ for (const middleware of middlewareEntries) {
147
+ const result = await callWithDtwo(dtwoApp, middleware, [to, from]);
148
+ if (process.server) {
149
+ if (result === false || result instanceof Error) {
150
+ const error = result || createError({
151
+ statusCode: 404,
152
+ statusMessage: `Page Not Found: ${initialURL}`
153
+ });
154
+ return callWithDtwo(dtwoApp, showError, [error]);
155
+ }
156
+ }
157
+ if (result || result === false) {
158
+ return result;
159
+ }
160
+ }
161
+ });
162
+ router.afterEach(() => {
163
+ delete dtwoApp._processingMiddleware;
164
+ });
165
+ await router.replace(initialURL);
166
+ if (!isEqual(route.fullPath, initialURL)) {
167
+ await callWithDtwo(dtwoApp, navigateTo, [route.fullPath]);
168
+ }
169
+ });
170
+ return {
171
+ provide: {
172
+ route,
173
+ router
174
+ }
175
+ };
176
+ });
@@ -0,0 +1,28 @@
1
+ import { DtwoApp } from '../dtwo'
2
+
3
+ declare global {
4
+ namespace NodeJS {
5
+ interface Process {
6
+ browser: boolean
7
+ client: boolean
8
+ dev: boolean
9
+ mode: 'spa' | 'universal'
10
+ server: boolean
11
+ static: boolean
12
+ }
13
+ }
14
+
15
+ interface Window {
16
+ __DTWO__?: Record<string, any>
17
+ }
18
+ }
19
+
20
+ declare module '@kdujs/runtime-core' {
21
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
22
+ interface App<HostElement> {
23
+ $dtwo: DtwoApp
24
+ }
25
+ interface ComponentInternalInstance {
26
+ _dtwoOnBeforeMountCbs: Function[]
27
+ }
28
+ }
@@ -0,0 +1,3 @@
1
+ import type { HoleErrorHandler } from 'holepack';
2
+ declare const _default: HoleErrorHandler;
3
+ export default _default;
@@ -0,0 +1,58 @@
1
+ import { joinURL, withQuery } from "ufo";
2
+ import { setResponseHeader, getRequestHeaders } from "h3";
3
+ import { useHoleApp, useRuntimeConfig } from "#internal/hole";
4
+ import { normalizeError, isJsonRequest } from "#internal/hole/utils";
5
+ export default (async function errorhandler(error, event) {
6
+ const { stack, statusCode, statusMessage, message } = normalizeError(error);
7
+ const errorObject = {
8
+ url: event.node.req.url,
9
+ statusCode,
10
+ statusMessage,
11
+ message,
12
+ stack: process.dev && statusCode !== 404 ? `<pre>${stack.map((i) => `<span class="stack${i.internal ? " internal" : ""}">${i.text}</span>`).join("\n")}</pre>` : "",
13
+ data: error.data
14
+ };
15
+ event.node.res.statusCode = errorObject.statusCode !== 200 && errorObject.statusCode || 500;
16
+ if (errorObject.statusMessage) {
17
+ event.node.res.statusMessage = errorObject.statusMessage;
18
+ }
19
+ if (error.unhandled || error.fatal) {
20
+ const tags = [
21
+ "[dtwo]",
22
+ "[request error]",
23
+ error.unhandled && "[unhandled]",
24
+ error.fatal && "[fatal]",
25
+ Number(errorObject.statusCode) !== 200 && `[${errorObject.statusCode}]`
26
+ ].filter(Boolean).join(" ");
27
+ console.error(tags, errorObject.message + "\n" + stack.map((l) => " " + l.text).join(" \n"));
28
+ }
29
+ if (isJsonRequest(event)) {
30
+ event.node.res.setHeader("Content-Type", "application/json");
31
+ event.node.res.end(JSON.stringify(errorObject));
32
+ return;
33
+ }
34
+ const isErrorPage = event.node.req.url?.startsWith("/__dtwo_error");
35
+ const res = !isErrorPage ? await useHoleApp().localFetch(withQuery(joinURL(useRuntimeConfig().app.baseURL, "/__dtwo_error"), errorObject), {
36
+ headers: getRequestHeaders(event),
37
+ redirect: "manual"
38
+ }).catch(() => null) : null;
39
+ if (!res) {
40
+ const { template } = process.dev ? await import("@dtwo/ui-templates/templates/error-dev.mjs") : await import("@dtwo/ui-templates/templates/error-500.mjs");
41
+ if (process.dev) {
42
+ errorObject.description = errorObject.message;
43
+ }
44
+ event.node.res.setHeader("Content-Type", "text/html;charset=UTF-8");
45
+ event.node.res.end(template(errorObject));
46
+ return;
47
+ }
48
+ for (const [header, value] of res.headers.entries()) {
49
+ setResponseHeader(event, header, value);
50
+ }
51
+ if (res.status && res.status !== 200) {
52
+ event.node.res.statusCode = res.status;
53
+ }
54
+ if (res.statusText) {
55
+ event.node.res.statusMessage = res.statusText;
56
+ }
57
+ event.node.res.end(await res.text());
58
+ });
@@ -0,0 +1,4 @@
1
+ export declare function baseURL(): string;
2
+ export declare function buildAssetsDir(): string;
3
+ export declare function buildAssetsURL(...path: string[]): string;
4
+ export declare function publicAssetsURL(...path: string[]): string;