@yimingliao/cms 0.0.61 → 0.0.62
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/{chunk-FXWRZAIN.js → chunk-QW5O7NHA.js} +1 -1
- package/dist/chunk-YDNPEEO6.js +4733 -0
- package/dist/index.d.ts +9 -1
- package/dist/index.js +1 -2
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +1 -4194
- package/dist/storage/r2/index.js +2 -2
- package/dist/storage/sftp/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-FUAJWL2N.js +0 -64
- package/dist/chunk-YAUBKQVA.js +0 -434
package/dist/storage/r2/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createObjectKey } from '../../chunk-
|
|
2
|
-
import '../../chunk-
|
|
1
|
+
import { createObjectKey } from '../../chunk-QW5O7NHA.js';
|
|
2
|
+
import '../../chunk-YDNPEEO6.js';
|
|
3
3
|
import { PutObjectCommand, DeleteObjectCommand, CopyObjectCommand } from '@aws-sdk/client-s3';
|
|
4
4
|
|
|
5
5
|
function createR2Service({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createObjectKey } from '../../chunk-
|
|
2
|
-
import '../../chunk-
|
|
1
|
+
import { createObjectKey } from '../../chunk-QW5O7NHA.js';
|
|
2
|
+
import '../../chunk-YDNPEEO6.js';
|
|
3
3
|
import path from 'path/posix';
|
|
4
4
|
import { createPool } from 'generic-pool';
|
|
5
5
|
import SFTPClient from 'ssh2-sftp-client';
|
package/package.json
CHANGED
package/dist/chunk-FUAJWL2N.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
// src/domain/resources/admin/props.ts
|
|
2
|
-
var ADMIN_ROLES = {
|
|
3
|
-
SUPER_ADMIN: "SUPER_ADMIN",
|
|
4
|
-
ADMIN: "ADMIN",
|
|
5
|
-
EDITOR: "EDITOR"
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
// src/domain/resources/file/utils/is-file-locked.ts
|
|
9
|
-
var isFileLocked = (file) => {
|
|
10
|
-
if (!file) return false;
|
|
11
|
-
if (!("adminAsAvatarImage" in file && "postsAsCoverImage" in file && "postsAsContentImage" in file && "postsAsImages1" in file && "postsAsImages2" in file && "postsAsImage1" in file && "postsAsImage2" in file && "postsAsImage3" in file && "postsAsImage4" in file)) {
|
|
12
|
-
return false;
|
|
13
|
-
}
|
|
14
|
-
const locked = file.adminAsAvatarImage.length > 0 || file.postsAsCoverImage.length > 0 || file.postsAsContentImage.length > 0 || file.postsAsImages1.length > 0 || file.postsAsImages2.length > 0 || file.postsAsImage1.length > 0 || file.postsAsImage2.length > 0 || file.postsAsImage3.length > 0 || file.postsAsImage4.length > 0;
|
|
15
|
-
return locked;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
// src/domain/resources/folder/utils/is-folder-locked.ts
|
|
19
|
-
var isFolderLocked = (folder) => {
|
|
20
|
-
if (!folder) return true;
|
|
21
|
-
if (!("subFolders" in folder)) return false;
|
|
22
|
-
const locked = folder.subFolders?.length > 0 || folder.files?.length > 0;
|
|
23
|
-
return locked;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
// src/domain/resources/post/props.ts
|
|
27
|
-
var POST_TYPES = {
|
|
28
|
-
TOPIC: "TOPIC",
|
|
29
|
-
CATEGORY: "CATEGORY",
|
|
30
|
-
POST: "POST",
|
|
31
|
-
TAG: "TAG",
|
|
32
|
-
PAGE: "PAGE"
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
// src/domain/resources/constants.ts
|
|
36
|
-
var ROOT_FOLDER_ID = "01ARZ3NDEKTSV4RRFFQ69G5FAV";
|
|
37
|
-
var ROOT_FOLDER_NAME = "ROOT";
|
|
38
|
-
var ROOT_FOLDER = {
|
|
39
|
-
id: ROOT_FOLDER_ID,
|
|
40
|
-
// core
|
|
41
|
-
name: ROOT_FOLDER_NAME,
|
|
42
|
-
key: "",
|
|
43
|
-
// states
|
|
44
|
-
isLocked: true,
|
|
45
|
-
// ---------------------------
|
|
46
|
-
// relations: Folder
|
|
47
|
-
// ---------------------------
|
|
48
|
-
parentFolder: null,
|
|
49
|
-
parentFolderId: null,
|
|
50
|
-
subFolders: [],
|
|
51
|
-
// ---------------------------
|
|
52
|
-
// relations: Folder
|
|
53
|
-
// ---------------------------
|
|
54
|
-
files: [],
|
|
55
|
-
// ---------------------------
|
|
56
|
-
// timestamps
|
|
57
|
-
// ---------------------------
|
|
58
|
-
createdAt: "",
|
|
59
|
-
updatedAt: ""
|
|
60
|
-
};
|
|
61
|
-
var SIMPLE_UPLOAD_FOLDER_NAME = "simple-upload";
|
|
62
|
-
var SIMPLE_UPLOAD_FOLDER_KEY = `${SIMPLE_UPLOAD_FOLDER_NAME}`;
|
|
63
|
-
|
|
64
|
-
export { ADMIN_ROLES, POST_TYPES, ROOT_FOLDER, ROOT_FOLDER_ID, ROOT_FOLDER_NAME, SIMPLE_UPLOAD_FOLDER_KEY, SIMPLE_UPLOAD_FOLDER_NAME, isFileLocked, isFolderLocked };
|
package/dist/chunk-YAUBKQVA.js
DELETED
|
@@ -1,434 +0,0 @@
|
|
|
1
|
-
import { extension, lookup } from 'mime-types';
|
|
2
|
-
|
|
3
|
-
// src/domain/resources/file/props.ts
|
|
4
|
-
var FILE_TYPES = {
|
|
5
|
-
IMAGE: "IMAGE",
|
|
6
|
-
AUDIO: "AUDIO",
|
|
7
|
-
VIDEO: "VIDEO",
|
|
8
|
-
DOCUMENT: "DOCUMENT",
|
|
9
|
-
ARCHIVE: "ARCHIVE",
|
|
10
|
-
OTHER: "OTHER"
|
|
11
|
-
};
|
|
12
|
-
var mimeToExtension = (mimeType) => {
|
|
13
|
-
if (!mimeType) return "unknown";
|
|
14
|
-
return (extension(mimeType) || "unknown").toLowerCase();
|
|
15
|
-
};
|
|
16
|
-
var ARCHIVE_MIME = /* @__PURE__ */ new Set([
|
|
17
|
-
"application/zip",
|
|
18
|
-
"application/x-rar-compressed",
|
|
19
|
-
"application/x-7z-compressed",
|
|
20
|
-
"application/gzip",
|
|
21
|
-
"application/x-tar"
|
|
22
|
-
]);
|
|
23
|
-
var classifyFileType = (mimeType, extension2) => {
|
|
24
|
-
if (!mimeType && extension2) {
|
|
25
|
-
mimeType = lookup(extension2) || void 0;
|
|
26
|
-
}
|
|
27
|
-
if (!mimeType) return FILE_TYPES.OTHER;
|
|
28
|
-
if (mimeType.startsWith("image/")) return FILE_TYPES.IMAGE;
|
|
29
|
-
if (mimeType.startsWith("video/")) return FILE_TYPES.VIDEO;
|
|
30
|
-
if (mimeType.startsWith("audio/")) return FILE_TYPES.AUDIO;
|
|
31
|
-
if (ARCHIVE_MIME.has(mimeType)) return FILE_TYPES.ARCHIVE;
|
|
32
|
-
if (mimeType.startsWith("text/") || mimeType === "application/pdf" || mimeType === "application/json" || mimeType === "application/xml") {
|
|
33
|
-
return FILE_TYPES.DOCUMENT;
|
|
34
|
-
}
|
|
35
|
-
if (mimeType.startsWith("application/")) return FILE_TYPES.DOCUMENT;
|
|
36
|
-
return FILE_TYPES.OTHER;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
// src/shared/blob-file/get-media-info/get-audio-info.ts
|
|
40
|
-
function getAudioInfo(file) {
|
|
41
|
-
return new Promise((resolve, reject) => {
|
|
42
|
-
const audio = document.createElement("audio");
|
|
43
|
-
const objectUrl = URL.createObjectURL(file);
|
|
44
|
-
audio.preload = "metadata";
|
|
45
|
-
const cleanup = () => {
|
|
46
|
-
audio.removeEventListener("loadedmetadata", onLoadedMetadata);
|
|
47
|
-
audio.removeEventListener("error", onError);
|
|
48
|
-
URL.revokeObjectURL(objectUrl);
|
|
49
|
-
};
|
|
50
|
-
const onLoadedMetadata = () => {
|
|
51
|
-
const duration = audio.duration;
|
|
52
|
-
cleanup();
|
|
53
|
-
resolve({ duration });
|
|
54
|
-
};
|
|
55
|
-
const onError = () => {
|
|
56
|
-
cleanup();
|
|
57
|
-
reject(new Error("Failed to load audio metadata."));
|
|
58
|
-
};
|
|
59
|
-
audio.addEventListener("loadedmetadata", onLoadedMetadata, { once: true });
|
|
60
|
-
audio.addEventListener("error", onError, { once: true });
|
|
61
|
-
audio.src = objectUrl;
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// src/shared/blob-file/get-media-info/get-image-info.ts
|
|
66
|
-
function getImageInfo(file) {
|
|
67
|
-
return new Promise((resolve, reject) => {
|
|
68
|
-
const img = new Image();
|
|
69
|
-
const objectUrl = URL.createObjectURL(file);
|
|
70
|
-
const cleanup = () => {
|
|
71
|
-
img.removeEventListener("load", onLoad);
|
|
72
|
-
img.removeEventListener("error", onError);
|
|
73
|
-
URL.revokeObjectURL(objectUrl);
|
|
74
|
-
};
|
|
75
|
-
const onLoad = () => {
|
|
76
|
-
const width = img.naturalWidth;
|
|
77
|
-
const height = img.naturalHeight;
|
|
78
|
-
cleanup();
|
|
79
|
-
resolve({ width, height });
|
|
80
|
-
};
|
|
81
|
-
const onError = () => {
|
|
82
|
-
cleanup();
|
|
83
|
-
reject(new Error("Failed to load image for size detection."));
|
|
84
|
-
};
|
|
85
|
-
img.addEventListener("load", onLoad, { once: true });
|
|
86
|
-
img.addEventListener("error", onError, { once: true });
|
|
87
|
-
img.src = objectUrl;
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// src/shared/blob-file/get-media-info/get-video-info.ts
|
|
92
|
-
function getVideoInfo(file) {
|
|
93
|
-
return new Promise((resolve, reject) => {
|
|
94
|
-
const video = document.createElement("video");
|
|
95
|
-
const objectUrl = URL.createObjectURL(file);
|
|
96
|
-
video.preload = "metadata";
|
|
97
|
-
const cleanup = () => {
|
|
98
|
-
video.removeEventListener("loadedmetadata", onLoadedMetadata);
|
|
99
|
-
video.removeEventListener("error", onError);
|
|
100
|
-
video.src = "";
|
|
101
|
-
URL.revokeObjectURL(objectUrl);
|
|
102
|
-
};
|
|
103
|
-
const onLoadedMetadata = () => {
|
|
104
|
-
const info = {
|
|
105
|
-
width: video.videoWidth,
|
|
106
|
-
height: video.videoHeight,
|
|
107
|
-
duration: video.duration
|
|
108
|
-
};
|
|
109
|
-
cleanup();
|
|
110
|
-
resolve(info);
|
|
111
|
-
};
|
|
112
|
-
const onError = () => {
|
|
113
|
-
cleanup();
|
|
114
|
-
reject(new Error("Failed to load video metadata."));
|
|
115
|
-
};
|
|
116
|
-
video.addEventListener("loadedmetadata", onLoadedMetadata, { once: true });
|
|
117
|
-
video.addEventListener("error", onError, { once: true });
|
|
118
|
-
video.src = objectUrl;
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// src/shared/blob-file/get-media-info/get-media-info.ts
|
|
123
|
-
var IMAGE_EXT = /\.(jpe?g|png|gif|webp|bmp|avif)$/i;
|
|
124
|
-
var VIDEO_EXT = /\.(mp4|webm|mov|mkv)$/i;
|
|
125
|
-
var AUDIO_EXT = /\.(mp3|wav|ogg|m4a)$/i;
|
|
126
|
-
var getMediaInfo = async (file) => {
|
|
127
|
-
const fallback = { width: null, height: null, duration: null };
|
|
128
|
-
const mime = file.type || "";
|
|
129
|
-
const name = file instanceof File ? file.name.toLowerCase() : "";
|
|
130
|
-
try {
|
|
131
|
-
if (mime.startsWith("image/") || IMAGE_EXT.test(name)) {
|
|
132
|
-
const { width, height } = await getImageInfo(file);
|
|
133
|
-
return { width, height, duration: null };
|
|
134
|
-
}
|
|
135
|
-
if (mime.startsWith("video/") || VIDEO_EXT.test(name)) {
|
|
136
|
-
const { width, height, duration } = await getVideoInfo(file);
|
|
137
|
-
return { width, height, duration };
|
|
138
|
-
}
|
|
139
|
-
if (mime.startsWith("audio/") || AUDIO_EXT.test(name)) {
|
|
140
|
-
const { duration } = await getAudioInfo(file);
|
|
141
|
-
return { width: null, height: null, duration };
|
|
142
|
-
}
|
|
143
|
-
return fallback;
|
|
144
|
-
} catch {
|
|
145
|
-
return fallback;
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
// src/shared/blob-file/format-file-size.ts
|
|
150
|
-
var formatFileSize = (size, decimals = 2) => {
|
|
151
|
-
const units = ["B", "KB", "MB", "GB", "TB"];
|
|
152
|
-
let value = size;
|
|
153
|
-
let unitIndex = 0;
|
|
154
|
-
while (value >= 1024 && unitIndex < units.length - 1) {
|
|
155
|
-
value /= 1024;
|
|
156
|
-
unitIndex++;
|
|
157
|
-
}
|
|
158
|
-
const display = unitIndex === 0 ? value.toString() : value.toFixed(decimals);
|
|
159
|
-
return `${display} ${units[unitIndex]}`;
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
// src/shared/result/result.ts
|
|
163
|
-
function success({
|
|
164
|
-
message,
|
|
165
|
-
data,
|
|
166
|
-
meta
|
|
167
|
-
}) {
|
|
168
|
-
return {
|
|
169
|
-
success: true,
|
|
170
|
-
...message !== void 0 ? { message } : {},
|
|
171
|
-
...data !== void 0 ? { data } : {},
|
|
172
|
-
...meta !== void 0 ? { meta } : {}
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
function error({ message, errors, code }) {
|
|
176
|
-
return {
|
|
177
|
-
success: false,
|
|
178
|
-
...message !== void 0 ? { message } : {},
|
|
179
|
-
...errors !== void 0 ? { errors } : {},
|
|
180
|
-
...code !== void 0 ? { code } : {}
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
var result = {
|
|
184
|
-
success,
|
|
185
|
-
error
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
// src/shared/seo-metadata/standards.ts
|
|
189
|
-
var OG_TYPE_ARRAY = [
|
|
190
|
-
"article",
|
|
191
|
-
"book",
|
|
192
|
-
"music.song",
|
|
193
|
-
"music.album",
|
|
194
|
-
"music.playlist",
|
|
195
|
-
"music.radio_station",
|
|
196
|
-
"profile",
|
|
197
|
-
"website",
|
|
198
|
-
"video.tv_show",
|
|
199
|
-
"video.other",
|
|
200
|
-
"video.movie",
|
|
201
|
-
"video.episode"
|
|
202
|
-
];
|
|
203
|
-
var TWITTER_CARD_ARRAY = [
|
|
204
|
-
"summary",
|
|
205
|
-
"summary_large_image",
|
|
206
|
-
"player",
|
|
207
|
-
"app"
|
|
208
|
-
];
|
|
209
|
-
|
|
210
|
-
// src/shared/translation/find-translation.ts
|
|
211
|
-
function findTranslation(translations, locale, defaultValue) {
|
|
212
|
-
const fallback = translations?.[0];
|
|
213
|
-
const found = translations?.find((t) => t.locale === locale) ?? fallback;
|
|
214
|
-
if (!found) return { locale: locale ?? "" };
|
|
215
|
-
const result2 = { ...found };
|
|
216
|
-
for (const key of Object.keys(result2)) {
|
|
217
|
-
if (key === "locale") continue;
|
|
218
|
-
if (result2[key] == null) result2[key] = defaultValue;
|
|
219
|
-
}
|
|
220
|
-
return result2;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// src/shared/translation/create-build-translations.ts
|
|
224
|
-
function createBuildTranslations(localArray) {
|
|
225
|
-
return function buildTranslations(fields) {
|
|
226
|
-
const entries = fields.map((f) => [f.key, f.value]);
|
|
227
|
-
return localArray.map((locale) => ({
|
|
228
|
-
locale,
|
|
229
|
-
...Object.fromEntries(entries)
|
|
230
|
-
}));
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// src/shared/seo-metadata/utils/build-alternate-map.ts
|
|
235
|
-
var buildAlternateMap = (alternates = []) => {
|
|
236
|
-
const result2 = {};
|
|
237
|
-
for (const { hreflang, href } of alternates) {
|
|
238
|
-
if (!href) continue;
|
|
239
|
-
result2[hreflang] = href;
|
|
240
|
-
}
|
|
241
|
-
return result2;
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
// src/shared/seo-metadata/utils/ensure-og-type.ts
|
|
245
|
-
var ensureOgType = (fallback, ogType) => {
|
|
246
|
-
if (typeof ogType !== "string") return fallback;
|
|
247
|
-
const isValid = OG_TYPE_ARRAY.includes(ogType);
|
|
248
|
-
return isValid ? ogType : fallback;
|
|
249
|
-
};
|
|
250
|
-
var buildOgImages = (url, alt, type, width, height) => {
|
|
251
|
-
if (!url) return void 0;
|
|
252
|
-
const mimeType = lookup(url);
|
|
253
|
-
const validType = typeof mimeType === "string" && mimeType.startsWith("image/") ? mimeType : void 0;
|
|
254
|
-
return [
|
|
255
|
-
{
|
|
256
|
-
url,
|
|
257
|
-
alt: alt ?? void 0,
|
|
258
|
-
type: type ?? validType,
|
|
259
|
-
width: width ?? 1200,
|
|
260
|
-
height: height ?? 630
|
|
261
|
-
}
|
|
262
|
-
];
|
|
263
|
-
};
|
|
264
|
-
|
|
265
|
-
// src/shared/seo-metadata/utils/sanitize-string-array.ts
|
|
266
|
-
var sanitizeStringArray = (array) => {
|
|
267
|
-
if (!Array.isArray(array)) return void 0;
|
|
268
|
-
return array.filter(
|
|
269
|
-
(a) => typeof a === "string" && a.trim() !== ""
|
|
270
|
-
);
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
// src/shared/seo-metadata/utils/ensure-twitter-card.ts
|
|
274
|
-
var ensureTwitterCard = (fallback, twitterCard) => {
|
|
275
|
-
if (typeof twitterCard !== "string") return fallback;
|
|
276
|
-
const isValid = TWITTER_CARD_ARRAY.includes(twitterCard);
|
|
277
|
-
return isValid ? twitterCard : fallback;
|
|
278
|
-
};
|
|
279
|
-
|
|
280
|
-
// src/shared/seo-metadata/build-website-metadata.ts
|
|
281
|
-
function createBuildWebsiteMetadata({
|
|
282
|
-
defaults
|
|
283
|
-
}) {
|
|
284
|
-
return function buildWebsiteMetadata(post, locale) {
|
|
285
|
-
const seoMetadata = findTranslation(post?.seoMetadatas, locale);
|
|
286
|
-
return {
|
|
287
|
-
metadataBase: defaults.metadataBase,
|
|
288
|
-
// -----------------------------------------------------------------------
|
|
289
|
-
// Basic
|
|
290
|
-
// -----------------------------------------------------------------------
|
|
291
|
-
title: seoMetadata?.title || defaults.title,
|
|
292
|
-
description: seoMetadata?.description,
|
|
293
|
-
// identity
|
|
294
|
-
authors: [{ name: seoMetadata?.author || defaults.author }],
|
|
295
|
-
// url
|
|
296
|
-
alternates: {
|
|
297
|
-
canonical: seoMetadata?.canonical,
|
|
298
|
-
languages: buildAlternateMap(seoMetadata?.alternate)
|
|
299
|
-
},
|
|
300
|
-
// robots
|
|
301
|
-
robots: seoMetadata?.robots || defaults.robots,
|
|
302
|
-
// -----------------------------------------------------------------------
|
|
303
|
-
// Open Graph
|
|
304
|
-
// -----------------------------------------------------------------------
|
|
305
|
-
openGraph: {
|
|
306
|
-
title: seoMetadata?.ogTitle || void 0,
|
|
307
|
-
description: seoMetadata?.ogDescription || void 0,
|
|
308
|
-
// url
|
|
309
|
-
url: seoMetadata?.ogUrl || seoMetadata?.canonical || void 0,
|
|
310
|
-
// identity
|
|
311
|
-
type: ensureOgType("website", seoMetadata?.ogType),
|
|
312
|
-
siteName: seoMetadata?.ogSiteName || defaults.ogSiteName,
|
|
313
|
-
// image
|
|
314
|
-
images: buildOgImages(
|
|
315
|
-
seoMetadata?.ogImage,
|
|
316
|
-
seoMetadata?.ogImageAlt,
|
|
317
|
-
seoMetadata?.ogImageType,
|
|
318
|
-
seoMetadata?.ogImageWidth,
|
|
319
|
-
seoMetadata?.ogImageHeight
|
|
320
|
-
),
|
|
321
|
-
// locale
|
|
322
|
-
locale: seoMetadata?.ogLocale || void 0,
|
|
323
|
-
alternateLocale: sanitizeStringArray(seoMetadata?.ogLocaleAlternate)
|
|
324
|
-
},
|
|
325
|
-
// -----------------------------------------------------------------------
|
|
326
|
-
// Twitter
|
|
327
|
-
// -----------------------------------------------------------------------
|
|
328
|
-
twitter: {
|
|
329
|
-
card: ensureTwitterCard(defaults.twitterCard, seoMetadata?.twitterCard),
|
|
330
|
-
// identity
|
|
331
|
-
site: seoMetadata?.twitterSite || void 0,
|
|
332
|
-
creator: seoMetadata?.twitterCreator || void 0
|
|
333
|
-
}
|
|
334
|
-
};
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// src/shared/seo-metadata/utils/to-iso-time.ts
|
|
339
|
-
var toIsoTime = (date) => {
|
|
340
|
-
if (!date) return void 0;
|
|
341
|
-
return date.toISOString();
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
// src/shared/seo-metadata/build-article-metadata.ts
|
|
345
|
-
function createBuildArticleMetadata({
|
|
346
|
-
defaults,
|
|
347
|
-
storageUrl
|
|
348
|
-
}) {
|
|
349
|
-
return function buildArticleMetadata(post, locale) {
|
|
350
|
-
const seoMetadata = findTranslation(post?.seoMetadatas, locale);
|
|
351
|
-
const authorT = findTranslation(post?.author?.translations, locale);
|
|
352
|
-
const coverImageT = findTranslation(post?.coverImage?.translations, locale);
|
|
353
|
-
return {
|
|
354
|
-
metadataBase: defaults.metadataBase,
|
|
355
|
-
// -----------------------------------------------------------------------
|
|
356
|
-
// Basic
|
|
357
|
-
// -----------------------------------------------------------------------
|
|
358
|
-
title: seoMetadata?.title || defaults.title,
|
|
359
|
-
description: seoMetadata?.description,
|
|
360
|
-
// identity
|
|
361
|
-
authors: [
|
|
362
|
-
{
|
|
363
|
-
name: seoMetadata?.author || authorT.authorName || defaults.author,
|
|
364
|
-
url: authorT.url || void 0
|
|
365
|
-
}
|
|
366
|
-
],
|
|
367
|
-
// url
|
|
368
|
-
alternates: {
|
|
369
|
-
canonical: seoMetadata?.canonical,
|
|
370
|
-
languages: buildAlternateMap(seoMetadata?.alternate)
|
|
371
|
-
},
|
|
372
|
-
// robots
|
|
373
|
-
robots: seoMetadata?.robots || defaults.robots,
|
|
374
|
-
// -----------------------------------------------------------------------
|
|
375
|
-
// Open Graph
|
|
376
|
-
// -----------------------------------------------------------------------
|
|
377
|
-
openGraph: {
|
|
378
|
-
title: seoMetadata?.ogTitle || void 0,
|
|
379
|
-
description: seoMetadata?.ogDescription || void 0,
|
|
380
|
-
// url
|
|
381
|
-
url: seoMetadata?.ogUrl || seoMetadata?.canonical || void 0,
|
|
382
|
-
// identity
|
|
383
|
-
type: ensureOgType("article", seoMetadata?.ogType),
|
|
384
|
-
siteName: seoMetadata?.ogSiteName || defaults.ogSiteName,
|
|
385
|
-
// image
|
|
386
|
-
images: buildOgImages(
|
|
387
|
-
seoMetadata?.ogImage || `${storageUrl}/${post?.coverImage?.key}`,
|
|
388
|
-
seoMetadata?.ogImageAlt || coverImageT.alt,
|
|
389
|
-
seoMetadata?.ogImageType,
|
|
390
|
-
seoMetadata?.ogImageWidth,
|
|
391
|
-
seoMetadata?.ogImageHeight
|
|
392
|
-
),
|
|
393
|
-
// locale
|
|
394
|
-
locale: seoMetadata?.ogLocale || void 0,
|
|
395
|
-
alternateLocale: sanitizeStringArray(seoMetadata?.ogLocaleAlternate),
|
|
396
|
-
// article
|
|
397
|
-
publishedTime: toIsoTime(seoMetadata?.ogArticlePublishedTime),
|
|
398
|
-
modifiedTime: toIsoTime(seoMetadata?.ogArticleModifiedTime),
|
|
399
|
-
authors: [
|
|
400
|
-
seoMetadata?.ogArticleAuthor || authorT.authorName || defaults.ogSiteName
|
|
401
|
-
],
|
|
402
|
-
section: seoMetadata?.ogArticleSection,
|
|
403
|
-
tags: sanitizeStringArray(seoMetadata?.ogArticleTag)
|
|
404
|
-
},
|
|
405
|
-
// -----------------------------------------------------------------------
|
|
406
|
-
// Twitter
|
|
407
|
-
// -----------------------------------------------------------------------
|
|
408
|
-
twitter: {
|
|
409
|
-
card: ensureTwitterCard(defaults.twitterCard, seoMetadata?.twitterCard),
|
|
410
|
-
// identity
|
|
411
|
-
site: seoMetadata?.twitterSite || void 0,
|
|
412
|
-
creator: seoMetadata?.twitterCreator || void 0
|
|
413
|
-
}
|
|
414
|
-
};
|
|
415
|
-
};
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
// src/shared/seo-metadata/serialize-json-ld.ts
|
|
419
|
-
var serializeJsonLd = (data) => {
|
|
420
|
-
if (data == null) return "";
|
|
421
|
-
return JSON.stringify(data).replaceAll("<", String.raw`\u003c`).replaceAll(">", String.raw`\u003e`).replaceAll("&", String.raw`\u0026`);
|
|
422
|
-
};
|
|
423
|
-
|
|
424
|
-
// src/shared/units.ts
|
|
425
|
-
var SIZE = {
|
|
426
|
-
BYTE: 1,
|
|
427
|
-
KB: 1024,
|
|
428
|
-
MB: 1024 ** 2,
|
|
429
|
-
GB: 1024 ** 3,
|
|
430
|
-
TB: 1024 ** 4,
|
|
431
|
-
PB: 1024 ** 5
|
|
432
|
-
};
|
|
433
|
-
|
|
434
|
-
export { FILE_TYPES, OG_TYPE_ARRAY, SIZE, TWITTER_CARD_ARRAY, classifyFileType, createBuildArticleMetadata, createBuildTranslations, createBuildWebsiteMetadata, findTranslation, formatFileSize, getMediaInfo, mimeToExtension, result, serializeJsonLd };
|