@ysgroup/core 0.1.0 → 0.1.2

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.
Files changed (3) hide show
  1. package/package.json +1 -4
  2. package/src/rest.ts +25 -26
  3. package/src/store.ts +24 -6
package/package.json CHANGED
@@ -1,12 +1,9 @@
1
1
  {
2
2
  "name": "@ysgroup/core",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
7
- "dependencies": {
8
- "@ysgroup/contracts": "0.1.1"
9
- },
10
7
  "peerDependencies": {
11
8
  "pinia": ">=2.2",
12
9
  "vue": ">=3.5"
package/src/rest.ts CHANGED
@@ -85,26 +85,30 @@ export class YsRest {
85
85
  deleteImpact(table: string, id: string) {
86
86
  return this.request<DeleteImpact>("GET", `/api/tables/${table}/${id}/delete-impact`);
87
87
  }
88
- revealCredentials(table: string, id: string, body: {
89
- fields: string[];
90
- password: string;
91
- reason: string;
92
- }) {
88
+ revealCredentials(
89
+ table: string,
90
+ id: string,
91
+ body: {
92
+ fields: string[];
93
+ password: string;
94
+ reason: string;
95
+ },
96
+ ) {
93
97
  return this.request<{
94
98
  credentials: Record<string, RevealedCredential>;
95
99
  expires_in: number;
96
100
  }>("POST", `/api/tables/${table}/${id}/credentials/reveal`, body);
97
101
  }
98
- updateCredentials(table: string, id: string, body: {
99
- credentials: Record<string, string>;
100
- password: string;
101
- reason: string;
102
- }) {
103
- return this.request<{ updated_fields: string[] }>(
104
- "POST",
105
- `/api/tables/${table}/${id}/credentials/update`,
106
- body,
107
- );
102
+ updateCredentials(
103
+ table: string,
104
+ id: string,
105
+ body: {
106
+ credentials: Record<string, string>;
107
+ password: string;
108
+ reason: string;
109
+ },
110
+ ) {
111
+ return this.request<{ updated_fields: string[] }>("POST", `/api/tables/${table}/${id}/credentials/update`, body);
108
112
  }
109
113
  listApps() {
110
114
  return this.request<Record<string, unknown>[]>("GET", "/api/apps");
@@ -186,17 +190,11 @@ export class YsRest {
186
190
  owner_ids: ownerIds,
187
191
  });
188
192
  }
189
- getRelations(entity: "owners" | "accounts", id: string,
190
- relation: "apps" | "strategies") {
191
- return this.request<{ ids: string[] }>(
192
- "GET", `/api/${entity}/${id}/relations/${relation}`,
193
- );
193
+ getRelations(entity: "owners" | "accounts", id: string, relation: "apps" | "strategies") {
194
+ return this.request<{ ids: string[] }>("GET", `/api/${entity}/${id}/relations/${relation}`);
194
195
  }
195
- setRelations(entity: "owners" | "accounts", id: string,
196
- relation: "apps" | "strategies", ids: string[]) {
197
- return this.request<{ ids: string[] }>(
198
- "PUT", `/api/${entity}/${id}/relations/${relation}`, { ids },
199
- );
196
+ setRelations(entity: "owners" | "accounts", id: string, relation: "apps" | "strategies", ids: string[]) {
197
+ return this.request<{ ids: string[] }>("PUT", `/api/${entity}/${id}/relations/${relation}`, { ids });
200
198
  }
201
199
  listOwnerFiles(ownerId: string) {
202
200
  return this.request<Record<string, unknown>[]>("GET", `/api/owners/${ownerId}/files`);
@@ -217,9 +215,10 @@ export class YsRest {
217
215
  export interface TopologyNode {
218
216
  name: string;
219
217
  title: string;
220
- kind: string;
218
+ kind: "service" | "link";
221
219
  status: string;
222
220
  port: number;
221
+ logo_url?: string;
223
222
  online: boolean;
224
223
  last_heartbeat_at: number;
225
224
  subscribed_tables: string[];
package/src/store.ts CHANGED
@@ -19,13 +19,14 @@ export const useYsStore = defineStore("ys", () => {
19
19
  const refreshToken = ref<string>(localStorage.getItem(LS_REFRESH) ?? "");
20
20
  const connected = ref(false);
21
21
  const appName = ref("");
22
+ const sessionMessage = ref("");
22
23
  /** 差量订阅的表数据:table -> Map<id, doc> */
23
24
  const tables = ref<Record<string, Map<string, Record<string, unknown>>>>({});
24
25
 
25
26
  let ws: YsWsClient | null = null;
26
27
  let renewTimer: ReturnType<typeof setTimeout> | null = null;
27
28
 
28
- const isLoggedIn = computed(() => !!accessToken.value);
29
+ const isLoggedIn = computed(() => !!accessToken.value && !!user.value);
29
30
 
30
31
  function tableList(table: string): Record<string, unknown>[] {
31
32
  return Array.from(tables.value[table]?.values() ?? []);
@@ -41,7 +42,7 @@ export const useYsStore = defineStore("ys", () => {
41
42
  ws.on("__disconnected", () => (connected.value = false));
42
43
  ws.on("snapshot", (d: unknown) => applySnapshot(d as SnapshotData));
43
44
  ws.on("delta", (d: unknown) => applyDelta(d as DeltaData));
44
- ws.on("user_revoked", (d: unknown) => onRevoked(d as { user_id: string }));
45
+ ws.on("user_revoked", (d: unknown) => onRevoked(d as { user_id: string; reason?: string }));
45
46
  ws.on("resync", () => {}); // 前端订阅本子系统后端,resync 由后端 SDK 处理
46
47
  ws.start();
47
48
  }
@@ -78,12 +79,28 @@ export const useYsStore = defineStore("ys", () => {
78
79
  tables.value = { ...tables.value, [d.table]: new Map(map) };
79
80
  }
80
81
 
81
- function onRevoked(d: { user_id: string }) {
82
- if (user.value && String(user.value._id) === d.user_id) void logout();
82
+ function onRevoked(d: { user_id: string; reason?: string }) {
83
+ if (!user.value || String(user.value._id) !== d.user_id) return;
84
+ clearSession();
85
+ sessionMessage.value = revokedMessage(d.reason);
86
+ }
87
+
88
+ function revokedMessage(reason = ""): string {
89
+ if (reason === "password_changed") {
90
+ return "登录密码已修改,您已从所有系统退出,请使用新密码重新登录。";
91
+ }
92
+ if (reason === "user_disabled" || reason === "disabled") {
93
+ return "账号已停用,请联系管理员。";
94
+ }
95
+ if (reason === "app_access_revoked") {
96
+ return "当前账号已无权访问该系统。";
97
+ }
98
+ return "登录状态已失效,请重新登录。";
83
99
  }
84
100
 
85
101
  async function login(username: string, password: string, otp = ""): Promise<void> {
86
102
  if (!ws) throw new Error("未连接");
103
+ sessionMessage.value = "";
87
104
  const result = (await ws.call("login", {
88
105
  username,
89
106
  password,
@@ -135,6 +152,7 @@ export const useYsStore = defineStore("ys", () => {
135
152
  }
136
153
 
137
154
  function setSession(result: LoginResult) {
155
+ sessionMessage.value = "";
138
156
  if (result.user) user.value = result.user;
139
157
  accessToken.value = result.access_token;
140
158
  refreshToken.value = result.refresh_token;
@@ -162,7 +180,7 @@ export const useYsStore = defineStore("ys", () => {
162
180
  localStorage.setItem(LS_REFRESH, result.refresh_token);
163
181
  scheduleRenew(result.access_expires_in);
164
182
  } catch {
165
- void logout();
183
+ clearSession();
166
184
  }
167
185
  }
168
186
 
@@ -189,7 +207,7 @@ export const useYsStore = defineStore("ys", () => {
189
207
  }
190
208
 
191
209
  return {
192
- user, accessToken, refreshToken, connected, isLoggedIn, tables,
210
+ user, accessToken, refreshToken, connected, isLoggedIn, sessionMessage, tables,
193
211
  tableList, connect, login, loginByCode, waitUntilConnected, changeMyPassword, renew, logout,
194
212
  client: () => ws,
195
213
  };