@monkeyplus/flow 6.0.6 → 6.0.8

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 (57) hide show
  1. package/modules/content/module.mjs +17 -2
  2. package/modules/content/query.d.ts +25 -0
  3. package/modules/content/query.mjs +105 -19
  4. package/modules/content/runtime/client.d.ts +2 -0
  5. package/modules/content/runtime/client.mjs +1 -0
  6. package/modules/images/ipx.d.ts +2 -0
  7. package/modules/images/ipx.mjs +55 -0
  8. package/modules/images/module.d.ts +4 -0
  9. package/modules/images/module.mjs +146 -0
  10. package/modules/images/runtime/build.d.ts +6 -0
  11. package/modules/images/runtime/build.mjs +174 -0
  12. package/modules/images/runtime/helpers.d.ts +16 -0
  13. package/modules/images/runtime/helpers.mjs +45 -0
  14. package/modules/images/runtime/image.d.ts +7 -0
  15. package/modules/images/runtime/image.mjs +252 -0
  16. package/modules/images/runtime/renames.d.ts +2 -0
  17. package/modules/images/runtime/renames.mjs +79 -0
  18. package/modules/images/runtime/server.d.ts +3 -0
  19. package/modules/images/runtime/server.mjs +80 -0
  20. package/modules/images/runtime/types.d.ts +79 -0
  21. package/modules/images/runtime/types.mjs +0 -0
  22. package/modules/sitemap/handler.mjs +6 -7
  23. package/modules/sitemap/module.mjs +236 -22
  24. package/modules/sitemap/xml.d.ts +7 -0
  25. package/modules/sitemap/xml.mjs +87 -0
  26. package/package.json +7 -1
  27. package/server/lib/pages.mjs +20 -21
  28. package/server/lib/render.mjs +16 -0
  29. package/server/renderer.d.ts +1 -1
  30. package/server/renderer.mjs +2 -1
  31. package/src/public/components.d.ts +3 -0
  32. package/src/public/components.mjs +3 -0
  33. package/src/public/index.d.ts +5 -3
  34. package/src/public/index.mjs +1 -0
  35. package/src/public/modules/images.d.ts +2 -0
  36. package/src/public/modules/images.mjs +1 -0
  37. package/src/public/nitro.mjs +4 -1
  38. package/src/public/query-content.d.ts +7 -0
  39. package/src/public/query-content.mjs +130 -0
  40. package/src/public/vite.mjs +18 -2
  41. package/src/runtime/components/MkImage.d.ts +188 -0
  42. package/src/runtime/components/MkImage.mjs +131 -0
  43. package/src/runtime/components/MkLink.d.ts +22 -0
  44. package/src/runtime/components/MkLink.mjs +72 -0
  45. package/src/runtime/components/MkPicture.d.ts +199 -0
  46. package/src/runtime/components/MkPicture.mjs +172 -0
  47. package/src/runtime/components/image-shared.d.ts +28 -0
  48. package/src/runtime/components/image-shared.mjs +68 -0
  49. package/src/runtime/config.d.ts +22 -0
  50. package/src/runtime/config.mjs +5 -2
  51. package/src/runtime/locale-routing.d.ts +12 -0
  52. package/src/runtime/locale-routing.mjs +93 -0
  53. package/src/runtime/modules.mjs +1 -0
  54. package/src/runtime/page-discovery.mjs +8 -15
  55. package/src/runtime/pages.d.ts +16 -0
  56. package/src/runtime/virtual.d.ts +17 -0
  57. package/src/runtime/vue.mjs +6 -0
@@ -1,5 +1,7 @@
1
+ export type { ContentDirectoryNode, ContentEntry, ContentFileNode, ContentTreeNode, } from '../../modules/content/query.ts';
2
+ export type { FlowBootPayload } from '../runtime/boot.ts';
1
3
  export { defineFlowConfig, defineFlowModule, resolveFlowConfig } from '../runtime/config.ts';
4
+ export type { FlowConfig, UserFlowConfig, } from '../runtime/config.ts';
2
5
  export { definePage } from '../runtime/pages.ts';
3
- export type { FlowConfig, FlowLocale, HeadDefinition, PageContextInput, UserFlowConfig, } from '../runtime/config.ts';
4
- export type { FlowBootPayload } from '../runtime/boot.ts';
5
- export type { FlowHydrationMode, PageDefinition, PageLocaleDefinition, PageViewDefinition, } from '../runtime/pages.ts';
6
+ export type { FlowHydrationMode, FlowLocale, HeadDefinition, PageContextInput, PageDefinition, PageLocaleDefinition, PageViewDefinition, } from '../runtime/pages.ts';
7
+ export { queryContent } from './query-content.ts';
@@ -1,2 +1,3 @@
1
1
  export { defineFlowConfig, defineFlowModule, resolveFlowConfig } from "../runtime/config.mjs";
2
2
  export { definePage } from "../runtime/pages.mjs";
3
+ export { queryContent } from "./query-content.mjs";
@@ -0,0 +1,2 @@
1
+ export { default } from '../../../modules/images/module.ts';
2
+ export type { ImagesModuleOptions } from '../../../modules/images/module.ts';
@@ -0,0 +1 @@
1
+ export { default } from "../../../modules/images/module.mjs";
@@ -16,7 +16,10 @@ export function createFlowNitroConfig(options = {}) {
16
16
  const flowConfig = resolveFlowConfig(options.userFlowConfig || {});
17
17
  const flowModules = loadFlowModules(projectRoot, flowConfig);
18
18
  const flowNitroConfig = { ...flowConfig.nitro || {} };
19
- const flowNitroHooks = flowNitroConfig.hooks || {};
19
+ const flowNitroHooks = {
20
+ ...flowNitroConfig.hooks || {},
21
+ ...flowModules.nitro.hooks
22
+ };
20
23
  const configuredNoExternals = Array.isArray(flowNitroConfig.noExternals) ? flowNitroConfig.noExternals : [];
21
24
  const flowPackagePattern = /^@monkeyplus\/flow(?:\/.*)?$/;
22
25
  const flowRuntimeConfig = typeof flowModules.nitro.runtimeConfig.flow === "object" && flowModules.nitro.runtimeConfig.flow ? flowModules.nitro.runtimeConfig.flow : {};
@@ -0,0 +1,7 @@
1
+ import type { ContentEntry, ContentTreeNode } from '../../modules/content/query.ts';
2
+ export interface QueryContentBuilder {
3
+ find: () => Promise<ContentEntry[]>;
4
+ findOne: () => Promise<ContentEntry | null>;
5
+ tree: () => Promise<ContentTreeNode[]>;
6
+ }
7
+ export declare function queryContent(path?: string): QueryContentBuilder;
@@ -0,0 +1,130 @@
1
+ const defaultContentConfig = {
2
+ apiBase: "/api/_content"
3
+ };
4
+ function getGlobalFetch() {
5
+ const candidate = globalThis.$fetch;
6
+ return typeof candidate === "function" ? candidate : void 0;
7
+ }
8
+ function withLeadingSlash(value) {
9
+ return value.startsWith("/") ? value : `/${value}`;
10
+ }
11
+ function withoutTrailingSlash(value) {
12
+ return value.endsWith("/") ? value.slice(0, -1) : value;
13
+ }
14
+ function normalizeQueryPath(path = "") {
15
+ if (!path) {
16
+ return "/";
17
+ }
18
+ const normalized = `/${path}`.replace(/\/+/g, "/");
19
+ return normalized.length > 1 && normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
20
+ }
21
+ function joinUrl(base, path = "") {
22
+ const normalizedBase = withoutTrailingSlash(base);
23
+ const normalizedPath = path ? withLeadingSlash(path) : "";
24
+ return `${normalizedBase}${normalizedPath}`;
25
+ }
26
+ function withQuery(url, params) {
27
+ if (!params || Object.keys(params).length === 0) {
28
+ return url;
29
+ }
30
+ const origin = typeof window !== "undefined" ? window.location.origin : "http://localhost:3000";
31
+ const target = new URL(url, origin);
32
+ Object.entries(params).forEach(([key, value]) => {
33
+ if (value == null || value === "") {
34
+ return;
35
+ }
36
+ target.searchParams.set(key, String(value));
37
+ });
38
+ return target.toString();
39
+ }
40
+ async function getRuntimeConfig() {
41
+ if (typeof window !== "undefined") {
42
+ return void 0;
43
+ }
44
+ try {
45
+ const loadRuntimeModule = new Function("specifier", "return import(specifier);");
46
+ const runtime = await loadRuntimeModule("nitro/runtime-config");
47
+ return typeof runtime.useRuntimeConfig === "function" ? runtime.useRuntimeConfig() : void 0;
48
+ } catch {
49
+ return void 0;
50
+ }
51
+ }
52
+ async function getNitroFetch() {
53
+ if (typeof window !== "undefined") {
54
+ return void 0;
55
+ }
56
+ try {
57
+ const loadNitroModule = new Function("specifier", "return import(specifier);");
58
+ const runtime = await loadNitroModule("nitro/app");
59
+ return typeof runtime.fetch === "function" ? runtime.fetch : void 0;
60
+ } catch {
61
+ return void 0;
62
+ }
63
+ }
64
+ async function resolveContentApiBase() {
65
+ const runtimeConfig = await getRuntimeConfig();
66
+ return runtimeConfig?.flow?.content?.apiBase || runtimeConfig?.public?.flow?.content?.apiBase || defaultContentConfig.apiBase;
67
+ }
68
+ async function resolveAbsoluteContentApiBase() {
69
+ const runtimeConfig = await getRuntimeConfig();
70
+ const apiBase = await resolveContentApiBase();
71
+ if (typeof window !== "undefined") {
72
+ return apiBase;
73
+ }
74
+ if (runtimeConfig?.flow?.siteUrl) {
75
+ return joinUrl(runtimeConfig.flow.siteUrl, apiBase);
76
+ }
77
+ return joinUrl("http://localhost:3000", apiBase);
78
+ }
79
+ async function fetchContent(route, path) {
80
+ const apiBase = await resolveContentApiBase();
81
+ const query = path && path !== "/" ? { path } : void 0;
82
+ const localFetch = getGlobalFetch();
83
+ const nitroFetch = await getNitroFetch();
84
+ if (typeof window === "undefined" && localFetch) {
85
+ console.debug(`[Flow Content] Fetching content from ${joinUrl(apiBase, route)} using global fetch`);
86
+ return await localFetch(joinUrl(apiBase, route), {
87
+ headers: {
88
+ accept: "application/json"
89
+ },
90
+ query
91
+ });
92
+ }
93
+ if (typeof window === "undefined" && nitroFetch) {
94
+ console.debug(`[Flow Content] Fetching content from ${joinUrl(apiBase, route)} using Nitro fetch`);
95
+ return await nitroFetch(joinUrl(apiBase, route), {
96
+ headers: {
97
+ accept: "application/json"
98
+ },
99
+ query
100
+ });
101
+ }
102
+ const absoluteBase = await resolveAbsoluteContentApiBase();
103
+ const target = withQuery(joinUrl(absoluteBase, route), query);
104
+ console.debug(`[Flow Content] Fetching content from ${target}`);
105
+ const response = await fetch(target, {
106
+ headers: {
107
+ accept: "application/json"
108
+ }
109
+ });
110
+ if (!response.ok) {
111
+ const details = await response.text();
112
+ throw new Error(`Content request failed (${response.status} ${response.statusText}): ${details}`);
113
+ }
114
+ return await response.json();
115
+ }
116
+ export function queryContent(path = "") {
117
+ const normalizedPath = normalizeQueryPath(path);
118
+ return {
119
+ async find() {
120
+ return await fetchContent("query", normalizedPath);
121
+ },
122
+ async findOne() {
123
+ const entries = await this.find();
124
+ return entries[0] || null;
125
+ },
126
+ async tree() {
127
+ return await fetchContent("tree", normalizedPath);
128
+ }
129
+ };
130
+ }
@@ -210,6 +210,10 @@ export function createFlowViteConfig(options = {}) {
210
210
  const flowNitroHooks = flowNitroConfig.hooks || {};
211
211
  const flowPackagePattern = /^@monkeyplus\/flow(?:\/.*)?$/;
212
212
  const userPrerenderRoutesHook = typeof flowNitroHooks["prerender:routes"] === "function" ? flowNitroHooks["prerender:routes"] : void 0;
213
+ const configuredServer = flowConfig.server || {};
214
+ const moduleServer = flowModules.vite.server || { watch: { additionalPaths: [] } };
215
+ const configuredWatch = typeof configuredServer.watch === "object" && configuredServer.watch ? configuredServer.watch : {};
216
+ const moduleWatch = typeof moduleServer.watch === "object" && moduleServer.watch ? moduleServer.watch : {};
213
217
  return defineConfig({
214
218
  plugins: [
215
219
  createFlowVirtualServerModules(projectRoot, flowConfig),
@@ -224,10 +228,14 @@ export function createFlowViteConfig(options = {}) {
224
228
  ui({
225
229
  router: false,
226
230
  components: {
231
+ ...options.userFlowConfig?.components,
227
232
  resolvers: [
228
- IconsResolver()
233
+ IconsResolver(),
234
+ ...options.userFlowConfig?.components?.resolvers || []
229
235
  ]
230
- }
236
+ // dirs: [],
237
+ },
238
+ autoImport: options.userFlowConfig?.autoImport
231
239
  }),
232
240
  nitro({
233
241
  ...flowNitroConfig,
@@ -270,6 +278,14 @@ export function createFlowViteConfig(options = {}) {
270
278
  ...flowModules.vite.resolve.alias
271
279
  }
272
280
  },
281
+ server: {
282
+ ...configuredServer,
283
+ ...moduleServer,
284
+ watch: {
285
+ ...configuredWatch,
286
+ ...moduleWatch
287
+ }
288
+ },
273
289
  ssr: {
274
290
  noExternal: [flowPackagePattern]
275
291
  }
@@ -0,0 +1,188 @@
1
+ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
2
+ src: {
3
+ type: StringConstructor;
4
+ required: true;
5
+ };
6
+ rename: StringConstructor;
7
+ eWidth: (StringConstructor | NumberConstructor)[];
8
+ eHeight: (StringConstructor | NumberConstructor)[];
9
+ sync: BooleanConstructor;
10
+ thumb: (StringConstructor | BooleanConstructor)[];
11
+ thumbnail: {
12
+ type: (StringConstructor | BooleanConstructor)[];
13
+ default: undefined;
14
+ };
15
+ format: {
16
+ type: StringConstructor;
17
+ default: undefined;
18
+ };
19
+ quality: {
20
+ type: (StringConstructor | NumberConstructor)[];
21
+ default: undefined;
22
+ };
23
+ background: {
24
+ type: StringConstructor;
25
+ default: undefined;
26
+ };
27
+ fit: {
28
+ type: StringConstructor;
29
+ default: undefined;
30
+ };
31
+ modifiers: {
32
+ type: () => Record<string, any>;
33
+ default: undefined;
34
+ };
35
+ preset: {
36
+ type: StringConstructor;
37
+ default: undefined;
38
+ };
39
+ provider: {
40
+ type: StringConstructor;
41
+ default: undefined;
42
+ };
43
+ sizes: {
44
+ type: () => string | Record<string, any>;
45
+ default: undefined;
46
+ };
47
+ width: {
48
+ type: (StringConstructor | NumberConstructor)[];
49
+ default: undefined;
50
+ };
51
+ height: {
52
+ type: (StringConstructor | NumberConstructor)[];
53
+ default: undefined;
54
+ };
55
+ alt: {
56
+ type: StringConstructor;
57
+ default: undefined;
58
+ };
59
+ title: {
60
+ type: StringConstructor;
61
+ default: undefined;
62
+ };
63
+ referrerpolicy: {
64
+ type: StringConstructor;
65
+ default: undefined;
66
+ };
67
+ usemap: {
68
+ type: StringConstructor;
69
+ default: undefined;
70
+ };
71
+ longdesc: {
72
+ type: StringConstructor;
73
+ default: undefined;
74
+ };
75
+ ismap: {
76
+ type: BooleanConstructor;
77
+ default: undefined;
78
+ };
79
+ loading: {
80
+ type: StringConstructor;
81
+ default: undefined;
82
+ };
83
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
84
+ [key: string]: any;
85
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
86
+ src: {
87
+ type: StringConstructor;
88
+ required: true;
89
+ };
90
+ rename: StringConstructor;
91
+ eWidth: (StringConstructor | NumberConstructor)[];
92
+ eHeight: (StringConstructor | NumberConstructor)[];
93
+ sync: BooleanConstructor;
94
+ thumb: (StringConstructor | BooleanConstructor)[];
95
+ thumbnail: {
96
+ type: (StringConstructor | BooleanConstructor)[];
97
+ default: undefined;
98
+ };
99
+ format: {
100
+ type: StringConstructor;
101
+ default: undefined;
102
+ };
103
+ quality: {
104
+ type: (StringConstructor | NumberConstructor)[];
105
+ default: undefined;
106
+ };
107
+ background: {
108
+ type: StringConstructor;
109
+ default: undefined;
110
+ };
111
+ fit: {
112
+ type: StringConstructor;
113
+ default: undefined;
114
+ };
115
+ modifiers: {
116
+ type: () => Record<string, any>;
117
+ default: undefined;
118
+ };
119
+ preset: {
120
+ type: StringConstructor;
121
+ default: undefined;
122
+ };
123
+ provider: {
124
+ type: StringConstructor;
125
+ default: undefined;
126
+ };
127
+ sizes: {
128
+ type: () => string | Record<string, any>;
129
+ default: undefined;
130
+ };
131
+ width: {
132
+ type: (StringConstructor | NumberConstructor)[];
133
+ default: undefined;
134
+ };
135
+ height: {
136
+ type: (StringConstructor | NumberConstructor)[];
137
+ default: undefined;
138
+ };
139
+ alt: {
140
+ type: StringConstructor;
141
+ default: undefined;
142
+ };
143
+ title: {
144
+ type: StringConstructor;
145
+ default: undefined;
146
+ };
147
+ referrerpolicy: {
148
+ type: StringConstructor;
149
+ default: undefined;
150
+ };
151
+ usemap: {
152
+ type: StringConstructor;
153
+ default: undefined;
154
+ };
155
+ longdesc: {
156
+ type: StringConstructor;
157
+ default: undefined;
158
+ };
159
+ ismap: {
160
+ type: BooleanConstructor;
161
+ default: undefined;
162
+ };
163
+ loading: {
164
+ type: StringConstructor;
165
+ default: undefined;
166
+ };
167
+ }>> & Readonly<{}>, {
168
+ width: string | number;
169
+ height: string | number;
170
+ fit: string;
171
+ format: string;
172
+ provider: string;
173
+ preset: string;
174
+ modifiers: Record<string, any>;
175
+ sizes: string | Record<string, any>;
176
+ alt: string;
177
+ referrerpolicy: string;
178
+ usemap: string;
179
+ longdesc: string;
180
+ ismap: boolean;
181
+ loading: string;
182
+ quality: string | number;
183
+ background: string;
184
+ title: string;
185
+ sync: boolean;
186
+ thumbnail: string | boolean;
187
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
188
+ export default _default;
@@ -0,0 +1,131 @@
1
+ import { computed, defineComponent, h } from "vue";
2
+ import { parseSize } from "../../../modules/images/runtime/helpers.mjs";
3
+ import { useImage, useLazySizes } from "./image-shared.mjs";
4
+ function resolveImageSource(value, fallback) {
5
+ if (typeof value === "string" && value.length) {
6
+ return value;
7
+ }
8
+ if (value && typeof value === "object" && typeof value.url === "string") {
9
+ return value.url;
10
+ }
11
+ return fallback;
12
+ }
13
+ function getLocalSource(src) {
14
+ return src.startsWith("http") ? "" : src;
15
+ }
16
+ function isRuntimeLambda() {
17
+ const runtimeProcess = typeof globalThis === "object" ? Reflect.get(globalThis, "process") : void 0;
18
+ return !!(runtimeProcess?.env?.LAMBDA_TASK_ROOT || runtimeProcess?.env?.AWS_LAMBDA_FUNCTION_VERSION);
19
+ }
20
+ function resolveThumbnailValue(value, fallback) {
21
+ return value !== void 0 ? value : fallback;
22
+ }
23
+ export default defineComponent({
24
+ name: "MkImage",
25
+ inheritAttrs: false,
26
+ props: {
27
+ src: {
28
+ type: String,
29
+ required: true
30
+ },
31
+ rename: String,
32
+ eWidth: [String, Number],
33
+ eHeight: [String, Number],
34
+ sync: Boolean,
35
+ thumb: [Boolean, String],
36
+ thumbnail: { type: [Boolean, String], default: void 0 },
37
+ format: { type: String, default: void 0 },
38
+ quality: { type: [Number, String], default: void 0 },
39
+ background: { type: String, default: void 0 },
40
+ fit: { type: String, default: void 0 },
41
+ modifiers: {
42
+ type: Object,
43
+ default: void 0
44
+ },
45
+ preset: { type: String, default: void 0 },
46
+ provider: { type: String, default: void 0 },
47
+ sizes: {
48
+ type: [Object, String],
49
+ default: void 0
50
+ },
51
+ width: { type: [String, Number], default: void 0 },
52
+ height: { type: [String, Number], default: void 0 },
53
+ alt: { type: String, default: void 0 },
54
+ title: { type: String, default: void 0 },
55
+ referrerpolicy: { type: String, default: void 0 },
56
+ usemap: { type: String, default: void 0 },
57
+ longdesc: { type: String, default: void 0 },
58
+ ismap: { type: Boolean, default: void 0 },
59
+ loading: { type: String, default: void 0 }
60
+ },
61
+ setup(props, { attrs }) {
62
+ const { imageUtils, image, nImgAttrs, nModifiers, nOption } = useImage(props);
63
+ const options = computed(() => imageUtils.getImageOptions?.() || {
64
+ lazy: true,
65
+ screens: {},
66
+ domains: {},
67
+ presets: {},
68
+ baseURL: "/_ipx",
69
+ dirImages: "/images"
70
+ });
71
+ const nSizes = computed(() => {
72
+ if (!props.sizes || !imageUtils.getImage?.getSizes) {
73
+ return void 0;
74
+ }
75
+ return imageUtils.getImage.getSizes(props.src, {
76
+ ...nOption.value,
77
+ sizes: props.sizes,
78
+ modifiers: {
79
+ ...nModifiers.value,
80
+ width: parseSize(props.width),
81
+ height: parseSize(props.height)
82
+ }
83
+ });
84
+ });
85
+ const nAttrs = computed(() => {
86
+ const resolvedAttrs = {
87
+ ...nImgAttrs.value
88
+ };
89
+ if (nSizes.value) {
90
+ resolvedAttrs.sizes = nSizes.value.sizes;
91
+ resolvedAttrs.srcset = nSizes.value.srcset;
92
+ }
93
+ if (options.value.lazy && !props.sync && !resolvedAttrs.loading) {
94
+ resolvedAttrs.loading = "lazy";
95
+ }
96
+ return resolvedAttrs;
97
+ });
98
+ const nSrc = computed(() => {
99
+ const normal = nSizes.value?.src || resolveImageSource(
100
+ imageUtils.getImage?.(props.src, nModifiers.value, nOption.value),
101
+ props.src
102
+ );
103
+ const thumb = resolveThumbnailValue(props.thumbnail, props.thumb);
104
+ const thumbnail = typeof thumb === "string" ? thumb : thumb ? resolveImageSource(
105
+ imageUtils.getImage?.(props.src, { quality: 10, width: 60 }, nOption.value),
106
+ props.src
107
+ ) : void 0;
108
+ return {
109
+ normal,
110
+ thumbnail
111
+ };
112
+ });
113
+ useLazySizes(() => !isRuntimeLambda() && !!nSrc.value.thumbnail);
114
+ return () => {
115
+ const compatibilityThumb = !isRuntimeLambda() && nSrc.value.thumbnail;
116
+ return h("img", {
117
+ ...attrs,
118
+ ...nAttrs.value,
119
+ "src": isRuntimeLambda() ? props.src : compatibilityThumb || nSrc.value.normal,
120
+ "data-src": compatibilityThumb ? nSrc.value.normal : void 0,
121
+ "data-thumb": compatibilityThumb,
122
+ "alt": props.alt || image.value.alt,
123
+ "title": props.title || image.value.title,
124
+ "class": compatibilityThumb ? [attrs.class, "lazyload"] : attrs.class,
125
+ "width": props.eWidth || nAttrs.value.width,
126
+ "height": props.eHeight || nAttrs.value.height,
127
+ "x-src": getLocalSource(props.src)
128
+ });
129
+ };
130
+ }
131
+ });
@@ -0,0 +1,22 @@
1
+ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
2
+ isSlot: BooleanConstructor;
3
+ to: {
4
+ type: StringConstructor;
5
+ required: true;
6
+ };
7
+ locale: StringConstructor;
8
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
9
+ [key: string]: any;
10
+ }> | import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
11
+ [key: string]: any;
12
+ }>[] | null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
13
+ isSlot: BooleanConstructor;
14
+ to: {
15
+ type: StringConstructor;
16
+ required: true;
17
+ };
18
+ locale: StringConstructor;
19
+ }>> & Readonly<{}>, {
20
+ isSlot: boolean;
21
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
22
+ export default _default;
@@ -0,0 +1,72 @@
1
+ import { defineComponent, h, inject, onServerPrefetch, ref, watch } from "vue";
2
+ const flowUtilsKey = "utils";
3
+ function isExternalTarget(value) {
4
+ return /^(?:[a-z][a-z\d+.-]*:|#|\/\/)/i.test(value);
5
+ }
6
+ function normalizeNamedTarget(value, localeCode, lang, loc) {
7
+ if (!value.startsWith("/")) {
8
+ return value;
9
+ }
10
+ const variants = [
11
+ localeCode ? `/${localeCode}/` : void 0,
12
+ lang && loc ? `/${lang}-${loc}/` : void 0,
13
+ lang && loc ? `/${lang}/${loc}/` : void 0,
14
+ lang ? `/${lang}/` : void 0
15
+ ].filter((candidate) => Boolean(candidate));
16
+ for (const prefix of variants) {
17
+ if (value.startsWith(prefix)) {
18
+ return value.slice(prefix.length);
19
+ }
20
+ }
21
+ return value;
22
+ }
23
+ export default defineComponent({
24
+ name: "MkLink",
25
+ props: {
26
+ isSlot: Boolean,
27
+ to: {
28
+ type: String,
29
+ required: true
30
+ },
31
+ locale: String
32
+ },
33
+ setup(props, { slots }) {
34
+ const utils = inject(flowUtilsKey, void 0);
35
+ const href = ref(props.to);
36
+ const isClient = typeof window !== "undefined";
37
+ const updateHref = async () => {
38
+ if (!utils) {
39
+ href.value = props.to;
40
+ return;
41
+ }
42
+ if (isExternalTarget(props.to)) {
43
+ href.value = props.to;
44
+ return;
45
+ }
46
+ const currentLocale = utils.getLocale();
47
+ const namedTarget = normalizeNamedTarget(
48
+ props.to,
49
+ currentLocale.code,
50
+ currentLocale.lang,
51
+ currentLocale.loc
52
+ );
53
+ if (namedTarget.startsWith("/")) {
54
+ href.value = namedTarget;
55
+ return;
56
+ }
57
+ href.value = await utils.getUrl(namedTarget, props.locale) || props.to;
58
+ };
59
+ onServerPrefetch(updateHref);
60
+ if (isClient) {
61
+ watch(() => [props.to, props.locale], () => {
62
+ void updateHref();
63
+ }, { immediate: true });
64
+ }
65
+ return () => {
66
+ if (props.isSlot) {
67
+ return slots.default?.({ href: href.value }) || null;
68
+ }
69
+ return h("a", { href: href.value }, slots.default ? slots.default() : href.value);
70
+ };
71
+ }
72
+ });