lexmount 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Lexmount
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,493 @@
1
+ # Lexmount Node.js SDK
2
+
3
+ [English](#english) | [中文](#中文)
4
+
5
+ ---
6
+
7
+ ## English
8
+
9
+ Node.js SDK for the Lexmount browser automation service.
10
+
11
+ ### Features
12
+
13
+ - Node.js 18+ only
14
+ - Typed public API with ESM and CommonJS support
15
+ - Session management with pagination support
16
+ - Persistent context management
17
+ - Structured SDK errors
18
+ - Configurable SDK logging
19
+ - TSDoc + TypeDoc based API documentation generation
20
+
21
+ ### Requirements
22
+
23
+ - Node.js 18 LTS or later
24
+ - npm 9+ recommended
25
+ - Playwright is optional and only needed when you connect to browser sessions
26
+
27
+ ### Installation
28
+
29
+ #### Internal package / tgz
30
+
31
+ ```bash
32
+ npm install <lexmount-package-or-tgz>
33
+ ```
34
+
35
+ #### From source
36
+
37
+ ```bash
38
+ git clone <repository-url>
39
+ cd lexmount-js-sdk
40
+ npm install
41
+ npm run build
42
+ ```
43
+
44
+ ### Configuration
45
+
46
+ The SDK reads credentials from constructor options or environment variables.
47
+
48
+ ```bash
49
+ LEXMOUNT_API_KEY=your-api-key
50
+ LEXMOUNT_PROJECT_ID=your-project-id
51
+ LEXMOUNT_BASE_URL=https://api.lexmount.cn
52
+ ```
53
+
54
+ `LEXMOUNT_BASE_URL` is optional. The default is `https://api.lexmount.cn`.
55
+
56
+ ### Quick Start
57
+
58
+ ```ts
59
+ import { Lexmount } from 'lexmount';
60
+
61
+ const client = new Lexmount({
62
+ apiKey: process.env.LEXMOUNT_API_KEY,
63
+ projectId: process.env.LEXMOUNT_PROJECT_ID,
64
+ });
65
+
66
+ const session = await client.sessions.create();
67
+ console.log(session.id);
68
+ console.log(session.connectUrl);
69
+
70
+ await session.close();
71
+ client.close();
72
+ ```
73
+
74
+ ### Sessions
75
+
76
+ Create a session:
77
+
78
+ ```ts
79
+ const session = await client.sessions.create({
80
+ browserMode: 'normal',
81
+ });
82
+ ```
83
+
84
+ Create a session with a persistent context:
85
+
86
+ ```ts
87
+ const context = await client.contexts.create({
88
+ metadata: { userId: '1001' },
89
+ });
90
+
91
+ const session = await client.sessions.create({
92
+ context: { id: context.id, mode: 'readWrite' },
93
+ });
94
+ ```
95
+
96
+ List sessions with pagination metadata:
97
+
98
+ ```ts
99
+ const result = await client.sessions.list({ status: 'active' });
100
+
101
+ console.log(result.pagination.totalCount);
102
+ for (const session of result) {
103
+ console.log(session.id, session.status);
104
+ }
105
+ ```
106
+
107
+ Delete a session:
108
+
109
+ ```ts
110
+ await client.sessions.delete({ sessionId: 'session-id' });
111
+ ```
112
+
113
+ ### Contexts
114
+
115
+ Create and inspect contexts:
116
+
117
+ ```ts
118
+ const context = await client.contexts.create({
119
+ metadata: { owner: 'demo' },
120
+ });
121
+
122
+ const details = await client.contexts.get(context.id);
123
+ console.log(details.status);
124
+ ```
125
+
126
+ List contexts:
127
+
128
+ ```ts
129
+ const contexts = await client.contexts.list({
130
+ status: 'available',
131
+ limit: 20,
132
+ });
133
+ ```
134
+
135
+ Force release a stuck lock:
136
+
137
+ ```ts
138
+ await client.contexts.forceRelease('context-id');
139
+ ```
140
+
141
+ ### Playwright Example
142
+
143
+ ```ts
144
+ import { chromium } from 'playwright';
145
+ import { Lexmount } from 'lexmount';
146
+
147
+ const client = new Lexmount();
148
+ const session = await client.sessions.create();
149
+
150
+ const browser = await chromium.connectOverCDP(session.connectUrl);
151
+ const context = browser.contexts()[0];
152
+ const page = context.pages()[0] ?? (await context.newPage());
153
+
154
+ await page.goto('https://example.com');
155
+ console.log(await page.title());
156
+
157
+ await browser.close();
158
+ await session.close();
159
+ client.close();
160
+ ```
161
+
162
+ ### Error Handling
163
+
164
+ ```ts
165
+ import {
166
+ AuthenticationError,
167
+ ContextLockedError,
168
+ NetworkError,
169
+ TimeoutError,
170
+ } from 'lexmount';
171
+
172
+ try {
173
+ await client.sessions.create({
174
+ context: { id: 'ctx_123', mode: 'readWrite' },
175
+ });
176
+ } catch (error) {
177
+ if (error instanceof AuthenticationError) {
178
+ console.error('Authentication failed');
179
+ } else if (error instanceof ContextLockedError) {
180
+ console.error(error.activeSessionId, error.retryAfter);
181
+ } else if (error instanceof TimeoutError || error instanceof NetworkError) {
182
+ console.error('Temporary connectivity issue');
183
+ } else {
184
+ throw error;
185
+ }
186
+ }
187
+ ```
188
+
189
+ ### Logging
190
+
191
+ ```ts
192
+ import { setLogLevel } from 'lexmount';
193
+
194
+ setLogLevel('DEBUG');
195
+ ```
196
+
197
+ Available levels:
198
+
199
+ - `DEBUG`
200
+ - `INFO`
201
+ - `WARNING`
202
+ - `ERROR`
203
+ - `CRITICAL`
204
+ - `SILENT`
205
+
206
+ ### Documentation Generation
207
+
208
+ Public API docs are generated from TSDoc comments.
209
+
210
+ ```bash
211
+ npm run docs:api
212
+ npm run docs:html
213
+ ```
214
+
215
+ Generated files are written to `generated-docs/` and are not meant to be committed.
216
+
217
+ ### Examples
218
+
219
+ Example scripts live in [examples](./examples):
220
+
221
+ - `playwright-basic.ts`
222
+ - `session-management.ts`
223
+ - `context-basic.ts`
224
+ - `context-list-get.ts`
225
+ - `context-modes.ts`
226
+ - `context-lock-handling.ts`
227
+
228
+ Run them with:
229
+
230
+ ```bash
231
+ cd examples
232
+ npm install
233
+ npm run playwright-basic
234
+ npm run session-management
235
+ ```
236
+
237
+ ### Development
238
+
239
+ ```bash
240
+ npm run build
241
+ npm run typecheck
242
+ npm test
243
+ npm run docs:api
244
+ ```
245
+
246
+ ### License
247
+
248
+ MIT License
249
+
250
+ ---
251
+
252
+ ## 中文
253
+
254
+ Lexmount 浏览器自动化服务的 Node.js SDK。
255
+
256
+ ### 特性
257
+
258
+ - 仅支持 Node.js 18+
259
+ - 提供完整类型定义,同时支持 ESM 和 CommonJS
260
+ - 会话管理,支持分页信息
261
+ - 持久化 context 管理
262
+ - 结构化 SDK 异常
263
+ - 可配置 SDK 日志
264
+ - 基于 TSDoc + TypeDoc 的自动文档生成能力
265
+
266
+ ### 运行要求
267
+
268
+ - Node.js 18 LTS 或更高版本
269
+ - 建议使用 npm 9+
270
+ - 如果需要连接浏览器会话,才需要额外安装 Playwright
271
+
272
+ ### 安装
273
+
274
+ #### 内部包 / tgz
275
+
276
+ ```bash
277
+ npm install <lexmount-package-or-tgz>
278
+ ```
279
+
280
+ #### 从源码安装
281
+
282
+ ```bash
283
+ git clone <repository-url>
284
+ cd lexmount-js-sdk
285
+ npm install
286
+ npm run build
287
+ ```
288
+
289
+ ### 配置
290
+
291
+ SDK 会优先读取构造参数,其次读取环境变量:
292
+
293
+ ```bash
294
+ LEXMOUNT_API_KEY=your-api-key
295
+ LEXMOUNT_PROJECT_ID=your-project-id
296
+ LEXMOUNT_BASE_URL=https://api.lexmount.cn
297
+ ```
298
+
299
+ `LEXMOUNT_BASE_URL` 可选,默认值是 `https://api.lexmount.cn`。
300
+
301
+ ### 快速开始
302
+
303
+ ```ts
304
+ import { Lexmount } from 'lexmount';
305
+
306
+ const client = new Lexmount({
307
+ apiKey: process.env.LEXMOUNT_API_KEY,
308
+ projectId: process.env.LEXMOUNT_PROJECT_ID,
309
+ });
310
+
311
+ const session = await client.sessions.create();
312
+ console.log(session.id);
313
+ console.log(session.connectUrl);
314
+
315
+ await session.close();
316
+ client.close();
317
+ ```
318
+
319
+ ### Sessions
320
+
321
+ 创建会话:
322
+
323
+ ```ts
324
+ const session = await client.sessions.create({
325
+ browserMode: 'normal',
326
+ });
327
+ ```
328
+
329
+ 结合持久化 context 创建会话:
330
+
331
+ ```ts
332
+ const context = await client.contexts.create({
333
+ metadata: { userId: '1001' },
334
+ });
335
+
336
+ const session = await client.sessions.create({
337
+ context: { id: context.id, mode: 'readWrite' },
338
+ });
339
+ ```
340
+
341
+ 分页列出会话:
342
+
343
+ ```ts
344
+ const result = await client.sessions.list({ status: 'active' });
345
+
346
+ console.log(result.pagination.totalCount);
347
+ for (const session of result) {
348
+ console.log(session.id, session.status);
349
+ }
350
+ ```
351
+
352
+ 删除会话:
353
+
354
+ ```ts
355
+ await client.sessions.delete({ sessionId: 'session-id' });
356
+ ```
357
+
358
+ ### Contexts
359
+
360
+ 创建并查看 context:
361
+
362
+ ```ts
363
+ const context = await client.contexts.create({
364
+ metadata: { owner: 'demo' },
365
+ });
366
+
367
+ const details = await client.contexts.get(context.id);
368
+ console.log(details.status);
369
+ ```
370
+
371
+ 列出 context:
372
+
373
+ ```ts
374
+ const contexts = await client.contexts.list({
375
+ status: 'available',
376
+ limit: 20,
377
+ });
378
+ ```
379
+
380
+ 强制释放卡住的锁:
381
+
382
+ ```ts
383
+ await client.contexts.forceRelease('context-id');
384
+ ```
385
+
386
+ ### Playwright 示例
387
+
388
+ ```ts
389
+ import { chromium } from 'playwright';
390
+ import { Lexmount } from 'lexmount';
391
+
392
+ const client = new Lexmount();
393
+ const session = await client.sessions.create();
394
+
395
+ const browser = await chromium.connectOverCDP(session.connectUrl);
396
+ const context = browser.contexts()[0];
397
+ const page = context.pages()[0] ?? (await context.newPage());
398
+
399
+ await page.goto('https://example.com');
400
+ console.log(await page.title());
401
+
402
+ await browser.close();
403
+ await session.close();
404
+ client.close();
405
+ ```
406
+
407
+ ### 错误处理
408
+
409
+ ```ts
410
+ import {
411
+ AuthenticationError,
412
+ ContextLockedError,
413
+ NetworkError,
414
+ TimeoutError,
415
+ } from 'lexmount';
416
+
417
+ try {
418
+ await client.sessions.create({
419
+ context: { id: 'ctx_123', mode: 'readWrite' },
420
+ });
421
+ } catch (error) {
422
+ if (error instanceof AuthenticationError) {
423
+ console.error('鉴权失败');
424
+ } else if (error instanceof ContextLockedError) {
425
+ console.error(error.activeSessionId, error.retryAfter);
426
+ } else if (error instanceof TimeoutError || error instanceof NetworkError) {
427
+ console.error('网络或超时问题');
428
+ } else {
429
+ throw error;
430
+ }
431
+ }
432
+ ```
433
+
434
+ ### 日志
435
+
436
+ ```ts
437
+ import { setLogLevel } from 'lexmount';
438
+
439
+ setLogLevel('DEBUG');
440
+ ```
441
+
442
+ 可用级别:
443
+
444
+ - `DEBUG`
445
+ - `INFO`
446
+ - `WARNING`
447
+ - `ERROR`
448
+ - `CRITICAL`
449
+ - `SILENT`
450
+
451
+ ### 自动文档生成
452
+
453
+ 公开 API 文档基于源码里的 TSDoc 注释生成。
454
+
455
+ ```bash
456
+ npm run docs:api
457
+ npm run docs:html
458
+ ```
459
+
460
+ 生成文件会输出到 `generated-docs/`,默认不提交到仓库。
461
+
462
+ ### 示例
463
+
464
+ 示例脚本位于 [examples](./examples):
465
+
466
+ - `playwright-basic.ts`
467
+ - `session-management.ts`
468
+ - `context-basic.ts`
469
+ - `context-list-get.ts`
470
+ - `context-modes.ts`
471
+ - `context-lock-handling.ts`
472
+
473
+ 运行方式:
474
+
475
+ ```bash
476
+ cd examples
477
+ npm install
478
+ npm run playwright-basic
479
+ npm run session-management
480
+ ```
481
+
482
+ ### 开发
483
+
484
+ ```bash
485
+ npm run build
486
+ npm run typecheck
487
+ npm test
488
+ npm run docs:api
489
+ ```
490
+
491
+ ### 许可证
492
+
493
+ MIT License