@mx-space/api-client 1.21.2 → 2.1.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/index.mjs CHANGED
@@ -244,6 +244,83 @@ var AIController = class {
244
244
  async getDeepReading(articleId) {
245
245
  return this.proxy("deep-readings").article(articleId).get();
246
246
  }
247
+ /**
248
+ * Get translation for an article
249
+ * @support core >= 9.4.0
250
+ */
251
+ async getTranslation({ articleId, lang }) {
252
+ return this.proxy.translations.article(articleId).get({ params: { lang } });
253
+ }
254
+ /**
255
+ * Get available translation languages for an article
256
+ * @support core >= 9.4.0
257
+ */
258
+ async getAvailableLanguages(articleId) {
259
+ return this.proxy.translations.article(articleId).languages.get();
260
+ }
261
+ /**
262
+ * Get URL for streaming summary generation (SSE)
263
+ *
264
+ * @see AISummaryStreamEvent for event types
265
+ * @support core >= 9.4.0
266
+ */
267
+ getSummaryGenerateUrl({ articleId, lang }) {
268
+ const baseUrl = this.client.endpoint;
269
+ const params = new URLSearchParams();
270
+ if (lang) params.set("lang", lang);
271
+ const query = params.toString();
272
+ return `${baseUrl}/${this.base}/summaries/article/${articleId}/generate${query ? `?${query}` : ""}`;
273
+ }
274
+ /**
275
+ * Stream summary generation using fetch
276
+ *
277
+ * @see AISummaryStreamEvent for event types
278
+ * @support core >= 9.4.0
279
+ */
280
+ async streamSummaryGenerate({ articleId, lang }, fetchOptions) {
281
+ const url = this.getSummaryGenerateUrl({
282
+ articleId,
283
+ lang
284
+ });
285
+ return fetch(url, {
286
+ ...fetchOptions,
287
+ headers: {
288
+ Accept: "text/event-stream",
289
+ ...fetchOptions?.headers
290
+ }
291
+ });
292
+ }
293
+ /**
294
+ * Get URL for streaming translation generation (SSE)
295
+ *
296
+ * @see AITranslationStreamEvent for event types
297
+ * @support core >= 9.4.0
298
+ */
299
+ getTranslationGenerateUrl({ articleId, lang }) {
300
+ const baseUrl = this.client.endpoint;
301
+ const params = new URLSearchParams();
302
+ params.set("lang", lang);
303
+ return `${baseUrl}/${this.base}/translations/article/${articleId}/generate?${params.toString()}`;
304
+ }
305
+ /**
306
+ * Stream translation generation using fetch
307
+ *
308
+ * @see AITranslationStreamEvent for event types
309
+ * @support core >= 9.4.0
310
+ */
311
+ async streamTranslationGenerate({ articleId, lang }, fetchOptions) {
312
+ const url = this.getTranslationGenerateUrl({
313
+ articleId,
314
+ lang
315
+ });
316
+ return fetch(url, {
317
+ ...fetchOptions,
318
+ headers: {
319
+ Accept: "text/event-stream",
320
+ ...fetchOptions?.headers
321
+ }
322
+ });
323
+ }
247
324
  };
248
325
 
249
326
  //#endregion
@@ -430,11 +507,12 @@ var NoteController = class {
430
507
  * @param options 可选参数:password, single, lang
431
508
  */
432
509
  getNoteByNid(nid, options) {
433
- const { password, single, lang } = options || {};
510
+ const { password, single, lang, prefer } = options || {};
434
511
  return this.proxy.nid(nid.toString()).get({ params: {
435
512
  password,
436
513
  single: single ? "1" : void 0,
437
- lang
514
+ lang,
515
+ prefer
438
516
  } });
439
517
  }
440
518
  /**
@@ -482,6 +560,81 @@ var NoteController = class {
482
560
  }
483
561
  };
484
562
 
563
+ //#endregion
564
+ //#region controllers/owner.ts
565
+ var UserController = class {
566
+ constructor(client) {
567
+ this.client = client;
568
+ this.base = "owner";
569
+ this.name = ["owner"];
570
+ autoBind(this);
571
+ }
572
+ get proxy() {
573
+ return this.client.proxy(this.base);
574
+ }
575
+ get authProxy() {
576
+ return this.client.proxy("auth");
577
+ }
578
+ normalizeToken(token) {
579
+ const normalized = token?.trim();
580
+ if (!normalized) return;
581
+ return normalized.replace(/^bearer\s+/i, "");
582
+ }
583
+ /**
584
+ * @deprecated Use `getOwnerInfo()` instead.
585
+ */
586
+ getMasterInfo() {
587
+ return this.getOwnerInfo();
588
+ }
589
+ getOwnerInfo() {
590
+ return this.proxy.get();
591
+ }
592
+ login(username, password, options) {
593
+ return this.authProxy("sign-in").username.post({ data: {
594
+ username,
595
+ password,
596
+ ...options
597
+ } });
598
+ }
599
+ logout() {
600
+ return this.authProxy("sign-out").post();
601
+ }
602
+ /**
603
+ * Better Auth raw session (`/auth/get-session`).
604
+ */
605
+ getAuthSession(options) {
606
+ return this.authProxy("get-session").get({ params: options });
607
+ }
608
+ /**
609
+ * Core session summary (`/auth/session`).
610
+ */
611
+ getSession() {
612
+ return this.authProxy.session.get();
613
+ }
614
+ getProviders() {
615
+ return this.authProxy.providers.get();
616
+ }
617
+ getAllowLoginMethods() {
618
+ return this.proxy("allow-login").get();
619
+ }
620
+ listSessions() {
621
+ return this.authProxy("list-sessions").get();
622
+ }
623
+ revokeSession(token) {
624
+ return this.authProxy("revoke-session").post({ data: { token } });
625
+ }
626
+ revokeSessions() {
627
+ return this.authProxy("revoke-sessions").post();
628
+ }
629
+ revokeOtherSessions() {
630
+ return this.authProxy("revoke-other-sessions").post();
631
+ }
632
+ checkTokenValid(token) {
633
+ const normalized = this.normalizeToken(token);
634
+ return this.proxy.check_logged.get({ params: normalized ? { token: normalized } : void 0 });
635
+ }
636
+ };
637
+
485
638
  //#endregion
486
639
  //#region controllers/page.ts
487
640
  var PageController = class {
@@ -518,8 +671,8 @@ var PageController = class {
518
671
  * @param slug 路径
519
672
  * @returns
520
673
  */
521
- getBySlug(slug) {
522
- return this.proxy.slug(slug).get({});
674
+ getBySlug(slug, options) {
675
+ return this.proxy.slug(slug).get({ params: options?.prefer ? { prefer: options.prefer } : void 0 });
523
676
  }
524
677
  };
525
678
 
@@ -557,7 +710,12 @@ var PostController = class {
557
710
  }
558
711
  getPost(idOrCategoryName, slug, options) {
559
712
  if (arguments.length == 1) return this.proxy(idOrCategoryName).get();
560
- else return this.proxy(idOrCategoryName)(slug).get({ params: options?.lang ? { lang: options.lang } : void 0 });
713
+ else {
714
+ const params = {};
715
+ if (options?.lang) params.lang = options.lang;
716
+ if (options?.prefer) params.prefer = options.prefer;
717
+ return this.proxy(idOrCategoryName)(slug).get({ params: Object.keys(params).length ? params : void 0 });
718
+ }
561
719
  }
562
720
  /**
563
721
  * 获取最新的文章
@@ -767,35 +925,6 @@ var TopicController = class extends BaseCrudController {
767
925
  }
768
926
  };
769
927
 
770
- //#endregion
771
- //#region controllers/user.ts
772
- var UserController = class {
773
- constructor(client) {
774
- this.client = client;
775
- this.base = "master";
776
- this.name = ["user", "master"];
777
- autoBind(this);
778
- }
779
- get proxy() {
780
- return this.client.proxy(this.base);
781
- }
782
- getMasterInfo() {
783
- return this.proxy.get();
784
- }
785
- login(username, password) {
786
- return this.proxy.login.post({ data: {
787
- username,
788
- password
789
- } });
790
- }
791
- loginWithToken(token) {
792
- return this.proxy.login.put({ params: token ? { token: `bearer ${token.replace(/^bearer\s/i, "")}` } : void 0 });
793
- }
794
- checkTokenValid(token) {
795
- return this.proxy.check_logged.get({ params: { token: `bearer ${token.replace(/^bearer\s/i, "")}` } });
796
- }
797
- };
798
-
799
928
  //#endregion
800
929
  //#region controllers/index.ts
801
930
  const allControllers = [
@@ -838,9 +967,8 @@ const allControllerNames = [
838
967
  "snippet",
839
968
  "serverless",
840
969
  "subscribe",
841
- "user",
970
+ "owner",
842
971
  "friend",
843
- "master",
844
972
  "shorthand"
845
973
  ];
846
974
 
@@ -1041,9 +1169,9 @@ let TimelineType = /* @__PURE__ */ function(TimelineType) {
1041
1169
 
1042
1170
  //#endregion
1043
1171
  //#region ../../apps/core/src/constants/db.constant.ts
1044
- const POST_COLLECTION_NAME = "posts";
1045
1172
  const NOTE_COLLECTION_NAME = "notes";
1046
1173
  const PAGE_COLLECTION_NAME = "pages";
1174
+ const POST_COLLECTION_NAME = "posts";
1047
1175
  const RECENTLY_COLLECTION_NAME = "recentlies";
1048
1176
  let CollectionRefTypes = /* @__PURE__ */ function(CollectionRefTypes) {
1049
1177
  CollectionRefTypes[CollectionRefTypes["Post"] = POST_COLLECTION_NAME] = "Post";
@@ -1108,7 +1236,7 @@ let SnippetType = /* @__PURE__ */ function(SnippetType) {
1108
1236
 
1109
1237
  //#endregion
1110
1238
  //#region ../../apps/core/src/modules/subscribe/subscribe.constant.ts
1111
- const SubscribePostCreateBit = Math.trunc(1);
1239
+ const SubscribePostCreateBit = 1;
1112
1240
  const SubscribeNoteCreateBit = 2;
1113
1241
  const SubscribeSayCreateBit = 4;
1114
1242
  const SubscribeRecentCreateBit = 8;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mx-space/api-client",
3
- "version": "1.21.2",
3
+ "version": "2.1.0",
4
4
  "description": "A api client for mx-space server@next",
5
5
  "type": "module",
6
6
  "engines": {
@@ -42,6 +42,13 @@
42
42
  "tag": false,
43
43
  "commit_message": "chore(release): bump @mx-space/api-client to v${NEW_VERSION}"
44
44
  },
45
+ "scripts": {
46
+ "package": "rm -rf dist && tsdown",
47
+ "build": "npm run package",
48
+ "prepackage": "rm -rf dist",
49
+ "test": "vitest",
50
+ "dev": "vitest"
51
+ },
45
52
  "devDependencies": {
46
53
  "@types/cors": "2.8.19",
47
54
  "@types/express": "5.0.6",
@@ -56,12 +63,5 @@
56
63
  "umi-request": "1.4.0",
57
64
  "vite": "^7.3.1",
58
65
  "vitest": "4.0.18"
59
- },
60
- "scripts": {
61
- "package": "rm -rf dist && tsdown",
62
- "build": "npm run package",
63
- "prepackage": "rm -rf dist",
64
- "test": "vitest",
65
- "dev": "vitest"
66
66
  }
67
- }
67
+ }
package/readme.md CHANGED
@@ -2,6 +2,75 @@
2
2
 
3
3
  这是一个适用于 MServer v3 的 JS SDK,封装了常用接口请求方法以及返回类型的声明,以快速开发前端应用。
4
4
 
5
+ ## 版本兼容性
6
+
7
+ | api-client 版本 | 支持的 Server 版本 | 说明 |
8
+ | --------------- | ------------------ | ----------------------------- |
9
+ | v2.x | >= 10 | 基于 Better Auth 的新认证系统 |
10
+ | v1.x | <= 9 | 旧版认证系统 |
11
+
12
+ **注意**: v2 版本与 v1 版本存在 Breaking Changes,升级时请参考下方迁移指南。
13
+
14
+ ## 迁移到 v2
15
+
16
+ ### Breaking Changes
17
+
18
+ #### 1. 控制器重命名
19
+
20
+ `user` 控制器已重命名为 `owner`,`master` 别名已被移除:
21
+
22
+ ```diff
23
+ - client.user.getMasterInfo()
24
+ + client.owner.getOwnerInfo()
25
+
26
+ - client.master.getMasterInfo()
27
+ + client.owner.getOwnerInfo()
28
+ ```
29
+
30
+ #### 2. 登录接口变更
31
+
32
+ 登录接口从 `POST /master/login` 变更为 `POST /auth/sign-in`:
33
+
34
+ ```diff
35
+ - client.user.login(username, password)
36
+ + client.owner.login(username, password, { rememberMe: boolean })
37
+ ```
38
+
39
+ v2 版本的 `login` 方法返回的数据结构也发生了变化,现在返回 `{ token, user }` 格式。
40
+
41
+ #### 3. 新增 Better Auth 相关接口
42
+
43
+ v2 版本新增了 Better Auth 认证相关的接口:
44
+
45
+ ```ts
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()
72
+ ```
73
+
5
74
  ## 迁移到 v1
6
75
 
7
76
  不再提供 camelcase-keys 的 re-export,此库不再依赖 camelcase-keys 库,如有需要可自行安装。
@@ -44,7 +113,7 @@ $axios.interceptors.request.use(
44
113
  (config) => {
45
114
  const token = getToken()
46
115
  if (token) {
47
- config.headers!.Authorization = `bearer ${ getToken()}`
116
+ config.headers!.Authorization = `bearer ${getToken()}`
48
117
  }
49
118
 
50
119
  return config
package/LICENSE DELETED
@@ -1,33 +0,0 @@
1
- ** Mix Space Open Source License**
2
-
3
- This project is dual-licensed under different terms for different parts of the project. It is important for users and contributors to understand the licensing terms applicable to each part of the project.
4
-
5
- ### For the `apps/` Directory
6
-
7
- **License:** GNU Affero General Public License v3.0 (AGPLv3) with Additional Terms (ADDITIONAL_TERMS).
8
-
9
- **Scope:** This license applies exclusively to all files within the `apps/` directory of this project.
10
-
11
- **Summary:**
12
- - The AGPLv3 is a free, copyleft license suitable for software that will be distributed over a network. It allows users to use, modify, and distribute the software and any modifications under the same terms.
13
- - The "Additional Terms" (ADDITIONAL_TERMS) are specific conditions that are added to the AGPLv3 license. These terms must be reviewed in the accompanying LICENSE file or documentation to understand any additional restrictions or permissions that apply to the software.
14
-
15
- ### For Other Parts of the Project
16
-
17
- **License:** MIT License.
18
-
19
- **Scope:** This license applies to all parts of the project that are not included within the `apps/` directory.
20
-
21
- **Summary:**
22
- - The MIT License is a permissive open-source license that allows users considerable freedom. It permits use, copying, modification, merging, publishing, distribution, sublicensing, and/or selling copies of the software.
23
- - It also protects the authors by including a limitation of liability and a disclaimer of warranty.
24
-
25
- **General Conditions:**
26
- - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the above license notices and this permission notice appear in all copies of the software.
27
- - The software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement.
28
-
29
- **Contribution:**
30
- - Contributions to this project are accepted under the terms of the same license as the part of the project to which the contribution is made.
31
-
32
- **Notice:**
33
- - This summary is not the license itself and is not a substitute for reading the licenses in their entirety. All users and contributors are encouraged to read the full text of the licenses for a comprehensive understanding.