@yimingliao/cms 0.0.65 → 0.0.66
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-3BIU5JZA.js → chunk-3J5YR2NA.js} +1 -1
- package/dist/client/index.js +4 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/server/index.d.ts +51 -50
- package/dist/server/index.js +129 -121
- package/dist/storage/r2/index.d.ts +1 -1
- package/dist/storage/r2/index.js +2 -2
- package/dist/storage/sftp/index.d.ts +2 -2
- package/dist/storage/sftp/index.js +2 -2
- package/package.json +14 -1
- package/dist/{chunk-HMJ53TVF.js → chunk-N2PRNBP2.js} +13 -13
package/dist/client/index.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -3,8 +3,8 @@ export { A as ADMIN_ROLES, d as Admin, e as AdminCard, f as AdminFull, g as Admi
|
|
|
3
3
|
export { B as BlobFile } from './types-0oS1A2K5.js';
|
|
4
4
|
import { E as ErrorDetail, S as SuccessResult, a as ErrorResult } from './types-DHlRoJwv.js';
|
|
5
5
|
export { R as Result } from './types-DHlRoJwv.js';
|
|
6
|
-
import { Metadata } from 'next';
|
|
7
6
|
import { Robots } from 'next/dist/lib/metadata/types/metadata-types';
|
|
7
|
+
import { Metadata } from 'next';
|
|
8
8
|
|
|
9
9
|
declare const isFolderLocked: (folder?: FolderFull | Folder) => boolean;
|
|
10
10
|
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { ADMIN_ROLES, POST_TYPES, ROOT_FOLDER, ROOT_FOLDER_ID, ROOT_FOLDER_NAME, SIMPLE_UPLOAD_FOLDER_KEY, SIMPLE_UPLOAD_FOLDER_NAME, isFileLocked, isFolderLocked } from './chunk-FUAJWL2N.js';
|
|
2
|
-
export { FILE_TYPES, OG_TYPE_ARRAY, SIZE, TWITTER_CARD_ARRAY, classifyFileType, createBuildArticleMetadata, createBuildTranslations, createBuildWebsiteMetadata, datetimeToDb, datetimeToUi, findTranslation, formatFileSize, getMediaInfo, jsonArrayToDb, jsonArrayToUi, mimeToExtension, result, serializeJsonLd } from './chunk-
|
|
2
|
+
export { FILE_TYPES, OG_TYPE_ARRAY, SIZE, TWITTER_CARD_ARRAY, classifyFileType, createBuildArticleMetadata, createBuildTranslations, createBuildWebsiteMetadata, datetimeToDb, datetimeToUi, findTranslation, formatFileSize, getMediaInfo, jsonArrayToDb, jsonArrayToUi, mimeToExtension, result, serializeJsonLd } from './chunk-N2PRNBP2.js';
|
package/dist/server/index.d.ts
CHANGED
|
@@ -3,15 +3,16 @@ import { BinaryLike } from 'node:crypto';
|
|
|
3
3
|
import { cookies } from 'next/headers';
|
|
4
4
|
import Keyv from 'keyv';
|
|
5
5
|
import { Logger } from 'logry';
|
|
6
|
+
import { PrismaClient } from '@prisma/client';
|
|
6
7
|
import * as zod from 'zod';
|
|
7
8
|
import zod__default, { z, ZodType } from 'zod';
|
|
8
9
|
import { B as BlobFile } from '../types-0oS1A2K5.js';
|
|
9
10
|
import * as zod_v4_core from 'zod/v4/core';
|
|
10
11
|
import { T as TocItem, h as AdminRole, v as SingleItem, B as BaseTranslation, d as Admin, f as AdminFull, i as AdminSafe, D as DeviceInfo, g as AdminRefreshToken, n as File$1, b as FileFull, p as FileType, a as Folder, F as FolderFull, u as PostType, M as MultiItems, E as ExternalLink, m as Faq, r as Post, s as PostListCard, t as PostTranslation, P as PostFull, k as Alternate, e as AdminCard, c as FileCard } from '../card-BG2vtuIz.js';
|
|
11
12
|
import * as nodemailer_lib_smtp_transport from 'nodemailer/lib/smtp-transport';
|
|
12
|
-
import nodemailer, { Transporter } from 'nodemailer';
|
|
13
|
-
import { BaseTranslator, LocaleMessages } from 'intor';
|
|
13
|
+
import nodemailer, { Transporter, SentMessageInfo } from 'nodemailer';
|
|
14
14
|
import { S as SuccessResult, R as Result } from '../types-DHlRoJwv.js';
|
|
15
|
+
import { BaseTranslator, LocaleMessages } from 'intor';
|
|
15
16
|
import { NextResponse } from 'next/server';
|
|
16
17
|
import { S as StorageService } from '../types-J25u1G6t.js';
|
|
17
18
|
|
|
@@ -109,6 +110,12 @@ declare function createIpRateLimiter({ appName, cache, headers, }: {
|
|
|
109
110
|
headers: () => Promise<Headers>;
|
|
110
111
|
}): ({ key: rawKey, maxAttempts, timeWindow, }: RateLimiterOptions) => Promise<boolean>;
|
|
111
112
|
|
|
113
|
+
type ExistOptions = {
|
|
114
|
+
table: string;
|
|
115
|
+
column?: string;
|
|
116
|
+
};
|
|
117
|
+
declare function createExist(prisma: PrismaClient): (value: string | number, options: ExistOptions) => Promise<boolean>;
|
|
118
|
+
|
|
112
119
|
type Scope = {
|
|
113
120
|
name: string;
|
|
114
121
|
value: string;
|
|
@@ -120,13 +127,7 @@ type UniqueOptions = {
|
|
|
120
127
|
scope?: Scope[];
|
|
121
128
|
excludeSelf?: Scope;
|
|
122
129
|
};
|
|
123
|
-
declare function createUnique(prisma:
|
|
124
|
-
|
|
125
|
-
type ExistOptions = {
|
|
126
|
-
table: string;
|
|
127
|
-
column?: string;
|
|
128
|
-
};
|
|
129
|
-
declare function createExist(prisma: any): (value: string | number, options: ExistOptions) => Promise<boolean>;
|
|
130
|
+
declare function createUnique(prisma: PrismaClient): (value: string, options: UniqueOptions) => Promise<boolean>;
|
|
130
131
|
|
|
131
132
|
declare module "zod" {
|
|
132
133
|
interface ZodString {
|
|
@@ -216,7 +217,7 @@ declare function createSendEmail({ transporter, config, }: {
|
|
|
216
217
|
replyToName: string;
|
|
217
218
|
replyToaddress: string;
|
|
218
219
|
};
|
|
219
|
-
}): (options: SendEmailOptions) => Promise<
|
|
220
|
+
}): (options: SendEmailOptions) => Promise<SentMessageInfo>;
|
|
220
221
|
|
|
221
222
|
declare function createRenderEmailTemplate({ siteName, webUrl, logoUrl, logger, }: {
|
|
222
223
|
siteName: string;
|
|
@@ -263,7 +264,7 @@ interface UpdateParams$3 {
|
|
|
263
264
|
emailVerifiedAt: Date | null;
|
|
264
265
|
}
|
|
265
266
|
|
|
266
|
-
declare function createAdminCommandRepository(prisma:
|
|
267
|
+
declare function createAdminCommandRepository(prisma: PrismaClient): {
|
|
267
268
|
create: ({ role, email, passwordHash, socialLinks, avatarImage, translations, }: CreateParams$4) => Promise<Admin>;
|
|
268
269
|
update: ({ id, role, email, socialLinks, avatarImage, translations, emailVerifiedAt, }: UpdateParams$3) => Promise<Admin>;
|
|
269
270
|
delete: ({ id }: {
|
|
@@ -284,7 +285,7 @@ interface FindParams$2 {
|
|
|
284
285
|
email?: string;
|
|
285
286
|
}
|
|
286
287
|
|
|
287
|
-
declare function createAdminQueryRepository(prisma:
|
|
288
|
+
declare function createAdminQueryRepository(prisma: PrismaClient): {
|
|
288
289
|
findListCards: ({ locale, searchString, role, adminIds, page, pageSize, }: FindListCardsParams$3) => Promise<{
|
|
289
290
|
items: AdminFull[];
|
|
290
291
|
total: number;
|
|
@@ -307,13 +308,13 @@ interface DeleteParams {
|
|
|
307
308
|
tokenHash?: string;
|
|
308
309
|
}
|
|
309
310
|
|
|
310
|
-
declare function createAdminRefreshTokenCommandRepository(prisma:
|
|
311
|
+
declare function createAdminRefreshTokenCommandRepository(prisma: PrismaClient): {
|
|
311
312
|
create: ({ adminId, ...params }: CreateParams$3) => Promise<AdminRefreshToken>;
|
|
312
313
|
delete: ({ id, tokenHash }: DeleteParams) => Promise<void>;
|
|
313
314
|
deleteManyByExpired: () => Promise<number>;
|
|
314
315
|
};
|
|
315
316
|
|
|
316
|
-
declare function createAdminRefreshTokenQueryRepository(prisma:
|
|
317
|
+
declare function createAdminRefreshTokenQueryRepository(prisma: PrismaClient): {
|
|
317
318
|
findManyByAdminId: ({ adminId, }: {
|
|
318
319
|
adminId: string;
|
|
319
320
|
}) => Promise<AdminRefreshToken[]>;
|
|
@@ -359,7 +360,7 @@ interface UpdateParams$2 {
|
|
|
359
360
|
})[];
|
|
360
361
|
}
|
|
361
362
|
|
|
362
|
-
declare function createFileCommandRepository(prisma:
|
|
363
|
+
declare function createFileCommandRepository(prisma: PrismaClient): {
|
|
363
364
|
create: ({ key, checksum, fileMeta, width, height, duration, folder, translations, }: CreateParams$2) => Promise<FileFull>;
|
|
364
365
|
update: ({ file, id, key, checksum, fileMeta, width, height, duration, folder, translations, }: UpdateParams$2) => Promise<File$1>;
|
|
365
366
|
softDelete: ({ id }: {
|
|
@@ -388,7 +389,7 @@ interface FindListCardsParams$2 {
|
|
|
388
389
|
pageSize?: number;
|
|
389
390
|
}
|
|
390
391
|
|
|
391
|
-
declare function createFileQueryRepository(prisma:
|
|
392
|
+
declare function createFileQueryRepository(prisma: PrismaClient): {
|
|
392
393
|
findListCards: ({ locale, page, pageSize, searchString, type, folderId, isLocked, isDeleted, fileIds, }: FindListCardsParams$2) => Promise<{
|
|
393
394
|
items: FileFull[];
|
|
394
395
|
total: number;
|
|
@@ -413,7 +414,7 @@ interface UpdateParams$1 {
|
|
|
413
414
|
parentFolder: Folder | null;
|
|
414
415
|
}
|
|
415
416
|
|
|
416
|
-
declare function createFolderCommandRepository(prisma:
|
|
417
|
+
declare function createFolderCommandRepository(prisma: PrismaClient): {
|
|
417
418
|
create: ({ key, name, parentFolder, }: CreateParams$1) => Promise<Folder>;
|
|
418
419
|
update: ({ id, key, name, parentFolder, }: UpdateParams$1) => Promise<Folder>;
|
|
419
420
|
delete: ({ id }: {
|
|
@@ -433,7 +434,7 @@ interface FindParams$1 {
|
|
|
433
434
|
key?: string;
|
|
434
435
|
}
|
|
435
436
|
|
|
436
|
-
declare function createFolderQueryRepository(prisma:
|
|
437
|
+
declare function createFolderQueryRepository(prisma: PrismaClient): {
|
|
437
438
|
findListCards: ({ searchString, parentFolderId, folderIds, page, pageSize, }: FindListCardsParams$1) => Promise<{
|
|
438
439
|
items: FolderFull[];
|
|
439
440
|
total: number;
|
|
@@ -591,7 +592,7 @@ interface UpdateParams {
|
|
|
591
592
|
})[];
|
|
592
593
|
}
|
|
593
594
|
|
|
594
|
-
declare function createPostCommandRepository(prisma:
|
|
595
|
+
declare function createPostCommandRepository(prisma: PrismaClient): {
|
|
595
596
|
create: ({ slug, author, topicId, parents, tags, relatedPosts, coverImage, contentImageIds, images1, images2, image1, image2, image3, image4, translations, ...params }: CreateParams) => Promise<Post>;
|
|
596
597
|
update: ({ id, slug, author, topicId, parents, tags, relatedPosts, coverImage, contentImageIds, images1, images2, image1, image2, image3, image4, translations, ...params }: UpdateParams) => Promise<Post>;
|
|
597
598
|
delete: ({ id }: {
|
|
@@ -639,7 +640,7 @@ interface FindManyParams {
|
|
|
639
640
|
topicId?: string;
|
|
640
641
|
}
|
|
641
642
|
|
|
642
|
-
declare function createPostQueryRepository(prisma:
|
|
643
|
+
declare function createPostQueryRepository(prisma: PrismaClient): {
|
|
643
644
|
findListCards: ({ locale, searchString, type, isActive, isIndexActive, isSlugActive, isFeatured, isShownOnHome, state1, state2, state3, state4, state5, state6, state7, state8, state9, state10, topicId, topicSlug, categoryId, categorySlug, postIds, excludeIds, page, pageSize, }: FindListCardsParams) => Promise<{
|
|
644
645
|
items: PostListCard[];
|
|
645
646
|
total: number;
|
|
@@ -686,7 +687,7 @@ interface UpsertParams {
|
|
|
686
687
|
})[];
|
|
687
688
|
}
|
|
688
689
|
|
|
689
|
-
declare function createSeoMetadataCommandRepository(prisma:
|
|
690
|
+
declare function createSeoMetadataCommandRepository(prisma: PrismaClient): {
|
|
690
691
|
upsert: ({ postId, translations, }: UpsertParams) => Promise<void>;
|
|
691
692
|
};
|
|
692
693
|
|
|
@@ -739,8 +740,36 @@ interface CreateExecuteApiParams {
|
|
|
739
740
|
}
|
|
740
741
|
declare function createExecuteApi({ initI18n, logger }: CreateExecuteApiParams): (fn: Api) => Promise<NextResponse<unknown>>;
|
|
741
742
|
|
|
743
|
+
interface CreateVerifyAccessTokenParams {
|
|
744
|
+
adminQueryRepository: ReturnType<typeof createAdminQueryRepository>;
|
|
745
|
+
jwtService: ReturnType<typeof createJwtService>;
|
|
746
|
+
cryptoService: ReturnType<typeof createCryptoService>;
|
|
747
|
+
cookieService: ReturnType<typeof createCookieService>;
|
|
748
|
+
config: {
|
|
749
|
+
accessTokenName: string;
|
|
750
|
+
accessTokenSecret: string;
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
declare function createVerifyAccessToken({ adminQueryRepository, jwtService, cryptoService, cookieService, config, }: CreateVerifyAccessTokenParams): () => Promise<{
|
|
754
|
+
admin: AdminFull;
|
|
755
|
+
} | null>;
|
|
756
|
+
|
|
757
|
+
interface CreateVerifyRefreshTokenParams {
|
|
758
|
+
adminQueryRepository: ReturnType<typeof createAdminQueryRepository>;
|
|
759
|
+
adminRefreshTokenQueryRepository: ReturnType<typeof createAdminRefreshTokenQueryRepository>;
|
|
760
|
+
cryptoService: ReturnType<typeof createCryptoService>;
|
|
761
|
+
cookieService: ReturnType<typeof createCookieService>;
|
|
762
|
+
config: {
|
|
763
|
+
refreshTokenName: string;
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
declare function createVerifyRefreshToken({ adminQueryRepository, adminRefreshTokenQueryRepository, cryptoService, cookieService, config, }: CreateVerifyRefreshTokenParams): () => Promise<{
|
|
767
|
+
adminRefreshToken: AdminRefreshToken;
|
|
768
|
+
admin: AdminFull;
|
|
769
|
+
} | null>;
|
|
770
|
+
|
|
742
771
|
interface CreateAuthUseCases {
|
|
743
|
-
prisma:
|
|
772
|
+
prisma: PrismaClient;
|
|
744
773
|
adminQueryRepository: ReturnType<typeof createAdminQueryRepository>;
|
|
745
774
|
adminRefreshTokenCommandRepository: ReturnType<typeof createAdminRefreshTokenCommandRepository>;
|
|
746
775
|
jwtService: ReturnType<typeof createJwtService>;
|
|
@@ -832,34 +861,6 @@ declare function createForgotPasswordEmail({ renderEmailTemplate, sendEmail, aut
|
|
|
832
861
|
send: ({ translator, admin }: SendParams) => Promise<any>;
|
|
833
862
|
};
|
|
834
863
|
|
|
835
|
-
interface CreateVerifyAccessTokenParams {
|
|
836
|
-
adminQueryRepository: ReturnType<typeof createAdminQueryRepository>;
|
|
837
|
-
jwtService: ReturnType<typeof createJwtService>;
|
|
838
|
-
cryptoService: ReturnType<typeof createCryptoService>;
|
|
839
|
-
cookieService: ReturnType<typeof createCookieService>;
|
|
840
|
-
config: {
|
|
841
|
-
accessTokenName: string;
|
|
842
|
-
accessTokenSecret: string;
|
|
843
|
-
};
|
|
844
|
-
}
|
|
845
|
-
declare function createVerifyAccessToken({ adminQueryRepository, jwtService, cryptoService, cookieService, config, }: CreateVerifyAccessTokenParams): () => Promise<{
|
|
846
|
-
admin: AdminFull;
|
|
847
|
-
} | null>;
|
|
848
|
-
|
|
849
|
-
interface CreateVerifyRefreshTokenParams {
|
|
850
|
-
adminQueryRepository: ReturnType<typeof createAdminQueryRepository>;
|
|
851
|
-
adminRefreshTokenQueryRepository: ReturnType<typeof createAdminRefreshTokenQueryRepository>;
|
|
852
|
-
cryptoService: ReturnType<typeof createCryptoService>;
|
|
853
|
-
cookieService: ReturnType<typeof createCookieService>;
|
|
854
|
-
config: {
|
|
855
|
-
refreshTokenName: string;
|
|
856
|
-
};
|
|
857
|
-
}
|
|
858
|
-
declare function createVerifyRefreshToken({ adminQueryRepository, adminRefreshTokenQueryRepository, cryptoService, cookieService, config, }: CreateVerifyRefreshTokenParams): () => Promise<{
|
|
859
|
-
adminRefreshToken: AdminRefreshToken;
|
|
860
|
-
admin: AdminFull;
|
|
861
|
-
} | null>;
|
|
862
|
-
|
|
863
864
|
interface CreateAuthMiddlewareParams {
|
|
864
865
|
adminRefreshTokenCommandRepository: ReturnType<typeof createAdminRefreshTokenCommandRepository>;
|
|
865
866
|
authUseCases: ReturnType<typeof createAuthUseCases>;
|
package/dist/server/index.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { ADMIN_ROLES, isFileLocked, isFolderLocked, ROOT_FOLDER_ID, ROOT_FOLDER, POST_TYPES } from '../chunk-FUAJWL2N.js';
|
|
2
|
-
import { SIZE, result, datetimeToDb, jsonArrayToDb, mimeToExtension, classifyFileType, TWITTER_CARD_ARRAY, OG_TYPE_ARRAY } from '../chunk-
|
|
2
|
+
import { SIZE, result, datetimeToDb, jsonArrayToDb, mimeToExtension, classifyFileType, TWITTER_CARD_ARRAY, OG_TYPE_ARRAY } from '../chunk-N2PRNBP2.js';
|
|
3
3
|
import jwt from 'jsonwebtoken';
|
|
4
4
|
import argon2 from 'argon2';
|
|
5
5
|
import crypto, { timingSafeEqual } from 'crypto';
|
|
6
|
-
import 'next/headers';
|
|
7
6
|
import KeyvRedis from '@keyv/redis';
|
|
8
7
|
import Keyv from 'keyv';
|
|
9
8
|
import { z, ZodError } from 'zod';
|
|
@@ -279,6 +278,8 @@ function createCacheResult(cache2, logger) {
|
|
|
279
278
|
}
|
|
280
279
|
};
|
|
281
280
|
}
|
|
281
|
+
|
|
282
|
+
// src/server/infrastructure/cache/create-ip-rate-limiter.ts
|
|
282
283
|
var DEFAULT_MAX_ATTEMPTS = 10;
|
|
283
284
|
var DEFAULT_TIME_WINDOW = 60;
|
|
284
285
|
var lua = `
|
|
@@ -318,6 +319,49 @@ function createIpRateLimiter({
|
|
|
318
319
|
};
|
|
319
320
|
}
|
|
320
321
|
|
|
322
|
+
// src/server/infrastructure/zod/rules/bcp47.ts
|
|
323
|
+
function bcp47(locale) {
|
|
324
|
+
if (typeof locale !== "string") return false;
|
|
325
|
+
const BCP47_REGEX = new RegExp(
|
|
326
|
+
"^[a-zA-Z]{2,3}(?:-[A-Z][a-z]{3})?" + // optional region
|
|
327
|
+
String.raw`(?:-(?:[A-Z]{2}|\d{3}))?` + // optional variants
|
|
328
|
+
String.raw`(?:-(?:[a-zA-Z0-9]{5,8}|\d[a-zA-Z0-9]{3}))*` + // optional extensions
|
|
329
|
+
"(?:-(?:[0-9A-WY-Za-wy-z]-[a-zA-Z0-9]{2,8}(?:-[a-zA-Z0-9]{2,8})*))*(?:-x(?:-[a-zA-Z0-9]{1,8})+)?$"
|
|
330
|
+
);
|
|
331
|
+
return BCP47_REGEX.test(locale);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// src/server/infrastructure/zod/rules/exist.ts
|
|
335
|
+
function createExist(prisma) {
|
|
336
|
+
return async function exist(value, options) {
|
|
337
|
+
if (!value) return false;
|
|
338
|
+
const column = options.column || "id";
|
|
339
|
+
const query = `
|
|
340
|
+
SELECT COUNT(*) AS count
|
|
341
|
+
FROM ${options.table}
|
|
342
|
+
WHERE ${column} = $1
|
|
343
|
+
`;
|
|
344
|
+
try {
|
|
345
|
+
const result2 = await prisma.$queryRawUnsafe(
|
|
346
|
+
query,
|
|
347
|
+
value
|
|
348
|
+
);
|
|
349
|
+
const count = Number(result2[0]?.count || 0);
|
|
350
|
+
return count > 0;
|
|
351
|
+
} catch (error) {
|
|
352
|
+
console.error("Exist check failed:", error);
|
|
353
|
+
return false;
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// src/server/infrastructure/zod/rules/og-locale.ts
|
|
359
|
+
function ogLocale(locale) {
|
|
360
|
+
if (typeof locale !== "string") return false;
|
|
361
|
+
const OG_LOCALE_REGEX = /^[a-z]{2}_[A-Z]{2}$/;
|
|
362
|
+
return OG_LOCALE_REGEX.test(locale);
|
|
363
|
+
}
|
|
364
|
+
|
|
321
365
|
// src/server/infrastructure/zod/rules/unique.ts
|
|
322
366
|
function createUnique(prisma) {
|
|
323
367
|
return async function unique(value, options) {
|
|
@@ -353,56 +397,13 @@ function createUnique(prisma) {
|
|
|
353
397
|
};
|
|
354
398
|
}
|
|
355
399
|
|
|
356
|
-
// src/server/infrastructure/zod/rules/exist.ts
|
|
357
|
-
function createExist(prisma) {
|
|
358
|
-
return async function exist(value, options) {
|
|
359
|
-
if (!value) return false;
|
|
360
|
-
const column = options.column || "id";
|
|
361
|
-
const query = `
|
|
362
|
-
SELECT COUNT(*) AS count
|
|
363
|
-
FROM ${options.table}
|
|
364
|
-
WHERE ${column} = $1
|
|
365
|
-
`;
|
|
366
|
-
try {
|
|
367
|
-
const result2 = await prisma.$queryRawUnsafe(
|
|
368
|
-
query,
|
|
369
|
-
value
|
|
370
|
-
);
|
|
371
|
-
const count = Number(result2[0]?.count || 0);
|
|
372
|
-
return count > 0;
|
|
373
|
-
} catch (error) {
|
|
374
|
-
console.error("Exist check failed:", error);
|
|
375
|
-
return false;
|
|
376
|
-
}
|
|
377
|
-
};
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
// src/server/infrastructure/zod/rules/bcp47.ts
|
|
381
|
-
function bcp47(locale) {
|
|
382
|
-
if (typeof locale !== "string") return false;
|
|
383
|
-
const BCP47_REGEX = new RegExp(
|
|
384
|
-
"^[a-zA-Z]{2,3}(?:-[A-Z][a-z]{3})?" + // optional region
|
|
385
|
-
String.raw`(?:-(?:[A-Z]{2}|\d{3}))?` + // optional variants
|
|
386
|
-
String.raw`(?:-(?:[a-zA-Z0-9]{5,8}|\d[a-zA-Z0-9]{3}))*` + // optional extensions
|
|
387
|
-
"(?:-(?:[0-9A-WY-Za-wy-z]-[a-zA-Z0-9]{2,8}(?:-[a-zA-Z0-9]{2,8})*))*(?:-x(?:-[a-zA-Z0-9]{1,8})+)?$"
|
|
388
|
-
);
|
|
389
|
-
return BCP47_REGEX.test(locale);
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
// src/server/infrastructure/zod/rules/og-locale.ts
|
|
393
|
-
function ogLocale(locale) {
|
|
394
|
-
if (typeof locale !== "string") return false;
|
|
395
|
-
const OG_LOCALE_REGEX = /^[a-z]{2}_[A-Z]{2}$/;
|
|
396
|
-
return OG_LOCALE_REGEX.test(locale);
|
|
397
|
-
}
|
|
398
|
-
|
|
399
400
|
// src/server/infrastructure/zod/create-zod.ts
|
|
400
401
|
function createZod({
|
|
401
402
|
unique,
|
|
402
403
|
exist
|
|
403
404
|
}) {
|
|
404
|
-
const stringProto = z.
|
|
405
|
-
const emailProto = z.
|
|
405
|
+
const stringProto = z.string().constructor.prototype;
|
|
406
|
+
const emailProto = z.email().constructor.prototype;
|
|
406
407
|
if (!stringProto.unique) {
|
|
407
408
|
Object.defineProperty(stringProto, "unique", {
|
|
408
409
|
configurable: true,
|
|
@@ -477,7 +478,7 @@ function createSchemas({
|
|
|
477
478
|
function positiveNumber() {
|
|
478
479
|
return z2.preprocess((val) => {
|
|
479
480
|
if (val == null || val === "") return;
|
|
480
|
-
const num = Number(
|
|
481
|
+
const num = Number(typeof val === "string" ? val.trim() : val);
|
|
481
482
|
return Number.isNaN(num) ? void 0 : num;
|
|
482
483
|
}, z2.number().min(0).max(MAX_NUMBER));
|
|
483
484
|
}
|
|
@@ -659,7 +660,9 @@ async function readTemplate(filePath) {
|
|
|
659
660
|
if (!isDev) cache.set(filePath, html);
|
|
660
661
|
return html;
|
|
661
662
|
} catch (error) {
|
|
662
|
-
throw new Error(`Email template file not found: ${filePath}
|
|
663
|
+
throw new Error(`Email template file not found: ${filePath}`, {
|
|
664
|
+
cause: error
|
|
665
|
+
});
|
|
663
666
|
}
|
|
664
667
|
}
|
|
665
668
|
function applyReplacements(html, replacements, logger) {
|
|
@@ -689,7 +692,7 @@ function createRenderEmailTemplate({
|
|
|
689
692
|
...replacements
|
|
690
693
|
};
|
|
691
694
|
const layoutHtml = await readTemplate(LAYOUT_PATH);
|
|
692
|
-
|
|
695
|
+
const contentHtml = await readTemplate(contentPath);
|
|
693
696
|
const merged = layoutHtml.replaceAll("{{{content}}}", contentHtml);
|
|
694
697
|
return applyReplacements(merged, vars, logger);
|
|
695
698
|
} catch (error) {
|
|
@@ -699,7 +702,7 @@ function createRenderEmailTemplate({
|
|
|
699
702
|
templateDir: TEMPLATE_DIR,
|
|
700
703
|
error
|
|
701
704
|
});
|
|
702
|
-
throw new Error(`Email template error: ${templateKey}
|
|
705
|
+
throw new Error(`Email template error: ${templateKey}`, { cause: error });
|
|
703
706
|
}
|
|
704
707
|
};
|
|
705
708
|
}
|
|
@@ -839,25 +842,14 @@ var POST_ORDER_BY = [
|
|
|
839
842
|
...ORDER_BY
|
|
840
843
|
];
|
|
841
844
|
|
|
842
|
-
// src/server/infrastructure/database/
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
// ---------------------------
|
|
851
|
-
avatarImage: { include: { translations: true } },
|
|
852
|
-
// ---------------------------
|
|
853
|
-
// relations: Post
|
|
854
|
-
// ---------------------------
|
|
855
|
-
posts: true,
|
|
856
|
-
// ---------------------------
|
|
857
|
-
// translation
|
|
858
|
-
// ---------------------------
|
|
859
|
-
translations: true
|
|
860
|
-
};
|
|
845
|
+
// src/server/infrastructure/database/utils/create-pagination.ts
|
|
846
|
+
function createPagination(page, pageSize) {
|
|
847
|
+
if (!page || !pageSize) return {};
|
|
848
|
+
return {
|
|
849
|
+
skip: (page - 1) * pageSize,
|
|
850
|
+
take: pageSize
|
|
851
|
+
};
|
|
852
|
+
}
|
|
861
853
|
|
|
862
854
|
// src/server/infrastructure/database/utils/create-search.ts
|
|
863
855
|
function buildContainsOr(fields, value) {
|
|
@@ -891,14 +883,25 @@ function createSearch({
|
|
|
891
883
|
return conditions.length > 0 ? { OR: conditions } : {};
|
|
892
884
|
}
|
|
893
885
|
|
|
894
|
-
// src/server/infrastructure/database/
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
886
|
+
// src/server/infrastructure/database/admin/include.ts
|
|
887
|
+
var ADMIN_FULL_INCLUDE = {
|
|
888
|
+
// ---------------------------
|
|
889
|
+
// relations: AdminRefreshToken
|
|
890
|
+
// ---------------------------
|
|
891
|
+
adminRefreshTokens: true,
|
|
892
|
+
// ---------------------------
|
|
893
|
+
// relations: File
|
|
894
|
+
// ---------------------------
|
|
895
|
+
avatarImage: { include: { translations: true } },
|
|
896
|
+
// ---------------------------
|
|
897
|
+
// relations: Post
|
|
898
|
+
// ---------------------------
|
|
899
|
+
posts: true,
|
|
900
|
+
// ---------------------------
|
|
901
|
+
// translation
|
|
902
|
+
// ---------------------------
|
|
903
|
+
translations: true
|
|
904
|
+
};
|
|
902
905
|
|
|
903
906
|
// src/server/infrastructure/database/admin/query/create-admin-query-repository.ts
|
|
904
907
|
var OMIT_PASSWORD = { omit: { passwordHash: true } };
|
|
@@ -1841,8 +1844,8 @@ function createSeoMetadataCommandRepository(prisma) {
|
|
|
1841
1844
|
seoMetadatas: {
|
|
1842
1845
|
upsert: translations.map((t) => ({
|
|
1843
1846
|
where: { postId_locale: { postId, locale: t.locale } },
|
|
1844
|
-
update: t,
|
|
1845
|
-
create: t
|
|
1847
|
+
update: { ...t, alternate: t.alternate },
|
|
1848
|
+
create: { ...t, alternate: t.alternate }
|
|
1846
1849
|
}))
|
|
1847
1850
|
}
|
|
1848
1851
|
}
|
|
@@ -1934,7 +1937,7 @@ function createExecuteAction({
|
|
|
1934
1937
|
...options.ttl ? { ttl: options.ttl } : {},
|
|
1935
1938
|
load: async () => fn(translator)
|
|
1936
1939
|
}) : await fn(translator);
|
|
1937
|
-
if (options.type === "command") cache2.clear();
|
|
1940
|
+
if (options.type === "command") await cache2.clear();
|
|
1938
1941
|
const finalMessage = i18nKey ? translator.t(i18nKey) : message;
|
|
1939
1942
|
return result.success({
|
|
1940
1943
|
...finalMessage ? { message: finalMessage } : {},
|
|
@@ -2815,6 +2818,8 @@ var fileUpdateValidator = (schemas) => schemas.z.object({
|
|
|
2815
2818
|
})
|
|
2816
2819
|
)
|
|
2817
2820
|
});
|
|
2821
|
+
|
|
2822
|
+
// src/server/interfaces/actions/resources/file/commands/update/create-file-update-action.ts
|
|
2818
2823
|
function createFileUpdateAction(ctx) {
|
|
2819
2824
|
const {
|
|
2820
2825
|
services: { storageService },
|
|
@@ -2869,43 +2874,6 @@ function createFileUpdateAction(ctx) {
|
|
|
2869
2874
|
};
|
|
2870
2875
|
}
|
|
2871
2876
|
|
|
2872
|
-
// src/server/interfaces/actions/resources/file/commands/create-many/file-create-many-validator.ts
|
|
2873
|
-
var fileCreateManyValidator = (schemas) => schemas.z.object({
|
|
2874
|
-
uploadResults: schemas.array(
|
|
2875
|
-
schemas.z.object({
|
|
2876
|
-
// core
|
|
2877
|
-
key: schemas.key(),
|
|
2878
|
-
checksum: schemas.sha256Hash(),
|
|
2879
|
-
// file meta
|
|
2880
|
-
fileMeta: schemas.z.object({
|
|
2881
|
-
type: schemas.text(),
|
|
2882
|
-
size: schemas.positiveNumber(),
|
|
2883
|
-
name: schemas.text()
|
|
2884
|
-
}),
|
|
2885
|
-
// media info
|
|
2886
|
-
width: schemas.positiveNumber().nullable(),
|
|
2887
|
-
height: schemas.positiveNumber().nullable(),
|
|
2888
|
-
duration: schemas.positiveNumber().nullable(),
|
|
2889
|
-
// ----------------------------------------------------------------------------
|
|
2890
|
-
// translation
|
|
2891
|
-
// ----------------------------------------------------------------------------
|
|
2892
|
-
translations: schemas.array(
|
|
2893
|
-
schemas.z.object({
|
|
2894
|
-
// core
|
|
2895
|
-
locale: schemas.locale(),
|
|
2896
|
-
// text
|
|
2897
|
-
name: schemas.text().nullable(),
|
|
2898
|
-
alt: schemas.text().nullable()
|
|
2899
|
-
})
|
|
2900
|
-
)
|
|
2901
|
-
})
|
|
2902
|
-
),
|
|
2903
|
-
// ----------------------------------------------------------------------------
|
|
2904
|
-
// relations
|
|
2905
|
-
// ----------------------------------------------------------------------------
|
|
2906
|
-
folder: schemas.z.object({ id: schemas.id().exist({ table: "folders", column: "id" }) }).nullable().optional()
|
|
2907
|
-
});
|
|
2908
|
-
|
|
2909
2877
|
// node_modules/yocto-queue/index.js
|
|
2910
2878
|
var Node = class {
|
|
2911
2879
|
value;
|
|
@@ -3046,6 +3014,43 @@ function validateConcurrency(concurrency) {
|
|
|
3046
3014
|
}
|
|
3047
3015
|
}
|
|
3048
3016
|
|
|
3017
|
+
// src/server/interfaces/actions/resources/file/commands/create-many/file-create-many-validator.ts
|
|
3018
|
+
var fileCreateManyValidator = (schemas) => schemas.z.object({
|
|
3019
|
+
uploadResults: schemas.array(
|
|
3020
|
+
schemas.z.object({
|
|
3021
|
+
// core
|
|
3022
|
+
key: schemas.key(),
|
|
3023
|
+
checksum: schemas.sha256Hash(),
|
|
3024
|
+
// file meta
|
|
3025
|
+
fileMeta: schemas.z.object({
|
|
3026
|
+
type: schemas.text(),
|
|
3027
|
+
size: schemas.positiveNumber(),
|
|
3028
|
+
name: schemas.text()
|
|
3029
|
+
}),
|
|
3030
|
+
// media info
|
|
3031
|
+
width: schemas.positiveNumber().nullable(),
|
|
3032
|
+
height: schemas.positiveNumber().nullable(),
|
|
3033
|
+
duration: schemas.positiveNumber().nullable(),
|
|
3034
|
+
// ----------------------------------------------------------------------------
|
|
3035
|
+
// translation
|
|
3036
|
+
// ----------------------------------------------------------------------------
|
|
3037
|
+
translations: schemas.array(
|
|
3038
|
+
schemas.z.object({
|
|
3039
|
+
// core
|
|
3040
|
+
locale: schemas.locale(),
|
|
3041
|
+
// text
|
|
3042
|
+
name: schemas.text().nullable(),
|
|
3043
|
+
alt: schemas.text().nullable()
|
|
3044
|
+
})
|
|
3045
|
+
)
|
|
3046
|
+
})
|
|
3047
|
+
),
|
|
3048
|
+
// ----------------------------------------------------------------------------
|
|
3049
|
+
// relations
|
|
3050
|
+
// ----------------------------------------------------------------------------
|
|
3051
|
+
folder: schemas.z.object({ id: schemas.id().exist({ table: "folders", column: "id" }) }).nullable().optional()
|
|
3052
|
+
});
|
|
3053
|
+
|
|
3049
3054
|
// src/server/interfaces/actions/resources/file/commands/create-many/create-file-create-many-action.ts
|
|
3050
3055
|
function createFileCreateManyAction(ctx) {
|
|
3051
3056
|
const {
|
|
@@ -3299,6 +3304,8 @@ var folderCreateValidator = (schemas) => schemas.z.object({
|
|
|
3299
3304
|
// Folder
|
|
3300
3305
|
parentFolder: schemas.z.object({ id: schemas.id().exist({ table: "folders", column: "id" }) }).nullable()
|
|
3301
3306
|
});
|
|
3307
|
+
|
|
3308
|
+
// src/server/interfaces/actions/resources/folder/commands/create/create-folder-create-action.ts
|
|
3302
3309
|
function createFolderCreateAction(ctx) {
|
|
3303
3310
|
const {
|
|
3304
3311
|
repositories: { folderCommandRepository },
|
|
@@ -3350,6 +3357,8 @@ var folderUpdateValidator = (schemas, id) => schemas.z.object({
|
|
|
3350
3357
|
// Folder
|
|
3351
3358
|
parentFolder: schemas.z.object({ id: schemas.id().exist({ table: "folders", column: "id" }) }).nullable()
|
|
3352
3359
|
});
|
|
3360
|
+
|
|
3361
|
+
// src/server/interfaces/actions/resources/folder/commands/update/create-folder-update-action.ts
|
|
3353
3362
|
function createFolderUpdateAction(ctx) {
|
|
3354
3363
|
const {
|
|
3355
3364
|
repositories: { folderCommandRepository },
|
|
@@ -4227,12 +4236,11 @@ function createAuthUseCases({
|
|
|
4227
4236
|
token,
|
|
4228
4237
|
admin
|
|
4229
4238
|
}) {
|
|
4230
|
-
let updatedAdmin = admin;
|
|
4231
4239
|
jwtService.verify({
|
|
4232
4240
|
token,
|
|
4233
4241
|
secret: config.verifyEmailSecret
|
|
4234
4242
|
});
|
|
4235
|
-
updatedAdmin = await prisma.admin.update({
|
|
4243
|
+
const updatedAdmin = await prisma.admin.update({
|
|
4236
4244
|
where: { email: admin.email },
|
|
4237
4245
|
data: { emailVerifiedAt: /* @__PURE__ */ new Date() }
|
|
4238
4246
|
});
|
|
@@ -4295,7 +4303,7 @@ function createForgotPasswordEmail({
|
|
|
4295
4303
|
const passwordResetToken = authUseCases.signPasswordResetToken({ admin });
|
|
4296
4304
|
const passwordResetUrl = `${webUrl}/cms/reset-password?passwordResetToken=${passwordResetToken}`;
|
|
4297
4305
|
const html = await generateHtml({ passwordResetUrl });
|
|
4298
|
-
return
|
|
4306
|
+
return sendEmail({
|
|
4299
4307
|
to: admin.email,
|
|
4300
4308
|
subject: translator.t("email.forgot-password.text"),
|
|
4301
4309
|
html
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { S as StorageService } from '../../types-J25u1G6t.js';
|
|
1
2
|
import { S3Client } from '@aws-sdk/client-s3';
|
|
2
3
|
import { Logger } from 'logry';
|
|
3
|
-
import { S as StorageService } from '../../types-J25u1G6t.js';
|
|
4
4
|
import '../../types-0oS1A2K5.js';
|
|
5
5
|
|
|
6
6
|
interface CreateR2ServiceParams {
|
package/dist/storage/r2/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createObjectKey } from '../../chunk-
|
|
2
|
-
import '../../chunk-
|
|
1
|
+
import { createObjectKey } from '../../chunk-3J5YR2NA.js';
|
|
2
|
+
import '../../chunk-N2PRNBP2.js';
|
|
3
3
|
import { PutObjectCommand, DeleteObjectCommand, CopyObjectCommand } from '@aws-sdk/client-s3';
|
|
4
4
|
|
|
5
5
|
function createR2Service({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { S as StorageService } from '../../types-J25u1G6t.js';
|
|
2
2
|
import { Pool } from 'generic-pool';
|
|
3
|
+
import { Logger } from 'logry';
|
|
3
4
|
import SFTPClient from 'ssh2-sftp-client';
|
|
4
|
-
import { S as StorageService } from '../../types-J25u1G6t.js';
|
|
5
5
|
import '../../types-0oS1A2K5.js';
|
|
6
6
|
|
|
7
7
|
interface CreateSftpServiceParams {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createObjectKey } from '../../chunk-
|
|
2
|
-
import '../../chunk-
|
|
1
|
+
import { createObjectKey } from '../../chunk-3J5YR2NA.js';
|
|
2
|
+
import '../../chunk-N2PRNBP2.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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yimingliao/cms",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.66",
|
|
4
4
|
"author": "Yiming Liao",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -37,6 +37,8 @@
|
|
|
37
37
|
],
|
|
38
38
|
"scripts": {
|
|
39
39
|
"type": "tsc --noEmit",
|
|
40
|
+
"lint": "eslint",
|
|
41
|
+
"knip": "knip --config .config/knip.config.ts",
|
|
40
42
|
"build": "tsup",
|
|
41
43
|
"prepublishOnly": "yarn build"
|
|
42
44
|
},
|
|
@@ -52,17 +54,28 @@
|
|
|
52
54
|
},
|
|
53
55
|
"devDependencies": {
|
|
54
56
|
"@aws-sdk/client-s3": "^3.1004.0",
|
|
57
|
+
"@eslint/js": "^10.0.1",
|
|
55
58
|
"@prisma/client": "6.5.0",
|
|
56
59
|
"@types/jsonwebtoken": "^9.0.10",
|
|
57
60
|
"@types/mime-types": "^3.0.1",
|
|
58
61
|
"@types/nodemailer": "^7.0.11",
|
|
59
62
|
"@types/ssh2-sftp-client": "^9.0.6",
|
|
63
|
+
"eslint": "^9",
|
|
64
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
65
|
+
"eslint-plugin-import": "^2.32.0",
|
|
66
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
67
|
+
"eslint-plugin-react": "^7.37.5",
|
|
68
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
69
|
+
"eslint-plugin-unicorn": "^63.0.0",
|
|
70
|
+
"eslint-plugin-unused-imports": "^4.4.1",
|
|
60
71
|
"generic-pool": "^3.9.0",
|
|
61
72
|
"intor": "^2.5.0",
|
|
73
|
+
"knip": "^5.86.0",
|
|
62
74
|
"next": "^16.1.6",
|
|
63
75
|
"prisma": "6.5.0",
|
|
64
76
|
"tsup": "^8.5.1",
|
|
65
77
|
"typescript": "^5.9.3",
|
|
78
|
+
"typescript-eslint": "^8.56.1",
|
|
66
79
|
"zod": "^4.3.6"
|
|
67
80
|
},
|
|
68
81
|
"peerDependencies": {
|
|
@@ -240,13 +240,6 @@ var buildAlternateMap = (alternates = []) => {
|
|
|
240
240
|
}
|
|
241
241
|
return result2;
|
|
242
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
243
|
var buildOgImages = (url, alt, type, width, height) => {
|
|
251
244
|
if (!url) return void 0;
|
|
252
245
|
const mimeType = lookup(url);
|
|
@@ -262,12 +255,11 @@ var buildOgImages = (url, alt, type, width, height) => {
|
|
|
262
255
|
];
|
|
263
256
|
};
|
|
264
257
|
|
|
265
|
-
// src/shared/seo-metadata/utils/
|
|
266
|
-
var
|
|
267
|
-
if (
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
);
|
|
258
|
+
// src/shared/seo-metadata/utils/ensure-og-type.ts
|
|
259
|
+
var ensureOgType = (fallback, ogType) => {
|
|
260
|
+
if (typeof ogType !== "string") return fallback;
|
|
261
|
+
const isValid = OG_TYPE_ARRAY.includes(ogType);
|
|
262
|
+
return isValid ? ogType : fallback;
|
|
271
263
|
};
|
|
272
264
|
|
|
273
265
|
// src/shared/seo-metadata/utils/ensure-twitter-card.ts
|
|
@@ -277,6 +269,14 @@ var ensureTwitterCard = (fallback, twitterCard) => {
|
|
|
277
269
|
return isValid ? twitterCard : fallback;
|
|
278
270
|
};
|
|
279
271
|
|
|
272
|
+
// src/shared/seo-metadata/utils/sanitize-string-array.ts
|
|
273
|
+
var sanitizeStringArray = (array) => {
|
|
274
|
+
if (!Array.isArray(array)) return void 0;
|
|
275
|
+
return array.filter(
|
|
276
|
+
(a) => typeof a === "string" && a.trim() !== ""
|
|
277
|
+
);
|
|
278
|
+
};
|
|
279
|
+
|
|
280
280
|
// src/shared/seo-metadata/build-website-metadata.ts
|
|
281
281
|
function createBuildWebsiteMetadata({
|
|
282
282
|
defaults
|