@xpert-ai/chatkit-wps-addin 0.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.
@@ -0,0 +1,235 @@
1
+ import { createReadStream, existsSync, readFileSync, statSync } from 'node:fs';
2
+ import { createServer } from 'node:http';
3
+ import { extname, join, resolve } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ const SESSION_COOKIE_NAME = 'chatkit_wps_session_id';
6
+ const SESSION_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 30;
7
+ const DEFAULT_PORT = 8789;
8
+ const DEFAULT_XPERTAI_API_URL = 'https://api.xpertai.cn/api/ai';
9
+ const __dirname = fileURLToPath(new URL('.', import.meta.url));
10
+ const packageRoot = resolve(__dirname, '../..');
11
+ const staticRoot = resolve(packageRoot, 'dist');
12
+ function loadEnvFile(path) {
13
+ if (!existsSync(path)) {
14
+ return;
15
+ }
16
+ for (const rawLine of readFileSync(path, 'utf8').split(/\r?\n/)) {
17
+ const line = rawLine.trim();
18
+ if (!line || line.startsWith('#') || !line.includes('=')) {
19
+ continue;
20
+ }
21
+ const [key, ...valueParts] = line.split('=');
22
+ const value = valueParts.join('=').trim().replace(/^['"]|['"]$/g, '');
23
+ if (key.trim() && process.env[key.trim()] === undefined) {
24
+ process.env[key.trim()] = value;
25
+ }
26
+ }
27
+ }
28
+ loadEnvFile(resolve(packageRoot, '.env'));
29
+ loadEnvFile(resolve(packageRoot, '.env.local'));
30
+ function getConfig() {
31
+ return {
32
+ port: Number(process.env.PORT ?? DEFAULT_PORT),
33
+ apiUrl: stripTrailingSlash(process.env.XPERTAI_API_URL ?? DEFAULT_XPERTAI_API_URL),
34
+ apiKey: process.env.XPERTAI_API_KEY,
35
+ xpertId: process.env.XPERTAI_XPERT_ID,
36
+ frameUrl: process.env.XPERTAI_CHATKIT_FRAME_URL ?? process.env.VITE_CHATKIT_FRAME_URL,
37
+ organizationId: process.env.XPERTAI_ORGANIZATION_ID,
38
+ principalUserId: process.env.XPERTAI_PRINCIPAL_USER_ID,
39
+ expiresAfter: readPositiveInteger(process.env.XPERTAI_CLIENT_SECRET_EXPIRES_AFTER) ?? 600,
40
+ allowedOrigin: process.env.CORS_ORIGIN ?? '*',
41
+ serveStatic: process.env.SERVE_STATIC === 'true',
42
+ };
43
+ }
44
+ function stripTrailingSlash(value) {
45
+ return value.replace(/\/+$/, '');
46
+ }
47
+ function readPositiveInteger(value) {
48
+ if (typeof value !== 'string' && typeof value !== 'number') {
49
+ return undefined;
50
+ }
51
+ const parsed = Number(value);
52
+ return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;
53
+ }
54
+ function sendJson(response, statusCode, payload, cookieValue) {
55
+ response.statusCode = statusCode;
56
+ response.setHeader('Content-Type', 'application/json; charset=utf-8');
57
+ if (cookieValue) {
58
+ response.setHeader('Set-Cookie', `${SESSION_COOKIE_NAME}=${cookieValue}; Max-Age=${SESSION_COOKIE_MAX_AGE_SECONDS}; Path=/; HttpOnly; SameSite=Lax`);
59
+ }
60
+ response.end(`${JSON.stringify(payload)}\n`);
61
+ }
62
+ function applyCors(request, response) {
63
+ const config = getConfig();
64
+ const origin = config.allowedOrigin === '*'
65
+ ? request.headers.origin ?? '*'
66
+ : config.allowedOrigin;
67
+ response.setHeader('Access-Control-Allow-Origin', origin);
68
+ response.setHeader('Access-Control-Allow-Credentials', 'true');
69
+ response.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
70
+ response.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
71
+ }
72
+ async function readJsonBody(request) {
73
+ const chunks = [];
74
+ for await (const chunk of request) {
75
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
76
+ }
77
+ if (chunks.length === 0) {
78
+ return {};
79
+ }
80
+ try {
81
+ const parsed = JSON.parse(Buffer.concat(chunks).toString('utf8'));
82
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
83
+ ? parsed
84
+ : {};
85
+ }
86
+ catch {
87
+ return {};
88
+ }
89
+ }
90
+ function readCookie(request, name) {
91
+ const cookie = request.headers.cookie;
92
+ if (!cookie) {
93
+ return undefined;
94
+ }
95
+ for (const segment of cookie.split(';')) {
96
+ const [rawKey, ...rawValue] = segment.trim().split('=');
97
+ if (rawKey === name) {
98
+ return decodeURIComponent(rawValue.join('='));
99
+ }
100
+ }
101
+ return undefined;
102
+ }
103
+ function resolveUserId(request) {
104
+ const existing = readCookie(request, SESSION_COOKIE_NAME);
105
+ if (existing) {
106
+ return { userId: existing };
107
+ }
108
+ const userId = crypto.randomUUID();
109
+ return { userId, cookie: userId };
110
+ }
111
+ async function createSession(request, response) {
112
+ const config = getConfig();
113
+ const body = await readJsonBody(request);
114
+ const expiresAfter = readPositiveInteger(body.expires_after) ??
115
+ readPositiveInteger(body.expiresAfter) ??
116
+ config.expiresAfter;
117
+ if (!config.apiKey) {
118
+ sendJson(response, 500, { error: 'Missing XPERTAI_API_KEY environment variable.' });
119
+ return;
120
+ }
121
+ if (!config.xpertId) {
122
+ sendJson(response, 500, { error: 'Missing XPERTAI_XPERT_ID environment variable.' });
123
+ return;
124
+ }
125
+ if (!config.frameUrl) {
126
+ sendJson(response, 500, { error: 'Missing XPERTAI_CHATKIT_FRAME_URL environment variable.' });
127
+ return;
128
+ }
129
+ const resolvedUser = resolveUserId(request);
130
+ const principalUserId = config.principalUserId ?? resolvedUser.userId;
131
+ const upstreamResponse = await fetch(`${config.apiUrl}/v1/chatkit/sessions`, {
132
+ method: 'POST',
133
+ headers: {
134
+ 'Content-Type': 'application/json',
135
+ 'x-api-key': config.apiKey,
136
+ ...(config.organizationId ? { 'organization-id': config.organizationId } : {}),
137
+ ...(principalUserId ? { 'x-principal-user-id': principalUserId } : {}),
138
+ },
139
+ body: JSON.stringify({
140
+ expires_after: expiresAfter,
141
+ }),
142
+ });
143
+ const payload = (await upstreamResponse.json().catch(() => ({})));
144
+ if (!upstreamResponse.ok) {
145
+ sendJson(response, upstreamResponse.status, {
146
+ error: typeof payload.error === 'string'
147
+ ? payload.error
148
+ : upstreamResponse.statusText || 'Failed to create ChatKit session.',
149
+ }, resolvedUser.cookie);
150
+ return;
151
+ }
152
+ const clientSecret = payload.client_secret;
153
+ if (typeof clientSecret !== 'string' || !clientSecret) {
154
+ sendJson(response, 502, { error: 'Missing client_secret in Xpert ChatKit session response.' }, resolvedUser.cookie);
155
+ return;
156
+ }
157
+ sendJson(response, 200, {
158
+ client_secret: clientSecret,
159
+ expires_at: payload.expires_at,
160
+ expires_after: payload.expires_after ?? expiresAfter,
161
+ apiUrl: config.apiUrl,
162
+ frameUrl: config.frameUrl,
163
+ xpertId: config.xpertId,
164
+ organizationId: config.organizationId ?? null,
165
+ }, resolvedUser.cookie);
166
+ }
167
+ function getContentType(path) {
168
+ switch (extname(path)) {
169
+ case '.html':
170
+ return 'text/html; charset=utf-8';
171
+ case '.js':
172
+ return 'text/javascript; charset=utf-8';
173
+ case '.css':
174
+ return 'text/css; charset=utf-8';
175
+ case '.svg':
176
+ return 'image/svg+xml';
177
+ case '.png':
178
+ return 'image/png';
179
+ case '.json':
180
+ return 'application/json; charset=utf-8';
181
+ case '.xml':
182
+ return 'application/xml; charset=utf-8';
183
+ default:
184
+ return 'application/octet-stream';
185
+ }
186
+ }
187
+ function serveStatic(request, response) {
188
+ const config = getConfig();
189
+ if (!config.serveStatic || !request.url) {
190
+ return false;
191
+ }
192
+ const url = new URL(request.url, 'http://localhost');
193
+ const pathname = url.pathname === '/' ? '/index.html' : url.pathname;
194
+ const target = resolve(join(staticRoot, pathname));
195
+ if (!target.startsWith(staticRoot) || !existsSync(target) || !statSync(target).isFile()) {
196
+ return false;
197
+ }
198
+ response.statusCode = 200;
199
+ response.setHeader('Content-Type', getContentType(target));
200
+ if (request.method === 'HEAD') {
201
+ response.end();
202
+ return true;
203
+ }
204
+ createReadStream(target).pipe(response);
205
+ return true;
206
+ }
207
+ const server = createServer(async (request, response) => {
208
+ applyCors(request, response);
209
+ if (request.method === 'OPTIONS') {
210
+ response.statusCode = 204;
211
+ response.end();
212
+ return;
213
+ }
214
+ if (request.method === 'POST' && request.url?.startsWith('/api/create-session')) {
215
+ try {
216
+ await createSession(request, response);
217
+ }
218
+ catch (error) {
219
+ sendJson(response, 502, {
220
+ error: error instanceof Error ? error.message : String(error),
221
+ });
222
+ }
223
+ return;
224
+ }
225
+ if ((request.method === 'GET' || request.method === 'HEAD') &&
226
+ serveStatic(request, response)) {
227
+ return;
228
+ }
229
+ sendJson(response, 404, { error: 'Not found.' });
230
+ });
231
+ const config = getConfig();
232
+ server.listen(config.port, () => {
233
+ console.log(`WPS ChatKit session proxy listening on http://localhost:${config.port}`);
234
+ });
235
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>XpertAI WPS Copilot</title>
7
+ <script type="module" crossorigin src="./assets/taskpane-6flg2Ej3.js"></script>
8
+ <link rel="modulepreload" crossorigin href="./assets/wps-api-DgiVmik0.js">
9
+ <link rel="stylesheet" crossorigin href="./assets/taskpane-BLKT3Knq.css">
10
+ </head>
11
+ <body>
12
+ <div id="root"></div>
13
+ </body>
14
+ </html>
package/env.example ADDED
@@ -0,0 +1,19 @@
1
+ PORT=8789
2
+ ADDIN_BASE_URL=http://localhost:3003
3
+
4
+ # Frontend mode. Use user-api-key for no local session proxy, or proxy for /api/create-session.
5
+ VITE_CHATKIT_SESSION_MODE=user-api-key
6
+
7
+ # Used by dist/config.js or VITE_* build-time defaults in user-api-key mode.
8
+ VITE_XPERTAI_API_URL=https://api.xpertai.cn/api/ai
9
+ VITE_XPERTAI_XPERT_ID=your-xpert-id
10
+ VITE_XPERTAI_CHATKIT_FRAME_URL=https://app.xpertai.cn/chatkit/index.html
11
+
12
+ # Server proxy mode only. Do not expose this through VITE_* in a shared build.
13
+ XPERTAI_API_URL=https://api.xpertai.cn/api/ai
14
+ XPERTAI_API_KEY=sk-x-your-api-key
15
+ XPERTAI_XPERT_ID=your-xpert-id
16
+ XPERTAI_CHATKIT_FRAME_URL=https://app.xpertai.cn/chatkit/index.html
17
+ # XPERTAI_ORGANIZATION_ID=org-xxx
18
+ # XPERTAI_PRINCIPAL_USER_ID=user-xxx
19
+ # XPERTAI_CLIENT_SECRET_EXPIRES_AFTER=600
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@xpert-ai/chatkit-wps-addin",
3
+ "version": "0.2.0",
4
+ "description": "WPS Writer task pane add-in that embeds Xpert ChatKit and exposes WPS client tools.",
5
+ "sideEffects": false,
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ "./package.json": "./package.json",
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "default": "./dist/index.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md",
21
+ "env.example",
22
+ "!**/*.tsbuildinfo"
23
+ ],
24
+ "dependencies": {
25
+ "react": "^19.0.0",
26
+ "react-dom": "^19.0.0",
27
+ "@xpert-ai/chatkit-types": "~0.3.12",
28
+ "@xpert-ai/chatkit-react": "~0.3.1"
29
+ },
30
+ "devDependencies": {
31
+ "@types/node": "^20.19.0",
32
+ "@types/react": "^19.0.0",
33
+ "@types/react-dom": "^19.0.0",
34
+ "@vitejs/plugin-react": "^4.3.4",
35
+ "rimraf": "^6.0.0",
36
+ "typescript": "^5.8.3",
37
+ "vite": "^6.0.0",
38
+ "vite-plugin-dts": "^3.7.0",
39
+ "vite-tsconfig-paths": "^6.1.1",
40
+ "vitest": "^3.2.4"
41
+ },
42
+ "keywords": [
43
+ "chatkit",
44
+ "wps-addin",
45
+ "wps",
46
+ "xpert"
47
+ ],
48
+ "repository": {
49
+ "directory": "packages/wps-addin",
50
+ "type": "git",
51
+ "url": "https://github.com/xpert-ai/chatkit-js"
52
+ },
53
+ "scripts": {
54
+ "build": "rimraf dist && pnpm build:lib && pnpm build:taskpane && pnpm build:server && pnpm manifest",
55
+ "build:lib": "vite build --config vite.lib.config.ts",
56
+ "build:taskpane": "vite build --config vite.config.ts",
57
+ "build:server": "tsc -p tsconfig.server.json",
58
+ "dev": "vite --host 0.0.0.0 --port 3003",
59
+ "manifest": "node scripts/generate-manifest.mjs",
60
+ "preview": "vite preview --host 0.0.0.0 --port 3003",
61
+ "server": "node dist/server/index.js",
62
+ "type-check": "tsc --noEmit",
63
+ "test": "vitest run"
64
+ }
65
+ }