@kora-platform/cli 0.8.0-rc2 → 0.8.0-rc6

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/dist/files.js CHANGED
@@ -2,20 +2,43 @@ import { Buffer } from "node:buffer";
2
2
  import { lstat, mkdir, readdir, readFile, writeFile } from "node:fs/promises";
3
3
  import { basename, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
4
4
  import { usageProblem } from "./cli-errors.js";
5
- import { parseDotEnv } from "./dotenv.js";
6
5
  import { shouldIgnoreWorkspacePath } from "./workspace-source.js";
7
6
  const MAX_IMPORT_FILE_COUNT = 500;
8
7
  const MAX_IMPORT_FILE_BYTES = 1_000_000;
9
8
  const MAX_PACKAGE_FILE_BYTES = 2_000_000;
10
9
  const MAX_IMPORT_TOTAL_BYTES = 10_000_000;
11
- export async function readJsonInputSpecifier(specifier, stdin, instance) {
10
+ export async function readJsonInputSpecifier(specifier, stdin, instance, options = {}) {
12
11
  if (specifier === "-") {
13
- return readJsonObject(await readStream(stdin), instance);
12
+ return readJsonObject(await readStream(stdin), instance, {
13
+ source: "stdin",
14
+ ...options
15
+ });
14
16
  }
15
17
  if (!specifier.startsWith("@")) {
16
- throw usageProblem("Structured JSON input must use @file.json or - for stdin.", instance);
18
+ throw usageProblem("Structured JSON input must use @file.json or - for stdin.", instance, {
19
+ ...(options.flag ? { flag: options.flag } : {})
20
+ });
21
+ }
22
+ const filePath = resolve(specifier.slice(1));
23
+ let source;
24
+ try {
25
+ source = await readFile(filePath, "utf8");
26
+ }
27
+ catch (error) {
28
+ const nativeCode = readNodeErrorCode(error);
29
+ if (nativeCode && isLocalPathReadErrorCode(nativeCode)) {
30
+ throw usageProblem(`Structured JSON input file ${filePath} could not be read: ${nativeCode}.`, instance, {
31
+ filePath,
32
+ ...(options.flag ? { flag: options.flag } : {}),
33
+ nativeCode
34
+ });
35
+ }
36
+ throw error;
17
37
  }
18
- return readJsonObject(await readFile(specifier.slice(1), "utf8"), instance);
38
+ return readJsonObject(source, instance, {
39
+ filePath,
40
+ ...options
41
+ });
19
42
  }
20
43
  export async function readTextInputSpecifier(specifier, stdin, instance) {
21
44
  if (specifier === "-") {
@@ -36,12 +59,26 @@ export function isZipArchivePath(pathValue) {
36
59
  return extname(pathValue).toLowerCase() === ".zip";
37
60
  }
38
61
  export async function readArchiveBytes(pathValue, instance) {
62
+ const file = await readLocalFileBytes(pathValue, instance, {
63
+ regularFileMessage: "Archive path must be a regular .zip file, not a directory or symbolic link."
64
+ });
65
+ return file.bytes;
66
+ }
67
+ export async function readLocalFileBytes(pathValue, instance, options = {}) {
39
68
  const absolutePath = resolve(pathValue);
40
- const pathStat = await lstat(absolutePath);
69
+ const pathStat = await readLocalPathStat(absolutePath, instance);
41
70
  if (pathStat.isSymbolicLink() || !pathStat.isFile()) {
42
- throw usageProblem("Archive path must be a regular .zip file, not a directory or symbolic link.", instance);
71
+ throw usageProblem(options.regularFileMessage ?? "Path must be a regular file, not a directory or symbolic link.", instance);
72
+ }
73
+ try {
74
+ return {
75
+ absolutePath,
76
+ bytes: await readFile(absolutePath)
77
+ };
78
+ }
79
+ catch (error) {
80
+ throwLocalPathReadProblem(error, absolutePath, instance);
43
81
  }
44
- return await readFile(absolutePath);
45
82
  }
46
83
  export async function readWorkspaceTestEntries(pathValue) {
47
84
  return await readUtf8Entries(pathValue, {
@@ -51,12 +88,16 @@ export async function readWorkspaceTestEntries(pathValue) {
51
88
  }
52
89
  async function readUtf8Entries(pathValue, options) {
53
90
  const absolutePath = resolve(pathValue);
54
- const pathStat = await lstat(absolutePath);
91
+ const pathStat = await readLocalPathStat(absolutePath, options.instance);
55
92
  if (pathStat.isSymbolicLink()) {
56
93
  throw usageProblem("Import path must be a regular file or directory, not a symbolic link.", options.instance);
57
94
  }
58
95
  if (pathStat.isFile()) {
59
- const content = await readLimitedUtf8File(absolutePath, basename(absolutePath), {
96
+ const pathName = basename(absolutePath);
97
+ if (shouldIgnoreSourceImportPath(pathName)) {
98
+ return [];
99
+ }
100
+ const content = await readLimitedUtf8File(absolutePath, pathName, {
60
101
  fileCount: 0,
61
102
  totalBytes: 0
62
103
  }, options);
@@ -148,7 +189,7 @@ export async function writePackageExport(outPath, envelope) {
148
189
  }
149
190
  export async function readPackageFileEntries(pathValue, instance) {
150
191
  const absolutePath = resolve(pathValue);
151
- const pathStat = await lstat(absolutePath);
192
+ const pathStat = await readLocalPathStat(absolutePath, instance);
152
193
  if (pathStat.isSymbolicLink()) {
153
194
  throw usageProblem("Package path must be a regular file or directory, not a symbolic link.", instance);
154
195
  }
@@ -158,7 +199,9 @@ export async function readPackageFileEntries(pathValue, instance) {
158
199
  totalBytes: 0
159
200
  }, instance);
160
201
  return [{
161
- contentBase64: (await readFile(absolutePath)).toString("base64"),
202
+ contentBase64: (await readLocalFileBytes(absolutePath, instance, {
203
+ regularFileMessage: "Package path must be a regular file or directory, not a symbolic link."
204
+ })).bytes.toString("base64"),
162
205
  path: basename(absolutePath)
163
206
  }];
164
207
  }
@@ -170,23 +213,24 @@ export async function readPackageFileEntries(pathValue, instance) {
170
213
  entries.sort((left, right) => left.path.localeCompare(right.path));
171
214
  return entries;
172
215
  }
173
- export async function parseEnvFile(pathValue) {
174
- const content = await readFile(pathValue, "utf8");
175
- return Object.entries(parseDotEnv(content)).map(([name, value]) => ({
176
- name,
177
- value
178
- }));
179
- }
180
- function readJsonObject(source, instance) {
216
+ function readJsonObject(source, instance, options) {
181
217
  let parsed;
182
218
  try {
183
219
  parsed = JSON.parse(source);
184
220
  }
185
221
  catch {
186
- throw usageProblem("Structured JSON input must be valid JSON.", instance);
222
+ const sourceLabel = "filePath" in options ? `file ${options.filePath}` : "from stdin";
223
+ throw usageProblem(`Structured JSON input ${sourceLabel} must be valid JSON.`, instance, {
224
+ ...("filePath" in options ? { filePath: options.filePath } : { source: options.source }),
225
+ ...(options.flag ? { flag: options.flag } : {})
226
+ });
187
227
  }
188
228
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
189
- throw usageProblem("Structured JSON input must be a JSON object.", instance);
229
+ const sourceLabel = "filePath" in options ? `file ${options.filePath}` : "from stdin";
230
+ throw usageProblem(`Structured JSON input ${sourceLabel} must be a JSON object.`, instance, {
231
+ ...("filePath" in options ? { filePath: options.filePath } : { source: options.source }),
232
+ ...(options.flag ? { flag: options.flag } : {})
233
+ });
190
234
  }
191
235
  return parsed;
192
236
  }
@@ -203,7 +247,7 @@ async function walkImportDirectory(root, current, entries, counters, options) {
203
247
  for (const child of children) {
204
248
  const childPath = join(current, child.name);
205
249
  const relativePath = relative(root, childPath).replaceAll("\\", "/");
206
- if (shouldIgnoreImportPath(relativePath)) {
250
+ if (shouldIgnoreSourceImportPath(relativePath)) {
207
251
  continue;
208
252
  }
209
253
  if (child.isDirectory()) {
@@ -236,10 +280,10 @@ async function walkPackageDirectory(root, current, entries, counters, instance)
236
280
  if (!child.isFile()) {
237
281
  continue;
238
282
  }
239
- const childStat = await lstat(childPath);
283
+ const childStat = await readLocalPathStat(childPath, instance);
240
284
  assertPackageFileCanBeRead(childStat.size, relativePath, counters, instance);
241
285
  entries.push({
242
- contentBase64: (await readFile(childPath)).toString("base64"),
286
+ contentBase64: (await readLocalFileBytes(childPath, instance)).bytes.toString("base64"),
243
287
  path: relativePath
244
288
  });
245
289
  }
@@ -247,6 +291,12 @@ async function walkPackageDirectory(root, current, entries, counters, instance)
247
291
  function shouldIgnoreImportPath(pathValue) {
248
292
  return shouldIgnoreWorkspacePath(pathValue);
249
293
  }
294
+ function shouldIgnoreSourceImportPath(pathValue) {
295
+ return shouldIgnoreImportPath(pathValue) || isRemovedRuntimeEnvironmentPath(pathValue);
296
+ }
297
+ function isRemovedRuntimeEnvironmentPath(pathValue) {
298
+ return pathValue === ".env" || pathValue === ".env.example";
299
+ }
250
300
  async function assertExportOutputIsEmpty(absolutePath, instance, outputLabel = "Export") {
251
301
  try {
252
302
  const pathStat = await lstat(absolutePath);
@@ -287,7 +337,13 @@ async function readLimitedUtf8File(filePath, displayPath, counters, options) {
287
337
  if (counters.fileCount >= MAX_IMPORT_FILE_COUNT) {
288
338
  throw usageProblem(`Import has more than ${String(MAX_IMPORT_FILE_COUNT)} files.`, options.instance);
289
339
  }
290
- const content = await readFile(filePath, "utf8");
340
+ let content;
341
+ try {
342
+ content = await readFile(filePath, "utf8");
343
+ }
344
+ catch (error) {
345
+ throwLocalPathReadProblem(error, filePath, options.instance);
346
+ }
291
347
  const bytes = Buffer.byteLength(content, "utf8");
292
348
  if (bytes > options.maxFileBytes) {
293
349
  throw usageProblem(`Import file ${displayPath} exceeds the per-file byte limit.`, options.instance);
@@ -318,3 +374,35 @@ function isNodeErrorWithCode(error, code) {
318
374
  "code" in error &&
319
375
  error.code === code;
320
376
  }
377
+ function readNodeErrorCode(error) {
378
+ if (typeof error !== "object" || error === null || !("code" in error)) {
379
+ return undefined;
380
+ }
381
+ const code = error.code;
382
+ return typeof code === "string" && code.length > 0 ? code : undefined;
383
+ }
384
+ function isLocalPathReadErrorCode(code) {
385
+ return code === "EACCES" ||
386
+ code === "EISDIR" ||
387
+ code === "ENOENT" ||
388
+ code === "ENOTDIR" ||
389
+ code === "EPERM";
390
+ }
391
+ async function readLocalPathStat(absolutePath, instance) {
392
+ try {
393
+ return await lstat(absolutePath);
394
+ }
395
+ catch (error) {
396
+ throwLocalPathReadProblem(error, absolutePath, instance);
397
+ }
398
+ }
399
+ function throwLocalPathReadProblem(error, absolutePath, instance) {
400
+ const nativeCode = readNodeErrorCode(error);
401
+ if (nativeCode && isLocalPathReadErrorCode(nativeCode)) {
402
+ throw usageProblem(`Local path ${absolutePath} could not be read: ${nativeCode}.`, instance, {
403
+ nativeCode,
404
+ path: absolutePath
405
+ });
406
+ }
407
+ throw error;
408
+ }
package/dist/format.d.ts CHANGED
@@ -10,6 +10,7 @@ export declare function renderJsonEnvelope(input: {
10
10
  meta?: Record<string, unknown>;
11
11
  }): string;
12
12
  export declare function renderProblemJson(input: {
13
+ code: string;
13
14
  detail: string;
14
15
  details?: Record<string, unknown>;
15
16
  instance: string;
package/dist/format.js CHANGED
@@ -7,12 +7,17 @@ export function renderJsonEnvelope(input) {
7
7
  }
8
8
  export function renderProblemJson(input) {
9
9
  return `${JSON.stringify({
10
- detail: input.detail,
11
- ...(input.details ? { details: input.details } : {}),
12
- instance: input.instance,
13
- status: input.status,
14
- title: input.title,
15
- type: input.type
10
+ error: {
11
+ code: input.code,
12
+ details: {
13
+ ...(input.details ?? {}),
14
+ instance: input.instance,
15
+ status: input.status,
16
+ title: input.title,
17
+ type: input.type
18
+ },
19
+ message: input.detail
20
+ }
16
21
  }, null, 2)}\n`;
17
22
  }
18
23
  export function renderTable(rows, columns) {
package/dist/runner.js CHANGED
@@ -89,6 +89,7 @@ export async function runCli(argv, input = {}) {
89
89
  : `${problem.title}: ${formatProblemDetail(problem.detail, details)}`}\n`,
90
90
  stdout: wantsJson
91
91
  ? renderProblemJson({
92
+ code: problem.code,
92
93
  detail: problem.detail,
93
94
  ...(details ? { details } : {}),
94
95
  instance: problem.instance,
@@ -2943,14 +2943,6 @@ export declare const CLI_SCHEMA_REGISTRY_DATA: readonly [{
2943
2943
  readonly maxLength: 4096;
2944
2944
  readonly type: "string";
2945
2945
  };
2946
- readonly env: {
2947
- readonly type: "object";
2948
- readonly patternProperties: {
2949
- readonly "^(.*)$": {
2950
- readonly type: "string";
2951
- };
2952
- };
2953
- };
2954
2946
  readonly parseStdoutAsJson: {
2955
2947
  readonly type: "boolean";
2956
2948
  };
@@ -2964,39 +2956,91 @@ export declare const CLI_SCHEMA_REGISTRY_DATA: readonly [{
2964
2956
  };
2965
2957
  };
2966
2958
  };
2967
- readonly runtimeSdk: {
2968
- readonly additionalProperties: true;
2969
- readonly type: "object";
2970
- readonly properties: {};
2971
- };
2972
- readonly credentials: {
2959
+ readonly bindings: {
2960
+ readonly additionalProperties: false;
2973
2961
  readonly type: "object";
2974
- readonly patternProperties: {
2975
- readonly "^(.*)$": {
2976
- readonly additionalProperties: false;
2977
- readonly type: "object";
2978
- readonly required: readonly ["bindingKind", "connectionRef", "inject"];
2979
- readonly properties: {
2980
- readonly bindingKind: {
2962
+ readonly properties: {
2963
+ readonly env: {
2964
+ readonly type: "array";
2965
+ readonly items: {
2966
+ readonly anyOf: readonly [{
2981
2967
  readonly minLength: 1;
2982
2968
  readonly maxLength: 128;
2969
+ readonly pattern: "^(?!KORA_)[A-Za-z_][A-Za-z0-9_]*$";
2983
2970
  readonly type: "string";
2984
- };
2985
- readonly connectionRef: {
2971
+ }, {
2972
+ readonly additionalProperties: false;
2973
+ readonly type: "object";
2974
+ readonly required: readonly ["name"];
2975
+ readonly properties: {
2976
+ readonly name: {
2977
+ readonly minLength: 1;
2978
+ readonly maxLength: 128;
2979
+ readonly pattern: "^(?!KORA_)[A-Za-z_][A-Za-z0-9_]*$";
2980
+ readonly type: "string";
2981
+ };
2982
+ readonly as: {
2983
+ readonly minLength: 1;
2984
+ readonly maxLength: 128;
2985
+ readonly pattern: "^(?!KORA_)[A-Za-z_][A-Za-z0-9_]*$";
2986
+ readonly type: "string";
2987
+ };
2988
+ };
2989
+ }];
2990
+ };
2991
+ };
2992
+ readonly secrets: {
2993
+ readonly type: "array";
2994
+ readonly items: {
2995
+ readonly anyOf: readonly [{
2986
2996
  readonly minLength: 1;
2987
2997
  readonly maxLength: 128;
2998
+ readonly pattern: "^(?!KORA_)[A-Za-z_][A-Za-z0-9_]*$";
2988
2999
  readonly type: "string";
2989
- };
2990
- readonly inject: {
3000
+ }, {
2991
3001
  readonly additionalProperties: false;
2992
3002
  readonly type: "object";
2993
- readonly required: readonly ["env"];
3003
+ readonly required: readonly ["name"];
2994
3004
  readonly properties: {
2995
- readonly env: {
3005
+ readonly name: {
2996
3006
  readonly minLength: 1;
2997
3007
  readonly maxLength: 128;
3008
+ readonly pattern: "^(?!KORA_)[A-Za-z_][A-Za-z0-9_]*$";
2998
3009
  readonly type: "string";
2999
3010
  };
3011
+ readonly as: {
3012
+ readonly minLength: 1;
3013
+ readonly maxLength: 128;
3014
+ readonly pattern: "^(?!KORA_)[A-Za-z_][A-Za-z0-9_]*$";
3015
+ readonly type: "string";
3016
+ };
3017
+ };
3018
+ }];
3019
+ };
3020
+ };
3021
+ readonly extensions: {
3022
+ readonly type: "object";
3023
+ readonly patternProperties: {
3024
+ readonly "^(.*)$": {
3025
+ readonly additionalProperties: false;
3026
+ readonly type: "object";
3027
+ readonly required: readonly ["install", "functions"];
3028
+ readonly properties: {
3029
+ readonly install: {
3030
+ readonly minLength: 1;
3031
+ readonly maxLength: 128;
3032
+ readonly type: "string";
3033
+ };
3034
+ readonly functions: {
3035
+ readonly minItems: 1;
3036
+ readonly uniqueItems: true;
3037
+ readonly type: "array";
3038
+ readonly items: {
3039
+ readonly minLength: 1;
3040
+ readonly maxLength: 128;
3041
+ readonly type: "string";
3042
+ };
3043
+ };
3000
3044
  };
3001
3045
  };
3002
3046
  };
@@ -3486,14 +3486,6 @@ export const CLI_SCHEMA_REGISTRY_DATA = [
3486
3486
  "maxLength": 4096,
3487
3487
  "type": "string"
3488
3488
  },
3489
- "env": {
3490
- "type": "object",
3491
- "patternProperties": {
3492
- "^(.*)$": {
3493
- "type": "string"
3494
- }
3495
- }
3496
- },
3497
3489
  "parseStdoutAsJson": {
3498
3490
  "type": "boolean"
3499
3491
  },
@@ -3507,44 +3499,103 @@ export const CLI_SCHEMA_REGISTRY_DATA = [
3507
3499
  }
3508
3500
  }
3509
3501
  },
3510
- "runtimeSdk": {
3511
- "additionalProperties": true,
3512
- "type": "object",
3513
- "properties": {}
3514
- },
3515
- "credentials": {
3502
+ "bindings": {
3503
+ "additionalProperties": false,
3516
3504
  "type": "object",
3517
- "patternProperties": {
3518
- "^(.*)$": {
3519
- "additionalProperties": false,
3505
+ "properties": {
3506
+ "env": {
3507
+ "type": "array",
3508
+ "items": {
3509
+ "anyOf": [
3510
+ {
3511
+ "minLength": 1,
3512
+ "maxLength": 128,
3513
+ "pattern": "^(?!KORA_)[A-Za-z_][A-Za-z0-9_]*$",
3514
+ "type": "string"
3515
+ },
3516
+ {
3517
+ "additionalProperties": false,
3518
+ "type": "object",
3519
+ "required": [
3520
+ "name"
3521
+ ],
3522
+ "properties": {
3523
+ "name": {
3524
+ "minLength": 1,
3525
+ "maxLength": 128,
3526
+ "pattern": "^(?!KORA_)[A-Za-z_][A-Za-z0-9_]*$",
3527
+ "type": "string"
3528
+ },
3529
+ "as": {
3530
+ "minLength": 1,
3531
+ "maxLength": 128,
3532
+ "pattern": "^(?!KORA_)[A-Za-z_][A-Za-z0-9_]*$",
3533
+ "type": "string"
3534
+ }
3535
+ }
3536
+ }
3537
+ ]
3538
+ }
3539
+ },
3540
+ "secrets": {
3541
+ "type": "array",
3542
+ "items": {
3543
+ "anyOf": [
3544
+ {
3545
+ "minLength": 1,
3546
+ "maxLength": 128,
3547
+ "pattern": "^(?!KORA_)[A-Za-z_][A-Za-z0-9_]*$",
3548
+ "type": "string"
3549
+ },
3550
+ {
3551
+ "additionalProperties": false,
3552
+ "type": "object",
3553
+ "required": [
3554
+ "name"
3555
+ ],
3556
+ "properties": {
3557
+ "name": {
3558
+ "minLength": 1,
3559
+ "maxLength": 128,
3560
+ "pattern": "^(?!KORA_)[A-Za-z_][A-Za-z0-9_]*$",
3561
+ "type": "string"
3562
+ },
3563
+ "as": {
3564
+ "minLength": 1,
3565
+ "maxLength": 128,
3566
+ "pattern": "^(?!KORA_)[A-Za-z_][A-Za-z0-9_]*$",
3567
+ "type": "string"
3568
+ }
3569
+ }
3570
+ }
3571
+ ]
3572
+ }
3573
+ },
3574
+ "extensions": {
3520
3575
  "type": "object",
3521
- "required": [
3522
- "bindingKind",
3523
- "connectionRef",
3524
- "inject"
3525
- ],
3526
- "properties": {
3527
- "bindingKind": {
3528
- "minLength": 1,
3529
- "maxLength": 128,
3530
- "type": "string"
3531
- },
3532
- "connectionRef": {
3533
- "minLength": 1,
3534
- "maxLength": 128,
3535
- "type": "string"
3536
- },
3537
- "inject": {
3576
+ "patternProperties": {
3577
+ "^(.*)$": {
3538
3578
  "additionalProperties": false,
3539
3579
  "type": "object",
3540
3580
  "required": [
3541
- "env"
3581
+ "install",
3582
+ "functions"
3542
3583
  ],
3543
3584
  "properties": {
3544
- "env": {
3585
+ "install": {
3545
3586
  "minLength": 1,
3546
3587
  "maxLength": 128,
3547
3588
  "type": "string"
3589
+ },
3590
+ "functions": {
3591
+ "minItems": 1,
3592
+ "uniqueItems": true,
3593
+ "type": "array",
3594
+ "items": {
3595
+ "minLength": 1,
3596
+ "maxLength": 128,
3597
+ "type": "string"
3598
+ }
3548
3599
  }
3549
3600
  }
3550
3601
  }
@@ -10,6 +10,19 @@ export interface CliAuthSettings {
10
10
  oidcEnabled: boolean;
11
11
  selfServiceOrgCreationEnabled: boolean;
12
12
  }
13
+ export interface CliDeviceLoginStart {
14
+ deviceCode: string;
15
+ expiresAt: string;
16
+ pollIntervalSeconds: number;
17
+ userCode: string;
18
+ verificationPath: string;
19
+ }
20
+ export type CliDeviceLoginClaim = {
21
+ session: CliSessionState;
22
+ status: "approved";
23
+ } | {
24
+ status: "denied" | "expired" | "pending";
25
+ };
13
26
  export type ApiErrorDetails = Record<string, unknown>;
14
27
  type RequestBody = unknown | ((session: CliSessionState) => unknown);
15
28
  type BytesRequest = {
@@ -26,6 +39,7 @@ type BytesRequest = {
26
39
  validateHeaders?: (headers: Headers) => void;
27
40
  };
28
41
  export declare class ApiError extends Error {
42
+ readonly code: string;
29
43
  readonly detail: string;
30
44
  readonly details?: ApiErrorDetails;
31
45
  readonly instance: string;
@@ -34,6 +48,7 @@ export declare class ApiError extends Error {
34
48
  readonly title: string;
35
49
  readonly type: string;
36
50
  constructor(input: {
51
+ code?: string;
37
52
  detail: string;
38
53
  details?: ApiErrorDetails;
39
54
  instance: string;
@@ -59,6 +74,11 @@ export declare function createPlatformTransport(input: {
59
74
  name: string;
60
75
  password: string;
61
76
  }): Promise<CliSessionState>;
77
+ startDeviceLogin(baseUrl: string): Promise<CliDeviceLoginStart>;
78
+ claimDeviceLogin(claim: {
79
+ baseUrl: string;
80
+ deviceCode: string;
81
+ }): Promise<CliDeviceLoginClaim>;
62
82
  refreshSession(session: CliSessionState): Promise<CliSessionState>;
63
83
  requestJson<T>(request: {
64
84
  body?: RequestBody;