@kweaver-ai/kweaver-sdk 0.4.9 → 0.4.11
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 +28 -1
- package/README.zh.md +28 -1
- package/dist/api/dataflow.d.ts +78 -0
- package/dist/api/dataflow.js +135 -0
- package/dist/api/dataviews.js +49 -0
- package/dist/auth/oauth.d.ts +6 -1
- package/dist/auth/oauth.js +240 -166
- package/dist/cli.js +4 -2
- package/dist/client.js +2 -0
- package/dist/commands/auth.js +45 -15
- package/dist/commands/bkn.d.ts +16 -0
- package/dist/commands/bkn.js +213 -25
- package/dist/commands/ds.d.ts +16 -0
- package/dist/commands/ds.js +204 -1
- package/dist/commands/import-csv.d.ts +47 -0
- package/dist/commands/import-csv.js +111 -0
- package/dist/config/store.d.ts +2 -0
- package/dist/config/tls-env.d.ts +8 -0
- package/dist/config/tls-env.js +22 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -98,7 +98,7 @@ const results = await cl.search({ query: "hypertension treatment" });
|
|
|
98
98
|
## CLI Reference
|
|
99
99
|
|
|
100
100
|
```
|
|
101
|
-
kweaver auth login
|
|
101
|
+
kweaver auth login <url> [--alias name] [-u user] [-p pass] [--playwright] [--insecure|-k] — also: status, list, use, delete, logout
|
|
102
102
|
kweaver token
|
|
103
103
|
kweaver bkn list/get/stats/export/create/update/delete
|
|
104
104
|
kweaver bkn object-type list/get/create/update/delete/query/properties
|
|
@@ -120,6 +120,33 @@ kweaver call <path> [-X METHOD] [-d BODY] [-H header]
|
|
|
120
120
|
| `KWEAVER_BASE_URL` | KWeaver instance URL |
|
|
121
121
|
| `KWEAVER_BUSINESS_DOMAIN` | Business domain identifier |
|
|
122
122
|
| `KWEAVER_TOKEN` | Access token |
|
|
123
|
+
| `KWEAVER_TLS_INSECURE` | Set to `1` or `true` to skip TLS certificate verification for all HTTPS in the process (dev only; prefer `kweaver auth … --insecure` which saves per platform) |
|
|
124
|
+
| `NODE_TLS_REJECT_UNAUTHORIZED` | Node.js built-in TLS switch: set to `0` to skip certificate verification for HTTPS in this process. The `kweaver` CLI sets this when `KWEAVER_TLS_INSECURE` is set or the saved token has insecure TLS (same scope as above; dev only). |
|
|
125
|
+
|
|
126
|
+
### TLS Certificate Troubleshooting
|
|
127
|
+
|
|
128
|
+
If you encounter errors like `fetch failed`, `self-signed certificate`, or `UNABLE_TO_GET_ISSUER_CERT`, the target server likely uses a self-signed certificate or Kubernetes Ingress default fake certificate. Try the following in order of preference:
|
|
129
|
+
|
|
130
|
+
1. **Recommended (persists per platform)** — add `--insecure` during login:
|
|
131
|
+
```bash
|
|
132
|
+
kweaver auth login https://your-host --insecure
|
|
133
|
+
# or shorthand
|
|
134
|
+
kweaver auth login https://your-host -k
|
|
135
|
+
```
|
|
136
|
+
The flag is saved to `token.json` in `~/.kweaver/`, so all subsequent CLI commands for that platform skip TLS verification automatically.
|
|
137
|
+
|
|
138
|
+
2. **Temporary (current shell)** — set an environment variable:
|
|
139
|
+
```bash
|
|
140
|
+
export KWEAVER_TLS_INSECURE=1
|
|
141
|
+
kweaver bkn list
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
3. **Node.js native** — set `NODE_TLS_REJECT_UNAUTHORIZED` directly:
|
|
145
|
+
```bash
|
|
146
|
+
NODE_TLS_REJECT_UNAUTHORIZED=0 kweaver bkn list
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
> **Security note:** All of the above disable HTTPS certificate verification and should only be used in development or internal network environments. Use trusted CA-signed certificates in production.
|
|
123
150
|
|
|
124
151
|
## Using with AI Agents
|
|
125
152
|
|
package/README.zh.md
CHANGED
|
@@ -98,7 +98,7 @@ const results = await cl.search({ query: "高血压 治疗" });
|
|
|
98
98
|
## 命令速查
|
|
99
99
|
|
|
100
100
|
```
|
|
101
|
-
kweaver auth login
|
|
101
|
+
kweaver auth login <url> [--alias name] [-u user] [-p pass] [--playwright] [--insecure|-k] — 另有 status、list、use、delete、logout
|
|
102
102
|
kweaver token
|
|
103
103
|
kweaver bkn list/get/stats/export/create/update/delete
|
|
104
104
|
kweaver bkn object-type list/get/create/update/delete/query/properties
|
|
@@ -120,6 +120,33 @@ kweaver call <path> [-X METHOD] [-d BODY] [-H header]
|
|
|
120
120
|
| `KWEAVER_BASE_URL` | KWeaver 实例地址 |
|
|
121
121
|
| `KWEAVER_BUSINESS_DOMAIN` | 业务域标识 |
|
|
122
122
|
| `KWEAVER_TOKEN` | 访问令牌 |
|
|
123
|
+
| `KWEAVER_TLS_INSECURE` | 设为 `1` 或 `true` 时跳过 TLS 证书校验(仅开发;更推荐 `kweaver auth … --insecure` 以按平台持久化) |
|
|
124
|
+
| `NODE_TLS_REJECT_UNAUTHORIZED` | Node.js 内置 TLS 开关:设为 `0` 时在本进程内跳过 HTTPS 证书校验。`kweaver` 在 `KWEAVER_TLS_INSECURE` 生效或已保存 token 为不安全 TLS 时会设置此项(范围同上;仅开发)。 |
|
|
125
|
+
|
|
126
|
+
### TLS 证书问题排查
|
|
127
|
+
|
|
128
|
+
如果遇到 `fetch failed`、`self-signed certificate`、`UNABLE_TO_GET_ISSUER_CERT` 等 TLS 相关错误,通常是目标服务器使用了自签名证书或 Kubernetes Ingress 默认假证书。可按优先级尝试以下方案:
|
|
129
|
+
|
|
130
|
+
1. **推荐(按平台持久化)** — 登录时加 `--insecure`:
|
|
131
|
+
```bash
|
|
132
|
+
kweaver auth login https://your-host --insecure
|
|
133
|
+
# 或简写
|
|
134
|
+
kweaver auth login https://your-host -k
|
|
135
|
+
```
|
|
136
|
+
该标记会写入 `~/.kweaver/` 的 `token.json`,后续所有 CLI 命令对该平台自动生效,无需额外操作。
|
|
137
|
+
|
|
138
|
+
2. **临时生效(当前 shell)** — 设置环境变量:
|
|
139
|
+
```bash
|
|
140
|
+
export KWEAVER_TLS_INSECURE=1
|
|
141
|
+
kweaver bkn list
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
3. **Node.js 原生方式** — 直接设置 `NODE_TLS_REJECT_UNAUTHORIZED`:
|
|
145
|
+
```bash
|
|
146
|
+
NODE_TLS_REJECT_UNAUTHORIZED=0 kweaver bkn list
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
> **安全提示:** 以上方式均会跳过 HTTPS 证书校验,仅适用于开发/内网环境。生产环境请使用受信任的 CA 签发证书。
|
|
123
150
|
|
|
124
151
|
## 在 AI 智能体中使用
|
|
125
152
|
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export interface DataflowStep {
|
|
2
|
+
id: string;
|
|
3
|
+
title: string;
|
|
4
|
+
operator: string;
|
|
5
|
+
parameters: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
export interface DataflowCreateBody {
|
|
8
|
+
title: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
trigger_config: {
|
|
11
|
+
operator: string;
|
|
12
|
+
};
|
|
13
|
+
steps: DataflowStep[];
|
|
14
|
+
}
|
|
15
|
+
export interface DataflowResult {
|
|
16
|
+
status: "success" | "completed" | "failed" | "error";
|
|
17
|
+
reason?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface CreateDataflowOptions {
|
|
20
|
+
baseUrl: string;
|
|
21
|
+
accessToken: string;
|
|
22
|
+
businessDomain?: string;
|
|
23
|
+
body: DataflowCreateBody;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create a new dataflow (DAG). Returns the new DAG id.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createDataflow(options: CreateDataflowOptions): Promise<string>;
|
|
29
|
+
export interface RunDataflowOptions {
|
|
30
|
+
baseUrl: string;
|
|
31
|
+
accessToken: string;
|
|
32
|
+
businessDomain?: string;
|
|
33
|
+
dagId: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Trigger a run for an existing dataflow DAG.
|
|
37
|
+
*/
|
|
38
|
+
export declare function runDataflow(options: RunDataflowOptions): Promise<void>;
|
|
39
|
+
export interface PollDataflowOptions {
|
|
40
|
+
baseUrl: string;
|
|
41
|
+
accessToken: string;
|
|
42
|
+
businessDomain?: string;
|
|
43
|
+
dagId: string;
|
|
44
|
+
/** Poll interval in seconds. Default: 3 */
|
|
45
|
+
interval?: number;
|
|
46
|
+
/** Maximum time to wait in seconds. Default: 900 */
|
|
47
|
+
timeout?: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Poll GET /api/automation/v1/dag/{dagId}/results until the run is done.
|
|
51
|
+
* Throws on "failed"/"error" status or timeout.
|
|
52
|
+
*/
|
|
53
|
+
export declare function pollDataflowResults(options: PollDataflowOptions): Promise<DataflowResult>;
|
|
54
|
+
export interface DeleteDataflowOptions {
|
|
55
|
+
baseUrl: string;
|
|
56
|
+
accessToken: string;
|
|
57
|
+
businessDomain?: string;
|
|
58
|
+
dagId: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Delete a dataflow DAG. Best-effort — does not throw on errors.
|
|
62
|
+
*/
|
|
63
|
+
export declare function deleteDataflow(options: DeleteDataflowOptions): Promise<void>;
|
|
64
|
+
export interface ExecuteDataflowOptions {
|
|
65
|
+
baseUrl: string;
|
|
66
|
+
accessToken: string;
|
|
67
|
+
businessDomain?: string;
|
|
68
|
+
body: DataflowCreateBody;
|
|
69
|
+
/** Poll interval in seconds. Default: 3 */
|
|
70
|
+
interval?: number;
|
|
71
|
+
/** Maximum polling time in seconds. Default: 900 */
|
|
72
|
+
timeout?: number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Full dataflow lifecycle: create → run → poll → delete (always, even on error).
|
|
76
|
+
* Returns the final DataflowResult.
|
|
77
|
+
*/
|
|
78
|
+
export declare function executeDataflow(options: ExecuteDataflowOptions): Promise<DataflowResult>;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { HttpError } from "../utils/http.js";
|
|
2
|
+
function buildHeaders(accessToken, businessDomain) {
|
|
3
|
+
return {
|
|
4
|
+
accept: "application/json, text/plain, */*",
|
|
5
|
+
"accept-language": "zh-cn",
|
|
6
|
+
authorization: `Bearer ${accessToken}`,
|
|
7
|
+
token: accessToken,
|
|
8
|
+
"x-business-domain": businessDomain,
|
|
9
|
+
"x-language": "zh-cn",
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function debugLog(method, url, headers, body) {
|
|
13
|
+
if (!process.env["KWEAVER_DEBUG_HTTP"])
|
|
14
|
+
return;
|
|
15
|
+
const masked = { ...headers };
|
|
16
|
+
if (masked.authorization)
|
|
17
|
+
masked.authorization = masked.authorization.slice(0, 20) + "…";
|
|
18
|
+
if (masked.token)
|
|
19
|
+
masked.token = masked.token.slice(0, 20) + "…";
|
|
20
|
+
process.stderr.write(`[debug] ${method} ${url}\n`);
|
|
21
|
+
process.stderr.write(`[debug] headers: ${JSON.stringify(masked)}\n`);
|
|
22
|
+
if (body)
|
|
23
|
+
process.stderr.write(`[debug] body (first 300): ${body.slice(0, 300)}\n`);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create a new dataflow (DAG). Returns the new DAG id.
|
|
27
|
+
*/
|
|
28
|
+
export async function createDataflow(options) {
|
|
29
|
+
const { baseUrl, accessToken, businessDomain = "bd_public", body } = options;
|
|
30
|
+
const base = baseUrl.replace(/\/+$/, "");
|
|
31
|
+
const url = `${base}/api/automation/v1/data-flow/flow`;
|
|
32
|
+
const reqHeaders = { ...buildHeaders(accessToken, businessDomain), "content-type": "application/json" };
|
|
33
|
+
const reqBody = JSON.stringify(body);
|
|
34
|
+
debugLog("POST", url, reqHeaders, reqBody);
|
|
35
|
+
const response = await fetch(url, {
|
|
36
|
+
method: "POST",
|
|
37
|
+
headers: reqHeaders,
|
|
38
|
+
body: reqBody,
|
|
39
|
+
});
|
|
40
|
+
const responseBody = await response.text();
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
throw new HttpError(response.status, response.statusText, responseBody);
|
|
43
|
+
}
|
|
44
|
+
const parsed = JSON.parse(responseBody);
|
|
45
|
+
return parsed.id;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Trigger a run for an existing dataflow DAG.
|
|
49
|
+
*/
|
|
50
|
+
export async function runDataflow(options) {
|
|
51
|
+
const { baseUrl, accessToken, businessDomain = "bd_public", dagId } = options;
|
|
52
|
+
const base = baseUrl.replace(/\/+$/, "");
|
|
53
|
+
const url = `${base}/api/automation/v1/run-instance/${encodeURIComponent(dagId)}`;
|
|
54
|
+
const response = await fetch(url, {
|
|
55
|
+
method: "POST",
|
|
56
|
+
headers: {
|
|
57
|
+
...buildHeaders(accessToken, businessDomain),
|
|
58
|
+
"content-type": "application/json",
|
|
59
|
+
},
|
|
60
|
+
body: "{}",
|
|
61
|
+
});
|
|
62
|
+
if (!response.ok) {
|
|
63
|
+
const responseBody = await response.text();
|
|
64
|
+
throw new HttpError(response.status, response.statusText, responseBody);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Poll GET /api/automation/v1/dag/{dagId}/results until the run is done.
|
|
69
|
+
* Throws on "failed"/"error" status or timeout.
|
|
70
|
+
*/
|
|
71
|
+
export async function pollDataflowResults(options) {
|
|
72
|
+
const { baseUrl, accessToken, businessDomain = "bd_public", dagId, interval = 3, timeout = 900, } = options;
|
|
73
|
+
const base = baseUrl.replace(/\/+$/, "");
|
|
74
|
+
const url = `${base}/api/automation/v1/dag/${encodeURIComponent(dagId)}/results`;
|
|
75
|
+
const deadlineMs = Date.now() + timeout * 1000;
|
|
76
|
+
while (Date.now() < deadlineMs) {
|
|
77
|
+
const response = await fetch(url, {
|
|
78
|
+
method: "GET",
|
|
79
|
+
headers: buildHeaders(accessToken, businessDomain),
|
|
80
|
+
});
|
|
81
|
+
const responseBody = await response.text();
|
|
82
|
+
if (!response.ok) {
|
|
83
|
+
throw new HttpError(response.status, response.statusText, responseBody);
|
|
84
|
+
}
|
|
85
|
+
const parsed = JSON.parse(responseBody);
|
|
86
|
+
const results = parsed.results ?? [];
|
|
87
|
+
const latest = results[0];
|
|
88
|
+
if (latest) {
|
|
89
|
+
if (latest.status === "success" || latest.status === "completed") {
|
|
90
|
+
return latest;
|
|
91
|
+
}
|
|
92
|
+
if (latest.status === "failed" || latest.status === "error") {
|
|
93
|
+
const reason = latest.reason ? `: ${latest.reason}` : "";
|
|
94
|
+
throw new Error(`Dataflow run ${latest.status}${reason}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Still running — wait before next poll
|
|
98
|
+
if (interval > 0) {
|
|
99
|
+
await new Promise((resolve) => setTimeout(resolve, interval * 1000));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
throw new Error(`Dataflow polling timed out after ${timeout}s for DAG ${dagId}`);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Delete a dataflow DAG. Best-effort — does not throw on errors.
|
|
106
|
+
*/
|
|
107
|
+
export async function deleteDataflow(options) {
|
|
108
|
+
const { baseUrl, accessToken, businessDomain = "bd_public", dagId } = options;
|
|
109
|
+
const base = baseUrl.replace(/\/+$/, "");
|
|
110
|
+
const url = `${base}/api/automation/v1/data-flow/flow/${encodeURIComponent(dagId)}`;
|
|
111
|
+
try {
|
|
112
|
+
await fetch(url, {
|
|
113
|
+
method: "DELETE",
|
|
114
|
+
headers: buildHeaders(accessToken, businessDomain),
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// Best-effort: swallow all errors
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Full dataflow lifecycle: create → run → poll → delete (always, even on error).
|
|
123
|
+
* Returns the final DataflowResult.
|
|
124
|
+
*/
|
|
125
|
+
export async function executeDataflow(options) {
|
|
126
|
+
const { baseUrl, accessToken, businessDomain = "bd_public", body, interval, timeout } = options;
|
|
127
|
+
const dagId = await createDataflow({ baseUrl, accessToken, businessDomain, body });
|
|
128
|
+
try {
|
|
129
|
+
await runDataflow({ baseUrl, accessToken, businessDomain, dagId });
|
|
130
|
+
return await pollDataflowResults({ baseUrl, accessToken, businessDomain, dagId, interval, timeout });
|
|
131
|
+
}
|
|
132
|
+
finally {
|
|
133
|
+
await deleteDataflow({ baseUrl, accessToken, businessDomain, dagId }).catch(() => { });
|
|
134
|
+
}
|
|
135
|
+
}
|
package/dist/api/dataviews.js
CHANGED
|
@@ -51,11 +51,60 @@ export async function createDataView(options) {
|
|
|
51
51
|
});
|
|
52
52
|
const responseBody = await response.text();
|
|
53
53
|
if (!response.ok) {
|
|
54
|
+
// If DataView already exists (403 with "Existed" error code), delete and recreate
|
|
55
|
+
if (response.status === 403) {
|
|
56
|
+
try {
|
|
57
|
+
const errBody = JSON.parse(responseBody);
|
|
58
|
+
if (errBody.error_code?.includes("Existed")) {
|
|
59
|
+
const actualId = await findDataViewByName({ baseUrl, accessToken, name, groupId: datasourceId, businessDomain });
|
|
60
|
+
if (actualId && fields.length > 0) {
|
|
61
|
+
// Delete the bare DataView (created by scanMetadata) and recreate with fields
|
|
62
|
+
await deleteDataView({ baseUrl, accessToken, id: actualId, businessDomain });
|
|
63
|
+
const retryResponse = await fetch(url, {
|
|
64
|
+
method: "POST",
|
|
65
|
+
headers: { ...buildHeaders(accessToken, businessDomain), "content-type": "application/json" },
|
|
66
|
+
body,
|
|
67
|
+
});
|
|
68
|
+
if (retryResponse.ok) {
|
|
69
|
+
const retryBody = await retryResponse.text();
|
|
70
|
+
const retryId = extractViewId(JSON.parse(retryBody));
|
|
71
|
+
return retryId ?? viewId;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (actualId)
|
|
75
|
+
return actualId;
|
|
76
|
+
return viewId;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch { /* fall through to throw */ }
|
|
80
|
+
}
|
|
54
81
|
throw new HttpError(response.status, response.statusText, responseBody);
|
|
55
82
|
}
|
|
56
83
|
const createdId = extractViewId(JSON.parse(responseBody));
|
|
57
84
|
return createdId ?? viewId;
|
|
58
85
|
}
|
|
86
|
+
async function findDataViewByName(options) {
|
|
87
|
+
const base = options.baseUrl.replace(/\/+$/, "");
|
|
88
|
+
const url = new URL(`${base}/api/mdl-data-model/v1/data-views`);
|
|
89
|
+
url.searchParams.set("keyword", options.name);
|
|
90
|
+
const response = await fetch(url.toString(), {
|
|
91
|
+
method: "GET",
|
|
92
|
+
headers: buildHeaders(options.accessToken, options.businessDomain),
|
|
93
|
+
});
|
|
94
|
+
if (!response.ok)
|
|
95
|
+
return null;
|
|
96
|
+
const body = JSON.parse(await response.text());
|
|
97
|
+
const match = body.entries?.find((e) => e.name === options.name && e.group_id === options.groupId);
|
|
98
|
+
return match?.id ?? null;
|
|
99
|
+
}
|
|
100
|
+
async function deleteDataView(options) {
|
|
101
|
+
const base = options.baseUrl.replace(/\/+$/, "");
|
|
102
|
+
const url = `${base}/api/mdl-data-model/v1/data-views/${encodeURIComponent(options.id)}`;
|
|
103
|
+
await fetch(url, {
|
|
104
|
+
method: "DELETE",
|
|
105
|
+
headers: buildHeaders(options.accessToken, options.businessDomain),
|
|
106
|
+
});
|
|
107
|
+
}
|
|
59
108
|
export async function getDataView(options) {
|
|
60
109
|
const { baseUrl, accessToken, id, businessDomain = "bd_public", } = options;
|
|
61
110
|
const base = baseUrl.replace(/\/+$/, "");
|
package/dist/auth/oauth.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { type TokenConfig } from "../config/store.js";
|
|
|
2
2
|
export declare function normalizeBaseUrl(value: string): string;
|
|
3
3
|
/**
|
|
4
4
|
* OAuth2 Authorization Code login flow.
|
|
5
|
-
* 1. Register client (if not already registered)
|
|
5
|
+
* 1. Register client (if not already registered), OR use a provided client ID
|
|
6
6
|
* 2. Open browser to /oauth2/auth
|
|
7
7
|
* 3. Receive authorization code via local HTTP callback
|
|
8
8
|
* 4. Exchange code for access_token + refresh_token
|
|
@@ -11,6 +11,10 @@ export declare function normalizeBaseUrl(value: string): string;
|
|
|
11
11
|
export declare function oauth2Login(baseUrl: string, options?: {
|
|
12
12
|
port?: number;
|
|
13
13
|
scope?: string;
|
|
14
|
+
clientId?: string;
|
|
15
|
+
clientSecret?: string;
|
|
16
|
+
/** Skip TLS certificate verification (self-signed / dev servers only). */
|
|
17
|
+
tlsInsecure?: boolean;
|
|
14
18
|
}): Promise<TokenConfig>;
|
|
15
19
|
/**
|
|
16
20
|
* Playwright-automated OAuth2 login.
|
|
@@ -28,6 +32,7 @@ export declare function playwrightLogin(baseUrl: string, options?: {
|
|
|
28
32
|
password?: string;
|
|
29
33
|
port?: number;
|
|
30
34
|
scope?: string;
|
|
35
|
+
tlsInsecure?: boolean;
|
|
31
36
|
}): Promise<TokenConfig>;
|
|
32
37
|
/**
|
|
33
38
|
* Exchange refresh_token for a new access token (OAuth2 password grant style, same as Python ConfigAuth).
|