@mx-space/api-client 2.1.1 → 2.2.0
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/adaptors/axios.cjs +1 -2
- package/dist/adaptors/axios.mjs +1 -2
- package/dist/adaptors/umi-request.cjs +1 -2
- package/dist/adaptors/umi-request.mjs +1 -2
- package/dist/index.cjs +24 -2
- package/dist/index.d.cts +68 -10
- package/dist/index.d.mts +68 -10
- package/dist/index.mjs +24 -2
- package/package.json +3 -3
- package/readme.md +223 -116
package/dist/adaptors/axios.cjs
CHANGED
|
@@ -56,9 +56,8 @@ const axiosAdaptor = Object.preventExtensions({
|
|
|
56
56
|
return $http.patch(url, data, config);
|
|
57
57
|
}
|
|
58
58
|
});
|
|
59
|
-
var axios_default = axiosAdaptor;
|
|
60
59
|
|
|
61
60
|
//#endregion
|
|
62
61
|
exports.__toESM = __toESM;
|
|
63
62
|
exports.axiosAdaptor = axiosAdaptor;
|
|
64
|
-
exports.default =
|
|
63
|
+
exports.default = axiosAdaptor;
|
package/dist/adaptors/axios.mjs
CHANGED
|
@@ -27,7 +27,6 @@ const axiosAdaptor = Object.preventExtensions({
|
|
|
27
27
|
return $http.patch(url, data, config);
|
|
28
28
|
}
|
|
29
29
|
});
|
|
30
|
-
var axios_default = axiosAdaptor;
|
|
31
30
|
|
|
32
31
|
//#endregion
|
|
33
|
-
export { axiosAdaptor,
|
|
32
|
+
export { axiosAdaptor, axiosAdaptor as default };
|
|
@@ -29,8 +29,7 @@ const umiAdaptor = Object.preventExtensions({
|
|
|
29
29
|
return $http.patch(url, options);
|
|
30
30
|
}
|
|
31
31
|
});
|
|
32
|
-
var umi_request_default = umiAdaptor;
|
|
33
32
|
|
|
34
33
|
//#endregion
|
|
35
|
-
exports.default =
|
|
34
|
+
exports.default = umiAdaptor;
|
|
36
35
|
exports.umiAdaptor = umiAdaptor;
|
|
@@ -27,7 +27,6 @@ const umiAdaptor = Object.preventExtensions({
|
|
|
27
27
|
return $http.patch(url, options);
|
|
28
28
|
}
|
|
29
29
|
});
|
|
30
|
-
var umi_request_default = umiAdaptor;
|
|
31
30
|
|
|
32
31
|
//#endregion
|
|
33
|
-
export {
|
|
32
|
+
export { umiAdaptor as default, umiAdaptor };
|
package/dist/index.cjs
CHANGED
|
@@ -201,6 +201,14 @@ var AggregateController = class {
|
|
|
201
201
|
year
|
|
202
202
|
} });
|
|
203
203
|
}
|
|
204
|
+
getLatest(options) {
|
|
205
|
+
const { limit, types, combined } = options || {};
|
|
206
|
+
return this.proxy.latest.get({ params: {
|
|
207
|
+
limit,
|
|
208
|
+
types: types?.join(","),
|
|
209
|
+
combined
|
|
210
|
+
} });
|
|
211
|
+
}
|
|
204
212
|
/**
|
|
205
213
|
* 获取聚合数据统计
|
|
206
214
|
*/
|
|
@@ -414,6 +422,9 @@ var CommentController = class {
|
|
|
414
422
|
size: size || 10
|
|
415
423
|
} });
|
|
416
424
|
}
|
|
425
|
+
getThreadReplies(rootCommentId, params = {}) {
|
|
426
|
+
return this.proxy.thread(rootCommentId).get({ params });
|
|
427
|
+
}
|
|
417
428
|
/**
|
|
418
429
|
* 评论
|
|
419
430
|
*/
|
|
@@ -517,18 +528,29 @@ var NoteController = class {
|
|
|
517
528
|
prefer
|
|
518
529
|
} });
|
|
519
530
|
}
|
|
531
|
+
getNoteBySlugDate(year, month, day, slug, options) {
|
|
532
|
+
const { password, single, lang, prefer } = options || {};
|
|
533
|
+
return this.proxy(year.toString())(month.toString())(day.toString())(slug).get({ params: {
|
|
534
|
+
password,
|
|
535
|
+
single: single ? "1" : void 0,
|
|
536
|
+
lang,
|
|
537
|
+
prefer
|
|
538
|
+
} });
|
|
539
|
+
}
|
|
520
540
|
/**
|
|
521
541
|
* 日记列表分页
|
|
522
542
|
*/
|
|
523
543
|
getList(page = 1, perPage = 10, options = {}) {
|
|
524
|
-
const { select, sortBy, sortOrder, year } = options;
|
|
544
|
+
const { select, sortBy, sortOrder, year, lang, withSummary } = options;
|
|
525
545
|
return this.proxy.get({ params: {
|
|
526
546
|
page,
|
|
527
547
|
size: perPage,
|
|
528
548
|
select: select?.join(" "),
|
|
529
549
|
sortBy,
|
|
530
550
|
sortOrder,
|
|
531
|
-
year
|
|
551
|
+
year,
|
|
552
|
+
lang,
|
|
553
|
+
withSummary: withSummary ? "1" : void 0
|
|
532
554
|
} });
|
|
533
555
|
}
|
|
534
556
|
/**
|
package/dist/index.d.cts
CHANGED
|
@@ -376,6 +376,7 @@ type NoteModel = TextBaseModel & {
|
|
|
376
376
|
publicAt?: Date;
|
|
377
377
|
password?: string | null;
|
|
378
378
|
nid: number;
|
|
379
|
+
slug?: string;
|
|
379
380
|
location?: string;
|
|
380
381
|
coordinates?: Coordinate;
|
|
381
382
|
topic?: TopicModel;
|
|
@@ -622,6 +623,19 @@ interface TimelineData {
|
|
|
622
623
|
url: string;
|
|
623
624
|
})[];
|
|
624
625
|
}
|
|
626
|
+
interface LatestPostItem extends Pick<PostModel, 'id' | 'title' | 'slug' | 'created' | 'modified' | 'tags'> {
|
|
627
|
+
category: Pick<CategoryModel, 'name' | 'slug'> | null;
|
|
628
|
+
}
|
|
629
|
+
interface LatestNoteItem extends Pick<NoteModel, 'id' | 'title' | 'nid' | 'created' | 'modified' | 'mood' | 'weather' | 'bookmark'> {}
|
|
630
|
+
interface LatestData {
|
|
631
|
+
posts?: LatestPostItem[];
|
|
632
|
+
notes?: LatestNoteItem[];
|
|
633
|
+
}
|
|
634
|
+
type LatestCombinedItem = (LatestPostItem & {
|
|
635
|
+
type: 'post';
|
|
636
|
+
}) | (LatestNoteItem & {
|
|
637
|
+
type: 'note';
|
|
638
|
+
});
|
|
625
639
|
interface AggregateStat {
|
|
626
640
|
allComments: number;
|
|
627
641
|
categories: number;
|
|
@@ -717,24 +731,44 @@ interface CommentModel extends BaseModel {
|
|
|
717
731
|
refType: CollectionRefTypes;
|
|
718
732
|
ref: string;
|
|
719
733
|
state: number;
|
|
720
|
-
commentsIndex: number;
|
|
721
734
|
author: string;
|
|
722
735
|
text: string;
|
|
723
736
|
mail?: string;
|
|
724
737
|
url?: string;
|
|
725
738
|
ip?: string;
|
|
726
739
|
agent?: string;
|
|
727
|
-
key: string;
|
|
728
740
|
pin?: boolean;
|
|
729
741
|
avatar: string;
|
|
730
|
-
|
|
731
|
-
|
|
742
|
+
parentCommentId?: string | null;
|
|
743
|
+
rootCommentId?: string | null;
|
|
744
|
+
replyCount?: number;
|
|
745
|
+
latestReplyAt?: string | null;
|
|
746
|
+
isDeleted?: boolean;
|
|
747
|
+
deletedAt?: string;
|
|
732
748
|
isWhispers?: boolean;
|
|
733
749
|
location?: string;
|
|
734
750
|
source?: string;
|
|
735
751
|
readerId?: string;
|
|
736
752
|
editedAt?: string;
|
|
737
753
|
}
|
|
754
|
+
interface CommentReplyWindow {
|
|
755
|
+
total: number;
|
|
756
|
+
returned: number;
|
|
757
|
+
threshold: number;
|
|
758
|
+
hasHidden: boolean;
|
|
759
|
+
hiddenCount: number;
|
|
760
|
+
nextCursor?: string;
|
|
761
|
+
}
|
|
762
|
+
interface CommentThreadItem extends CommentModel {
|
|
763
|
+
replies: CommentModel[];
|
|
764
|
+
replyWindow: CommentReplyWindow;
|
|
765
|
+
}
|
|
766
|
+
interface CommentThreadReplies {
|
|
767
|
+
replies: CommentModel[];
|
|
768
|
+
nextCursor?: string;
|
|
769
|
+
remaining: number;
|
|
770
|
+
done: boolean;
|
|
771
|
+
}
|
|
738
772
|
interface CommentRef {
|
|
739
773
|
id: string;
|
|
740
774
|
categoryId?: string;
|
|
@@ -1050,6 +1084,16 @@ declare class AggregateController<ResponseWrapper> implements IController {
|
|
|
1050
1084
|
data: TimelineData;
|
|
1051
1085
|
};
|
|
1052
1086
|
}>;
|
|
1087
|
+
getLatest(options: {
|
|
1088
|
+
limit?: number;
|
|
1089
|
+
types?: TimelineType[];
|
|
1090
|
+
combined: true;
|
|
1091
|
+
}): RequestProxyResult<LatestCombinedItem[], ResponseWrapper>;
|
|
1092
|
+
getLatest(options?: {
|
|
1093
|
+
limit?: number;
|
|
1094
|
+
types?: TimelineType[];
|
|
1095
|
+
combined?: false;
|
|
1096
|
+
}): RequestProxyResult<LatestData, ResponseWrapper>;
|
|
1053
1097
|
/**
|
|
1054
1098
|
* 获取聚合数据统计
|
|
1055
1099
|
*/
|
|
@@ -1571,30 +1615,40 @@ declare class CommentController<ResponseWrapper> implements IController {
|
|
|
1571
1615
|
* 获取文章的评论列表
|
|
1572
1616
|
* @param refId 文章 Id
|
|
1573
1617
|
*/
|
|
1574
|
-
getByRefId(refId: string, pagination?: PaginationParams): RequestProxyResult<PaginateResult<
|
|
1618
|
+
getByRefId(refId: string, pagination?: PaginationParams): RequestProxyResult<PaginateResult<CommentThreadItem & {
|
|
1575
1619
|
ref: string;
|
|
1576
1620
|
}> & {
|
|
1577
1621
|
readers: Record<string, ReaderModel>;
|
|
1578
1622
|
}, ResponseWrapper, ResponseWrapper extends unknown ? {
|
|
1579
1623
|
[key: string]: any;
|
|
1580
|
-
data: PaginateResult<
|
|
1624
|
+
data: PaginateResult<CommentThreadItem & {
|
|
1581
1625
|
ref: string;
|
|
1582
1626
|
}> & {
|
|
1583
1627
|
readers: Record<string, ReaderModel>;
|
|
1584
1628
|
};
|
|
1585
1629
|
} : ResponseWrapper extends {
|
|
1586
|
-
data: PaginateResult<
|
|
1630
|
+
data: PaginateResult<CommentThreadItem & {
|
|
1587
1631
|
ref: string;
|
|
1588
1632
|
}> & {
|
|
1589
1633
|
readers: Record<string, ReaderModel>;
|
|
1590
1634
|
};
|
|
1591
1635
|
} ? ResponseWrapper : Omit<ResponseWrapper, "data"> & {
|
|
1592
|
-
data: PaginateResult<
|
|
1636
|
+
data: PaginateResult<CommentThreadItem & {
|
|
1593
1637
|
ref: string;
|
|
1594
1638
|
}> & {
|
|
1595
1639
|
readers: Record<string, ReaderModel>;
|
|
1596
1640
|
};
|
|
1597
1641
|
}>;
|
|
1642
|
+
getThreadReplies(rootCommentId: string, params?: PaginationParams & {
|
|
1643
|
+
cursor?: string;
|
|
1644
|
+
}): RequestProxyResult<CommentThreadReplies, ResponseWrapper, ResponseWrapper extends unknown ? {
|
|
1645
|
+
[key: string]: any;
|
|
1646
|
+
data: CommentThreadReplies;
|
|
1647
|
+
} : ResponseWrapper extends {
|
|
1648
|
+
data: CommentThreadReplies;
|
|
1649
|
+
} ? ResponseWrapper : Omit<ResponseWrapper, "data"> & {
|
|
1650
|
+
data: CommentThreadReplies;
|
|
1651
|
+
}>;
|
|
1598
1652
|
/**
|
|
1599
1653
|
* 评论
|
|
1600
1654
|
*/
|
|
@@ -1690,6 +1744,8 @@ type NoteListOptions = {
|
|
|
1690
1744
|
year?: number;
|
|
1691
1745
|
sortBy?: 'weather' | 'mood' | 'title' | 'created' | 'modified';
|
|
1692
1746
|
sortOrder?: 1 | -1;
|
|
1747
|
+
lang?: string;
|
|
1748
|
+
withSummary?: boolean;
|
|
1693
1749
|
};
|
|
1694
1750
|
type NoteByNidOptions = {
|
|
1695
1751
|
password?: string;
|
|
@@ -1697,13 +1753,14 @@ type NoteByNidOptions = {
|
|
|
1697
1753
|
lang?: string;
|
|
1698
1754
|
prefer?: 'lexical';
|
|
1699
1755
|
};
|
|
1756
|
+
type NoteBySlugDateOptions = NoteByNidOptions;
|
|
1700
1757
|
type NoteMiddleListOptions = {
|
|
1701
1758
|
lang?: string;
|
|
1702
1759
|
};
|
|
1703
1760
|
type NoteTopicListOptions = SortOptions & {
|
|
1704
1761
|
lang?: string;
|
|
1705
1762
|
};
|
|
1706
|
-
type NoteTimelineItem = Pick<NoteModel, 'id' | 'title' | 'nid' | 'created' | 'isPublished'> & {
|
|
1763
|
+
type NoteTimelineItem = Pick<NoteModel, 'id' | 'title' | 'nid' | 'slug' | 'created' | 'isPublished'> & {
|
|
1707
1764
|
isTranslated?: boolean;
|
|
1708
1765
|
translationMeta?: TranslationMeta;
|
|
1709
1766
|
};
|
|
@@ -1744,6 +1801,7 @@ declare class NoteController<ResponseWrapper> implements IController {
|
|
|
1744
1801
|
* @param options 可选参数:password, single, lang
|
|
1745
1802
|
*/
|
|
1746
1803
|
getNoteByNid(nid: number, options?: NoteByNidOptions): RequestProxyResult<NoteWrappedWithLikedAndTranslationPayload, ResponseWrapper>;
|
|
1804
|
+
getNoteBySlugDate(year: number, month: number, day: number, slug: string, options?: NoteBySlugDateOptions): RequestProxyResult<NoteWrappedWithLikedAndTranslationPayload, ResponseWrapper>;
|
|
1747
1805
|
/**
|
|
1748
1806
|
* 日记列表分页
|
|
1749
1807
|
*/
|
|
@@ -2500,4 +2558,4 @@ declare const allControllerNames: readonly ["ai", "ack", "activity", "aggregate"
|
|
|
2500
2558
|
*/
|
|
2501
2559
|
declare const camelcaseKeys: <T = any>(obj: any) => T;
|
|
2502
2560
|
//#endregion
|
|
2503
|
-
export { AIController, AIDeepReadingModel, AISummaryModel, AISummaryStreamEvent, AITranslationModel, AITranslationStreamEvent, AckController, ActivityController, ActivityPresence, AdminExtraModel, AggregateAIConfig, AggregateController, AggregateRoot, AggregateRootWithTheme, AggregateStat, AggregateTop, AggregateTopNote, AggregateTopPost, AlgoliaSearchOptionsModel, AuthUser, BackupOptionsModel, BaiduSearchOptionsModel, BaseCommentIndexModel, BaseModel, BetterAuthSession, BetterAuthSessionResult, BetterAuthSignInResult, BetterAuthUser, BetterAuthUserRole, BingSearchOptionsModel, CategoryController, CategoryEntries, CategoryModel, CategoryType, CategoryWithChildrenModel, CheckLoggedResult, CollectionRefTypes, CommentController, CommentDto, CommentModel, CommentOptionsModel, CommentRef, CommentState, Coordinate, Count, EnumPageType, type HTTPClient, IConfig, IConfigKeys, type IRequestAdapter, Image, LastYearPublication, LinkController, LinkModel, LinkState, LinkType, MailOptionsModel, ModelWithLiked, ModelWithTranslation, NoteController, type NoteMiddleListOptions, NoteModel, type NoteTimelineItem, type NoteTopicListItem, type NoteTopicListOptions, NoteWrappedPayload, NoteWrappedWithLikedAndTranslationPayload, NoteWrappedWithLikedPayload, OwnerAllowLoginResult, OwnerSessionResult, PageController, PageModel, Pager, PaginateResult, PostController, type PostListItem, type PostListOptions, PostModel, ProjectController, ProjectModel, ReaderModel, RecentActivities, RecentComment, RecentLike, RecentNote, RecentPost, RecentRecent, RecentlyAttitudeEnum, RecentlyAttitudeResultEnum, RecentlyController, RecentlyModel, RecentlyRefType, RecentlyRefTypes, RequestError, RoomOmittedNote, RoomOmittedPage, RoomOmittedPost, RoomsData, SayController, SayModel, SearchController, SeoOptionModel, ServerlessController, SnippetController, SnippetModel, SnippetType, SubscribeAllBit, SubscribeController, SubscribeNoteCreateBit, SubscribePostCreateBit, SubscribeRecentCreateBit, SubscribeSayCreateBit, SubscribeType, SubscribeTypeToBitMap, TLogin, TagModel, TextBaseModel, TextBaseModelLexical, TextBaseModelMarkdown, ThirdPartyServiceIntegrationModel, TimelineData, TimelineType, TopicController, TopicModel, TranslationMeta, Url, UrlOptionModel, UserController, UserModel, allControllerNames, allControllers, createClient, createClient as default, camelcaseKeys as simpleCamelcaseKeys };
|
|
2561
|
+
export { AIController, AIDeepReadingModel, AISummaryModel, AISummaryStreamEvent, AITranslationModel, AITranslationStreamEvent, AckController, ActivityController, ActivityPresence, AdminExtraModel, AggregateAIConfig, AggregateController, AggregateRoot, AggregateRootWithTheme, AggregateStat, AggregateTop, AggregateTopNote, AggregateTopPost, AlgoliaSearchOptionsModel, AuthUser, BackupOptionsModel, BaiduSearchOptionsModel, BaseCommentIndexModel, BaseModel, BetterAuthSession, BetterAuthSessionResult, BetterAuthSignInResult, BetterAuthUser, BetterAuthUserRole, BingSearchOptionsModel, CategoryController, CategoryEntries, CategoryModel, CategoryType, CategoryWithChildrenModel, CheckLoggedResult, CollectionRefTypes, CommentController, CommentDto, CommentModel, CommentOptionsModel, CommentRef, CommentReplyWindow, CommentState, CommentThreadItem, CommentThreadReplies, Coordinate, Count, EnumPageType, type HTTPClient, IConfig, IConfigKeys, type IRequestAdapter, Image, LastYearPublication, LatestCombinedItem, LatestData, LatestNoteItem, LatestPostItem, LinkController, LinkModel, LinkState, LinkType, MailOptionsModel, ModelWithLiked, ModelWithTranslation, NoteController, type NoteMiddleListOptions, NoteModel, type NoteTimelineItem, type NoteTopicListItem, type NoteTopicListOptions, NoteWrappedPayload, NoteWrappedWithLikedAndTranslationPayload, NoteWrappedWithLikedPayload, OwnerAllowLoginResult, OwnerSessionResult, PageController, PageModel, Pager, PaginateResult, PostController, type PostListItem, type PostListOptions, PostModel, ProjectController, ProjectModel, ReaderModel, RecentActivities, RecentComment, RecentLike, RecentNote, RecentPost, RecentRecent, RecentlyAttitudeEnum, RecentlyAttitudeResultEnum, RecentlyController, RecentlyModel, RecentlyRefType, RecentlyRefTypes, RequestError, RoomOmittedNote, RoomOmittedPage, RoomOmittedPost, RoomsData, SayController, SayModel, SearchController, SeoOptionModel, ServerlessController, SnippetController, SnippetModel, SnippetType, SubscribeAllBit, SubscribeController, SubscribeNoteCreateBit, SubscribePostCreateBit, SubscribeRecentCreateBit, SubscribeSayCreateBit, SubscribeType, SubscribeTypeToBitMap, TLogin, TagModel, TextBaseModel, TextBaseModelLexical, TextBaseModelMarkdown, ThirdPartyServiceIntegrationModel, TimelineData, TimelineType, TopicController, TopicModel, TranslationMeta, Url, UrlOptionModel, UserController, UserModel, allControllerNames, allControllers, createClient, createClient as default, camelcaseKeys as simpleCamelcaseKeys };
|
package/dist/index.d.mts
CHANGED
|
@@ -376,6 +376,7 @@ type NoteModel = TextBaseModel & {
|
|
|
376
376
|
publicAt?: Date;
|
|
377
377
|
password?: string | null;
|
|
378
378
|
nid: number;
|
|
379
|
+
slug?: string;
|
|
379
380
|
location?: string;
|
|
380
381
|
coordinates?: Coordinate;
|
|
381
382
|
topic?: TopicModel;
|
|
@@ -622,6 +623,19 @@ interface TimelineData {
|
|
|
622
623
|
url: string;
|
|
623
624
|
})[];
|
|
624
625
|
}
|
|
626
|
+
interface LatestPostItem extends Pick<PostModel, 'id' | 'title' | 'slug' | 'created' | 'modified' | 'tags'> {
|
|
627
|
+
category: Pick<CategoryModel, 'name' | 'slug'> | null;
|
|
628
|
+
}
|
|
629
|
+
interface LatestNoteItem extends Pick<NoteModel, 'id' | 'title' | 'nid' | 'created' | 'modified' | 'mood' | 'weather' | 'bookmark'> {}
|
|
630
|
+
interface LatestData {
|
|
631
|
+
posts?: LatestPostItem[];
|
|
632
|
+
notes?: LatestNoteItem[];
|
|
633
|
+
}
|
|
634
|
+
type LatestCombinedItem = (LatestPostItem & {
|
|
635
|
+
type: 'post';
|
|
636
|
+
}) | (LatestNoteItem & {
|
|
637
|
+
type: 'note';
|
|
638
|
+
});
|
|
625
639
|
interface AggregateStat {
|
|
626
640
|
allComments: number;
|
|
627
641
|
categories: number;
|
|
@@ -717,24 +731,44 @@ interface CommentModel extends BaseModel {
|
|
|
717
731
|
refType: CollectionRefTypes;
|
|
718
732
|
ref: string;
|
|
719
733
|
state: number;
|
|
720
|
-
commentsIndex: number;
|
|
721
734
|
author: string;
|
|
722
735
|
text: string;
|
|
723
736
|
mail?: string;
|
|
724
737
|
url?: string;
|
|
725
738
|
ip?: string;
|
|
726
739
|
agent?: string;
|
|
727
|
-
key: string;
|
|
728
740
|
pin?: boolean;
|
|
729
741
|
avatar: string;
|
|
730
|
-
|
|
731
|
-
|
|
742
|
+
parentCommentId?: string | null;
|
|
743
|
+
rootCommentId?: string | null;
|
|
744
|
+
replyCount?: number;
|
|
745
|
+
latestReplyAt?: string | null;
|
|
746
|
+
isDeleted?: boolean;
|
|
747
|
+
deletedAt?: string;
|
|
732
748
|
isWhispers?: boolean;
|
|
733
749
|
location?: string;
|
|
734
750
|
source?: string;
|
|
735
751
|
readerId?: string;
|
|
736
752
|
editedAt?: string;
|
|
737
753
|
}
|
|
754
|
+
interface CommentReplyWindow {
|
|
755
|
+
total: number;
|
|
756
|
+
returned: number;
|
|
757
|
+
threshold: number;
|
|
758
|
+
hasHidden: boolean;
|
|
759
|
+
hiddenCount: number;
|
|
760
|
+
nextCursor?: string;
|
|
761
|
+
}
|
|
762
|
+
interface CommentThreadItem extends CommentModel {
|
|
763
|
+
replies: CommentModel[];
|
|
764
|
+
replyWindow: CommentReplyWindow;
|
|
765
|
+
}
|
|
766
|
+
interface CommentThreadReplies {
|
|
767
|
+
replies: CommentModel[];
|
|
768
|
+
nextCursor?: string;
|
|
769
|
+
remaining: number;
|
|
770
|
+
done: boolean;
|
|
771
|
+
}
|
|
738
772
|
interface CommentRef {
|
|
739
773
|
id: string;
|
|
740
774
|
categoryId?: string;
|
|
@@ -1050,6 +1084,16 @@ declare class AggregateController<ResponseWrapper> implements IController {
|
|
|
1050
1084
|
data: TimelineData;
|
|
1051
1085
|
};
|
|
1052
1086
|
}>;
|
|
1087
|
+
getLatest(options: {
|
|
1088
|
+
limit?: number;
|
|
1089
|
+
types?: TimelineType[];
|
|
1090
|
+
combined: true;
|
|
1091
|
+
}): RequestProxyResult<LatestCombinedItem[], ResponseWrapper>;
|
|
1092
|
+
getLatest(options?: {
|
|
1093
|
+
limit?: number;
|
|
1094
|
+
types?: TimelineType[];
|
|
1095
|
+
combined?: false;
|
|
1096
|
+
}): RequestProxyResult<LatestData, ResponseWrapper>;
|
|
1053
1097
|
/**
|
|
1054
1098
|
* 获取聚合数据统计
|
|
1055
1099
|
*/
|
|
@@ -1571,30 +1615,40 @@ declare class CommentController<ResponseWrapper> implements IController {
|
|
|
1571
1615
|
* 获取文章的评论列表
|
|
1572
1616
|
* @param refId 文章 Id
|
|
1573
1617
|
*/
|
|
1574
|
-
getByRefId(refId: string, pagination?: PaginationParams): RequestProxyResult<PaginateResult<
|
|
1618
|
+
getByRefId(refId: string, pagination?: PaginationParams): RequestProxyResult<PaginateResult<CommentThreadItem & {
|
|
1575
1619
|
ref: string;
|
|
1576
1620
|
}> & {
|
|
1577
1621
|
readers: Record<string, ReaderModel>;
|
|
1578
1622
|
}, ResponseWrapper, ResponseWrapper extends unknown ? {
|
|
1579
1623
|
[key: string]: any;
|
|
1580
|
-
data: PaginateResult<
|
|
1624
|
+
data: PaginateResult<CommentThreadItem & {
|
|
1581
1625
|
ref: string;
|
|
1582
1626
|
}> & {
|
|
1583
1627
|
readers: Record<string, ReaderModel>;
|
|
1584
1628
|
};
|
|
1585
1629
|
} : ResponseWrapper extends {
|
|
1586
|
-
data: PaginateResult<
|
|
1630
|
+
data: PaginateResult<CommentThreadItem & {
|
|
1587
1631
|
ref: string;
|
|
1588
1632
|
}> & {
|
|
1589
1633
|
readers: Record<string, ReaderModel>;
|
|
1590
1634
|
};
|
|
1591
1635
|
} ? ResponseWrapper : Omit<ResponseWrapper, "data"> & {
|
|
1592
|
-
data: PaginateResult<
|
|
1636
|
+
data: PaginateResult<CommentThreadItem & {
|
|
1593
1637
|
ref: string;
|
|
1594
1638
|
}> & {
|
|
1595
1639
|
readers: Record<string, ReaderModel>;
|
|
1596
1640
|
};
|
|
1597
1641
|
}>;
|
|
1642
|
+
getThreadReplies(rootCommentId: string, params?: PaginationParams & {
|
|
1643
|
+
cursor?: string;
|
|
1644
|
+
}): RequestProxyResult<CommentThreadReplies, ResponseWrapper, ResponseWrapper extends unknown ? {
|
|
1645
|
+
[key: string]: any;
|
|
1646
|
+
data: CommentThreadReplies;
|
|
1647
|
+
} : ResponseWrapper extends {
|
|
1648
|
+
data: CommentThreadReplies;
|
|
1649
|
+
} ? ResponseWrapper : Omit<ResponseWrapper, "data"> & {
|
|
1650
|
+
data: CommentThreadReplies;
|
|
1651
|
+
}>;
|
|
1598
1652
|
/**
|
|
1599
1653
|
* 评论
|
|
1600
1654
|
*/
|
|
@@ -1690,6 +1744,8 @@ type NoteListOptions = {
|
|
|
1690
1744
|
year?: number;
|
|
1691
1745
|
sortBy?: 'weather' | 'mood' | 'title' | 'created' | 'modified';
|
|
1692
1746
|
sortOrder?: 1 | -1;
|
|
1747
|
+
lang?: string;
|
|
1748
|
+
withSummary?: boolean;
|
|
1693
1749
|
};
|
|
1694
1750
|
type NoteByNidOptions = {
|
|
1695
1751
|
password?: string;
|
|
@@ -1697,13 +1753,14 @@ type NoteByNidOptions = {
|
|
|
1697
1753
|
lang?: string;
|
|
1698
1754
|
prefer?: 'lexical';
|
|
1699
1755
|
};
|
|
1756
|
+
type NoteBySlugDateOptions = NoteByNidOptions;
|
|
1700
1757
|
type NoteMiddleListOptions = {
|
|
1701
1758
|
lang?: string;
|
|
1702
1759
|
};
|
|
1703
1760
|
type NoteTopicListOptions = SortOptions & {
|
|
1704
1761
|
lang?: string;
|
|
1705
1762
|
};
|
|
1706
|
-
type NoteTimelineItem = Pick<NoteModel, 'id' | 'title' | 'nid' | 'created' | 'isPublished'> & {
|
|
1763
|
+
type NoteTimelineItem = Pick<NoteModel, 'id' | 'title' | 'nid' | 'slug' | 'created' | 'isPublished'> & {
|
|
1707
1764
|
isTranslated?: boolean;
|
|
1708
1765
|
translationMeta?: TranslationMeta;
|
|
1709
1766
|
};
|
|
@@ -1744,6 +1801,7 @@ declare class NoteController<ResponseWrapper> implements IController {
|
|
|
1744
1801
|
* @param options 可选参数:password, single, lang
|
|
1745
1802
|
*/
|
|
1746
1803
|
getNoteByNid(nid: number, options?: NoteByNidOptions): RequestProxyResult<NoteWrappedWithLikedAndTranslationPayload, ResponseWrapper>;
|
|
1804
|
+
getNoteBySlugDate(year: number, month: number, day: number, slug: string, options?: NoteBySlugDateOptions): RequestProxyResult<NoteWrappedWithLikedAndTranslationPayload, ResponseWrapper>;
|
|
1747
1805
|
/**
|
|
1748
1806
|
* 日记列表分页
|
|
1749
1807
|
*/
|
|
@@ -2500,4 +2558,4 @@ declare const allControllerNames: readonly ["ai", "ack", "activity", "aggregate"
|
|
|
2500
2558
|
*/
|
|
2501
2559
|
declare const camelcaseKeys: <T = any>(obj: any) => T;
|
|
2502
2560
|
//#endregion
|
|
2503
|
-
export { AIController, AIDeepReadingModel, AISummaryModel, AISummaryStreamEvent, AITranslationModel, AITranslationStreamEvent, AckController, ActivityController, ActivityPresence, AdminExtraModel, AggregateAIConfig, AggregateController, AggregateRoot, AggregateRootWithTheme, AggregateStat, AggregateTop, AggregateTopNote, AggregateTopPost, AlgoliaSearchOptionsModel, AuthUser, BackupOptionsModel, BaiduSearchOptionsModel, BaseCommentIndexModel, BaseModel, BetterAuthSession, BetterAuthSessionResult, BetterAuthSignInResult, BetterAuthUser, BetterAuthUserRole, BingSearchOptionsModel, CategoryController, CategoryEntries, CategoryModel, CategoryType, CategoryWithChildrenModel, CheckLoggedResult, CollectionRefTypes, CommentController, CommentDto, CommentModel, CommentOptionsModel, CommentRef, CommentState, Coordinate, Count, EnumPageType, type HTTPClient, IConfig, IConfigKeys, type IRequestAdapter, Image, LastYearPublication, LinkController, LinkModel, LinkState, LinkType, MailOptionsModel, ModelWithLiked, ModelWithTranslation, NoteController, type NoteMiddleListOptions, NoteModel, type NoteTimelineItem, type NoteTopicListItem, type NoteTopicListOptions, NoteWrappedPayload, NoteWrappedWithLikedAndTranslationPayload, NoteWrappedWithLikedPayload, OwnerAllowLoginResult, OwnerSessionResult, PageController, PageModel, Pager, PaginateResult, PostController, type PostListItem, type PostListOptions, PostModel, ProjectController, ProjectModel, ReaderModel, RecentActivities, RecentComment, RecentLike, RecentNote, RecentPost, RecentRecent, RecentlyAttitudeEnum, RecentlyAttitudeResultEnum, RecentlyController, RecentlyModel, RecentlyRefType, RecentlyRefTypes, RequestError, RoomOmittedNote, RoomOmittedPage, RoomOmittedPost, RoomsData, SayController, SayModel, SearchController, SeoOptionModel, ServerlessController, SnippetController, SnippetModel, SnippetType, SubscribeAllBit, SubscribeController, SubscribeNoteCreateBit, SubscribePostCreateBit, SubscribeRecentCreateBit, SubscribeSayCreateBit, SubscribeType, SubscribeTypeToBitMap, TLogin, TagModel, TextBaseModel, TextBaseModelLexical, TextBaseModelMarkdown, ThirdPartyServiceIntegrationModel, TimelineData, TimelineType, TopicController, TopicModel, TranslationMeta, Url, UrlOptionModel, UserController, UserModel, allControllerNames, allControllers, createClient, createClient as default, camelcaseKeys as simpleCamelcaseKeys };
|
|
2561
|
+
export { AIController, AIDeepReadingModel, AISummaryModel, AISummaryStreamEvent, AITranslationModel, AITranslationStreamEvent, AckController, ActivityController, ActivityPresence, AdminExtraModel, AggregateAIConfig, AggregateController, AggregateRoot, AggregateRootWithTheme, AggregateStat, AggregateTop, AggregateTopNote, AggregateTopPost, AlgoliaSearchOptionsModel, AuthUser, BackupOptionsModel, BaiduSearchOptionsModel, BaseCommentIndexModel, BaseModel, BetterAuthSession, BetterAuthSessionResult, BetterAuthSignInResult, BetterAuthUser, BetterAuthUserRole, BingSearchOptionsModel, CategoryController, CategoryEntries, CategoryModel, CategoryType, CategoryWithChildrenModel, CheckLoggedResult, CollectionRefTypes, CommentController, CommentDto, CommentModel, CommentOptionsModel, CommentRef, CommentReplyWindow, CommentState, CommentThreadItem, CommentThreadReplies, Coordinate, Count, EnumPageType, type HTTPClient, IConfig, IConfigKeys, type IRequestAdapter, Image, LastYearPublication, LatestCombinedItem, LatestData, LatestNoteItem, LatestPostItem, LinkController, LinkModel, LinkState, LinkType, MailOptionsModel, ModelWithLiked, ModelWithTranslation, NoteController, type NoteMiddleListOptions, NoteModel, type NoteTimelineItem, type NoteTopicListItem, type NoteTopicListOptions, NoteWrappedPayload, NoteWrappedWithLikedAndTranslationPayload, NoteWrappedWithLikedPayload, OwnerAllowLoginResult, OwnerSessionResult, PageController, PageModel, Pager, PaginateResult, PostController, type PostListItem, type PostListOptions, PostModel, ProjectController, ProjectModel, ReaderModel, RecentActivities, RecentComment, RecentLike, RecentNote, RecentPost, RecentRecent, RecentlyAttitudeEnum, RecentlyAttitudeResultEnum, RecentlyController, RecentlyModel, RecentlyRefType, RecentlyRefTypes, RequestError, RoomOmittedNote, RoomOmittedPage, RoomOmittedPost, RoomsData, SayController, SayModel, SearchController, SeoOptionModel, ServerlessController, SnippetController, SnippetModel, SnippetType, SubscribeAllBit, SubscribeController, SubscribeNoteCreateBit, SubscribePostCreateBit, SubscribeRecentCreateBit, SubscribeSayCreateBit, SubscribeType, SubscribeTypeToBitMap, TLogin, TagModel, TextBaseModel, TextBaseModelLexical, TextBaseModelMarkdown, ThirdPartyServiceIntegrationModel, TimelineData, TimelineType, TopicController, TopicModel, TranslationMeta, Url, UrlOptionModel, UserController, UserModel, allControllerNames, allControllers, createClient, createClient as default, camelcaseKeys as simpleCamelcaseKeys };
|
package/dist/index.mjs
CHANGED
|
@@ -199,6 +199,14 @@ var AggregateController = class {
|
|
|
199
199
|
year
|
|
200
200
|
} });
|
|
201
201
|
}
|
|
202
|
+
getLatest(options) {
|
|
203
|
+
const { limit, types, combined } = options || {};
|
|
204
|
+
return this.proxy.latest.get({ params: {
|
|
205
|
+
limit,
|
|
206
|
+
types: types?.join(","),
|
|
207
|
+
combined
|
|
208
|
+
} });
|
|
209
|
+
}
|
|
202
210
|
/**
|
|
203
211
|
* 获取聚合数据统计
|
|
204
212
|
*/
|
|
@@ -412,6 +420,9 @@ var CommentController = class {
|
|
|
412
420
|
size: size || 10
|
|
413
421
|
} });
|
|
414
422
|
}
|
|
423
|
+
getThreadReplies(rootCommentId, params = {}) {
|
|
424
|
+
return this.proxy.thread(rootCommentId).get({ params });
|
|
425
|
+
}
|
|
415
426
|
/**
|
|
416
427
|
* 评论
|
|
417
428
|
*/
|
|
@@ -515,18 +526,29 @@ var NoteController = class {
|
|
|
515
526
|
prefer
|
|
516
527
|
} });
|
|
517
528
|
}
|
|
529
|
+
getNoteBySlugDate(year, month, day, slug, options) {
|
|
530
|
+
const { password, single, lang, prefer } = options || {};
|
|
531
|
+
return this.proxy(year.toString())(month.toString())(day.toString())(slug).get({ params: {
|
|
532
|
+
password,
|
|
533
|
+
single: single ? "1" : void 0,
|
|
534
|
+
lang,
|
|
535
|
+
prefer
|
|
536
|
+
} });
|
|
537
|
+
}
|
|
518
538
|
/**
|
|
519
539
|
* 日记列表分页
|
|
520
540
|
*/
|
|
521
541
|
getList(page = 1, perPage = 10, options = {}) {
|
|
522
|
-
const { select, sortBy, sortOrder, year } = options;
|
|
542
|
+
const { select, sortBy, sortOrder, year, lang, withSummary } = options;
|
|
523
543
|
return this.proxy.get({ params: {
|
|
524
544
|
page,
|
|
525
545
|
size: perPage,
|
|
526
546
|
select: select?.join(" "),
|
|
527
547
|
sortBy,
|
|
528
548
|
sortOrder,
|
|
529
|
-
year
|
|
549
|
+
year,
|
|
550
|
+
lang,
|
|
551
|
+
withSummary: withSummary ? "1" : void 0
|
|
530
552
|
} });
|
|
531
553
|
}
|
|
532
554
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mx-space/api-client",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "A api client for mx-space server@next",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -56,10 +56,10 @@
|
|
|
56
56
|
"axios": "^1.13.3",
|
|
57
57
|
"camelcase-keys": "^10.0.2",
|
|
58
58
|
"cors": "2.8.6",
|
|
59
|
-
"es-toolkit": "1.
|
|
59
|
+
"es-toolkit": "1.45.0",
|
|
60
60
|
"express": "4.21.2",
|
|
61
61
|
"form-data": "4.0.5",
|
|
62
|
-
"tsdown": "0.
|
|
62
|
+
"tsdown": "0.21.0-beta.2",
|
|
63
63
|
"umi-request": "1.4.0",
|
|
64
64
|
"vite": "^7.3.1",
|
|
65
65
|
"vitest": "4.0.18"
|
package/readme.md
CHANGED
|
@@ -1,133 +1,74 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @mx-space/api-client
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A framework-agnostic TypeScript/JavaScript SDK for the MX Space server (MServer v3). It wraps common API endpoints with typed request methods and response types for fast frontend and server-side integration.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
---
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
| --------------- | ------------------ | ----------------------------- |
|
|
9
|
-
| v2.x | >= 10 | 基于 Better Auth 的新认证系统 |
|
|
10
|
-
| v1.x | <= 9 | 旧版认证系统 |
|
|
7
|
+
## Table of Contents
|
|
11
8
|
|
|
12
|
-
|
|
9
|
+
- [Requirements](#requirements)
|
|
10
|
+
- [Installation](#installation)
|
|
11
|
+
- [Quick Start](#quick-start)
|
|
12
|
+
- [Architecture](#architecture)
|
|
13
|
+
- [Adapters](#adapters)
|
|
14
|
+
- [Controllers](#controllers)
|
|
15
|
+
- [Client Options](#client-options)
|
|
16
|
+
- [Proxy API](#proxy-api)
|
|
17
|
+
- [Version Compatibility & Migration](#version-compatibility--migration)
|
|
18
|
+
- [Development](#development)
|
|
19
|
+
- [License](#license)
|
|
13
20
|
|
|
14
|
-
|
|
21
|
+
---
|
|
15
22
|
|
|
16
|
-
|
|
23
|
+
## Requirements
|
|
17
24
|
|
|
18
|
-
|
|
25
|
+
- **Node.js** ≥ 22 (see `engines` in `package.json`)
|
|
26
|
+
- **MX Space server** v10+ for api-client v2.x (Better Auth); v9 or below use api-client v1.x
|
|
19
27
|
|
|
20
|
-
|
|
28
|
+
---
|
|
21
29
|
|
|
22
|
-
|
|
23
|
-
- client.user.getMasterInfo()
|
|
24
|
-
+ client.owner.getOwnerInfo()
|
|
25
|
-
|
|
26
|
-
- client.master.getMasterInfo()
|
|
27
|
-
+ client.owner.getOwnerInfo()
|
|
28
|
-
```
|
|
30
|
+
## Installation
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
From the monorepo root (recommended):
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
```diff
|
|
35
|
-
- client.user.login(username, password)
|
|
36
|
-
+ client.owner.login(username, password, { rememberMe: boolean })
|
|
34
|
+
```bash
|
|
35
|
+
pnpm add @mx-space/api-client
|
|
37
36
|
```
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
#### 3. 新增 Better Auth 相关接口
|
|
42
|
-
|
|
43
|
-
v2 版本新增了 Better Auth 认证相关的接口:
|
|
38
|
+
Or with npm:
|
|
44
39
|
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
client.owner.getSession()
|
|
48
|
-
|
|
49
|
-
// 获取 Better Auth 原生会话
|
|
50
|
-
client.owner.getAuthSession()
|
|
51
|
-
|
|
52
|
-
// 登出
|
|
53
|
-
client.owner.logout()
|
|
54
|
-
|
|
55
|
-
// 获取支持的登录方式
|
|
56
|
-
client.owner.getAllowLoginMethods()
|
|
57
|
-
|
|
58
|
-
// 获取 OAuth 提供商列表
|
|
59
|
-
client.owner.getProviders()
|
|
60
|
-
|
|
61
|
-
// 列出所有会话
|
|
62
|
-
client.owner.listSessions()
|
|
63
|
-
|
|
64
|
-
// 撤销指定会话
|
|
65
|
-
client.owner.revokeSession(token)
|
|
66
|
-
|
|
67
|
-
// 撤销所有会话
|
|
68
|
-
client.owner.revokeSessions()
|
|
69
|
-
|
|
70
|
-
// 撤销其他会话
|
|
71
|
-
client.owner.revokeOtherSessions()
|
|
40
|
+
```bash
|
|
41
|
+
npm install @mx-space/api-client
|
|
72
42
|
```
|
|
73
43
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
不再提供 camelcase-keys 的 re-export,此库不再依赖 camelcase-keys 库,如有需要可自行安装。
|
|
44
|
+
The package is **framework-agnostic** and does not bundle a specific HTTP client. You must provide an adapter (e.g. Axios or fetch). Install the HTTP library you use:
|
|
77
45
|
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
|
|
46
|
+
```bash
|
|
47
|
+
pnpm add axios
|
|
48
|
+
# or use the built-in fetch adapter (no extra install)
|
|
81
49
|
```
|
|
82
50
|
|
|
83
|
-
|
|
51
|
+
---
|
|
84
52
|
|
|
85
|
-
|
|
53
|
+
## Quick Start
|
|
86
54
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
55
|
+
1. **Create a client** with an endpoint and an adapter.
|
|
56
|
+
2. **Inject controllers** you need (tree-shakeable).
|
|
57
|
+
3. **Call methods** on the client (e.g. `client.post`, `client.note`).
|
|
90
58
|
|
|
91
59
|
```ts
|
|
92
60
|
import {
|
|
93
|
-
AggregateController,
|
|
94
|
-
allControllers, // ...
|
|
95
|
-
CategoryController,
|
|
96
61
|
createClient,
|
|
97
|
-
NoteController,
|
|
98
62
|
PostController,
|
|
63
|
+
NoteController,
|
|
64
|
+
AggregateController,
|
|
65
|
+
CategoryController,
|
|
99
66
|
} from '@mx-space/api-client'
|
|
100
67
|
import { axiosAdaptor } from '@mx-space/api-client/adaptors/axios'
|
|
101
68
|
|
|
102
|
-
const endpoint = 'https://api.
|
|
69
|
+
const endpoint = 'https://api.example.com/v2'
|
|
103
70
|
const client = createClient(axiosAdaptor)(endpoint)
|
|
104
71
|
|
|
105
|
-
// `default` is AxiosInstance
|
|
106
|
-
// you can do anything else on this
|
|
107
|
-
// interceptor or re-configure
|
|
108
|
-
const $axios = axiosAdaptor.default
|
|
109
|
-
// re-config (optional)
|
|
110
|
-
$axios.defaults.timeout = 10000
|
|
111
|
-
// set interceptors (optional)
|
|
112
|
-
$axios.interceptors.request.use(
|
|
113
|
-
(config) => {
|
|
114
|
-
const token = getToken()
|
|
115
|
-
if (token) {
|
|
116
|
-
config.headers!.Authorization = `bearer ${getToken()}`
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return config
|
|
120
|
-
},
|
|
121
|
-
(error) => {
|
|
122
|
-
if (__DEV__) {
|
|
123
|
-
console.log(error.message)
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return Promise.reject(error)
|
|
127
|
-
},
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
// inject controller first.
|
|
131
72
|
client.injectControllers([
|
|
132
73
|
PostController,
|
|
133
74
|
NoteController,
|
|
@@ -135,40 +76,206 @@ client.injectControllers([
|
|
|
135
76
|
CategoryController,
|
|
136
77
|
])
|
|
137
78
|
|
|
138
|
-
//
|
|
139
|
-
client.
|
|
79
|
+
// Typed API calls
|
|
80
|
+
const posts = await client.post.post.getList(1, 10, { year: 2024 })
|
|
81
|
+
const aggregate = await client.aggregate.getAggregateData()
|
|
82
|
+
```
|
|
140
83
|
|
|
141
|
-
|
|
84
|
+
**Optional: set token and interceptors** (example with Axios):
|
|
142
85
|
|
|
143
|
-
|
|
144
|
-
|
|
86
|
+
```ts
|
|
87
|
+
const $axios = axiosAdaptor.default
|
|
88
|
+
$axios.defaults.timeout = 10000
|
|
89
|
+
$axios.interceptors.request.use((config) => {
|
|
90
|
+
const token = getToken()
|
|
91
|
+
if (token) config.headers!.Authorization = `bearer ${token}`
|
|
92
|
+
return config
|
|
145
93
|
})
|
|
146
94
|
```
|
|
147
95
|
|
|
148
|
-
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Architecture
|
|
99
|
+
|
|
100
|
+
- **Core**: `HTTPClient` in `core/client.ts` — builds a route proxy and delegates HTTP calls to an adapter.
|
|
101
|
+
- **Adapters**: Implement `IRequestAdapter` (get/post/put/patch/delete + optional `default` client). Responses are normalized to `{ data }`; optional `transformResponse` (e.g. camelCase) runs on `data`.
|
|
102
|
+
- **Controllers**: Classes that receive the client and attach methods under a name (e.g. `post`, `note`). Controllers are **injected at runtime** so you only bundle what you use.
|
|
103
|
+
- **Proxy**: `client.proxy` allows arbitrary path chains and HTTP methods for endpoints not modeled by a controller (e.g. `client.note.proxy.something.other('123').info.get()`).
|
|
104
|
+
|
|
105
|
+
**Response shape**: The adapter is expected to return a value with a `data` property. By default, `getDataFromResponse` uses `(res) => res.data`, and `transformResponse` converts keys to camelCase. Each returned object gets attached `$raw` (adapter response), `$request` (url, method, options), and `$serialized` (transformed data).
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Adapters
|
|
149
110
|
|
|
150
|
-
|
|
111
|
+
Official adapters live under `@mx-space/api-client/adaptors/`:
|
|
151
112
|
|
|
152
|
-
|
|
113
|
+
| Adapter | Import path | Notes |
|
|
114
|
+
|----------------|------------------------------------------|--------------------------|
|
|
115
|
+
| **Axios** | `@mx-space/api-client/adaptors/axios` | Exposes `axiosAdaptor.default` (AxiosInstance). |
|
|
116
|
+
| **umi-request**| `@mx-space/api-client/adaptors/umi-request` | For umi-request users. |
|
|
117
|
+
| **Fetch** | `@mx-space/api-client/adaptors/fetch` | Uses global `fetch`; no extra dependency. |
|
|
153
118
|
|
|
154
|
-
|
|
119
|
+
**Custom adapter**: Implement `IRequestAdapter` from `@mx-space/api-client` (methods: `get`, `post`, `put`, `patch`, `delete`; optional `default`). See `src/adaptors/axios.ts` and `src/adaptors/umi-request.ts` for reference.
|
|
155
120
|
|
|
156
|
-
|
|
121
|
+
---
|
|
157
122
|
|
|
158
|
-
|
|
123
|
+
## Controllers
|
|
159
124
|
|
|
160
|
-
|
|
125
|
+
Inject one or more controllers so the client exposes them (e.g. `client.post`, `client.note`). Use `allControllers` to inject everything, or list only what you need for smaller bundles.
|
|
161
126
|
|
|
162
|
-
|
|
127
|
+
| Controller | Client name | Purpose (high level) |
|
|
128
|
+
|-------------|---------------|-----------------------------|
|
|
129
|
+
| PostController | `post` | Blog posts |
|
|
130
|
+
| NoteController | `note` | Notes / private posts |
|
|
131
|
+
| PageController | `page` | Pages |
|
|
132
|
+
| CategoryController | `category` | Categories |
|
|
133
|
+
| AggregateController | `aggregate` | Site aggregate data |
|
|
134
|
+
| CommentController | `comment` | Comments |
|
|
135
|
+
| UserController (owner) | `owner` | Auth, session, login, OAuth |
|
|
136
|
+
| SayController | `say` | Says / short notes |
|
|
137
|
+
| LinkController | `link` | Links |
|
|
138
|
+
| SnippetController| `snippet` | Snippets |
|
|
139
|
+
| ProjectController | `project` | Projects |
|
|
140
|
+
| TopicController | `topic` | Topics |
|
|
141
|
+
| RecentlyController | `recently` | Recently items |
|
|
142
|
+
| SearchController | `search` | Search |
|
|
143
|
+
| ActivityController| `activity`| Activity |
|
|
144
|
+
| AIController | `ai` | AI-related endpoints |
|
|
145
|
+
| SubscribeController | `subscribe` | Subscriptions |
|
|
146
|
+
| ServerlessController | `serverless` | Serverless functions |
|
|
147
|
+
| AckController | `ack` | Ack |
|
|
148
|
+
|
|
149
|
+
**Example — inject all controllers:**
|
|
163
150
|
|
|
164
151
|
```ts
|
|
165
|
-
client
|
|
152
|
+
import { createClient, allControllers } from '@mx-space/api-client'
|
|
153
|
+
import { axiosAdaptor } from '@mx-space/api-client/adaptors/axios'
|
|
154
|
+
|
|
155
|
+
const client = createClient(axiosAdaptor)('https://api.example.com/v2')
|
|
156
|
+
client.injectControllers(allControllers)
|
|
166
157
|
```
|
|
167
158
|
|
|
168
|
-
|
|
159
|
+
**Why inject manually?** To keep bundle size small (tree-shaking) and to avoid pulling in a specific HTTP library by default.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Client Options
|
|
164
|
+
|
|
165
|
+
`createClient(adapter)(endpoint, options)` accepts optional second argument:
|
|
166
|
+
|
|
167
|
+
| Option | Description |
|
|
168
|
+
|----------------------------|-------------|
|
|
169
|
+
| `controllers` | Array of controller classes to inject immediately. |
|
|
170
|
+
| `transformResponse` | `(data) => transformed`. Default: camelCase keys. |
|
|
171
|
+
| `getDataFromResponse` | `(response) => data`. Default: `(res) => res.data`. |
|
|
172
|
+
| `getCodeMessageFromException` | `(error) => { message?, code? }` for custom error parsing. |
|
|
173
|
+
| `customThrowResponseError` | `(error) => Error` to throw a custom error type. |
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Proxy API
|
|
178
|
+
|
|
179
|
+
For paths not covered by a controller, use the **proxy** to build URLs and perform requests:
|
|
169
180
|
|
|
170
181
|
```ts
|
|
171
|
-
|
|
182
|
+
// GET /notes/something/other/123456/info
|
|
183
|
+
const data = await client.note.proxy.something.other('123456').info.get()
|
|
184
|
+
|
|
185
|
+
// Get path only (no request)
|
|
186
|
+
client.note.proxy.something.other('123456').info.toString()
|
|
187
|
+
// => '/notes/something/other/123456/info'
|
|
188
|
+
|
|
189
|
+
// Full URL (with base endpoint)
|
|
190
|
+
client.note.proxy.something.other('123456').info.toString(true)
|
|
191
|
+
// => 'https://api.example.com/v2/notes/something/other/123456/info'
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Version Compatibility & Migration
|
|
197
|
+
|
|
198
|
+
### Compatibility
|
|
199
|
+
|
|
200
|
+
| api-client version | Server version | Notes |
|
|
201
|
+
|--------------------|----------------|-------|
|
|
202
|
+
| v2.x | ≥ 10 | Better Auth; owner API; new auth endpoints. |
|
|
203
|
+
| v1.x | ≤ 9 | Legacy auth. |
|
|
204
|
+
|
|
205
|
+
v2 introduces breaking changes; see migration below.
|
|
206
|
+
|
|
207
|
+
### Migrating to v2
|
|
208
|
+
|
|
209
|
+
**1. Controller renames**
|
|
210
|
+
|
|
211
|
+
- `user` / `master` → `owner`. Use `client.owner` for auth and owner info.
|
|
212
|
+
|
|
213
|
+
```diff
|
|
214
|
+
- client.user.getMasterInfo()
|
|
215
|
+
- client.master.getMasterInfo()
|
|
216
|
+
+ client.owner.getOwnerInfo()
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**2. Login**
|
|
220
|
+
|
|
221
|
+
- Endpoint: `POST /master/login` → `POST /auth/sign-in`.
|
|
222
|
+
- v2 `login` returns `{ token, user }`.
|
|
223
|
+
|
|
224
|
+
```diff
|
|
225
|
+
- client.user.login(username, password)
|
|
226
|
+
+ client.owner.login(username, password, { rememberMe: boolean })
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**3. New auth-related APIs (v2)**
|
|
230
|
+
|
|
231
|
+
- `client.owner.getSession()`
|
|
232
|
+
- `client.owner.getAuthSession()`
|
|
233
|
+
- `client.owner.logout()`
|
|
234
|
+
- `client.owner.getAllowLoginMethods()`
|
|
235
|
+
- `client.owner.getProviders()`
|
|
236
|
+
- `client.owner.listSessions()`
|
|
237
|
+
- `client.owner.revokeSession(token)` / `revokeSessions()` / `revokeOtherSessions()`
|
|
238
|
+
|
|
239
|
+
### Migrating from v2 to v1 (downgrade)
|
|
172
240
|
|
|
173
|
-
|
|
241
|
+
- No re-export of `camelcase-keys`. Use the built-in helper or install yourself:
|
|
242
|
+
|
|
243
|
+
```diff
|
|
244
|
+
- import { camelcaseKeysDeep, camelcaseKeys } from '@mx-space/api-client'
|
|
245
|
+
+ import { simpleCamelcaseKeys as camelcaseKeysDeep } from '@mx-space/api-client'
|
|
174
246
|
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Development
|
|
251
|
+
|
|
252
|
+
**From repo root:**
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
pnpm i
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**From `packages/api-client`:**
|
|
259
|
+
|
|
260
|
+
- **Build**: `pnpm run package` or `pnpm run build` (cleans `dist`, runs `tsdown`).
|
|
261
|
+
- **Test**: `pnpm test` (Vitest).
|
|
262
|
+
- **Dev (watch tests)**: `pnpm run dev`.
|
|
263
|
+
|
|
264
|
+
**Project layout (high level):**
|
|
265
|
+
|
|
266
|
+
- `core/` — client, request attachment, error type.
|
|
267
|
+
- `controllers/` — one class per API area; names listed in `controllers/index.ts`.
|
|
268
|
+
- `adaptors/` — axios, umi-request, fetch.
|
|
269
|
+
- `models/`, `dtos/`, `interfaces/` — types and DTOs for requests/responses.
|
|
270
|
+
- `utils/` — path resolution, camelCase, auto-bind.
|
|
271
|
+
|
|
272
|
+
**Exports:**
|
|
273
|
+
|
|
274
|
+
- Main: `createClient`, `RequestError`, controllers, models, DTOs, `simpleCamelcaseKeys`, `HTTPClient` type, `IRequestAdapter` type.
|
|
275
|
+
- Adapters: `@mx-space/api-client/adaptors/axios`, `/adaptors/umi-request`, `/adaptors/fetch`.
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## License
|
|
280
|
+
|
|
281
|
+
MIT.
|