@niiiiiiile/iw-jira-cli 0.5.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/.env.example +14 -0
- package/README.md +277 -0
- package/dist/adf-mentions.d.ts +3 -0
- package/dist/adf-mentions.js +103 -0
- package/dist/adf.d.ts +4 -0
- package/dist/adf.js +38 -0
- package/dist/agent-compact.d.ts +164 -0
- package/dist/agent-compact.js +132 -0
- package/dist/bootstrap.d.ts +1 -0
- package/dist/bootstrap.js +4 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +101 -0
- package/dist/config.d.ts +30 -0
- package/dist/config.js +47 -0
- package/dist/issue-cli.d.ts +127 -0
- package/dist/issue-cli.js +407 -0
- package/dist/issue-fields.d.ts +4 -0
- package/dist/issue-fields.js +20 -0
- package/dist/jira-client.d.ts +67 -0
- package/dist/jira-client.js +77 -0
- package/dist/jira-env.d.ts +10 -0
- package/dist/jira-env.js +23 -0
- package/dist/jsonl-lines.d.ts +3 -0
- package/dist/jsonl-lines.js +57 -0
- package/dist/load-dotenv.d.ts +1 -0
- package/dist/load-dotenv.js +24 -0
- package/dist/output.d.ts +7 -0
- package/dist/output.js +9 -0
- package/dist/parse-jira-input.d.ts +9 -0
- package/dist/parse-jira-input.js +97 -0
- package/dist/profile-cli.d.ts +2 -0
- package/dist/profile-cli.js +105 -0
- package/dist/project-cli.d.ts +14 -0
- package/dist/project-cli.js +36 -0
- package/dist/shared.d.ts +8 -0
- package/dist/shared.js +8 -0
- package/dist/user-cli.d.ts +15 -0
- package/dist/user-cli.js +37 -0
- package/package.json +52 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
const DESC_MAX = 800;
|
|
2
|
+
const COMMENT_BODY_MAX = 600;
|
|
3
|
+
/** `JIRA_CLI_COMPACT`: 1/true=常に圧縮、0/false=常にフル、未設定=非TTY のときだけ圧縮 */
|
|
4
|
+
export function wantCompact(agent) {
|
|
5
|
+
const v = process.env.JIRA_CLI_COMPACT?.trim().toLowerCase();
|
|
6
|
+
if (v === '1' || v === 'true' || v === 'yes' || v === 'on')
|
|
7
|
+
return true;
|
|
8
|
+
if (v === '0' || v === 'false' || v === 'no' || v === 'off')
|
|
9
|
+
return false;
|
|
10
|
+
return agent;
|
|
11
|
+
}
|
|
12
|
+
export function truncateText(s, max) {
|
|
13
|
+
const t = s.trim();
|
|
14
|
+
if (t.length <= max)
|
|
15
|
+
return t;
|
|
16
|
+
return `${t.slice(0, max - 1)}…`;
|
|
17
|
+
}
|
|
18
|
+
/** エージェント向け: id/self を落とし、空フィールド省略、説明は切り詰め */
|
|
19
|
+
export function slimIssue(i) {
|
|
20
|
+
const o = {
|
|
21
|
+
key: i.key,
|
|
22
|
+
summary: i.summary,
|
|
23
|
+
status: i.status,
|
|
24
|
+
issuetype: i.issuetype,
|
|
25
|
+
};
|
|
26
|
+
if (i.assignee)
|
|
27
|
+
o.assignee = i.assignee;
|
|
28
|
+
if (i.reporter)
|
|
29
|
+
o.reporter = i.reporter;
|
|
30
|
+
if (i.priority)
|
|
31
|
+
o.priority = i.priority;
|
|
32
|
+
if (i.created)
|
|
33
|
+
o.created = i.created;
|
|
34
|
+
if (i.updated)
|
|
35
|
+
o.updated = i.updated;
|
|
36
|
+
if (i.labels?.length)
|
|
37
|
+
o.labels = i.labels;
|
|
38
|
+
if (i.components?.length)
|
|
39
|
+
o.components = i.components;
|
|
40
|
+
if (i.duedate)
|
|
41
|
+
o.duedate = i.duedate;
|
|
42
|
+
if (i.parent)
|
|
43
|
+
o.parent = i.parent;
|
|
44
|
+
const d = i.description?.trim();
|
|
45
|
+
if (d)
|
|
46
|
+
o.description = truncateText(d, DESC_MAX);
|
|
47
|
+
return o;
|
|
48
|
+
}
|
|
49
|
+
export function slimIssueEnvelope(issue, compact) {
|
|
50
|
+
if (!compact)
|
|
51
|
+
return { issue };
|
|
52
|
+
return { issue: slimIssue(issue) };
|
|
53
|
+
}
|
|
54
|
+
export function slimSearch(data, compact) {
|
|
55
|
+
if (!compact)
|
|
56
|
+
return data;
|
|
57
|
+
return {
|
|
58
|
+
n: data.count,
|
|
59
|
+
...(data.isLast !== undefined ? { last: data.isLast } : {}),
|
|
60
|
+
...(data.nextPageToken ? { next: data.nextPageToken } : {}),
|
|
61
|
+
/** issues(短縮キー i) */
|
|
62
|
+
i: data.issues.map(slimIssue),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export function slimMyself(data, compact) {
|
|
66
|
+
if (!compact)
|
|
67
|
+
return data;
|
|
68
|
+
const o = {
|
|
69
|
+
id: data.accountId,
|
|
70
|
+
n: data.displayName,
|
|
71
|
+
};
|
|
72
|
+
if (data.emailAddress)
|
|
73
|
+
o.m = data.emailAddress;
|
|
74
|
+
return o;
|
|
75
|
+
}
|
|
76
|
+
export function slimComments(data, compact) {
|
|
77
|
+
if (!compact)
|
|
78
|
+
return data;
|
|
79
|
+
return {
|
|
80
|
+
k: data.key,
|
|
81
|
+
n: data.total,
|
|
82
|
+
c: data.comments.map((x) => ({
|
|
83
|
+
id: x.id,
|
|
84
|
+
a: x.author || undefined,
|
|
85
|
+
t: x.created,
|
|
86
|
+
b: x.body ? truncateText(x.body, COMMENT_BODY_MAX) : undefined,
|
|
87
|
+
})),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
export function slimProjects(data, compact) {
|
|
91
|
+
if (!compact)
|
|
92
|
+
return data;
|
|
93
|
+
return {
|
|
94
|
+
n: data.count,
|
|
95
|
+
p: data.projects.map((x) => ({
|
|
96
|
+
k: x.key,
|
|
97
|
+
name: x.name,
|
|
98
|
+
type: x.projectTypeKey,
|
|
99
|
+
})),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
export function slimUsers(data, compact) {
|
|
103
|
+
if (!compact)
|
|
104
|
+
return data;
|
|
105
|
+
return {
|
|
106
|
+
n: data.count,
|
|
107
|
+
u: data.users.map((x) => ({
|
|
108
|
+
id: x.accountId,
|
|
109
|
+
n: x.displayName,
|
|
110
|
+
m: x.emailAddress || undefined,
|
|
111
|
+
ph: x.mention,
|
|
112
|
+
})),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
export function slimCreate(data, compact) {
|
|
116
|
+
if (!compact)
|
|
117
|
+
return data;
|
|
118
|
+
return { k: data.key, id: data.id };
|
|
119
|
+
}
|
|
120
|
+
export function slimUpdate(data, compact) {
|
|
121
|
+
if (!compact)
|
|
122
|
+
return data;
|
|
123
|
+
return { ok: data.ok, k: data.key };
|
|
124
|
+
}
|
|
125
|
+
export function slimTransitions(data, compact) {
|
|
126
|
+
if (!compact)
|
|
127
|
+
return data;
|
|
128
|
+
return {
|
|
129
|
+
k: data.key,
|
|
130
|
+
t: data.transitions.map((x) => ({ id: x.id, n: x.name, s: x.toStatus })),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function bootstrapCli(): void;
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Cli, z } from 'incur';
|
|
3
|
+
import { slimIssueEnvelope, slimMyself } from './agent-compact.js';
|
|
4
|
+
import { bootstrapCli } from './bootstrap.js';
|
|
5
|
+
import { DEFAULT_PROFILE_NAME, readConfig, resolveCredentials, writeConfig } from './config.js';
|
|
6
|
+
import { jiraRequest } from './jira-client.js';
|
|
7
|
+
import { finalizeCompactOutput } from './output.js';
|
|
8
|
+
import { issueCli, loadIssueSummary } from './issue-cli.js';
|
|
9
|
+
import { profileCli } from './profile-cli.js';
|
|
10
|
+
import { projectCli } from './project-cli.js';
|
|
11
|
+
import { authOptions } from './shared.js';
|
|
12
|
+
import { userCli } from './user-cli.js';
|
|
13
|
+
bootstrapCli();
|
|
14
|
+
async function loadMyself(opts) {
|
|
15
|
+
const creds = resolveCredentials(opts);
|
|
16
|
+
return jiraRequest(creds, '/myself');
|
|
17
|
+
}
|
|
18
|
+
Cli.create('iw-jira-cli', {
|
|
19
|
+
description: 'Jira Cloud REST API v3 用 CLI。setup/profile、キー/URL、メンション(@[accountId] / @[email:...])、JIRA_CLI_COMPACT 対応。出力は TOON(--format jsonl で NDJSON に切替)',
|
|
20
|
+
version: '0.5.0',
|
|
21
|
+
format: 'toon',
|
|
22
|
+
})
|
|
23
|
+
.command('show', {
|
|
24
|
+
description: '課題を1件表示(`issue get` の短縮。キーまたは browse URL)',
|
|
25
|
+
args: z.object({
|
|
26
|
+
ref: z.string().describe('WEC-41 または .../browse/WEC-41 等'),
|
|
27
|
+
}),
|
|
28
|
+
options: authOptions,
|
|
29
|
+
output: z.any(),
|
|
30
|
+
async run(c) {
|
|
31
|
+
const full = await loadIssueSummary(resolveCredentials(c.options), c.args.ref);
|
|
32
|
+
return finalizeCompactOutput(c, full.issue, (issue) => slimIssueEnvelope(issue, true));
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
.command('setup', {
|
|
36
|
+
description: '初回セットアップ向けにプロファイルを保存',
|
|
37
|
+
options: z.object({
|
|
38
|
+
profile: z
|
|
39
|
+
.string()
|
|
40
|
+
.optional()
|
|
41
|
+
.describe(`保存先プロファイル名(省略時: ${DEFAULT_PROFILE_NAME})`),
|
|
42
|
+
host: z.string().describe('Jira サイトホストまたは URL'),
|
|
43
|
+
email: z.string().email().describe('Atlassian アカウントのメール'),
|
|
44
|
+
apiToken: z.string().describe('Jira API トークン'),
|
|
45
|
+
default: z.boolean().optional().describe('このプロファイルをデフォルトに設定'),
|
|
46
|
+
}),
|
|
47
|
+
run(c) {
|
|
48
|
+
const config = readConfig();
|
|
49
|
+
const name = c.options.profile ?? DEFAULT_PROFILE_NAME;
|
|
50
|
+
config.profiles[name] = {
|
|
51
|
+
host: c.options.host.trim(),
|
|
52
|
+
email: c.options.email.trim(),
|
|
53
|
+
apiToken: c.options.apiToken.trim(),
|
|
54
|
+
};
|
|
55
|
+
const isFirst = Object.keys(config.profiles).length === 1;
|
|
56
|
+
if (c.options.default || isFirst || !config.default) {
|
|
57
|
+
config.default = name;
|
|
58
|
+
}
|
|
59
|
+
writeConfig(config);
|
|
60
|
+
return {
|
|
61
|
+
saved: name,
|
|
62
|
+
isDefault: config.default === name,
|
|
63
|
+
hint: '接続確認は `iw-jira-cli whoami` を実行してください',
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
})
|
|
67
|
+
.command(issueCli)
|
|
68
|
+
.command(projectCli)
|
|
69
|
+
.command(profileCli)
|
|
70
|
+
.command(userCli)
|
|
71
|
+
.command('myself', {
|
|
72
|
+
description: '認証ユーザー情報を取得',
|
|
73
|
+
options: authOptions,
|
|
74
|
+
output: z.any(),
|
|
75
|
+
async run(c) {
|
|
76
|
+
const me = await loadMyself(c.options);
|
|
77
|
+
const full = {
|
|
78
|
+
accountId: me.accountId,
|
|
79
|
+
displayName: me.displayName,
|
|
80
|
+
emailAddress: me.emailAddress,
|
|
81
|
+
active: me.active,
|
|
82
|
+
};
|
|
83
|
+
return finalizeCompactOutput(c, full, (data) => slimMyself(data, true));
|
|
84
|
+
},
|
|
85
|
+
})
|
|
86
|
+
.command('whoami', {
|
|
87
|
+
description: '認証ユーザー情報を取得(`myself` の別名)',
|
|
88
|
+
options: authOptions,
|
|
89
|
+
output: z.any(),
|
|
90
|
+
async run(c) {
|
|
91
|
+
const me = await loadMyself(c.options);
|
|
92
|
+
const full = {
|
|
93
|
+
accountId: me.accountId,
|
|
94
|
+
displayName: me.displayName,
|
|
95
|
+
emailAddress: me.emailAddress,
|
|
96
|
+
active: me.active,
|
|
97
|
+
};
|
|
98
|
+
return finalizeCompactOutput(c, full, (data) => slimMyself(data, true));
|
|
99
|
+
},
|
|
100
|
+
})
|
|
101
|
+
.serve();
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface Profile {
|
|
2
|
+
host: string;
|
|
3
|
+
email: string;
|
|
4
|
+
apiToken: string;
|
|
5
|
+
}
|
|
6
|
+
export interface Config {
|
|
7
|
+
default?: string;
|
|
8
|
+
profiles: Record<string, Profile>;
|
|
9
|
+
}
|
|
10
|
+
export interface JiraCredentials {
|
|
11
|
+
host: string;
|
|
12
|
+
email: string;
|
|
13
|
+
apiToken: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ResolveOptions {
|
|
16
|
+
profile?: string;
|
|
17
|
+
host?: string;
|
|
18
|
+
email?: string;
|
|
19
|
+
apiToken?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare const DEFAULT_PROFILE_NAME = "default";
|
|
22
|
+
export declare function readConfig(): Config;
|
|
23
|
+
export declare function writeConfig(config: Config): void;
|
|
24
|
+
/**
|
|
25
|
+
* 認証情報を以下の優先順位で解決する:
|
|
26
|
+
* 1. コマンドフラグ (--host / --email / --api-token)
|
|
27
|
+
* 2. 設定ファイルのプロファイル (--profile または default)
|
|
28
|
+
* 3. 環境変数 / .env (JIRA_HOST / JIRA_EMAIL / JIRA_API_TOKEN)
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveCredentials(opts: ResolveOptions): JiraCredentials;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
export const DEFAULT_PROFILE_NAME = 'default';
|
|
5
|
+
const CONFIG_PATH = join(homedir(), '.config', 'jira-cli', 'config.json');
|
|
6
|
+
export function readConfig() {
|
|
7
|
+
if (!existsSync(CONFIG_PATH))
|
|
8
|
+
return { profiles: {} };
|
|
9
|
+
try {
|
|
10
|
+
return JSON.parse(readFileSync(CONFIG_PATH, 'utf-8'));
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return { profiles: {} };
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function writeConfig(config) {
|
|
17
|
+
mkdirSync(dirname(CONFIG_PATH), { recursive: true });
|
|
18
|
+
writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + '\n');
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 認証情報を以下の優先順位で解決する:
|
|
22
|
+
* 1. コマンドフラグ (--host / --email / --api-token)
|
|
23
|
+
* 2. 設定ファイルのプロファイル (--profile または default)
|
|
24
|
+
* 3. 環境変数 / .env (JIRA_HOST / JIRA_EMAIL / JIRA_API_TOKEN)
|
|
25
|
+
*/
|
|
26
|
+
export function resolveCredentials(opts) {
|
|
27
|
+
const config = readConfig();
|
|
28
|
+
const profileName = opts.profile ?? config.default;
|
|
29
|
+
const profileData = profileName ? config.profiles[profileName] : undefined;
|
|
30
|
+
const host = opts.host ?? profileData?.host ?? process.env.JIRA_HOST;
|
|
31
|
+
const email = opts.email ?? profileData?.email ?? process.env.JIRA_EMAIL;
|
|
32
|
+
const apiToken = opts.apiToken ?? profileData?.apiToken ?? process.env.JIRA_API_TOKEN;
|
|
33
|
+
if (!host) {
|
|
34
|
+
throw new Error('Jira host が未設定です。--host フラグ、プロファイル、または JIRA_HOST 環境変数を設定してください。');
|
|
35
|
+
}
|
|
36
|
+
if (!email) {
|
|
37
|
+
throw new Error('Jira email が未設定です。--email フラグ、プロファイル、または JIRA_EMAIL 環境変数を設定してください。');
|
|
38
|
+
}
|
|
39
|
+
if (!apiToken) {
|
|
40
|
+
throw new Error('Jira API token が未設定です。--api-token フラグ、プロファイル、または JIRA_API_TOKEN 環境変数を設定してください。');
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
host: host.trim(),
|
|
44
|
+
email: email.trim(),
|
|
45
|
+
apiToken: apiToken.trim(),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { Cli } from 'incur';
|
|
2
|
+
import { type JiraCredentials } from './config.js';
|
|
3
|
+
import { type IssueSummary } from './jira-client.js';
|
|
4
|
+
export declare function loadIssueSummary(env: JiraCredentials, ref: string): Promise<{
|
|
5
|
+
issue: IssueSummary;
|
|
6
|
+
}>;
|
|
7
|
+
export declare const issueCli: Cli.Cli<{
|
|
8
|
+
get: {
|
|
9
|
+
args: {
|
|
10
|
+
ref: string;
|
|
11
|
+
};
|
|
12
|
+
options: {
|
|
13
|
+
profile?: string | undefined;
|
|
14
|
+
host?: string | undefined;
|
|
15
|
+
email?: string | undefined;
|
|
16
|
+
apiToken?: string | undefined;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
} & {
|
|
20
|
+
search: {
|
|
21
|
+
args: {
|
|
22
|
+
target?: string | undefined;
|
|
23
|
+
};
|
|
24
|
+
options: {
|
|
25
|
+
limit: number;
|
|
26
|
+
profile?: string | undefined;
|
|
27
|
+
host?: string | undefined;
|
|
28
|
+
email?: string | undefined;
|
|
29
|
+
apiToken?: string | undefined;
|
|
30
|
+
jql?: string | undefined;
|
|
31
|
+
project?: string | undefined;
|
|
32
|
+
nextPageToken?: string | undefined;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
} & {
|
|
36
|
+
create: {
|
|
37
|
+
args: {};
|
|
38
|
+
options: {
|
|
39
|
+
project: string;
|
|
40
|
+
summary: string;
|
|
41
|
+
type: string;
|
|
42
|
+
profile?: string | undefined;
|
|
43
|
+
host?: string | undefined;
|
|
44
|
+
email?: string | undefined;
|
|
45
|
+
apiToken?: string | undefined;
|
|
46
|
+
description?: string | undefined;
|
|
47
|
+
parent?: string | undefined;
|
|
48
|
+
assignee?: string | undefined;
|
|
49
|
+
labels?: string | undefined;
|
|
50
|
+
priority?: string | undefined;
|
|
51
|
+
'start-date'?: string | undefined;
|
|
52
|
+
'due-date'?: string | undefined;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
} & {
|
|
56
|
+
update: {
|
|
57
|
+
args: {
|
|
58
|
+
ref: string;
|
|
59
|
+
};
|
|
60
|
+
options: {
|
|
61
|
+
profile?: string | undefined;
|
|
62
|
+
host?: string | undefined;
|
|
63
|
+
email?: string | undefined;
|
|
64
|
+
apiToken?: string | undefined;
|
|
65
|
+
summary?: string | undefined;
|
|
66
|
+
description?: string | undefined;
|
|
67
|
+
assignee?: string | undefined;
|
|
68
|
+
parent?: string | undefined;
|
|
69
|
+
labels?: string | undefined;
|
|
70
|
+
priority?: string | undefined;
|
|
71
|
+
'start-date'?: string | undefined;
|
|
72
|
+
'due-date'?: string | undefined;
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
} & {
|
|
76
|
+
transitions: {
|
|
77
|
+
args: {
|
|
78
|
+
ref: string;
|
|
79
|
+
};
|
|
80
|
+
options: {
|
|
81
|
+
profile?: string | undefined;
|
|
82
|
+
host?: string | undefined;
|
|
83
|
+
email?: string | undefined;
|
|
84
|
+
apiToken?: string | undefined;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
} & {
|
|
88
|
+
transition: {
|
|
89
|
+
args: {
|
|
90
|
+
ref: string;
|
|
91
|
+
};
|
|
92
|
+
options: {
|
|
93
|
+
profile?: string | undefined;
|
|
94
|
+
host?: string | undefined;
|
|
95
|
+
email?: string | undefined;
|
|
96
|
+
apiToken?: string | undefined;
|
|
97
|
+
id?: string | undefined;
|
|
98
|
+
name?: string | undefined;
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
} & {
|
|
102
|
+
comments: {
|
|
103
|
+
args: {
|
|
104
|
+
ref: string;
|
|
105
|
+
};
|
|
106
|
+
options: {
|
|
107
|
+
limit: number;
|
|
108
|
+
profile?: string | undefined;
|
|
109
|
+
host?: string | undefined;
|
|
110
|
+
email?: string | undefined;
|
|
111
|
+
apiToken?: string | undefined;
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
} & {
|
|
115
|
+
comment: {
|
|
116
|
+
args: {
|
|
117
|
+
ref: string;
|
|
118
|
+
};
|
|
119
|
+
options: {
|
|
120
|
+
body: string;
|
|
121
|
+
profile?: string | undefined;
|
|
122
|
+
host?: string | undefined;
|
|
123
|
+
email?: string | undefined;
|
|
124
|
+
apiToken?: string | undefined;
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
}, undefined, undefined>;
|