@yimingliao/cms 0.0.6 → 0.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/dist/index.d.ts +84 -64
- package/dist/index.js +188 -74
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -83,6 +83,20 @@ declare function createCookieService(nextCookies: () => Promise<Awaited<ReturnTy
|
|
|
83
83
|
}) => Promise<void>;
|
|
84
84
|
};
|
|
85
85
|
|
|
86
|
+
type SingleItem = {
|
|
87
|
+
id: string;
|
|
88
|
+
} | null;
|
|
89
|
+
type MultiItems = {
|
|
90
|
+
id: string;
|
|
91
|
+
}[];
|
|
92
|
+
|
|
93
|
+
type BaseTranslation<T extends string = string> = {
|
|
94
|
+
locale: T;
|
|
95
|
+
};
|
|
96
|
+
type Translation<T extends string = string> = BaseTranslation<T> & {
|
|
97
|
+
[k: string]: unknown;
|
|
98
|
+
};
|
|
99
|
+
|
|
86
100
|
declare const ADMIN_ROLES: {
|
|
87
101
|
SUPER_ADMIN: "SUPER_ADMIN";
|
|
88
102
|
ADMIN: "ADMIN";
|
|
@@ -103,13 +117,6 @@ interface Admin {
|
|
|
103
117
|
}
|
|
104
118
|
type AdminSafe = Omit<Admin, "passwordHash">;
|
|
105
119
|
|
|
106
|
-
type BaseTranslation<T extends string = string> = {
|
|
107
|
-
locale: T;
|
|
108
|
-
};
|
|
109
|
-
type Translation<T extends string = string> = BaseTranslation<T> & {
|
|
110
|
-
[k: string]: unknown;
|
|
111
|
-
};
|
|
112
|
-
|
|
113
120
|
interface AdminTranslation extends Translation {
|
|
114
121
|
id: string;
|
|
115
122
|
locale: string;
|
|
@@ -163,7 +170,7 @@ declare const FILE_TYPES: {
|
|
|
163
170
|
};
|
|
164
171
|
type FileType = (typeof FILE_TYPES)[keyof typeof FILE_TYPES];
|
|
165
172
|
|
|
166
|
-
interface File {
|
|
173
|
+
interface File$1 {
|
|
167
174
|
id: string;
|
|
168
175
|
key: string;
|
|
169
176
|
checksum: string;
|
|
@@ -205,10 +212,10 @@ interface Folder {
|
|
|
205
212
|
type FolderFull = Folder & {
|
|
206
213
|
parentFolder: (Folder & {
|
|
207
214
|
subFolders: Folder[];
|
|
208
|
-
files: File[];
|
|
215
|
+
files: File$1[];
|
|
209
216
|
}) | null;
|
|
210
217
|
subFolders: Folder[];
|
|
211
|
-
files: File[];
|
|
218
|
+
files: File$1[];
|
|
212
219
|
};
|
|
213
220
|
|
|
214
221
|
declare const POST_TYPES: {
|
|
@@ -320,7 +327,7 @@ type PostListCard = Post & {
|
|
|
320
327
|
postsInTopic: Post[];
|
|
321
328
|
children: Post[];
|
|
322
329
|
taggedPosts: Post[];
|
|
323
|
-
coverImage: File | null;
|
|
330
|
+
coverImage: File$1 | null;
|
|
324
331
|
translations: PostTranslation[];
|
|
325
332
|
};
|
|
326
333
|
|
|
@@ -344,7 +351,7 @@ type PostFull = Post & {
|
|
|
344
351
|
translations: PostTranslation[];
|
|
345
352
|
};
|
|
346
353
|
|
|
347
|
-
type FileFull = File & {
|
|
354
|
+
type FileFull = File$1 & {
|
|
348
355
|
folder: Folder | null;
|
|
349
356
|
adminAsAvatarImage: Admin[];
|
|
350
357
|
postsAsCoverImage: Post[];
|
|
@@ -358,13 +365,13 @@ type FileFull = File & {
|
|
|
358
365
|
translations: FileTranslation[];
|
|
359
366
|
};
|
|
360
367
|
|
|
361
|
-
type FileCard = File & {
|
|
368
|
+
type FileCard = File$1 & {
|
|
362
369
|
translations: FileTranslation[];
|
|
363
370
|
};
|
|
364
371
|
|
|
365
372
|
type AdminFull = AdminSafe & {
|
|
366
373
|
adminRefreshTokens: AdminRefreshToken[];
|
|
367
|
-
avatarImage: (File & {
|
|
374
|
+
avatarImage: (File$1 & {
|
|
368
375
|
translations: FileTranslation[];
|
|
369
376
|
}) | null;
|
|
370
377
|
posts: Post[];
|
|
@@ -375,12 +382,45 @@ type AdminCard = AdminSafe & {
|
|
|
375
382
|
translations: AdminTranslation[];
|
|
376
383
|
};
|
|
377
384
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
385
|
+
interface Alternate {
|
|
386
|
+
hreflang: string;
|
|
387
|
+
href: string | null;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
interface SeoMetadata {
|
|
382
391
|
id: string;
|
|
383
|
-
|
|
392
|
+
locale: string;
|
|
393
|
+
title: string | null;
|
|
394
|
+
description: string | null;
|
|
395
|
+
author: string | null;
|
|
396
|
+
canonical: string | null;
|
|
397
|
+
alternate: Alternate[];
|
|
398
|
+
robots: string | null;
|
|
399
|
+
ogTitle: string | null;
|
|
400
|
+
ogDescription: string | null;
|
|
401
|
+
ogUrl: string | null;
|
|
402
|
+
ogType: string | null;
|
|
403
|
+
ogSiteName: string | null;
|
|
404
|
+
ogImage: string | null;
|
|
405
|
+
ogImageAlt: string | null;
|
|
406
|
+
ogImageType: string | null;
|
|
407
|
+
ogImageWidth: number | null;
|
|
408
|
+
ogImageHeight: number | null;
|
|
409
|
+
ogLocale: string | null;
|
|
410
|
+
ogLocaleAlternate: string[];
|
|
411
|
+
ogArticlePublishedTime: Date | null;
|
|
412
|
+
ogArticleModifiedTime: Date | null;
|
|
413
|
+
ogArticleAuthor: string | null;
|
|
414
|
+
ogArticleSection: string | null;
|
|
415
|
+
ogArticleTag: string[];
|
|
416
|
+
twitterCard: string | null;
|
|
417
|
+
twitterSite: string | null;
|
|
418
|
+
twitterCreator: string | null;
|
|
419
|
+
jsonLd: object[];
|
|
420
|
+
postId: string;
|
|
421
|
+
createdAt: Date;
|
|
422
|
+
updatedAt: Date;
|
|
423
|
+
}
|
|
384
424
|
|
|
385
425
|
interface CreateParams$4 {
|
|
386
426
|
email: string;
|
|
@@ -498,7 +538,7 @@ interface CreateParams$2 {
|
|
|
498
538
|
}
|
|
499
539
|
interface UpdateParams$2 {
|
|
500
540
|
id: string;
|
|
501
|
-
file: File;
|
|
541
|
+
file: File$1;
|
|
502
542
|
key: string;
|
|
503
543
|
checksum: string;
|
|
504
544
|
fileMeta: {
|
|
@@ -518,10 +558,10 @@ interface UpdateParams$2 {
|
|
|
518
558
|
|
|
519
559
|
declare function createFileCommandRepository(prisma: any): {
|
|
520
560
|
create: ({ fileMeta, folder, translations, ...params }: CreateParams$2) => Promise<FileFull>;
|
|
521
|
-
update: ({ file, id, fileMeta, folder, translations, ...params }: UpdateParams$2) => Promise<File>;
|
|
561
|
+
update: ({ file, id, fileMeta, folder, translations, ...params }: UpdateParams$2) => Promise<File$1>;
|
|
522
562
|
softDelete: ({ id }: {
|
|
523
563
|
id: string;
|
|
524
|
-
}) => Promise<File>;
|
|
564
|
+
}) => Promise<File$1>;
|
|
525
565
|
softDeleteMany: ({ ids }: {
|
|
526
566
|
ids: string[];
|
|
527
567
|
}) => Promise<number>;
|
|
@@ -530,7 +570,7 @@ declare function createFileCommandRepository(prisma: any): {
|
|
|
530
570
|
}) => Promise<number>;
|
|
531
571
|
delete: ({ id }: {
|
|
532
572
|
id: string;
|
|
533
|
-
}) => Promise<File>;
|
|
573
|
+
}) => Promise<File$1>;
|
|
534
574
|
};
|
|
535
575
|
|
|
536
576
|
interface FindListCardsParams$2 {
|
|
@@ -756,46 +796,6 @@ declare function createPostCommandRepository(prisma: any): {
|
|
|
756
796
|
}) => Promise<Post>;
|
|
757
797
|
};
|
|
758
798
|
|
|
759
|
-
interface Alternate {
|
|
760
|
-
hreflang: string;
|
|
761
|
-
href: string | null;
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
interface SeoMetadata {
|
|
765
|
-
id: string;
|
|
766
|
-
locale: string;
|
|
767
|
-
title: string | null;
|
|
768
|
-
description: string | null;
|
|
769
|
-
author: string | null;
|
|
770
|
-
canonical: string | null;
|
|
771
|
-
alternate: Alternate[];
|
|
772
|
-
robots: string | null;
|
|
773
|
-
ogTitle: string | null;
|
|
774
|
-
ogDescription: string | null;
|
|
775
|
-
ogUrl: string | null;
|
|
776
|
-
ogType: string | null;
|
|
777
|
-
ogSiteName: string | null;
|
|
778
|
-
ogImage: string | null;
|
|
779
|
-
ogImageAlt: string | null;
|
|
780
|
-
ogImageType: string | null;
|
|
781
|
-
ogImageWidth: number | null;
|
|
782
|
-
ogImageHeight: number | null;
|
|
783
|
-
ogLocale: string | null;
|
|
784
|
-
ogLocaleAlternate: string[];
|
|
785
|
-
ogArticlePublishedTime: Date | null;
|
|
786
|
-
ogArticleModifiedTime: Date | null;
|
|
787
|
-
ogArticleAuthor: string | null;
|
|
788
|
-
ogArticleSection: string | null;
|
|
789
|
-
ogArticleTag: string[];
|
|
790
|
-
twitterCard: string | null;
|
|
791
|
-
twitterSite: string | null;
|
|
792
|
-
twitterCreator: string | null;
|
|
793
|
-
jsonLd: object[];
|
|
794
|
-
postId: string;
|
|
795
|
-
createdAt: Date;
|
|
796
|
-
updatedAt: Date;
|
|
797
|
-
}
|
|
798
|
-
|
|
799
799
|
interface FindListCardsParams {
|
|
800
800
|
locale: string;
|
|
801
801
|
type: PostType | null;
|
|
@@ -901,4 +901,24 @@ declare const POST_ORDER_BY: ({
|
|
|
901
901
|
index: "asc";
|
|
902
902
|
})[];
|
|
903
903
|
|
|
904
|
-
|
|
904
|
+
declare const mimeToExtension: (mimeType?: string) => string;
|
|
905
|
+
|
|
906
|
+
declare const classifyFileType: (mimeType?: string, extension?: string) => "IMAGE" | "AUDIO" | "VIDEO" | "DOCUMENT" | "ARCHIVE" | "OTHER";
|
|
907
|
+
|
|
908
|
+
interface MediaInfo {
|
|
909
|
+
width: number | null;
|
|
910
|
+
height: number | null;
|
|
911
|
+
duration: number | null;
|
|
912
|
+
}
|
|
913
|
+
declare const getMediaInfo: (file: Blob) => Promise<MediaInfo>;
|
|
914
|
+
|
|
915
|
+
declare const formatFileSize: (size: number, decimals?: number) => string;
|
|
916
|
+
|
|
917
|
+
interface BlobFile extends File {
|
|
918
|
+
id: string;
|
|
919
|
+
width: number | null;
|
|
920
|
+
height: number | null;
|
|
921
|
+
duration: number | null;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
export { ADMIN_ORDER_BY, ADMIN_ROLES, type Admin, type AdminCard, type AdminFull, type AdminRefreshToken, type AdminRole, type AdminSafe, type AdminTranslation, type Alternate, type BaseTranslation, type BlobFile, type DeviceInfo, type ExternalLink, FILE_TYPES, type Faq, type File$1 as File, type FileCard, type FileFull, type FileTranslation, type FileType, type Folder, type FolderFull, type MultiItems, ORDER_BY, POST_ORDER_BY, POST_TYPES, type Post, type PostFull, type PostListCard, type PostTranslation, type PostType, type SeoMetadata, type SingleItem, type TocItem, type Translation, classifyFileType, createAdminCommandRepository, createAdminQueryRepository, createAdminRefreshTokenCommandRepository, createAdminRefreshTokenQueryRepository, createArgon2Service, createCookieService, createCryptoService, createFileCommandRepository, createFileQueryRepository, createFolderCommandRepository, createFolderQueryRepository, createJwtService, createPostCommandRepository, createPostQueryRepository, createSeoMetadataCommandRepository, formatFileSize, getMediaInfo, mimeToExtension };
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import 'next/headers';
|
|
|
5
5
|
import { extension, lookup } from 'mime-types';
|
|
6
6
|
import { ulid } from 'ulid';
|
|
7
7
|
|
|
8
|
-
// src/infrastructure/jwt/jwt.service.ts
|
|
8
|
+
// src/server/infrastructure/jwt/jwt.service.ts
|
|
9
9
|
function createJwtService(config) {
|
|
10
10
|
const { defaultSecret, ...options } = config;
|
|
11
11
|
function sign({
|
|
@@ -195,7 +195,7 @@ function createCookieService(nextCookies, cryptoService) {
|
|
|
195
195
|
};
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
-
// src/database/utils/connect.ts
|
|
198
|
+
// src/server/infrastructure/database/utils/connect.ts
|
|
199
199
|
var ids = (items) => items.map(({ id }) => ({ id }));
|
|
200
200
|
function connectOne(item) {
|
|
201
201
|
return item ? { connect: { id: item.id } } : {};
|
|
@@ -210,7 +210,7 @@ function updateMany(items) {
|
|
|
210
210
|
return { set: ids(items) };
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
// src/database/admin/command/create-admin-command-repository.ts
|
|
213
|
+
// src/server/infrastructure/database/admin/command/create-admin-command-repository.ts
|
|
214
214
|
function createAdminCommandRepository(prisma) {
|
|
215
215
|
async function create({
|
|
216
216
|
// ------------------------------------
|
|
@@ -291,7 +291,7 @@ function createAdminCommandRepository(prisma) {
|
|
|
291
291
|
};
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
-
// src/database/constants.ts
|
|
294
|
+
// src/server/infrastructure/database/constants.ts
|
|
295
295
|
var ORDER_BY = [
|
|
296
296
|
{ updatedAt: "desc" },
|
|
297
297
|
{ createdAt: "desc" },
|
|
@@ -306,14 +306,36 @@ var POST_ORDER_BY = [
|
|
|
306
306
|
...ORDER_BY
|
|
307
307
|
];
|
|
308
308
|
|
|
309
|
-
// src/domain/admin/props.ts
|
|
309
|
+
// src/domain/resources/admin/props.ts
|
|
310
310
|
var ADMIN_ROLES = {
|
|
311
311
|
SUPER_ADMIN: "SUPER_ADMIN",
|
|
312
312
|
ADMIN: "ADMIN",
|
|
313
313
|
EDITOR: "EDITOR"
|
|
314
314
|
};
|
|
315
315
|
|
|
316
|
-
// src/
|
|
316
|
+
// src/domain/resources/file/props.ts
|
|
317
|
+
var FILE_TYPES = {
|
|
318
|
+
IMAGE: "IMAGE",
|
|
319
|
+
AUDIO: "AUDIO",
|
|
320
|
+
VIDEO: "VIDEO",
|
|
321
|
+
DOCUMENT: "DOCUMENT",
|
|
322
|
+
ARCHIVE: "ARCHIVE",
|
|
323
|
+
OTHER: "OTHER"
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
// src/domain/resources/post/props.ts
|
|
327
|
+
var POST_TYPES = {
|
|
328
|
+
TOPIC: "TOPIC",
|
|
329
|
+
CATEGORY: "CATEGORY",
|
|
330
|
+
POST: "POST",
|
|
331
|
+
TAG: "TAG",
|
|
332
|
+
PAGE: "PAGE"
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
// src/domain/resources/constants.ts
|
|
336
|
+
var ROOT_FOLDER_ID = "01ARZ3NDEKTSV4RRFFQ69G5FAV";
|
|
337
|
+
|
|
338
|
+
// src/server/infrastructure/database/admin/include.ts
|
|
317
339
|
var ADMIN_FULL_INCLUDE = {
|
|
318
340
|
// ---------------------------
|
|
319
341
|
// relations: AdminRefreshToken
|
|
@@ -333,7 +355,7 @@ var ADMIN_FULL_INCLUDE = {
|
|
|
333
355
|
translations: true
|
|
334
356
|
};
|
|
335
357
|
|
|
336
|
-
// src/database/utils/create-search.ts
|
|
358
|
+
// src/server/infrastructure/database/utils/create-search.ts
|
|
337
359
|
function buildContainsOr(fields, value) {
|
|
338
360
|
return fields.map((field) => ({
|
|
339
361
|
[field]: { contains: value, mode: "insensitive" }
|
|
@@ -365,7 +387,7 @@ function createSearch({
|
|
|
365
387
|
return conditions.length > 0 ? { OR: conditions } : {};
|
|
366
388
|
}
|
|
367
389
|
|
|
368
|
-
// src/database/utils/create-pagination.ts
|
|
390
|
+
// src/server/infrastructure/database/utils/create-pagination.ts
|
|
369
391
|
function createPagination(page, pageSize) {
|
|
370
392
|
if (!page || !pageSize) return {};
|
|
371
393
|
return {
|
|
@@ -374,7 +396,7 @@ function createPagination(page, pageSize) {
|
|
|
374
396
|
};
|
|
375
397
|
}
|
|
376
398
|
|
|
377
|
-
// src/database/admin/query/create-admin-query-repository.ts
|
|
399
|
+
// src/server/infrastructure/database/admin/query/create-admin-query-repository.ts
|
|
378
400
|
var OMIT_PASSWORD = { omit: { passwordHash: true } };
|
|
379
401
|
function buildWhere(params) {
|
|
380
402
|
if (params.id) return { id: params.id };
|
|
@@ -448,7 +470,7 @@ function createAdminQueryRepository(prisma) {
|
|
|
448
470
|
};
|
|
449
471
|
}
|
|
450
472
|
|
|
451
|
-
// src/database/admin-refresh-token/command/create-admin-refresh-token-command-repository.ts
|
|
473
|
+
// src/server/infrastructure/database/admin-refresh-token/command/create-admin-refresh-token-command-repository.ts
|
|
452
474
|
function createAdminRefreshTokenCommandRepository(prisma) {
|
|
453
475
|
async function create({
|
|
454
476
|
adminId,
|
|
@@ -484,7 +506,7 @@ function createAdminRefreshTokenCommandRepository(prisma) {
|
|
|
484
506
|
};
|
|
485
507
|
}
|
|
486
508
|
|
|
487
|
-
// src/database/admin-refresh-token/query/create-admin-refresh-token-query-repository.ts
|
|
509
|
+
// src/server/infrastructure/database/admin-refresh-token/query/create-admin-refresh-token-query-repository.ts
|
|
488
510
|
function createAdminRefreshTokenQueryRepository(prisma) {
|
|
489
511
|
async function findManyByAdminId({
|
|
490
512
|
adminId
|
|
@@ -507,7 +529,7 @@ function createAdminRefreshTokenQueryRepository(prisma) {
|
|
|
507
529
|
};
|
|
508
530
|
}
|
|
509
531
|
|
|
510
|
-
// src/database/file/include.ts
|
|
532
|
+
// src/server/infrastructure/database/file/include.ts
|
|
511
533
|
var FILE_FULL_INCLUDE = {
|
|
512
534
|
// ---------------------------
|
|
513
535
|
// relations: Folder
|
|
@@ -536,53 +558,157 @@ var FILE_FULL_INCLUDE = {
|
|
|
536
558
|
// ---------------------------
|
|
537
559
|
translations: true
|
|
538
560
|
};
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
IMAGE: "IMAGE",
|
|
543
|
-
AUDIO: "AUDIO",
|
|
544
|
-
VIDEO: "VIDEO",
|
|
545
|
-
DOCUMENT: "DOCUMENT",
|
|
546
|
-
ARCHIVE: "ARCHIVE",
|
|
547
|
-
OTHER: "OTHER"
|
|
561
|
+
var mimeToExtension = (mimeType) => {
|
|
562
|
+
if (!mimeType) return "unknown";
|
|
563
|
+
return (extension(mimeType) || "unknown").toLowerCase();
|
|
548
564
|
};
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
565
|
+
var ARCHIVE_MIME = /* @__PURE__ */ new Set([
|
|
566
|
+
"application/zip",
|
|
567
|
+
"application/x-rar-compressed",
|
|
568
|
+
"application/x-7z-compressed",
|
|
569
|
+
"application/gzip",
|
|
570
|
+
"application/x-tar"
|
|
571
|
+
]);
|
|
572
|
+
var classifyFileType = (mimeType, extension2) => {
|
|
552
573
|
if (!mimeType && extension2) {
|
|
553
|
-
mimeType = lookup(extension2) ||
|
|
554
|
-
}
|
|
555
|
-
if (!mimeType) {
|
|
556
|
-
return FILE_TYPES.OTHER;
|
|
574
|
+
mimeType = lookup(extension2) || void 0;
|
|
557
575
|
}
|
|
558
|
-
if (mimeType
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
if (mimeType.startsWith("
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
if (mimeType.startsWith("audio/")) {
|
|
565
|
-
return FILE_TYPES.AUDIO;
|
|
566
|
-
}
|
|
567
|
-
if (mimeType.startsWith("text/") || mimeType.startsWith("application/")) {
|
|
576
|
+
if (!mimeType) return FILE_TYPES.OTHER;
|
|
577
|
+
if (mimeType.startsWith("image/")) return FILE_TYPES.IMAGE;
|
|
578
|
+
if (mimeType.startsWith("video/")) return FILE_TYPES.VIDEO;
|
|
579
|
+
if (mimeType.startsWith("audio/")) return FILE_TYPES.AUDIO;
|
|
580
|
+
if (ARCHIVE_MIME.has(mimeType)) return FILE_TYPES.ARCHIVE;
|
|
581
|
+
if (mimeType.startsWith("text/") || mimeType === "application/pdf" || mimeType === "application/json" || mimeType === "application/xml") {
|
|
568
582
|
return FILE_TYPES.DOCUMENT;
|
|
569
583
|
}
|
|
570
|
-
if (mimeType
|
|
571
|
-
return FILE_TYPES.ARCHIVE;
|
|
572
|
-
}
|
|
573
|
-
if (mimeType.startsWith("application/x-") || mimeType === "application/octet-stream") {
|
|
574
|
-
return FILE_TYPES.OTHER;
|
|
575
|
-
}
|
|
584
|
+
if (mimeType.startsWith("application/")) return FILE_TYPES.DOCUMENT;
|
|
576
585
|
return FILE_TYPES.OTHER;
|
|
577
586
|
};
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
587
|
+
|
|
588
|
+
// src/shared/blob-file/get-media-info/get-audio-info.ts
|
|
589
|
+
function getAudioInfo(file) {
|
|
590
|
+
return new Promise((resolve, reject) => {
|
|
591
|
+
const audio = document.createElement("audio");
|
|
592
|
+
const objectUrl = URL.createObjectURL(file);
|
|
593
|
+
audio.preload = "metadata";
|
|
594
|
+
const cleanup = () => {
|
|
595
|
+
audio.removeEventListener("loadedmetadata", onLoadedMetadata);
|
|
596
|
+
audio.removeEventListener("error", onError);
|
|
597
|
+
URL.revokeObjectURL(objectUrl);
|
|
598
|
+
};
|
|
599
|
+
const onLoadedMetadata = () => {
|
|
600
|
+
const duration = audio.duration;
|
|
601
|
+
cleanup();
|
|
602
|
+
resolve({ duration });
|
|
603
|
+
};
|
|
604
|
+
const onError = () => {
|
|
605
|
+
cleanup();
|
|
606
|
+
reject(new Error("Failed to load audio metadata."));
|
|
607
|
+
};
|
|
608
|
+
audio.addEventListener("loadedmetadata", onLoadedMetadata, { once: true });
|
|
609
|
+
audio.addEventListener("error", onError, { once: true });
|
|
610
|
+
audio.src = objectUrl;
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// src/shared/blob-file/get-media-info/get-image-info.ts
|
|
615
|
+
function getImageInfo(file) {
|
|
616
|
+
return new Promise((resolve, reject) => {
|
|
617
|
+
const img = new Image();
|
|
618
|
+
const objectUrl = URL.createObjectURL(file);
|
|
619
|
+
const cleanup = () => {
|
|
620
|
+
img.removeEventListener("load", onLoad);
|
|
621
|
+
img.removeEventListener("error", onError);
|
|
622
|
+
URL.revokeObjectURL(objectUrl);
|
|
623
|
+
};
|
|
624
|
+
const onLoad = () => {
|
|
625
|
+
const width = img.naturalWidth;
|
|
626
|
+
const height = img.naturalHeight;
|
|
627
|
+
cleanup();
|
|
628
|
+
resolve({ width, height });
|
|
629
|
+
};
|
|
630
|
+
const onError = () => {
|
|
631
|
+
cleanup();
|
|
632
|
+
reject(new Error("Failed to load image for size detection."));
|
|
633
|
+
};
|
|
634
|
+
img.addEventListener("load", onLoad, { once: true });
|
|
635
|
+
img.addEventListener("error", onError, { once: true });
|
|
636
|
+
img.src = objectUrl;
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
// src/shared/blob-file/get-media-info/get-video-info.ts
|
|
641
|
+
function getVideoInfo(file) {
|
|
642
|
+
return new Promise((resolve, reject) => {
|
|
643
|
+
const video = document.createElement("video");
|
|
644
|
+
const objectUrl = URL.createObjectURL(file);
|
|
645
|
+
video.preload = "metadata";
|
|
646
|
+
const cleanup = () => {
|
|
647
|
+
video.removeEventListener("loadedmetadata", onLoadedMetadata);
|
|
648
|
+
video.removeEventListener("error", onError);
|
|
649
|
+
video.src = "";
|
|
650
|
+
URL.revokeObjectURL(objectUrl);
|
|
651
|
+
};
|
|
652
|
+
const onLoadedMetadata = () => {
|
|
653
|
+
const info = {
|
|
654
|
+
width: video.videoWidth,
|
|
655
|
+
height: video.videoHeight,
|
|
656
|
+
duration: video.duration
|
|
657
|
+
};
|
|
658
|
+
cleanup();
|
|
659
|
+
resolve(info);
|
|
660
|
+
};
|
|
661
|
+
const onError = () => {
|
|
662
|
+
cleanup();
|
|
663
|
+
reject(new Error("Failed to load video metadata."));
|
|
664
|
+
};
|
|
665
|
+
video.addEventListener("loadedmetadata", onLoadedMetadata, { once: true });
|
|
666
|
+
video.addEventListener("error", onError, { once: true });
|
|
667
|
+
video.src = objectUrl;
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// src/shared/blob-file/get-media-info/get-media-info.ts
|
|
672
|
+
var IMAGE_EXT = /\.(jpe?g|png|gif|webp|bmp|avif)$/i;
|
|
673
|
+
var VIDEO_EXT = /\.(mp4|webm|mov|mkv)$/i;
|
|
674
|
+
var AUDIO_EXT = /\.(mp3|wav|ogg|m4a)$/i;
|
|
675
|
+
var getMediaInfo = async (file) => {
|
|
676
|
+
const fallback = { width: null, height: null, duration: null };
|
|
677
|
+
const mime = file.type || "";
|
|
678
|
+
const name = file instanceof File ? file.name.toLowerCase() : "";
|
|
679
|
+
try {
|
|
680
|
+
if (mime.startsWith("image/") || IMAGE_EXT.test(name)) {
|
|
681
|
+
const { width, height } = await getImageInfo(file);
|
|
682
|
+
return { width, height, duration: null };
|
|
683
|
+
}
|
|
684
|
+
if (mime.startsWith("video/") || VIDEO_EXT.test(name)) {
|
|
685
|
+
const { width, height, duration } = await getVideoInfo(file);
|
|
686
|
+
return { width, height, duration };
|
|
687
|
+
}
|
|
688
|
+
if (mime.startsWith("audio/") || AUDIO_EXT.test(name)) {
|
|
689
|
+
const { duration } = await getAudioInfo(file);
|
|
690
|
+
return { width: null, height: null, duration };
|
|
691
|
+
}
|
|
692
|
+
return fallback;
|
|
693
|
+
} catch {
|
|
694
|
+
return fallback;
|
|
695
|
+
}
|
|
696
|
+
};
|
|
697
|
+
|
|
698
|
+
// src/shared/blob-file/format-file-size.ts
|
|
699
|
+
var formatFileSize = (size, decimals = 2) => {
|
|
700
|
+
const units = ["B", "KB", "MB", "GB", "TB"];
|
|
701
|
+
let value = size;
|
|
702
|
+
let unitIndex = 0;
|
|
703
|
+
while (value >= 1024 && unitIndex < units.length - 1) {
|
|
704
|
+
value /= 1024;
|
|
705
|
+
unitIndex++;
|
|
581
706
|
}
|
|
582
|
-
|
|
707
|
+
const display = unitIndex === 0 ? value.toString() : value.toFixed(decimals);
|
|
708
|
+
return `${display} ${units[unitIndex]}`;
|
|
583
709
|
};
|
|
584
710
|
|
|
585
|
-
// src/database/file/command/create-file-command-repository.ts
|
|
711
|
+
// src/server/infrastructure/database/file/command/create-file-command-repository.ts
|
|
586
712
|
function createFileCommandRepository(prisma) {
|
|
587
713
|
async function create({
|
|
588
714
|
// meta
|
|
@@ -599,7 +725,7 @@ function createFileCommandRepository(prisma) {
|
|
|
599
725
|
// rest
|
|
600
726
|
...params
|
|
601
727
|
}) {
|
|
602
|
-
const extension2 =
|
|
728
|
+
const extension2 = mimeToExtension(fileMeta.type);
|
|
603
729
|
const created = await prisma.file.create({
|
|
604
730
|
data: {
|
|
605
731
|
...params,
|
|
@@ -608,7 +734,7 @@ function createFileCommandRepository(prisma) {
|
|
|
608
734
|
size: fileMeta.size ?? 0,
|
|
609
735
|
extension: extension2,
|
|
610
736
|
mimeType: fileMeta.type || "unknown",
|
|
611
|
-
type:
|
|
737
|
+
type: classifyFileType(fileMeta.type, extension2),
|
|
612
738
|
// ------------------------------------------------------------------------
|
|
613
739
|
// relations
|
|
614
740
|
// ------------------------------------------------------------------------
|
|
@@ -646,7 +772,7 @@ function createFileCommandRepository(prisma) {
|
|
|
646
772
|
// rest
|
|
647
773
|
...params
|
|
648
774
|
}) {
|
|
649
|
-
const extension2 =
|
|
775
|
+
const extension2 = mimeToExtension(fileMeta.type);
|
|
650
776
|
const updated = await prisma.file.update({
|
|
651
777
|
where: { id: file.id },
|
|
652
778
|
data: {
|
|
@@ -655,7 +781,7 @@ function createFileCommandRepository(prisma) {
|
|
|
655
781
|
size: fileMeta.size ?? file.size,
|
|
656
782
|
extension: fileMeta ? extension2 : file.extension,
|
|
657
783
|
mimeType: fileMeta.type || file.mimeType,
|
|
658
|
-
type: fileMeta.type ?
|
|
784
|
+
type: fileMeta.type ? classifyFileType(fileMeta.type, extension2) : file.type,
|
|
659
785
|
// ------------------------------------------------------------------------
|
|
660
786
|
// relations
|
|
661
787
|
// ------------------------------------------------------------------------
|
|
@@ -712,7 +838,7 @@ function createFileCommandRepository(prisma) {
|
|
|
712
838
|
};
|
|
713
839
|
}
|
|
714
840
|
|
|
715
|
-
// src/database/utils/build-file-usage.ts
|
|
841
|
+
// src/server/infrastructure/database/utils/build-file-usage.ts
|
|
716
842
|
function buildFileUsage(isLocked) {
|
|
717
843
|
const relations = [
|
|
718
844
|
"adminAsAvatarImage",
|
|
@@ -732,10 +858,7 @@ function buildFileUsage(isLocked) {
|
|
|
732
858
|
return isLocked ? { OR: condition } : { AND: condition };
|
|
733
859
|
}
|
|
734
860
|
|
|
735
|
-
// src/
|
|
736
|
-
var ROOT_FOLDER_ID = "01ARZ3NDEKTSV4RRFFQ69G5FAV";
|
|
737
|
-
|
|
738
|
-
// src/database/file/query/create-file-query-repository.ts
|
|
861
|
+
// src/server/infrastructure/database/file/query/create-file-query-repository.ts
|
|
739
862
|
function createFileQueryRepository(prisma) {
|
|
740
863
|
async function findListCards({
|
|
741
864
|
locale,
|
|
@@ -801,7 +924,7 @@ function createFileQueryRepository(prisma) {
|
|
|
801
924
|
};
|
|
802
925
|
}
|
|
803
926
|
|
|
804
|
-
// src/database/folder/command/create-folder-command-repository.ts
|
|
927
|
+
// src/server/infrastructure/database/folder/command/create-folder-command-repository.ts
|
|
805
928
|
function createFolderCommandRepository(prisma) {
|
|
806
929
|
async function create({
|
|
807
930
|
// ------------------------------------
|
|
@@ -860,7 +983,7 @@ function createFolderCommandRepository(prisma) {
|
|
|
860
983
|
};
|
|
861
984
|
}
|
|
862
985
|
|
|
863
|
-
// src/database/folder/include.ts
|
|
986
|
+
// src/server/infrastructure/database/folder/include.ts
|
|
864
987
|
var FOLDER_FULL_INCLUDE = {
|
|
865
988
|
// ---------------------------
|
|
866
989
|
// relations: Folder
|
|
@@ -873,7 +996,7 @@ var FOLDER_FULL_INCLUDE = {
|
|
|
873
996
|
files: true
|
|
874
997
|
};
|
|
875
998
|
|
|
876
|
-
// src/database/folder/query/create-folder-query-repository.ts
|
|
999
|
+
// src/server/infrastructure/database/folder/query/create-folder-query-repository.ts
|
|
877
1000
|
function buildWhere2(params) {
|
|
878
1001
|
if (params.id) return { id: params.id };
|
|
879
1002
|
if (params.key) return { key: params.key };
|
|
@@ -1108,7 +1231,7 @@ function createPostCommandRepository(prisma) {
|
|
|
1108
1231
|
};
|
|
1109
1232
|
}
|
|
1110
1233
|
|
|
1111
|
-
// src/database/post/include.ts
|
|
1234
|
+
// src/server/infrastructure/database/post/include.ts
|
|
1112
1235
|
var POST_LIST_CARD_INCLUDE = {
|
|
1113
1236
|
// ---------------------------
|
|
1114
1237
|
// relations: Post
|
|
@@ -1165,7 +1288,7 @@ var POST_FULL_INCLUDE = {
|
|
|
1165
1288
|
translations: true
|
|
1166
1289
|
};
|
|
1167
1290
|
|
|
1168
|
-
// src/database/post/query/create-post-query-repository.ts
|
|
1291
|
+
// src/server/infrastructure/database/post/query/create-post-query-repository.ts
|
|
1169
1292
|
function buildWhere3(params) {
|
|
1170
1293
|
if (params.id) return { id: params.id };
|
|
1171
1294
|
if (params.type && params.slug)
|
|
@@ -1264,7 +1387,7 @@ function createPostQueryRepository(prisma) {
|
|
|
1264
1387
|
};
|
|
1265
1388
|
}
|
|
1266
1389
|
|
|
1267
|
-
// src/database/seo-metadata/command/create-seo-metadata-command-repository.ts
|
|
1390
|
+
// src/server/infrastructure/database/seo-metadata/command/create-seo-metadata-command-repository.ts
|
|
1268
1391
|
function createSeoMetadataCommandRepository(prisma) {
|
|
1269
1392
|
async function upsert({
|
|
1270
1393
|
// ------------------------------------
|
|
@@ -1295,13 +1418,4 @@ function createSeoMetadataCommandRepository(prisma) {
|
|
|
1295
1418
|
};
|
|
1296
1419
|
}
|
|
1297
1420
|
|
|
1298
|
-
|
|
1299
|
-
var POST_TYPES = {
|
|
1300
|
-
TOPIC: "TOPIC",
|
|
1301
|
-
CATEGORY: "CATEGORY",
|
|
1302
|
-
POST: "POST",
|
|
1303
|
-
TAG: "TAG",
|
|
1304
|
-
PAGE: "PAGE"
|
|
1305
|
-
};
|
|
1306
|
-
|
|
1307
|
-
export { ADMIN_ORDER_BY, ADMIN_ROLES, FILE_TYPES, ORDER_BY, POST_ORDER_BY, POST_TYPES, createAdminCommandRepository, createAdminQueryRepository, createAdminRefreshTokenCommandRepository, createAdminRefreshTokenQueryRepository, createArgon2Service, createCookieService, createCryptoService, createFileCommandRepository, createFileQueryRepository, createFolderCommandRepository, createFolderQueryRepository, createJwtService, createPostCommandRepository, createPostQueryRepository, createSeoMetadataCommandRepository };
|
|
1421
|
+
export { ADMIN_ORDER_BY, ADMIN_ROLES, FILE_TYPES, ORDER_BY, POST_ORDER_BY, POST_TYPES, classifyFileType, createAdminCommandRepository, createAdminQueryRepository, createAdminRefreshTokenCommandRepository, createAdminRefreshTokenQueryRepository, createArgon2Service, createCookieService, createCryptoService, createFileCommandRepository, createFileQueryRepository, createFolderCommandRepository, createFolderQueryRepository, createJwtService, createPostCommandRepository, createPostQueryRepository, createSeoMetadataCommandRepository, formatFileSize, getMediaInfo, mimeToExtension };
|