@monkeyplus/flow 6.0.6 → 6.0.7
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/modules/content/module.mjs +17 -2
- package/modules/content/query.d.ts +25 -0
- package/modules/content/query.mjs +105 -19
- package/modules/content/runtime/client.d.ts +2 -0
- package/modules/content/runtime/client.mjs +1 -0
- package/modules/images/ipx.d.ts +5 -0
- package/modules/images/ipx.mjs +31 -0
- package/modules/images/module.d.ts +4 -0
- package/modules/images/module.mjs +96 -0
- package/modules/images/plugin.d.ts +2 -0
- package/modules/images/plugin.mjs +19 -0
- package/modules/images/runtime/build.d.ts +6 -0
- package/modules/images/runtime/build.mjs +142 -0
- package/modules/images/runtime/helpers.d.ts +16 -0
- package/modules/images/runtime/helpers.mjs +45 -0
- package/modules/images/runtime/image.d.ts +7 -0
- package/modules/images/runtime/image.mjs +235 -0
- package/modules/images/runtime/renames.d.ts +2 -0
- package/modules/images/runtime/renames.mjs +79 -0
- package/modules/images/runtime/server.d.ts +3 -0
- package/modules/images/runtime/server.mjs +68 -0
- package/modules/images/runtime/types.d.ts +77 -0
- package/modules/images/runtime/types.mjs +0 -0
- package/package.json +7 -1
- package/server/lib/pages.mjs +20 -21
- package/server/lib/render.mjs +16 -0
- package/server/renderer.d.ts +1 -1
- package/server/renderer.mjs +2 -1
- package/src/public/components.d.ts +3 -0
- package/src/public/components.mjs +3 -0
- package/src/public/index.d.ts +5 -3
- package/src/public/index.mjs +1 -0
- package/src/public/modules/images.d.ts +2 -0
- package/src/public/modules/images.mjs +1 -0
- package/src/public/query-content.d.ts +7 -0
- package/src/public/query-content.mjs +127 -0
- package/src/public/vite.mjs +18 -2
- package/src/runtime/components/MkImage.d.ts +188 -0
- package/src/runtime/components/MkImage.mjs +130 -0
- package/src/runtime/components/MkLink.d.ts +22 -0
- package/src/runtime/components/MkLink.mjs +72 -0
- package/src/runtime/components/MkPicture.d.ts +199 -0
- package/src/runtime/components/MkPicture.mjs +171 -0
- package/src/runtime/components/image-shared.d.ts +27 -0
- package/src/runtime/components/image-shared.mjs +51 -0
- package/src/runtime/config.d.ts +18 -0
- package/src/runtime/config.mjs +5 -2
- package/src/runtime/locale-routing.d.ts +12 -0
- package/src/runtime/locale-routing.mjs +93 -0
- package/src/runtime/page-discovery.mjs +8 -15
- package/src/runtime/pages.d.ts +16 -0
- package/src/runtime/virtual.d.ts +17 -0
- package/src/runtime/vue.mjs +6 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
2
|
+
src: {
|
|
3
|
+
type: StringConstructor;
|
|
4
|
+
required: true;
|
|
5
|
+
};
|
|
6
|
+
rename: StringConstructor;
|
|
7
|
+
thumb: (StringConstructor | BooleanConstructor)[];
|
|
8
|
+
thumbnail: {
|
|
9
|
+
type: (StringConstructor | BooleanConstructor)[];
|
|
10
|
+
default: undefined;
|
|
11
|
+
};
|
|
12
|
+
classImg: StringConstructor;
|
|
13
|
+
format: {
|
|
14
|
+
type: StringConstructor;
|
|
15
|
+
default: undefined;
|
|
16
|
+
};
|
|
17
|
+
quality: {
|
|
18
|
+
type: (StringConstructor | NumberConstructor)[];
|
|
19
|
+
default: undefined;
|
|
20
|
+
};
|
|
21
|
+
background: {
|
|
22
|
+
type: StringConstructor;
|
|
23
|
+
default: undefined;
|
|
24
|
+
};
|
|
25
|
+
fit: {
|
|
26
|
+
type: StringConstructor;
|
|
27
|
+
default: undefined;
|
|
28
|
+
};
|
|
29
|
+
modifiers: {
|
|
30
|
+
type: () => Record<string, any>;
|
|
31
|
+
default: undefined;
|
|
32
|
+
};
|
|
33
|
+
preset: {
|
|
34
|
+
type: StringConstructor;
|
|
35
|
+
default: undefined;
|
|
36
|
+
};
|
|
37
|
+
provider: {
|
|
38
|
+
type: StringConstructor;
|
|
39
|
+
default: undefined;
|
|
40
|
+
};
|
|
41
|
+
sizes: {
|
|
42
|
+
type: () => string | Record<string, any>;
|
|
43
|
+
default: undefined;
|
|
44
|
+
};
|
|
45
|
+
sync: BooleanConstructor;
|
|
46
|
+
eWidth: (StringConstructor | NumberConstructor)[];
|
|
47
|
+
eHeight: (StringConstructor | NumberConstructor)[];
|
|
48
|
+
width: {
|
|
49
|
+
type: (StringConstructor | NumberConstructor)[];
|
|
50
|
+
default: undefined;
|
|
51
|
+
};
|
|
52
|
+
height: {
|
|
53
|
+
type: (StringConstructor | NumberConstructor)[];
|
|
54
|
+
default: undefined;
|
|
55
|
+
};
|
|
56
|
+
alt: {
|
|
57
|
+
type: StringConstructor;
|
|
58
|
+
default: undefined;
|
|
59
|
+
};
|
|
60
|
+
title: {
|
|
61
|
+
type: StringConstructor;
|
|
62
|
+
default: undefined;
|
|
63
|
+
};
|
|
64
|
+
referrerpolicy: {
|
|
65
|
+
type: StringConstructor;
|
|
66
|
+
default: undefined;
|
|
67
|
+
};
|
|
68
|
+
usemap: {
|
|
69
|
+
type: StringConstructor;
|
|
70
|
+
default: undefined;
|
|
71
|
+
};
|
|
72
|
+
longdesc: {
|
|
73
|
+
type: StringConstructor;
|
|
74
|
+
default: undefined;
|
|
75
|
+
};
|
|
76
|
+
ismap: {
|
|
77
|
+
type: BooleanConstructor;
|
|
78
|
+
default: undefined;
|
|
79
|
+
};
|
|
80
|
+
loading: {
|
|
81
|
+
type: StringConstructor;
|
|
82
|
+
default: undefined;
|
|
83
|
+
};
|
|
84
|
+
legacyFormat: {
|
|
85
|
+
type: StringConstructor;
|
|
86
|
+
default: null;
|
|
87
|
+
};
|
|
88
|
+
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
89
|
+
[key: string]: any;
|
|
90
|
+
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
91
|
+
src: {
|
|
92
|
+
type: StringConstructor;
|
|
93
|
+
required: true;
|
|
94
|
+
};
|
|
95
|
+
rename: StringConstructor;
|
|
96
|
+
thumb: (StringConstructor | BooleanConstructor)[];
|
|
97
|
+
thumbnail: {
|
|
98
|
+
type: (StringConstructor | BooleanConstructor)[];
|
|
99
|
+
default: undefined;
|
|
100
|
+
};
|
|
101
|
+
classImg: StringConstructor;
|
|
102
|
+
format: {
|
|
103
|
+
type: StringConstructor;
|
|
104
|
+
default: undefined;
|
|
105
|
+
};
|
|
106
|
+
quality: {
|
|
107
|
+
type: (StringConstructor | NumberConstructor)[];
|
|
108
|
+
default: undefined;
|
|
109
|
+
};
|
|
110
|
+
background: {
|
|
111
|
+
type: StringConstructor;
|
|
112
|
+
default: undefined;
|
|
113
|
+
};
|
|
114
|
+
fit: {
|
|
115
|
+
type: StringConstructor;
|
|
116
|
+
default: undefined;
|
|
117
|
+
};
|
|
118
|
+
modifiers: {
|
|
119
|
+
type: () => Record<string, any>;
|
|
120
|
+
default: undefined;
|
|
121
|
+
};
|
|
122
|
+
preset: {
|
|
123
|
+
type: StringConstructor;
|
|
124
|
+
default: undefined;
|
|
125
|
+
};
|
|
126
|
+
provider: {
|
|
127
|
+
type: StringConstructor;
|
|
128
|
+
default: undefined;
|
|
129
|
+
};
|
|
130
|
+
sizes: {
|
|
131
|
+
type: () => string | Record<string, any>;
|
|
132
|
+
default: undefined;
|
|
133
|
+
};
|
|
134
|
+
sync: BooleanConstructor;
|
|
135
|
+
eWidth: (StringConstructor | NumberConstructor)[];
|
|
136
|
+
eHeight: (StringConstructor | NumberConstructor)[];
|
|
137
|
+
width: {
|
|
138
|
+
type: (StringConstructor | NumberConstructor)[];
|
|
139
|
+
default: undefined;
|
|
140
|
+
};
|
|
141
|
+
height: {
|
|
142
|
+
type: (StringConstructor | NumberConstructor)[];
|
|
143
|
+
default: undefined;
|
|
144
|
+
};
|
|
145
|
+
alt: {
|
|
146
|
+
type: StringConstructor;
|
|
147
|
+
default: undefined;
|
|
148
|
+
};
|
|
149
|
+
title: {
|
|
150
|
+
type: StringConstructor;
|
|
151
|
+
default: undefined;
|
|
152
|
+
};
|
|
153
|
+
referrerpolicy: {
|
|
154
|
+
type: StringConstructor;
|
|
155
|
+
default: undefined;
|
|
156
|
+
};
|
|
157
|
+
usemap: {
|
|
158
|
+
type: StringConstructor;
|
|
159
|
+
default: undefined;
|
|
160
|
+
};
|
|
161
|
+
longdesc: {
|
|
162
|
+
type: StringConstructor;
|
|
163
|
+
default: undefined;
|
|
164
|
+
};
|
|
165
|
+
ismap: {
|
|
166
|
+
type: BooleanConstructor;
|
|
167
|
+
default: undefined;
|
|
168
|
+
};
|
|
169
|
+
loading: {
|
|
170
|
+
type: StringConstructor;
|
|
171
|
+
default: undefined;
|
|
172
|
+
};
|
|
173
|
+
legacyFormat: {
|
|
174
|
+
type: StringConstructor;
|
|
175
|
+
default: null;
|
|
176
|
+
};
|
|
177
|
+
}>> & Readonly<{}>, {
|
|
178
|
+
width: string | number;
|
|
179
|
+
height: string | number;
|
|
180
|
+
fit: string;
|
|
181
|
+
format: string;
|
|
182
|
+
provider: string;
|
|
183
|
+
preset: string;
|
|
184
|
+
modifiers: Record<string, any>;
|
|
185
|
+
sizes: string | Record<string, any>;
|
|
186
|
+
alt: string;
|
|
187
|
+
referrerpolicy: string;
|
|
188
|
+
usemap: string;
|
|
189
|
+
longdesc: string;
|
|
190
|
+
ismap: boolean;
|
|
191
|
+
loading: string;
|
|
192
|
+
quality: string | number;
|
|
193
|
+
background: string;
|
|
194
|
+
title: string;
|
|
195
|
+
sync: boolean;
|
|
196
|
+
thumbnail: string | boolean;
|
|
197
|
+
legacyFormat: string;
|
|
198
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
199
|
+
export default _default;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { computed, defineComponent, h } from "vue";
|
|
2
|
+
import { getFileExtension, screens } from "../../../modules/images/runtime/helpers.mjs";
|
|
3
|
+
import { useImage } from "./image-shared.mjs";
|
|
4
|
+
function getLocalSource(src) {
|
|
5
|
+
return src.startsWith("http") ? "" : src;
|
|
6
|
+
}
|
|
7
|
+
function isRuntimeLambda() {
|
|
8
|
+
const runtimeProcess = typeof globalThis === "object" ? Reflect.get(globalThis, "process") : void 0;
|
|
9
|
+
return !!(runtimeProcess?.env?.LAMBDA_TASK_ROOT || runtimeProcess?.env?.AWS_LAMBDA_FUNCTION_VERSION);
|
|
10
|
+
}
|
|
11
|
+
function resolveThumbnailValue(value, fallback) {
|
|
12
|
+
return value !== void 0 ? value : fallback;
|
|
13
|
+
}
|
|
14
|
+
export default defineComponent({
|
|
15
|
+
name: "MkPicture",
|
|
16
|
+
inheritAttrs: false,
|
|
17
|
+
props: {
|
|
18
|
+
src: {
|
|
19
|
+
type: String,
|
|
20
|
+
required: true
|
|
21
|
+
},
|
|
22
|
+
rename: String,
|
|
23
|
+
thumb: [Boolean, String],
|
|
24
|
+
thumbnail: { type: [Boolean, String], default: void 0 },
|
|
25
|
+
classImg: String,
|
|
26
|
+
format: { type: String, default: void 0 },
|
|
27
|
+
quality: { type: [Number, String], default: void 0 },
|
|
28
|
+
background: { type: String, default: void 0 },
|
|
29
|
+
fit: { type: String, default: void 0 },
|
|
30
|
+
modifiers: {
|
|
31
|
+
type: Object,
|
|
32
|
+
default: void 0
|
|
33
|
+
},
|
|
34
|
+
preset: { type: String, default: void 0 },
|
|
35
|
+
provider: { type: String, default: void 0 },
|
|
36
|
+
sizes: {
|
|
37
|
+
type: [Object, String],
|
|
38
|
+
default: void 0
|
|
39
|
+
},
|
|
40
|
+
sync: Boolean,
|
|
41
|
+
eWidth: [String, Number],
|
|
42
|
+
eHeight: [String, Number],
|
|
43
|
+
width: { type: [String, Number], default: void 0 },
|
|
44
|
+
height: { type: [String, Number], default: void 0 },
|
|
45
|
+
alt: { type: String, default: void 0 },
|
|
46
|
+
title: { type: String, default: void 0 },
|
|
47
|
+
referrerpolicy: { type: String, default: void 0 },
|
|
48
|
+
usemap: { type: String, default: void 0 },
|
|
49
|
+
longdesc: { type: String, default: void 0 },
|
|
50
|
+
ismap: { type: Boolean, default: void 0 },
|
|
51
|
+
loading: { type: String, default: void 0 },
|
|
52
|
+
legacyFormat: { type: String, default: null }
|
|
53
|
+
},
|
|
54
|
+
setup(props, { attrs }) {
|
|
55
|
+
const { imageUtils, image, nImgAttrs, nModifiers, nOption } = useImage(props);
|
|
56
|
+
const options = computed(() => imageUtils.getImageOptions?.() || {
|
|
57
|
+
lazy: true,
|
|
58
|
+
screens: {},
|
|
59
|
+
domains: {},
|
|
60
|
+
presets: {},
|
|
61
|
+
baseURL: "/_ipx",
|
|
62
|
+
dirImages: "/images"
|
|
63
|
+
});
|
|
64
|
+
const originalFormat = () => getFileExtension(props.src);
|
|
65
|
+
const isTransparent = () => ["png", "webp", "gif"].includes(originalFormat());
|
|
66
|
+
const nFormat = () => {
|
|
67
|
+
if (props.format) {
|
|
68
|
+
return props.format;
|
|
69
|
+
}
|
|
70
|
+
if (originalFormat() === "svg") {
|
|
71
|
+
return "svg";
|
|
72
|
+
}
|
|
73
|
+
return "webp";
|
|
74
|
+
};
|
|
75
|
+
const nLegacyFormat = () => {
|
|
76
|
+
if (props.legacyFormat) {
|
|
77
|
+
return props.legacyFormat;
|
|
78
|
+
}
|
|
79
|
+
const formats = {
|
|
80
|
+
webp: isTransparent() ? "png" : "jpeg",
|
|
81
|
+
svg: "png"
|
|
82
|
+
};
|
|
83
|
+
return formats[nFormat()] || originalFormat();
|
|
84
|
+
};
|
|
85
|
+
const nSources = computed(() => {
|
|
86
|
+
if (nFormat() === "svg" || !imageUtils.getImage?.getSizes) {
|
|
87
|
+
return [{ src: props.src, srcset: props.src }];
|
|
88
|
+
}
|
|
89
|
+
const formats = nLegacyFormat() !== nFormat() ? [nLegacyFormat(), nFormat()] : [nFormat()];
|
|
90
|
+
return formats.map((format) => {
|
|
91
|
+
const result = imageUtils.getImage.getSizes(props.src, {
|
|
92
|
+
...nOption.value,
|
|
93
|
+
modifiers: {
|
|
94
|
+
...nModifiers.value,
|
|
95
|
+
format
|
|
96
|
+
},
|
|
97
|
+
sizes: props.sizes || options.value.screens || screens
|
|
98
|
+
});
|
|
99
|
+
return {
|
|
100
|
+
src: result.src,
|
|
101
|
+
type: `image/${format}`,
|
|
102
|
+
sizes: result.sizes,
|
|
103
|
+
srcset: result.srcset
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
const nThumbnail = computed(() => {
|
|
108
|
+
const thumb = resolveThumbnailValue(props.thumbnail, props.thumb);
|
|
109
|
+
if (typeof thumb === "string") {
|
|
110
|
+
return thumb;
|
|
111
|
+
}
|
|
112
|
+
if (!thumb) {
|
|
113
|
+
return void 0;
|
|
114
|
+
}
|
|
115
|
+
const thumbnail = imageUtils.getImage?.(props.src, {
|
|
116
|
+
quality: 10,
|
|
117
|
+
width: 60
|
|
118
|
+
}, nOption.value);
|
|
119
|
+
return typeof thumbnail === "string" ? thumbnail : props.src;
|
|
120
|
+
});
|
|
121
|
+
return () => {
|
|
122
|
+
if (isRuntimeLambda()) {
|
|
123
|
+
return h("img", {
|
|
124
|
+
...attrs,
|
|
125
|
+
...nImgAttrs.value,
|
|
126
|
+
src: props.src,
|
|
127
|
+
alt: props.alt || image.value.alt,
|
|
128
|
+
title: props.title || image.value.title,
|
|
129
|
+
width: props.eWidth || nImgAttrs.value.width,
|
|
130
|
+
height: props.eHeight || nImgAttrs.value.height,
|
|
131
|
+
"x-src": getLocalSource(props.src)
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
const primarySource = nSources.value[0] || { src: props.src, srcset: props.src };
|
|
135
|
+
const fallbackSource = nSources.value[1];
|
|
136
|
+
const compatibilityThumb = nThumbnail.value;
|
|
137
|
+
const sourceSrcsetProp = compatibilityThumb ? "data-srcset" : "srcset";
|
|
138
|
+
const sourceSizesProp = compatibilityThumb ? "data-sizes" : "sizes";
|
|
139
|
+
const imgAttrs = {
|
|
140
|
+
...attrs,
|
|
141
|
+
...nImgAttrs.value,
|
|
142
|
+
src: compatibilityThumb || primarySource.src,
|
|
143
|
+
srcset: compatibilityThumb ? void 0 : primarySource.srcset,
|
|
144
|
+
sizes: compatibilityThumb ? void 0 : primarySource.sizes,
|
|
145
|
+
"data-src": compatibilityThumb ? primarySource.src : void 0,
|
|
146
|
+
"data-srcset": compatibilityThumb ? primarySource.srcset : void 0,
|
|
147
|
+
"data-sizes": compatibilityThumb ? primarySource.sizes : void 0,
|
|
148
|
+
"data-thumb": compatibilityThumb,
|
|
149
|
+
alt: props.alt || image.value.alt,
|
|
150
|
+
title: props.title || image.value.title,
|
|
151
|
+
width: props.eWidth || nImgAttrs.value.width,
|
|
152
|
+
height: props.eHeight || nImgAttrs.value.height,
|
|
153
|
+
class: compatibilityThumb ? [attrs.class, "lazyload", props.classImg] : [attrs.class, props.classImg],
|
|
154
|
+
"x-src": getLocalSource(props.src)
|
|
155
|
+
};
|
|
156
|
+
if (options.value.lazy && !props.sync && !imgAttrs.loading) {
|
|
157
|
+
imgAttrs.loading = "lazy";
|
|
158
|
+
}
|
|
159
|
+
const children = [];
|
|
160
|
+
if (fallbackSource) {
|
|
161
|
+
children.push(h("source", {
|
|
162
|
+
type: fallbackSource.type,
|
|
163
|
+
[sourceSrcsetProp]: fallbackSource.srcset,
|
|
164
|
+
[sourceSizesProp]: fallbackSource.sizes
|
|
165
|
+
}));
|
|
166
|
+
}
|
|
167
|
+
children.push(h("img", imgAttrs));
|
|
168
|
+
return h("picture", { key: primarySource.src }, children);
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { FlowImageMeta, FlowImageOptions, GetImageFunction } from '../../../modules/images/runtime/types.ts';
|
|
2
|
+
export interface InjectedImageUtils {
|
|
3
|
+
getImage?: GetImageFunction;
|
|
4
|
+
getImageMeta?: (src: string) => FlowImageMeta | undefined;
|
|
5
|
+
getImageOptions?: () => FlowImageOptions | undefined;
|
|
6
|
+
}
|
|
7
|
+
export declare function useInjectedImageUtils(): InjectedImageUtils;
|
|
8
|
+
export declare function useImage(props: Record<string, any>): {
|
|
9
|
+
imageUtils: InjectedImageUtils;
|
|
10
|
+
image: import("vue").ComputedRef<FlowImageMeta>;
|
|
11
|
+
nImgAttrs: import("vue").ComputedRef<{
|
|
12
|
+
width: number | undefined;
|
|
13
|
+
height: number | undefined;
|
|
14
|
+
alt: any;
|
|
15
|
+
referrerpolicy: any;
|
|
16
|
+
usemap: any;
|
|
17
|
+
longdesc: any;
|
|
18
|
+
ismap: any;
|
|
19
|
+
loading: any;
|
|
20
|
+
}>;
|
|
21
|
+
nModifiers: import("vue").ComputedRef<any>;
|
|
22
|
+
nOption: import("vue").ComputedRef<{
|
|
23
|
+
provider: any;
|
|
24
|
+
preset: any;
|
|
25
|
+
rename: any;
|
|
26
|
+
}>;
|
|
27
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { computed, inject } from "vue";
|
|
2
|
+
import { getNormalName, parseSize } from "../../../modules/images/runtime/helpers.mjs";
|
|
3
|
+
export function useInjectedImageUtils() {
|
|
4
|
+
return inject("utils", {});
|
|
5
|
+
}
|
|
6
|
+
export function useImage(props) {
|
|
7
|
+
const imageUtils = useInjectedImageUtils();
|
|
8
|
+
const nImgAttrs = computed(() => ({
|
|
9
|
+
width: parseSize(props.width),
|
|
10
|
+
height: parseSize(props.height),
|
|
11
|
+
alt: props.alt,
|
|
12
|
+
referrerpolicy: props.referrerpolicy,
|
|
13
|
+
usemap: props.usemap,
|
|
14
|
+
longdesc: props.longdesc,
|
|
15
|
+
ismap: props.ismap,
|
|
16
|
+
loading: props.loading
|
|
17
|
+
}));
|
|
18
|
+
const nModifiers = computed(() => ({
|
|
19
|
+
...props.modifiers,
|
|
20
|
+
width: parseSize(props.width),
|
|
21
|
+
height: parseSize(props.height),
|
|
22
|
+
format: props.format,
|
|
23
|
+
quality: props.quality,
|
|
24
|
+
background: props.background,
|
|
25
|
+
fit: props.fit
|
|
26
|
+
}));
|
|
27
|
+
const nOption = computed(() => ({
|
|
28
|
+
provider: props.provider,
|
|
29
|
+
preset: props.preset,
|
|
30
|
+
rename: props.rename
|
|
31
|
+
}));
|
|
32
|
+
const image = computed(() => {
|
|
33
|
+
const meta = {
|
|
34
|
+
...imageUtils.getImageMeta?.(props.src) || { name: props.src }
|
|
35
|
+
};
|
|
36
|
+
if (!meta.alt) {
|
|
37
|
+
meta.alt = getNormalName(meta.name);
|
|
38
|
+
}
|
|
39
|
+
if (!meta.title) {
|
|
40
|
+
meta.title = getNormalName(meta.name);
|
|
41
|
+
}
|
|
42
|
+
return meta;
|
|
43
|
+
});
|
|
44
|
+
return {
|
|
45
|
+
imageUtils,
|
|
46
|
+
image,
|
|
47
|
+
nImgAttrs,
|
|
48
|
+
nModifiers,
|
|
49
|
+
nOption
|
|
50
|
+
};
|
|
51
|
+
}
|
package/src/runtime/config.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { Options as AutoimportOptions } from 'unplugin-auto-import/types';
|
|
2
|
+
import type { Options as ComponentOptions } from 'unplugin-vue-components/types';
|
|
1
3
|
export interface FlowDirEntry {
|
|
2
4
|
dir: string;
|
|
3
5
|
}
|
|
@@ -23,6 +25,18 @@ export interface FlowLocaleConfig {
|
|
|
23
25
|
locales: string[];
|
|
24
26
|
location: string;
|
|
25
27
|
language: string;
|
|
28
|
+
prefixStrategy?: 'auto' | 'manual';
|
|
29
|
+
prefixFormat?: 'compact' | 'nested';
|
|
30
|
+
}
|
|
31
|
+
export interface FlowServerConfig extends Record<string, unknown> {
|
|
32
|
+
host?: string | boolean;
|
|
33
|
+
port?: number;
|
|
34
|
+
strictPort?: boolean;
|
|
35
|
+
open?: boolean;
|
|
36
|
+
https?: Record<string, unknown>;
|
|
37
|
+
watch?: Record<string, unknown> & {
|
|
38
|
+
additionalPaths?: string[];
|
|
39
|
+
};
|
|
26
40
|
}
|
|
27
41
|
export interface FlowConfig {
|
|
28
42
|
modules: FlowModuleInput[];
|
|
@@ -31,6 +45,7 @@ export interface FlowConfig {
|
|
|
31
45
|
};
|
|
32
46
|
build: FlowBuildConfig;
|
|
33
47
|
locale: FlowLocaleConfig;
|
|
48
|
+
server?: FlowServerConfig;
|
|
34
49
|
siteUrl?: string;
|
|
35
50
|
nitro?: Record<string, unknown>;
|
|
36
51
|
[key: string]: unknown;
|
|
@@ -41,7 +56,10 @@ export type UserFlowConfig = Partial<FlowConfig> & Record<string, unknown> & {
|
|
|
41
56
|
pages?: FlowDirEntry[];
|
|
42
57
|
};
|
|
43
58
|
locale?: Partial<FlowLocaleConfig>;
|
|
59
|
+
server?: FlowServerConfig;
|
|
44
60
|
siteUrl?: string;
|
|
61
|
+
components?: Partial<ComponentOptions>;
|
|
62
|
+
autoImport?: Partial<AutoimportOptions>;
|
|
45
63
|
};
|
|
46
64
|
export interface FlowModuleNitroConfig extends Record<string, unknown> {
|
|
47
65
|
plugins: string[];
|
package/src/runtime/config.mjs
CHANGED
|
@@ -20,7 +20,10 @@ export function resolveFlowConfig(userFlowConfig = {}) {
|
|
|
20
20
|
locale: {
|
|
21
21
|
locales: userFlowConfig.locale?.locales?.length ? userFlowConfig.locale.locales : ["es-ec"],
|
|
22
22
|
location: userFlowConfig.locale?.location || "ec",
|
|
23
|
-
language: userFlowConfig.locale?.language || "es"
|
|
24
|
-
|
|
23
|
+
language: userFlowConfig.locale?.language || "es",
|
|
24
|
+
prefixStrategy: userFlowConfig.locale?.prefixStrategy || "auto",
|
|
25
|
+
prefixFormat: userFlowConfig.locale?.prefixFormat || "compact"
|
|
26
|
+
},
|
|
27
|
+
server: userFlowConfig.server
|
|
25
28
|
};
|
|
26
29
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FlowConfig, FlowLocaleConfig } from './config';
|
|
2
|
+
export type FlowLocalePrefixStrategy = 'auto' | 'manual';
|
|
3
|
+
export type FlowLocalePrefixFormat = 'compact' | 'nested';
|
|
4
|
+
interface FlowLocaleConfigInput {
|
|
5
|
+
locale?: Partial<FlowLocaleConfig>;
|
|
6
|
+
}
|
|
7
|
+
export declare function normalizePath(value: string): string;
|
|
8
|
+
export declare function getDefaultLocaleCode(config?: FlowLocaleConfigInput): string;
|
|
9
|
+
export declare function getLocalePrefix(config: FlowLocaleConfigInput | undefined, localeCode: string): string;
|
|
10
|
+
export declare function localizeRoutePattern(config: FlowConfig | FlowLocaleConfigInput | undefined, localeCode: string, route: string): string;
|
|
11
|
+
export declare function toPublicRoute(config: FlowConfig | FlowLocaleConfigInput | undefined, localeCode: string, route: string): string;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
function ensureLeadingSlash(value) {
|
|
2
|
+
if (!value) {
|
|
3
|
+
return "/";
|
|
4
|
+
}
|
|
5
|
+
return value.startsWith("/") ? value : `/${value}`;
|
|
6
|
+
}
|
|
7
|
+
function ensureTrailingSlash(value) {
|
|
8
|
+
if (value === "/" || value.endsWith("/")) {
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
return `${value}/`;
|
|
12
|
+
}
|
|
13
|
+
function preserveTrailingSlash(value, source) {
|
|
14
|
+
return source.endsWith("/") ? ensureTrailingSlash(value) : value;
|
|
15
|
+
}
|
|
16
|
+
function resolveLocaleConfig(config) {
|
|
17
|
+
return {
|
|
18
|
+
locales: config?.locale?.locales?.length ? config.locale.locales : ["es-ec"],
|
|
19
|
+
location: config?.locale?.location || "ec",
|
|
20
|
+
language: config?.locale?.language || "es",
|
|
21
|
+
prefixStrategy: config?.locale?.prefixStrategy || "auto",
|
|
22
|
+
prefixFormat: config?.locale?.prefixFormat || "compact"
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function resolveLocaleParts(config, code) {
|
|
26
|
+
const localeConfig = resolveLocaleConfig(config);
|
|
27
|
+
const [lang = localeConfig.language, loc = localeConfig.location] = code.split("-");
|
|
28
|
+
return {
|
|
29
|
+
lang,
|
|
30
|
+
loc
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function routeHasPrefix(route, prefix) {
|
|
34
|
+
return route === prefix || route === `${prefix}/` || route.startsWith(`${prefix}/`);
|
|
35
|
+
}
|
|
36
|
+
function getLocalePrefixVariants(config, localeCode) {
|
|
37
|
+
const localeConfig = resolveLocaleConfig(config);
|
|
38
|
+
const { lang, loc } = resolveLocaleParts(config, localeCode);
|
|
39
|
+
const prefixes = /* @__PURE__ */ new Set();
|
|
40
|
+
if (loc === localeConfig.location) {
|
|
41
|
+
prefixes.add(`/${lang}`);
|
|
42
|
+
return [...prefixes];
|
|
43
|
+
}
|
|
44
|
+
prefixes.add(`/${lang}-${loc}`);
|
|
45
|
+
prefixes.add(`/${lang}/${loc}`);
|
|
46
|
+
return [...prefixes];
|
|
47
|
+
}
|
|
48
|
+
export function normalizePath(value) {
|
|
49
|
+
if (!value || value === "/") {
|
|
50
|
+
return "/";
|
|
51
|
+
}
|
|
52
|
+
return value.length > 1 && value.endsWith("/") ? value.slice(0, -1) : value;
|
|
53
|
+
}
|
|
54
|
+
export function getDefaultLocaleCode(config) {
|
|
55
|
+
const localeConfig = resolveLocaleConfig(config);
|
|
56
|
+
return `${localeConfig.language}-${localeConfig.location}`;
|
|
57
|
+
}
|
|
58
|
+
export function getLocalePrefix(config, localeCode) {
|
|
59
|
+
const localeConfig = resolveLocaleConfig(config);
|
|
60
|
+
if (localeConfig.prefixStrategy === "manual") {
|
|
61
|
+
return "";
|
|
62
|
+
}
|
|
63
|
+
if (localeCode === getDefaultLocaleCode(config)) {
|
|
64
|
+
return "";
|
|
65
|
+
}
|
|
66
|
+
const { lang, loc } = resolveLocaleParts(config, localeCode);
|
|
67
|
+
if (loc === localeConfig.location) {
|
|
68
|
+
return `/${lang}`;
|
|
69
|
+
}
|
|
70
|
+
if (localeConfig.prefixFormat === "nested") {
|
|
71
|
+
return `/${lang}/${loc}`;
|
|
72
|
+
}
|
|
73
|
+
return `/${lang}-${loc}`;
|
|
74
|
+
}
|
|
75
|
+
export function localizeRoutePattern(config, localeCode, route) {
|
|
76
|
+
const normalizedRoute = ensureLeadingSlash(route || "/");
|
|
77
|
+
const prefix = getLocalePrefix(config, localeCode);
|
|
78
|
+
if (!prefix) {
|
|
79
|
+
return normalizedRoute;
|
|
80
|
+
}
|
|
81
|
+
if (getLocalePrefixVariants(config, localeCode).some((candidate) => routeHasPrefix(normalizedRoute, candidate))) {
|
|
82
|
+
return normalizedRoute;
|
|
83
|
+
}
|
|
84
|
+
if (normalizedRoute === "/") {
|
|
85
|
+
return ensureTrailingSlash(prefix);
|
|
86
|
+
}
|
|
87
|
+
return preserveTrailingSlash(`${normalizePath(prefix)}${normalizedRoute}`, normalizedRoute);
|
|
88
|
+
}
|
|
89
|
+
export function toPublicRoute(config, localeCode, route) {
|
|
90
|
+
const localizedRoute = localizeRoutePattern(config, localeCode, route);
|
|
91
|
+
const publicRoute = localizedRoute.replaceAll("*", "");
|
|
92
|
+
return preserveTrailingSlash(normalizePath(publicRoute), localizedRoute);
|
|
93
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, readdirSync } from "node:fs";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { createJiti } from "jiti";
|
|
4
|
+
import { localizeRoutePattern, normalizePath, toPublicRoute } from "./locale-routing.mjs";
|
|
4
5
|
const jiti = createJiti(import.meta.url, {
|
|
5
6
|
fsCache: false,
|
|
6
7
|
moduleCache: false
|
|
@@ -25,12 +26,6 @@ function collectFiles(rootDir, currentDir = rootDir) {
|
|
|
25
26
|
}
|
|
26
27
|
return files.sort((left, right) => left.localeCompare(right));
|
|
27
28
|
}
|
|
28
|
-
function normalizePath(value) {
|
|
29
|
-
if (!value || value === "/") {
|
|
30
|
-
return "/";
|
|
31
|
-
}
|
|
32
|
-
return value.length > 1 && value.endsWith("/") ? value.slice(0, -1) : value;
|
|
33
|
-
}
|
|
34
29
|
function createLocale(flowConfig, code) {
|
|
35
30
|
const [lang = flowConfig.locale.language || "es", loc = flowConfig.locale.location || "ec"] = code.split("-");
|
|
36
31
|
return {
|
|
@@ -55,9 +50,6 @@ function replacePath(pattern, url) {
|
|
|
55
50
|
}
|
|
56
51
|
return normalizePath(resolved.replaceAll("**", ""));
|
|
57
52
|
}
|
|
58
|
-
function toPublicRoutePattern(url) {
|
|
59
|
-
return normalizePath(url.replaceAll("*", ""));
|
|
60
|
-
}
|
|
61
53
|
function combineName(name, dynamicName) {
|
|
62
54
|
return `${name.replace(/\/*$/, "")}/${dynamicName.replace(/^\/*/, "")}`;
|
|
63
55
|
}
|
|
@@ -124,14 +116,15 @@ export async function getUrlFromDefinitions(definitions, flowConfig, namePage, l
|
|
|
124
116
|
return void 0;
|
|
125
117
|
}
|
|
126
118
|
const localePage = definition.locales[localeCode];
|
|
119
|
+
const localizedRoute = localizeRoutePattern(flowConfig, localeCode, localePage?.url || "/");
|
|
127
120
|
if (!localePage) {
|
|
128
121
|
return void 0;
|
|
129
122
|
}
|
|
130
123
|
if (options.url) {
|
|
131
|
-
return replacePath(
|
|
124
|
+
return replacePath(localizedRoute, options.url);
|
|
132
125
|
}
|
|
133
126
|
if (options.params) {
|
|
134
|
-
return replacePath(
|
|
127
|
+
return replacePath(localizedRoute, options.params);
|
|
135
128
|
}
|
|
136
129
|
if (localePage.dynamic && options.dynamicName) {
|
|
137
130
|
const entries = await getDynamicEntries(definitions, flowConfig, definition, localeCode, localePage);
|
|
@@ -139,9 +132,9 @@ export async function getUrlFromDefinitions(definitions, flowConfig, namePage, l
|
|
|
139
132
|
if (!entry) {
|
|
140
133
|
return void 0;
|
|
141
134
|
}
|
|
142
|
-
return replacePath(
|
|
135
|
+
return replacePath(localizedRoute, entry.url);
|
|
143
136
|
}
|
|
144
|
-
return
|
|
137
|
+
return toPublicRoute(flowConfig, localeCode, localePage.url);
|
|
145
138
|
}
|
|
146
139
|
export async function getUrlsFromDefinitions(definitions, flowConfig, withLocale = false, omitNoPublish = false) {
|
|
147
140
|
const urls = [];
|
|
@@ -157,12 +150,12 @@ export async function getUrlsFromDefinitions(definitions, flowConfig, withLocale
|
|
|
157
150
|
if (localePage.dynamic) {
|
|
158
151
|
const entries = await getDynamicEntries(definitions, flowConfig, definition, localeCode, localePage);
|
|
159
152
|
for (const entry of entries) {
|
|
160
|
-
const url2 = replacePath(localePage.url, entry.url);
|
|
153
|
+
const url2 = replacePath(localizeRoutePattern(flowConfig, localeCode, localePage.url), entry.url);
|
|
161
154
|
urls.push(withLocale ? { url: url2, locale: localeCode, name: combineName(definition.name, entry.name) } : url2);
|
|
162
155
|
}
|
|
163
156
|
continue;
|
|
164
157
|
}
|
|
165
|
-
const url =
|
|
158
|
+
const url = toPublicRoute(flowConfig, localeCode, localePage.url);
|
|
166
159
|
urls.push(withLocale ? { url, locale: localeCode, name: definition.name } : url);
|
|
167
160
|
}
|
|
168
161
|
}
|