@choiceform/shared-auth 0.1.13 → 0.1.15
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/README.md +106 -450
- package/dist/api/auth-api.d.ts +28 -0
- package/dist/api/auth-api.d.ts.map +1 -0
- package/dist/api/auth-api.js +133 -0
- package/dist/api/client.d.ts +34 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +104 -0
- package/dist/api/index.d.ts +12 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +7 -0
- package/dist/api/organization-api.d.ts +96 -0
- package/dist/api/organization-api.d.ts.map +1 -0
- package/dist/api/organization-api.js +228 -0
- package/dist/api/team-api.d.ts +57 -0
- package/dist/api/team-api.d.ts.map +1 -0
- package/dist/api/team-api.js +118 -0
- package/dist/config.d.ts +4 -50
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -6
- package/dist/core.d.ts +307 -1717
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +35 -17
- package/dist/index.d.ts +11 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -12
- package/dist/init.d.ts +326 -1732
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +13 -14
- package/dist/lib/auth-client.d.ts +232 -1689
- package/dist/lib/auth-client.d.ts.map +1 -1
- package/dist/lib/auth-client.js +10 -16
- package/dist/services/companion-team.d.ts +16 -0
- package/dist/services/companion-team.d.ts.map +1 -0
- package/dist/services/companion-team.js +73 -0
- package/dist/services/index.d.ts +5 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +4 -0
- package/dist/store/actions.d.ts +45 -30
- package/dist/store/actions.d.ts.map +1 -1
- package/dist/store/actions.js +139 -103
- package/dist/store/index.d.ts +8 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +7 -0
- package/dist/store/state.d.ts +10 -7
- package/dist/store/state.d.ts.map +1 -1
- package/dist/store/state.js +31 -23
- package/dist/store/utils.d.ts +22 -71
- package/dist/store/utils.d.ts.map +1 -1
- package/dist/store/utils.js +28 -146
- package/dist/types/auth.d.ts +107 -0
- package/dist/types/auth.d.ts.map +1 -0
- package/dist/types/auth.js +4 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/organization.d.ts +111 -0
- package/dist/types/organization.d.ts.map +1 -0
- package/dist/types/organization.js +4 -0
- package/dist/types/team.d.ts +52 -0
- package/dist/types/team.d.ts.map +1 -0
- package/dist/types/team.js +4 -0
- package/dist/types/user.d.ts +44 -0
- package/dist/types/user.d.ts.map +1 -0
- package/dist/types/user.js +4 -0
- package/dist/utils/date.d.ts +10 -0
- package/dist/utils/date.d.ts.map +1 -0
- package/dist/utils/date.js +13 -0
- package/dist/utils/env.d.ts +20 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/env.js +23 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/user-mapper.d.ts +21 -0
- package/dist/utils/user-mapper.d.ts.map +1 -0
- package/dist/utils/user-mapper.js +55 -0
- package/package.json +3 -4
- package/dist/components/auth-sync.d.ts +0 -25
- package/dist/components/auth-sync.d.ts.map +0 -1
- package/dist/components/auth-sync.js +0 -346
- package/dist/components/protected-route.d.ts +0 -18
- package/dist/components/protected-route.d.ts.map +0 -1
- package/dist/components/protected-route.js +0 -34
- package/dist/components/sign-in-page.d.ts +0 -21
- package/dist/components/sign-in-page.d.ts.map +0 -1
- package/dist/components/sign-in-page.js +0 -31
- package/dist/core/init-auth-sync.d.ts +0 -7
- package/dist/core/init-auth-sync.d.ts.map +0 -1
- package/dist/core/init-auth-sync.js +0 -34
- package/dist/types.d.ts +0 -87
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -4
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 认证 API
|
|
3
|
+
*/
|
|
4
|
+
import { extractSessionUser } from "../utils";
|
|
5
|
+
import { parseErrorResponse } from "./client";
|
|
6
|
+
export function createAuthApi(apiClient, baseURL) {
|
|
7
|
+
return {
|
|
8
|
+
async getSession(token) {
|
|
9
|
+
const options = token
|
|
10
|
+
? { headers: { Authorization: `Bearer ${token}` } }
|
|
11
|
+
: undefined;
|
|
12
|
+
const response = await apiClient.fetch("/v1/auth/get-session", options);
|
|
13
|
+
if (!response.ok)
|
|
14
|
+
return null;
|
|
15
|
+
try {
|
|
16
|
+
return extractSessionUser(await response.json());
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
async getSessionWithToken(token) {
|
|
23
|
+
const response = await fetch(`${baseURL}/v1/auth/get-session`, {
|
|
24
|
+
method: "GET",
|
|
25
|
+
headers: {
|
|
26
|
+
Authorization: `Bearer ${token}`,
|
|
27
|
+
"Content-Type": "application/json",
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
if (!response.ok) {
|
|
31
|
+
throw new Error(`Failed to fetch session: ${await parseErrorResponse(response)}`);
|
|
32
|
+
}
|
|
33
|
+
return extractSessionUser(await response.json());
|
|
34
|
+
},
|
|
35
|
+
async setActiveOrganization(params, token) {
|
|
36
|
+
const headers = { "Content-Type": "application/json" };
|
|
37
|
+
if (token)
|
|
38
|
+
headers.Authorization = `Bearer ${token}`;
|
|
39
|
+
const response = await fetch(`${baseURL}/v1/auth/organization/set-active`, {
|
|
40
|
+
method: "POST",
|
|
41
|
+
headers,
|
|
42
|
+
body: JSON.stringify(params),
|
|
43
|
+
});
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
throw new Error(`Failed to set active organization: ${await parseErrorResponse(response)}`);
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
async setActiveTeam(params, token) {
|
|
49
|
+
const headers = { "Content-Type": "application/json" };
|
|
50
|
+
if (token)
|
|
51
|
+
headers.Authorization = `Bearer ${token}`;
|
|
52
|
+
const response = await fetch(`${baseURL}/v1/auth/organization/set-active-team`, {
|
|
53
|
+
method: "POST",
|
|
54
|
+
headers,
|
|
55
|
+
body: JSON.stringify(params),
|
|
56
|
+
});
|
|
57
|
+
if (!response.ok) {
|
|
58
|
+
throw new Error(`Failed to set active team: ${await parseErrorResponse(response)}`);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
async onboard(token) {
|
|
62
|
+
const response = await fetch(`${baseURL}/v1/auth/onboard`, {
|
|
63
|
+
method: "POST",
|
|
64
|
+
headers: {
|
|
65
|
+
"Content-Type": "application/json",
|
|
66
|
+
Authorization: `Bearer ${token}`,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
if (!response.ok) {
|
|
70
|
+
throw new Error(`Failed to onboard: ${await parseErrorResponse(response)}`);
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
async updateUser(data) {
|
|
74
|
+
const response = await apiClient.post("/v1/auth/update-user", data);
|
|
75
|
+
if (!response.ok) {
|
|
76
|
+
throw new Error(`Failed to update user: ${response.status}`);
|
|
77
|
+
}
|
|
78
|
+
return this.getSession();
|
|
79
|
+
},
|
|
80
|
+
async sendMagicLink(params) {
|
|
81
|
+
const response = await fetch(`${baseURL}/v1/auth/sign-in/magic-link`, {
|
|
82
|
+
method: "POST",
|
|
83
|
+
headers: { "Content-Type": "application/json" },
|
|
84
|
+
body: JSON.stringify(params),
|
|
85
|
+
});
|
|
86
|
+
if (!response.ok) {
|
|
87
|
+
throw new Error(`Failed to send magic link: ${await parseErrorResponse(response)}`);
|
|
88
|
+
}
|
|
89
|
+
return response.json();
|
|
90
|
+
},
|
|
91
|
+
/**
|
|
92
|
+
* 为已登录用户绑定密码
|
|
93
|
+
* 用于通过 OAuth 或 Magic Link 登录的用户设置密码
|
|
94
|
+
*/
|
|
95
|
+
async linkCredential(newPassword, token) {
|
|
96
|
+
const headers = { "Content-Type": "application/json" };
|
|
97
|
+
if (token)
|
|
98
|
+
headers.Authorization = `Bearer ${token}`;
|
|
99
|
+
const response = await fetch(`${baseURL}/v1/auth/link-credential`, {
|
|
100
|
+
method: "POST",
|
|
101
|
+
headers,
|
|
102
|
+
credentials: "include",
|
|
103
|
+
body: JSON.stringify({ newPassword }),
|
|
104
|
+
});
|
|
105
|
+
if (!response.ok) {
|
|
106
|
+
throw new Error(`Failed to link credential: ${await parseErrorResponse(response)}`);
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
/**
|
|
110
|
+
* 检查邮箱是否已注册
|
|
111
|
+
* 注意:此 API 可能不存在,调用时需要处理错误
|
|
112
|
+
*/
|
|
113
|
+
async checkEmailExists(email) {
|
|
114
|
+
try {
|
|
115
|
+
const response = await fetch(`${baseURL}/v1/auth/check-email`, {
|
|
116
|
+
method: "POST",
|
|
117
|
+
headers: { "Content-Type": "application/json" },
|
|
118
|
+
body: JSON.stringify({ email }),
|
|
119
|
+
});
|
|
120
|
+
if (!response.ok) {
|
|
121
|
+
// API 不存在或其他错误,返回 false 让流程继续
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
const data = await response.json();
|
|
125
|
+
return data.exists === true;
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// 网络错误等,返回 false 让流程继续
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 基础 HTTP 客户端
|
|
3
|
+
*/
|
|
4
|
+
import type { Observable } from "@legendapp/state";
|
|
5
|
+
import type { AuthState } from "../types";
|
|
6
|
+
export interface TokenStorage {
|
|
7
|
+
clear(): void;
|
|
8
|
+
get(): string | null;
|
|
9
|
+
save(token: string | null): void;
|
|
10
|
+
}
|
|
11
|
+
export interface UnauthorizedHandler {
|
|
12
|
+
handleUnauthorized(): void;
|
|
13
|
+
}
|
|
14
|
+
export interface ApiClientConfig {
|
|
15
|
+
authStore: Observable<AuthState>;
|
|
16
|
+
baseURL?: string;
|
|
17
|
+
tokenStorage: TokenStorage;
|
|
18
|
+
unauthorizedHandler: UnauthorizedHandler;
|
|
19
|
+
}
|
|
20
|
+
export interface ApiResponse<T = unknown> {
|
|
21
|
+
data: T;
|
|
22
|
+
ok: boolean;
|
|
23
|
+
status: number;
|
|
24
|
+
}
|
|
25
|
+
export declare function parseErrorResponse(response: Response): Promise<string>;
|
|
26
|
+
export declare function createApiClient(config: ApiClientConfig): {
|
|
27
|
+
get<T = unknown>(path: string, options?: RequestInit): Promise<ApiResponse<T>>;
|
|
28
|
+
post<T = unknown>(path: string, body?: unknown, options?: RequestInit): Promise<ApiResponse<T>>;
|
|
29
|
+
put<T = unknown>(path: string, body?: unknown, options?: RequestInit): Promise<ApiResponse<T>>;
|
|
30
|
+
delete<T = unknown>(path: string, options?: RequestInit): Promise<ApiResponse<T>>;
|
|
31
|
+
fetch(path: string, options?: RequestInit): Promise<Response>;
|
|
32
|
+
};
|
|
33
|
+
export type ApiClient = ReturnType<typeof createApiClient>;
|
|
34
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,MAAM,WAAW,YAAY;IAC3B,KAAK,IAAI,IAAI,CAAA;IACb,GAAG,IAAI,MAAM,GAAG,IAAI,CAAA;IACpB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAA;CACjC;AAED,MAAM,WAAW,mBAAmB;IAClC,kBAAkB,IAAI,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC,CAAA;IAChC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,YAAY,CAAA;IAC1B,mBAAmB,EAAE,mBAAmB,CAAA;CACzC;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACtC,IAAI,EAAE,CAAC,CAAA;IACP,EAAE,EAAE,OAAO,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;CACf;AA2BD,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAmB5E;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe;QAMzC,CAAC,kBAAkB,MAAM,YAAY,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;SASzE,CAAC,kBAAkB,MAAM,SAAS,OAAO,YAAY,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAc3F,CAAC,kBAAkB,MAAM,SAAS,OAAO,YAAY,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;WAcvF,CAAC,kBAAkB,MAAM,YAAY,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;gBASrE,MAAM,YAAY,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;EAWtE;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAA"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 基础 HTTP 客户端
|
|
3
|
+
*/
|
|
4
|
+
function getAuthHeaders(tokenStorage) {
|
|
5
|
+
const token = tokenStorage.get();
|
|
6
|
+
return token ? { Authorization: `Bearer ${token}` } : {};
|
|
7
|
+
}
|
|
8
|
+
async function handleResponse(response, unauthorizedHandler) {
|
|
9
|
+
if (response.status === 401) {
|
|
10
|
+
unauthorizedHandler.handleUnauthorized();
|
|
11
|
+
}
|
|
12
|
+
let data = null;
|
|
13
|
+
if (response.headers.get("content-type")?.includes("application/json")) {
|
|
14
|
+
try {
|
|
15
|
+
data = await response.json();
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
data = null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return { data: data, ok: response.ok, status: response.status };
|
|
22
|
+
}
|
|
23
|
+
export async function parseErrorResponse(response) {
|
|
24
|
+
try {
|
|
25
|
+
const text = await response.text();
|
|
26
|
+
if (text) {
|
|
27
|
+
try {
|
|
28
|
+
const json = JSON.parse(text);
|
|
29
|
+
if (typeof json.error === "object" && json.error !== null) {
|
|
30
|
+
const msg = json.error.message;
|
|
31
|
+
if (typeof msg === "string")
|
|
32
|
+
return msg;
|
|
33
|
+
}
|
|
34
|
+
if (typeof json.message === "string")
|
|
35
|
+
return json.message;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return text.length < 200 ? text : `${text.substring(0, 200)}...`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// ignore
|
|
44
|
+
}
|
|
45
|
+
return `HTTP ${response.status}: ${response.statusText}`;
|
|
46
|
+
}
|
|
47
|
+
export function createApiClient(config) {
|
|
48
|
+
const { tokenStorage, unauthorizedHandler, baseURL = "" } = config;
|
|
49
|
+
const buildUrl = (path) => (path.startsWith("http") ? path : `${baseURL}${path}`);
|
|
50
|
+
return {
|
|
51
|
+
async get(path, options) {
|
|
52
|
+
const response = await fetch(buildUrl(path), {
|
|
53
|
+
...options,
|
|
54
|
+
method: "GET",
|
|
55
|
+
headers: { ...getAuthHeaders(tokenStorage), ...options?.headers },
|
|
56
|
+
});
|
|
57
|
+
return handleResponse(response, unauthorizedHandler);
|
|
58
|
+
},
|
|
59
|
+
async post(path, body, options) {
|
|
60
|
+
const response = await fetch(buildUrl(path), {
|
|
61
|
+
...options,
|
|
62
|
+
method: "POST",
|
|
63
|
+
headers: {
|
|
64
|
+
"Content-Type": "application/json",
|
|
65
|
+
...getAuthHeaders(tokenStorage),
|
|
66
|
+
...options?.headers,
|
|
67
|
+
},
|
|
68
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
69
|
+
});
|
|
70
|
+
return handleResponse(response, unauthorizedHandler);
|
|
71
|
+
},
|
|
72
|
+
async put(path, body, options) {
|
|
73
|
+
const response = await fetch(buildUrl(path), {
|
|
74
|
+
...options,
|
|
75
|
+
method: "PUT",
|
|
76
|
+
headers: {
|
|
77
|
+
"Content-Type": "application/json",
|
|
78
|
+
...getAuthHeaders(tokenStorage),
|
|
79
|
+
...options?.headers,
|
|
80
|
+
},
|
|
81
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
82
|
+
});
|
|
83
|
+
return handleResponse(response, unauthorizedHandler);
|
|
84
|
+
},
|
|
85
|
+
async delete(path, options) {
|
|
86
|
+
const response = await fetch(buildUrl(path), {
|
|
87
|
+
...options,
|
|
88
|
+
method: "DELETE",
|
|
89
|
+
headers: { ...getAuthHeaders(tokenStorage), ...options?.headers },
|
|
90
|
+
});
|
|
91
|
+
return handleResponse(response, unauthorizedHandler);
|
|
92
|
+
},
|
|
93
|
+
async fetch(path, options) {
|
|
94
|
+
const response = await fetch(buildUrl(path), {
|
|
95
|
+
...options,
|
|
96
|
+
headers: { ...getAuthHeaders(tokenStorage), ...options?.headers },
|
|
97
|
+
});
|
|
98
|
+
if (response.status === 401) {
|
|
99
|
+
unauthorizedHandler.handleUnauthorized();
|
|
100
|
+
}
|
|
101
|
+
return response;
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API 层导出
|
|
3
|
+
*/
|
|
4
|
+
export { createApiClient, parseErrorResponse } from "./client";
|
|
5
|
+
export type { ApiClient, ApiClientConfig, ApiResponse, TokenStorage, UnauthorizedHandler } from "./client";
|
|
6
|
+
export { createAuthApi } from "./auth-api";
|
|
7
|
+
export type { AuthApi } from "./auth-api";
|
|
8
|
+
export { createOrganizationApi } from "./organization-api";
|
|
9
|
+
export type { OrganizationApi } from "./organization-api";
|
|
10
|
+
export { createTeamApi } from "./team-api";
|
|
11
|
+
export type { TeamApi } from "./team-api";
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAC9D,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAE1G,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 组织相关 API
|
|
3
|
+
*
|
|
4
|
+
* 封装所有组织管理的 API 调用
|
|
5
|
+
* 基于 Core AI Auth API 文档
|
|
6
|
+
*/
|
|
7
|
+
import type { Organization, FullOrganization, CreateOrganizationRequest, UpdateOrganizationRequest, DeleteOrganizationRequest, SetActiveOrganizationRequest, CheckSlugRequest, Member, RemoveMemberRequest, UpdateMemberRoleRequest, Invitation, InvitationDetail, InviteMemberRequest, CancelInvitationRequest, AcceptInvitationRequest, RejectInvitationRequest, InvitationResponse } from "../types/organization";
|
|
8
|
+
import type { ApiClient } from "./client";
|
|
9
|
+
/**
|
|
10
|
+
* 创建组织 API
|
|
11
|
+
*
|
|
12
|
+
* @param apiClient - API 客户端实例
|
|
13
|
+
* @param _baseURL - Auth API 基础 URL(保留参数,与其他 API 保持一致)
|
|
14
|
+
*/
|
|
15
|
+
export declare function createOrganizationApi(apiClient: ApiClient, _baseURL: string): {
|
|
16
|
+
/**
|
|
17
|
+
* 创建组织
|
|
18
|
+
*/
|
|
19
|
+
create(request: CreateOrganizationRequest): Promise<Organization>;
|
|
20
|
+
/**
|
|
21
|
+
* 更新组织
|
|
22
|
+
*/
|
|
23
|
+
update(request: UpdateOrganizationRequest): Promise<Organization>;
|
|
24
|
+
/**
|
|
25
|
+
* 删除组织
|
|
26
|
+
*/
|
|
27
|
+
delete(request: DeleteOrganizationRequest): Promise<string>;
|
|
28
|
+
/**
|
|
29
|
+
* 获取组织列表
|
|
30
|
+
*/
|
|
31
|
+
list(): Promise<Organization[]>;
|
|
32
|
+
/**
|
|
33
|
+
* 获取当前活跃组织详情(包含成员列表和用户信息)
|
|
34
|
+
*/
|
|
35
|
+
getFullOrganization(): Promise<FullOrganization | null>;
|
|
36
|
+
/**
|
|
37
|
+
* 设置活跃组织
|
|
38
|
+
*/
|
|
39
|
+
setActive(request: SetActiveOrganizationRequest): Promise<Organization>;
|
|
40
|
+
/**
|
|
41
|
+
* 检查 slug 可用性
|
|
42
|
+
*/
|
|
43
|
+
checkSlug(request: CheckSlugRequest): Promise<boolean>;
|
|
44
|
+
/**
|
|
45
|
+
* 获取当前活跃成员信息
|
|
46
|
+
*/
|
|
47
|
+
getActiveMember(): Promise<Member | null>;
|
|
48
|
+
/**
|
|
49
|
+
* 获取当前用户在活跃组织中的角色
|
|
50
|
+
*/
|
|
51
|
+
getActiveMemberRole(): Promise<{
|
|
52
|
+
role: string;
|
|
53
|
+
} | null>;
|
|
54
|
+
/**
|
|
55
|
+
* 移除成员
|
|
56
|
+
*/
|
|
57
|
+
removeMember(request: RemoveMemberRequest): Promise<Member>;
|
|
58
|
+
/**
|
|
59
|
+
* 更新成员角色
|
|
60
|
+
*/
|
|
61
|
+
updateMemberRole(request: UpdateMemberRoleRequest): Promise<Member>;
|
|
62
|
+
/**
|
|
63
|
+
* 邀请成员
|
|
64
|
+
* @param request 邀请请求参数
|
|
65
|
+
* @param inviteLink 邀请链接(会添加到 Choiceform-Invite-Link header 中)
|
|
66
|
+
*/
|
|
67
|
+
inviteMember(request: InviteMemberRequest, inviteLink?: string): Promise<Invitation>;
|
|
68
|
+
/**
|
|
69
|
+
* 获取邀请列表
|
|
70
|
+
*/
|
|
71
|
+
listInvitations(): Promise<Invitation[]>;
|
|
72
|
+
/**
|
|
73
|
+
* 获取邀请详情
|
|
74
|
+
*/
|
|
75
|
+
getInvitation(invitationId: string): Promise<InvitationDetail | null>;
|
|
76
|
+
/**
|
|
77
|
+
* 取消邀请
|
|
78
|
+
*/
|
|
79
|
+
cancelInvitation(request: CancelInvitationRequest): Promise<void>;
|
|
80
|
+
/**
|
|
81
|
+
* 接受邀请
|
|
82
|
+
*/
|
|
83
|
+
acceptInvitation(request: AcceptInvitationRequest): Promise<InvitationResponse>;
|
|
84
|
+
/**
|
|
85
|
+
* 拒绝邀请
|
|
86
|
+
*/
|
|
87
|
+
rejectInvitation(request: RejectInvitationRequest): Promise<InvitationResponse>;
|
|
88
|
+
/**
|
|
89
|
+
* 离开组织
|
|
90
|
+
*
|
|
91
|
+
* 当用户在非伴生组织中只剩最后一个团队时,离开该团队等于离开整个组织
|
|
92
|
+
*/
|
|
93
|
+
leave(organizationId: string): Promise<void>;
|
|
94
|
+
};
|
|
95
|
+
export type OrganizationApi = ReturnType<typeof createOrganizationApi>;
|
|
96
|
+
//# sourceMappingURL=organization-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"organization-api.d.ts","sourceRoot":"","sources":["../../src/api/organization-api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,4BAA4B,EAC5B,gBAAgB,EAChB,MAAM,EACN,mBAAmB,EACnB,uBAAuB,EACvB,UAAU,EACV,gBAAgB,EAChB,mBAAmB,EACnB,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EACnB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM;IAQxE;;OAEG;oBACmB,yBAAyB,GAAG,OAAO,CAAC,YAAY,CAAC;IAQvE;;OAEG;oBACmB,yBAAyB,GAAG,OAAO,CAAC,YAAY,CAAC;IAQvE;;OAEG;oBACmB,yBAAyB,GAAG,OAAO,CAAC,MAAM,CAAC;IAQjE;;OAEG;YACW,OAAO,CAAC,YAAY,EAAE,CAAC;IAQrC;;OAEG;2BAC0B,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAW7D;;OAEG;uBACsB,4BAA4B,GAAG,OAAO,CAAC,YAAY,CAAC;IAQ7E;;OAEG;uBACsB,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAgB5D;;OAEG;uBACsB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAW/C;;OAEG;2BAC0B,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAW7D;;OAEG;0BACyB,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC;IAQjE;;OAEG;8BAC6B,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC;IAYzE;;;;OAIG;0BACyB,mBAAmB,eAAe,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAiB1F;;OAEG;uBACsB,OAAO,CAAC,UAAU,EAAE,CAAC;IAQ9C;;OAEG;gCAC+B,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAa3E;;OAEG;8BAC6B,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvE;;OAEG;8BAC6B,uBAAuB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAQrF;;OAEG;8BAC6B,uBAAuB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAQrF;;;;OAIG;0BACyB,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;EAOrD;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAA"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 组织相关 API
|
|
3
|
+
*
|
|
4
|
+
* 封装所有组织管理的 API 调用
|
|
5
|
+
* 基于 Core AI Auth API 文档
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* 创建组织 API
|
|
9
|
+
*
|
|
10
|
+
* @param apiClient - API 客户端实例
|
|
11
|
+
* @param _baseURL - Auth API 基础 URL(保留参数,与其他 API 保持一致)
|
|
12
|
+
*/
|
|
13
|
+
export function createOrganizationApi(apiClient, _baseURL) {
|
|
14
|
+
const basePath = "/v1/auth/organization";
|
|
15
|
+
return {
|
|
16
|
+
// ============================================================
|
|
17
|
+
// 组织 CRUD
|
|
18
|
+
// ============================================================
|
|
19
|
+
/**
|
|
20
|
+
* 创建组织
|
|
21
|
+
*/
|
|
22
|
+
async create(request) {
|
|
23
|
+
const response = await apiClient.post(`${basePath}/create`, request);
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
throw new Error(`Failed to create organization: ${response.status}`);
|
|
26
|
+
}
|
|
27
|
+
return response.data;
|
|
28
|
+
},
|
|
29
|
+
/**
|
|
30
|
+
* 更新组织
|
|
31
|
+
*/
|
|
32
|
+
async update(request) {
|
|
33
|
+
const response = await apiClient.post(`${basePath}/update`, request);
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
throw new Error(`Failed to update organization: ${response.status}`);
|
|
36
|
+
}
|
|
37
|
+
return response.data;
|
|
38
|
+
},
|
|
39
|
+
/**
|
|
40
|
+
* 删除组织
|
|
41
|
+
*/
|
|
42
|
+
async delete(request) {
|
|
43
|
+
const response = await apiClient.post(`${basePath}/delete`, request);
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
throw new Error(`Failed to delete organization: ${response.status}`);
|
|
46
|
+
}
|
|
47
|
+
return response.data;
|
|
48
|
+
},
|
|
49
|
+
/**
|
|
50
|
+
* 获取组织列表
|
|
51
|
+
*/
|
|
52
|
+
async list() {
|
|
53
|
+
const response = await apiClient.get(`${basePath}/list`);
|
|
54
|
+
if (!response.ok) {
|
|
55
|
+
throw new Error(`Failed to list organizations: ${response.status}`);
|
|
56
|
+
}
|
|
57
|
+
return response.data || [];
|
|
58
|
+
},
|
|
59
|
+
/**
|
|
60
|
+
* 获取当前活跃组织详情(包含成员列表和用户信息)
|
|
61
|
+
*/
|
|
62
|
+
async getFullOrganization() {
|
|
63
|
+
const response = await apiClient.get(`${basePath}/get-full-organization`);
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
if (response.status === 404) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
throw new Error(`Failed to get organization: ${response.status}`);
|
|
69
|
+
}
|
|
70
|
+
return response.data;
|
|
71
|
+
},
|
|
72
|
+
/**
|
|
73
|
+
* 设置活跃组织
|
|
74
|
+
*/
|
|
75
|
+
async setActive(request) {
|
|
76
|
+
const response = await apiClient.post(`${basePath}/set-active`, request);
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
throw new Error(`Failed to set active organization: ${response.status}`);
|
|
79
|
+
}
|
|
80
|
+
return response.data;
|
|
81
|
+
},
|
|
82
|
+
/**
|
|
83
|
+
* 检查 slug 可用性
|
|
84
|
+
*/
|
|
85
|
+
async checkSlug(request) {
|
|
86
|
+
const response = await apiClient.post(`${basePath}/check-slug`, request);
|
|
87
|
+
if (!response.ok) {
|
|
88
|
+
// 400 表示 slug 不可用
|
|
89
|
+
if (response.status === 400) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
throw new Error(`Failed to check slug: ${response.status}`);
|
|
93
|
+
}
|
|
94
|
+
return true;
|
|
95
|
+
},
|
|
96
|
+
// ============================================================
|
|
97
|
+
// 成员管理
|
|
98
|
+
// ============================================================
|
|
99
|
+
/**
|
|
100
|
+
* 获取当前活跃成员信息
|
|
101
|
+
*/
|
|
102
|
+
async getActiveMember() {
|
|
103
|
+
const response = await apiClient.get(`${basePath}/get-active-member`);
|
|
104
|
+
if (!response.ok) {
|
|
105
|
+
if (response.status === 404) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
throw new Error(`Failed to get active member: ${response.status}`);
|
|
109
|
+
}
|
|
110
|
+
return response.data;
|
|
111
|
+
},
|
|
112
|
+
/**
|
|
113
|
+
* 获取当前用户在活跃组织中的角色
|
|
114
|
+
*/
|
|
115
|
+
async getActiveMemberRole() {
|
|
116
|
+
const response = await apiClient.get(`${basePath}/get-active-member-role`);
|
|
117
|
+
if (!response.ok) {
|
|
118
|
+
if (response.status === 404) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
throw new Error(`Failed to get active member role: ${response.status}`);
|
|
122
|
+
}
|
|
123
|
+
return response.data;
|
|
124
|
+
},
|
|
125
|
+
/**
|
|
126
|
+
* 移除成员
|
|
127
|
+
*/
|
|
128
|
+
async removeMember(request) {
|
|
129
|
+
const response = await apiClient.post(`${basePath}/remove-member`, request);
|
|
130
|
+
if (!response.ok) {
|
|
131
|
+
throw new Error(`Failed to remove member: ${response.status}`);
|
|
132
|
+
}
|
|
133
|
+
return response.data.member;
|
|
134
|
+
},
|
|
135
|
+
/**
|
|
136
|
+
* 更新成员角色
|
|
137
|
+
*/
|
|
138
|
+
async updateMemberRole(request) {
|
|
139
|
+
const response = await apiClient.post(`${basePath}/update-member-role`, request);
|
|
140
|
+
if (!response.ok) {
|
|
141
|
+
throw new Error(`Failed to update member role: ${response.status}`);
|
|
142
|
+
}
|
|
143
|
+
return response.data.member;
|
|
144
|
+
},
|
|
145
|
+
// ============================================================
|
|
146
|
+
// 邀请管理
|
|
147
|
+
// ============================================================
|
|
148
|
+
/**
|
|
149
|
+
* 邀请成员
|
|
150
|
+
* @param request 邀请请求参数
|
|
151
|
+
* @param inviteLink 邀请链接(会添加到 Choiceform-Invite-Link header 中)
|
|
152
|
+
*/
|
|
153
|
+
async inviteMember(request, inviteLink) {
|
|
154
|
+
const headers = {};
|
|
155
|
+
if (inviteLink) {
|
|
156
|
+
headers["Choiceform-Invite-Link"] = inviteLink;
|
|
157
|
+
}
|
|
158
|
+
const response = await apiClient.post(`${basePath}/invite-member`, request, { headers });
|
|
159
|
+
if (!response.ok) {
|
|
160
|
+
throw new Error(`Failed to invite member: ${response.status}`);
|
|
161
|
+
}
|
|
162
|
+
return response.data;
|
|
163
|
+
},
|
|
164
|
+
/**
|
|
165
|
+
* 获取邀请列表
|
|
166
|
+
*/
|
|
167
|
+
async listInvitations() {
|
|
168
|
+
const response = await apiClient.get(`${basePath}/list-invitations`);
|
|
169
|
+
if (!response.ok) {
|
|
170
|
+
throw new Error(`Failed to list invitations: ${response.status}`);
|
|
171
|
+
}
|
|
172
|
+
return response.data || [];
|
|
173
|
+
},
|
|
174
|
+
/**
|
|
175
|
+
* 获取邀请详情
|
|
176
|
+
*/
|
|
177
|
+
async getInvitation(invitationId) {
|
|
178
|
+
const response = await apiClient.get(`${basePath}/get-invitation?id=${encodeURIComponent(invitationId)}`);
|
|
179
|
+
if (!response.ok) {
|
|
180
|
+
if (response.status === 404) {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
throw new Error(`Failed to get invitation: ${response.status}`);
|
|
184
|
+
}
|
|
185
|
+
return response.data;
|
|
186
|
+
},
|
|
187
|
+
/**
|
|
188
|
+
* 取消邀请
|
|
189
|
+
*/
|
|
190
|
+
async cancelInvitation(request) {
|
|
191
|
+
const response = await apiClient.post(`${basePath}/cancel-invitation`, request);
|
|
192
|
+
if (!response.ok) {
|
|
193
|
+
throw new Error(`Failed to cancel invitation: ${response.status}`);
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
/**
|
|
197
|
+
* 接受邀请
|
|
198
|
+
*/
|
|
199
|
+
async acceptInvitation(request) {
|
|
200
|
+
const response = await apiClient.post(`${basePath}/accept-invitation`, request);
|
|
201
|
+
if (!response.ok) {
|
|
202
|
+
throw new Error(`Failed to accept invitation: ${response.status}`);
|
|
203
|
+
}
|
|
204
|
+
return response.data;
|
|
205
|
+
},
|
|
206
|
+
/**
|
|
207
|
+
* 拒绝邀请
|
|
208
|
+
*/
|
|
209
|
+
async rejectInvitation(request) {
|
|
210
|
+
const response = await apiClient.post(`${basePath}/reject-invitation`, request);
|
|
211
|
+
if (!response.ok) {
|
|
212
|
+
throw new Error(`Failed to reject invitation: ${response.status}`);
|
|
213
|
+
}
|
|
214
|
+
return response.data;
|
|
215
|
+
},
|
|
216
|
+
/**
|
|
217
|
+
* 离开组织
|
|
218
|
+
*
|
|
219
|
+
* 当用户在非伴生组织中只剩最后一个团队时,离开该团队等于离开整个组织
|
|
220
|
+
*/
|
|
221
|
+
async leave(organizationId) {
|
|
222
|
+
const response = await apiClient.post(`${basePath}/leave`, { organizationId });
|
|
223
|
+
if (!response.ok) {
|
|
224
|
+
throw new Error(`Failed to leave organization: ${response.status}`);
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 团队相关 API
|
|
3
|
+
*
|
|
4
|
+
* 封装所有团队管理的 API 调用
|
|
5
|
+
* 基于 Core AI Auth API 文档
|
|
6
|
+
*/
|
|
7
|
+
import type { AddTeamMemberRequest, CreateTeamRequest, DeleteTeamRequest, RemoveTeamMemberRequest, SetActiveTeamRequest, Team, TeamMember, UpdateTeamRequest } from "../types/team";
|
|
8
|
+
import type { ApiClient } from "./client";
|
|
9
|
+
/**
|
|
10
|
+
* 创建团队 API
|
|
11
|
+
*
|
|
12
|
+
* @param apiClient - API 客户端实例
|
|
13
|
+
*/
|
|
14
|
+
export declare function createTeamApi(apiClient: ApiClient): {
|
|
15
|
+
/**
|
|
16
|
+
* 创建团队
|
|
17
|
+
*/
|
|
18
|
+
create(request: CreateTeamRequest): Promise<Team>;
|
|
19
|
+
/**
|
|
20
|
+
* 获取团队列表
|
|
21
|
+
*/
|
|
22
|
+
list(): Promise<Team[]>;
|
|
23
|
+
/**
|
|
24
|
+
* 更新团队
|
|
25
|
+
*/
|
|
26
|
+
update(request: UpdateTeamRequest): Promise<Team>;
|
|
27
|
+
/**
|
|
28
|
+
* 删除团队
|
|
29
|
+
*/
|
|
30
|
+
delete(request: DeleteTeamRequest): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* 设置活跃团队
|
|
33
|
+
*/
|
|
34
|
+
setActive(request: SetActiveTeamRequest): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* 获取用户所属的团队列表
|
|
37
|
+
*/
|
|
38
|
+
listUserTeams(): Promise<Team[]>;
|
|
39
|
+
/**
|
|
40
|
+
* 获取团队成员列表
|
|
41
|
+
*/
|
|
42
|
+
listMembers(teamId: string): Promise<TeamMember[]>;
|
|
43
|
+
/**
|
|
44
|
+
* 添加团队成员
|
|
45
|
+
*/
|
|
46
|
+
addMember(request: AddTeamMemberRequest): Promise<TeamMember>;
|
|
47
|
+
/**
|
|
48
|
+
* 移除团队成员(需要管理员权限)
|
|
49
|
+
*/
|
|
50
|
+
removeMember(request: RemoveTeamMemberRequest): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* 离开团队(普通成员可自行调用)
|
|
53
|
+
*/
|
|
54
|
+
leaveTeam(teamId: string): Promise<void>;
|
|
55
|
+
};
|
|
56
|
+
export type TeamApi = ReturnType<typeof createTeamApi>;
|
|
57
|
+
//# sourceMappingURL=team-api.d.ts.map
|