cawplan 0.0.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.
Files changed (52) hide show
  1. package/config/products.json +17 -0
  2. package/dist/commands/activities.d.ts +2 -0
  3. package/dist/commands/activities.js +43 -0
  4. package/dist/commands/analytics.d.ts +2 -0
  5. package/dist/commands/analytics.js +30 -0
  6. package/dist/commands/auth.d.ts +2 -0
  7. package/dist/commands/auth.js +145 -0
  8. package/dist/commands/community.d.ts +2 -0
  9. package/dist/commands/community.js +30 -0
  10. package/dist/commands/critical.d.ts +2 -0
  11. package/dist/commands/critical.js +205 -0
  12. package/dist/commands/knowledge.d.ts +2 -0
  13. package/dist/commands/knowledge.js +24 -0
  14. package/dist/commands/metrics.d.ts +2 -0
  15. package/dist/commands/metrics.js +27 -0
  16. package/dist/commands/product-activity.d.ts +2 -0
  17. package/dist/commands/product-activity.js +26 -0
  18. package/dist/commands/products.d.ts +2 -0
  19. package/dist/commands/products.js +100 -0
  20. package/dist/commands/qa-reports.d.ts +2 -0
  21. package/dist/commands/qa-reports.js +71 -0
  22. package/dist/commands/tickets.d.ts +2 -0
  23. package/dist/commands/tickets.js +431 -0
  24. package/dist/commands/todos.d.ts +2 -0
  25. package/dist/commands/todos.js +24 -0
  26. package/dist/commands/user-activity.d.ts +2 -0
  27. package/dist/commands/user-activity.js +31 -0
  28. package/dist/commands/users.d.ts +2 -0
  29. package/dist/commands/users.js +80 -0
  30. package/dist/commands/versions.d.ts +2 -0
  31. package/dist/commands/versions.js +65 -0
  32. package/dist/index.d.ts +2 -0
  33. package/dist/index.js +82 -0
  34. package/dist/lib/auth-state.d.ts +11 -0
  35. package/dist/lib/auth-state.js +27 -0
  36. package/dist/lib/cache.d.ts +20 -0
  37. package/dist/lib/cache.js +135 -0
  38. package/dist/lib/config.d.ts +8 -0
  39. package/dist/lib/config.js +25 -0
  40. package/dist/lib/credentials.d.ts +15 -0
  41. package/dist/lib/credentials.js +50 -0
  42. package/dist/lib/http.d.ts +14 -0
  43. package/dist/lib/http.js +174 -0
  44. package/dist/lib/oauth.d.ts +20 -0
  45. package/dist/lib/oauth.js +155 -0
  46. package/dist/lib/output.d.ts +3 -0
  47. package/dist/lib/output.js +9 -0
  48. package/dist/lib/products.d.ts +24 -0
  49. package/dist/lib/products.js +87 -0
  50. package/dist/lib/user-config.d.ts +10 -0
  51. package/dist/lib/user-config.js +47 -0
  52. package/package.json +49 -0
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerUsersCommand(program: Command): void;
@@ -0,0 +1,80 @@
1
+ import { cawplanRequest } from "../lib/http.js";
2
+ import { getCache, setCache, buildScopedCacheKey, buildQueryFromFlags } from "../lib/cache.js";
3
+ export function registerUsersCommand(program) {
4
+ const users = program.command("users").description("Manage users");
5
+ users
6
+ .command("list")
7
+ .description("List users")
8
+ .option("--search <q>", "Search query")
9
+ .option("--page_size <n>", "Page size")
10
+ .option("--page_num <n>", "Page number")
11
+ .option("--refresh", "Bypass cache")
12
+ .action(async (opts) => {
13
+ const flags = {};
14
+ if (opts.search)
15
+ flags.search = opts.search;
16
+ if (opts.page_size)
17
+ flags.page_size = opts.page_size;
18
+ if (opts.page_num)
19
+ flags.page_num = opts.page_num;
20
+ const refresh = Boolean(opts.refresh);
21
+ const query = buildQueryFromFlags(flags, ["search", "page_size", "page_num"]);
22
+ const key = await buildScopedCacheKey("users:list", query);
23
+ const cached = getCache(key, refresh);
24
+ if (cached) {
25
+ console.log(JSON.stringify(cached, null, 2));
26
+ return;
27
+ }
28
+ const result = await cawplanRequest({
29
+ method: "GET",
30
+ path: "/api/v1/public/openapi/users",
31
+ query,
32
+ });
33
+ setCache(key, result);
34
+ console.log(JSON.stringify(result, null, 2));
35
+ });
36
+ users
37
+ .command("query")
38
+ .description("Query users by email or keyword")
39
+ .option("--email <email>", "User email")
40
+ .option("--keyword <q>", "Search keyword")
41
+ .option("--page_size <n>", "Page size")
42
+ .option("--page_num <n>", "Page number")
43
+ .option("--refresh", "Bypass cache")
44
+ .action(async (opts) => {
45
+ if (!opts.email && !opts.keyword) {
46
+ console.error("Error: users query requires --email or --keyword");
47
+ process.exit(1);
48
+ }
49
+ const refresh = Boolean(opts.refresh);
50
+ const key = await buildScopedCacheKey("users:query", {
51
+ email: opts.email || "",
52
+ keyword: opts.keyword || "",
53
+ page_num: opts.page_num || "",
54
+ page_size: opts.page_size || "",
55
+ });
56
+ const cached = getCache(key, refresh);
57
+ if (cached) {
58
+ console.log(JSON.stringify(cached, null, 2));
59
+ return;
60
+ }
61
+ const body = {};
62
+ if (opts.email) {
63
+ body.email = opts.email;
64
+ }
65
+ else if (opts.keyword) {
66
+ body.keyword = opts.keyword;
67
+ }
68
+ if (opts.page_num)
69
+ body.page_num = opts.page_num;
70
+ if (opts.page_size)
71
+ body.page_size = opts.page_size;
72
+ const result = await cawplanRequest({
73
+ method: "POST",
74
+ path: "/api/v1/public/openapi/users/query",
75
+ body,
76
+ });
77
+ setCache(key, result);
78
+ console.log(JSON.stringify(result, null, 2));
79
+ });
80
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerVersionsCommand(program: Command): void;
@@ -0,0 +1,65 @@
1
+ import { cawplanRequest } from "../lib/http.js";
2
+ import { buildQueryFromFlags } from "../lib/cache.js";
3
+ export function registerVersionsCommand(program) {
4
+ const versions = program.command("versions").description("Manage versions");
5
+ versions
6
+ .command("list <product_id>")
7
+ .description("List versions for a product")
8
+ .option("--page_size <n>", "Page size")
9
+ .option("--page_num <n>", "Page number")
10
+ .action(async (productId, opts) => {
11
+ const flags = {};
12
+ if (opts.page_size)
13
+ flags.page_size = opts.page_size;
14
+ if (opts.page_num)
15
+ flags.page_num = opts.page_num;
16
+ const query = buildQueryFromFlags(flags, ["page_size", "page_num"]);
17
+ const result = await cawplanRequest({
18
+ method: "GET",
19
+ path: `/api/v1/public/openapi/product/${productId}/versions`,
20
+ query,
21
+ });
22
+ console.log(JSON.stringify(result, null, 2));
23
+ });
24
+ versions
25
+ .command("get <product_id> <version_id>")
26
+ .description("Get version details")
27
+ .action(async (productId, versionId) => {
28
+ const result = await cawplanRequest({
29
+ method: "GET",
30
+ path: `/api/v1/public/openapi/product/${productId}/versions/${versionId}`,
31
+ });
32
+ console.log(JSON.stringify(result, null, 2));
33
+ });
34
+ versions
35
+ .command("create <product_id>")
36
+ .description("Create a new version")
37
+ .requiredOption("--name <version>", "Version name (e.g. X.Y.Z)")
38
+ .option("--major_id <id>", "Major version unique_id")
39
+ .option("--description <text>", "Description")
40
+ .action(async (productId, opts) => {
41
+ const body = { name: opts.name };
42
+ if (opts.major_id)
43
+ body.major_id = opts.major_id;
44
+ if (opts.description !== undefined)
45
+ body.description = opts.description;
46
+ const result = await cawplanRequest({
47
+ method: "POST",
48
+ path: `/api/v1/public/openapi/product/${productId}/versions`,
49
+ body,
50
+ });
51
+ console.log(JSON.stringify(result, null, 2));
52
+ });
53
+ // Releases subcommand lives naturally alongside versions
54
+ const releases = program.command("releases").description("Manage releases");
55
+ releases
56
+ .command("list <product_id> <version_id>")
57
+ .description("List releases for a version")
58
+ .action(async (productId, versionId) => {
59
+ const result = await cawplanRequest({
60
+ method: "GET",
61
+ path: `/api/v1/public/openapi/product/${productId}/versions/${versionId}/release`,
62
+ });
63
+ console.log(JSON.stringify(result, null, 2));
64
+ });
65
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { createRequire } from "node:module";
4
+ import { registerAuthCommand } from "./commands/auth.js";
5
+ import { registerProductsCommand } from "./commands/products.js";
6
+ import { registerVersionsCommand } from "./commands/versions.js";
7
+ import { registerTicketsCommand } from "./commands/tickets.js";
8
+ import { registerCriticalCommand } from "./commands/critical.js";
9
+ import { registerMetricsCommand } from "./commands/metrics.js";
10
+ import { registerTodosCommand } from "./commands/todos.js";
11
+ import { registerUsersCommand } from "./commands/users.js";
12
+ import { registerActivitiesCommand } from "./commands/activities.js";
13
+ import { registerUserActivityCommand } from "./commands/user-activity.js";
14
+ import { registerProductActivityCommand } from "./commands/product-activity.js";
15
+ import { registerKnowledgeCommand } from "./commands/knowledge.js";
16
+ import { registerAnalyticsCommand } from "./commands/analytics.js";
17
+ import { registerQAReportsCommand } from "./commands/qa-reports.js";
18
+ import { registerCommunityCommand } from "./commands/community.js";
19
+ const require = createRequire(import.meta.url);
20
+ const { version } = require("../package.json");
21
+ const program = new Command();
22
+ program
23
+ .name("cawplan")
24
+ .description("CawPlan CLI")
25
+ .version(version);
26
+ // Register all commands
27
+ registerAuthCommand(program);
28
+ registerProductsCommand(program);
29
+ registerVersionsCommand(program);
30
+ registerTicketsCommand(program);
31
+ registerCriticalCommand(program);
32
+ registerMetricsCommand(program);
33
+ registerTodosCommand(program);
34
+ registerUsersCommand(program);
35
+ registerActivitiesCommand(program);
36
+ registerUserActivityCommand(program);
37
+ registerProductActivityCommand(program);
38
+ registerKnowledgeCommand(program);
39
+ registerAnalyticsCommand(program);
40
+ registerQAReportsCommand(program);
41
+ registerCommunityCommand(program);
42
+ // Raw API passthrough
43
+ program
44
+ .command("api <method> <path>")
45
+ .description("Raw API request passthrough")
46
+ .option("--query <params>", "Query params as key=val&key2=val2")
47
+ .option("--body <json>", "Request body as JSON")
48
+ .action(async (method, path, opts) => {
49
+ const { cawplanRequest } = await import("./lib/http.js");
50
+ let body;
51
+ if (opts.body) {
52
+ try {
53
+ body = JSON.parse(opts.body);
54
+ }
55
+ catch {
56
+ console.error("Error: --body must be valid JSON");
57
+ process.exit(1);
58
+ }
59
+ }
60
+ const query = opts.query
61
+ ? Object.fromEntries(new URLSearchParams(opts.query).entries())
62
+ : undefined;
63
+ const result = await cawplanRequest({
64
+ method: method.toUpperCase(),
65
+ path,
66
+ query,
67
+ body,
68
+ });
69
+ console.log(JSON.stringify(result, null, 2));
70
+ });
71
+ // Cache management
72
+ program
73
+ .command("cache")
74
+ .description("Manage local cache")
75
+ .command("clear")
76
+ .description("Clear the local cache")
77
+ .action(async () => {
78
+ const { clearCache } = await import("./lib/cache.js");
79
+ clearCache();
80
+ console.log(JSON.stringify({ code: "SUCCESS", msg: "cache cleared" }, null, 2));
81
+ });
82
+ await program.parseAsync(process.argv);
@@ -0,0 +1,11 @@
1
+ import { type Credentials } from "./credentials.js";
2
+ export type ActiveAuthKind = "oauth" | "apiKey" | "none";
3
+ export interface AuthState {
4
+ credentials: Credentials | null;
5
+ envApiKey?: string;
6
+ hasOAuth: boolean;
7
+ hasApiKey: boolean;
8
+ active: ActiveAuthKind;
9
+ }
10
+ export declare function getAuthState(): Promise<AuthState>;
11
+ export declare function isAuthenticated(): Promise<boolean>;
@@ -0,0 +1,27 @@
1
+ import { getApiKey } from "./config.js";
2
+ import { isAccessTokenExpired, readCredentials } from "./credentials.js";
3
+ export async function getAuthState() {
4
+ const credentials = await readCredentials();
5
+ const envApiKey = getApiKey();
6
+ const hasOAuth = Boolean(credentials?.accessToken &&
7
+ (!isAccessTokenExpired(credentials) || credentials.refreshToken));
8
+ const hasApiKey = Boolean(credentials?.apiKey || envApiKey);
9
+ let active = "none";
10
+ if (hasOAuth) {
11
+ active = "oauth";
12
+ }
13
+ else if (hasApiKey) {
14
+ active = "apiKey";
15
+ }
16
+ return {
17
+ credentials,
18
+ envApiKey,
19
+ hasOAuth,
20
+ hasApiKey,
21
+ active,
22
+ };
23
+ }
24
+ export async function isAuthenticated() {
25
+ const state = await getAuthState();
26
+ return state.active !== "none";
27
+ }
@@ -0,0 +1,20 @@
1
+ type CacheEntry = {
2
+ fetched_at: number;
3
+ data: unknown;
4
+ };
5
+ type CacheStore = {
6
+ version: 1;
7
+ entries: Record<string, CacheEntry>;
8
+ };
9
+ export declare function loadCache(): CacheStore;
10
+ export declare function saveCache(store: CacheStore): void;
11
+ export declare function getCache(key: string, refresh: boolean): unknown | undefined;
12
+ export declare function setCache(key: string, data: unknown): void;
13
+ export declare function clearCache(): void;
14
+ export declare function buildCacheKey(prefix: string, query: Record<string, string> | undefined): string;
15
+ export declare function getCacheScope(): Promise<string>;
16
+ export declare function buildScopedCacheKey(prefix: string, query: Record<string, string> | undefined): Promise<string>;
17
+ export declare function stableStringify(value: unknown): string;
18
+ export declare function buildQueryFromFlags(flags: Record<string, string>, allow: string[]): Record<string, string> | undefined;
19
+ export declare function csvToArray(value: string | undefined): string[] | undefined;
20
+ export {};
@@ -0,0 +1,135 @@
1
+ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
2
+ import { createHash } from "node:crypto";
3
+ import { resolve } from "node:path";
4
+ import { getBaseUrl, getCachePath, getCacheTtlMs } from "./config.js";
5
+ import { readCredentials } from "./credentials.js";
6
+ export function loadCache() {
7
+ const cachePath = getCachePath();
8
+ if (!existsSync(cachePath))
9
+ return { version: 1, entries: {} };
10
+ try {
11
+ const raw = readFileSync(cachePath, "utf-8");
12
+ const parsed = JSON.parse(raw);
13
+ if (parsed && parsed.version === 1 && typeof parsed.entries === "object") {
14
+ return parsed;
15
+ }
16
+ }
17
+ catch {
18
+ // Ignore cache read/parse errors
19
+ }
20
+ return { version: 1, entries: {} };
21
+ }
22
+ export function saveCache(store) {
23
+ const cachePath = getCachePath();
24
+ try {
25
+ mkdirSync(resolve(cachePath, ".."), { recursive: true });
26
+ writeFileSync(cachePath, JSON.stringify(store, null, 2));
27
+ }
28
+ catch {
29
+ // Ignore cache write errors
30
+ }
31
+ }
32
+ export function getCache(key, refresh) {
33
+ if (refresh)
34
+ return undefined;
35
+ const store = loadCache();
36
+ const entry = store.entries[key];
37
+ if (!entry)
38
+ return undefined;
39
+ const ttlMs = getCacheTtlMs();
40
+ if (Date.now() - entry.fetched_at > ttlMs)
41
+ return undefined;
42
+ return entry.data;
43
+ }
44
+ export function setCache(key, data) {
45
+ const store = loadCache();
46
+ store.entries[key] = { fetched_at: Date.now(), data };
47
+ saveCache(store);
48
+ }
49
+ export function clearCache() {
50
+ const cachePath = getCachePath();
51
+ try {
52
+ if (existsSync(cachePath)) {
53
+ unlinkSync(cachePath);
54
+ }
55
+ }
56
+ catch {
57
+ // Ignore cache delete errors
58
+ }
59
+ }
60
+ export function buildCacheKey(prefix, query) {
61
+ if (!query)
62
+ return prefix;
63
+ const normalized = Object.keys(query)
64
+ .sort()
65
+ .map((k) => `${k}=${query[k]}`)
66
+ .join("&");
67
+ return `${prefix}?${normalized}`;
68
+ }
69
+ function shortHash(value) {
70
+ return createHash("sha256").update(value).digest("hex").slice(0, 16);
71
+ }
72
+ function decodeJwtPayload(token) {
73
+ const payload = token.split(".")[1];
74
+ if (!payload)
75
+ return null;
76
+ try {
77
+ return JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
78
+ }
79
+ catch {
80
+ return null;
81
+ }
82
+ }
83
+ export async function getCacheScope() {
84
+ const base = `base:${shortHash(getBaseUrl())}`;
85
+ const credentials = await readCredentials();
86
+ if (credentials?.accessToken) {
87
+ const payload = decodeJwtPayload(credentials.accessToken);
88
+ const workspaceId = payload?.workspace_id;
89
+ if (typeof workspaceId === "string" && workspaceId.trim()) {
90
+ return `${base}:workspace:${workspaceId}`;
91
+ }
92
+ const userId = payload?.uid_id ?? payload?.user_id ?? payload?.sub ?? credentials.email;
93
+ if (typeof userId === "string" && userId.trim()) {
94
+ return `${base}:oauth:${shortHash(userId)}`;
95
+ }
96
+ }
97
+ if (credentials?.apiKey) {
98
+ return `${base}:api-key:${shortHash(credentials.apiKey)}`;
99
+ }
100
+ return `${base}:anonymous`;
101
+ }
102
+ export async function buildScopedCacheKey(prefix, query) {
103
+ const scope = await getCacheScope();
104
+ return `${scope}:${buildCacheKey(prefix, query)}`;
105
+ }
106
+ export function stableStringify(value) {
107
+ if (value === null || typeof value !== "object") {
108
+ return JSON.stringify(value);
109
+ }
110
+ if (Array.isArray(value)) {
111
+ return `[${value.map((item) => stableStringify(item)).join(",")}]`;
112
+ }
113
+ const obj = value;
114
+ const keys = Object.keys(obj).sort();
115
+ const entries = keys.map((key) => `${JSON.stringify(key)}:${stableStringify(obj[key])}`);
116
+ return `{${entries.join(",")}}`;
117
+ }
118
+ export function buildQueryFromFlags(flags, allow) {
119
+ const query = {};
120
+ for (const key of allow) {
121
+ if (flags[key] !== undefined) {
122
+ query[key] = flags[key];
123
+ }
124
+ }
125
+ return Object.keys(query).length ? query : undefined;
126
+ }
127
+ export function csvToArray(value) {
128
+ if (!value)
129
+ return undefined;
130
+ const items = value
131
+ .split(",")
132
+ .map((item) => item.trim())
133
+ .filter(Boolean);
134
+ return items.length ? items : undefined;
135
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * API base URL. Reads from products.json (env selected by CAWPLAN_ENV),
3
+ * overridable via CAWPLAN_BASE_URL for advanced use / debugging.
4
+ */
5
+ export declare function getBaseUrl(): string;
6
+ export declare function getApiKey(): string | undefined;
7
+ export declare function getCachePath(): string;
8
+ export declare function getCacheTtlMs(): number;
@@ -0,0 +1,25 @@
1
+ import { homedir } from "node:os";
2
+ import { resolve } from "node:path";
3
+ import { getApiBase } from "./products.js";
4
+ /**
5
+ * API base URL. Reads from products.json (env selected by CAWPLAN_ENV),
6
+ * overridable via CAWPLAN_BASE_URL for advanced use / debugging.
7
+ */
8
+ export function getBaseUrl() {
9
+ return getApiBase();
10
+ }
11
+ export function getApiKey() {
12
+ return process.env.CAWPLAN_API_KEY;
13
+ }
14
+ export function getCachePath() {
15
+ return process.env.CAWPLAN_CACHE_PATH ?? resolve(homedir(), ".cawplan", "cache.json");
16
+ }
17
+ export function getCacheTtlMs() {
18
+ const hoursRaw = process.env.CAWPLAN_CACHE_TTL_HOURS;
19
+ if (hoursRaw !== undefined) {
20
+ const hours = Number(hoursRaw);
21
+ if (Number.isFinite(hours) && hours > 0)
22
+ return hours * 60 * 60 * 1000;
23
+ }
24
+ return 12 * 60 * 60 * 1000;
25
+ }
@@ -0,0 +1,15 @@
1
+ export interface Credentials {
2
+ apiKey?: string;
3
+ accessToken?: string;
4
+ refreshToken?: string;
5
+ /** Unix timestamp (seconds) when access token expires */
6
+ expire?: number;
7
+ /** Email of the authenticated user (from OAuth) */
8
+ email?: string;
9
+ }
10
+ export declare const CREDENTIALS_PATH: string;
11
+ export declare function getCredentialsPath(): string;
12
+ export declare function isAccessTokenExpired(credentials: Credentials, nowSeconds?: number): boolean;
13
+ export declare function readCredentials(): Promise<Credentials | null>;
14
+ export declare function writeCredentials(creds: Credentials): Promise<void>;
15
+ export declare function deleteCredentials(): Promise<void>;
@@ -0,0 +1,50 @@
1
+ import { chmod, mkdir, readFile, unlink, writeFile } from "node:fs/promises";
2
+ import { dirname, join } from "node:path";
3
+ import { homedir } from "node:os";
4
+ const CREDENTIALS_MODE = 0o600;
5
+ export const CREDENTIALS_PATH = join(homedir(), ".cawplan", "credentials.json");
6
+ export function getCredentialsPath() {
7
+ return process.env.CAWPLAN_CREDENTIALS_PATH ?? CREDENTIALS_PATH;
8
+ }
9
+ export function isAccessTokenExpired(credentials, nowSeconds = Math.floor(Date.now() / 1000)) {
10
+ if (credentials.expire == null)
11
+ return true;
12
+ return credentials.expire <= nowSeconds;
13
+ }
14
+ export async function readCredentials() {
15
+ try {
16
+ const raw = await readFile(getCredentialsPath(), "utf8");
17
+ const parsed = JSON.parse(raw);
18
+ // Return whatever fields are present; no required fields check
19
+ return {
20
+ apiKey: parsed.apiKey,
21
+ accessToken: parsed.accessToken,
22
+ refreshToken: parsed.refreshToken,
23
+ expire: parsed.expire,
24
+ email: parsed.email,
25
+ };
26
+ }
27
+ catch (err) {
28
+ if (err.code === "ENOENT") {
29
+ return null;
30
+ }
31
+ throw err;
32
+ }
33
+ }
34
+ export async function writeCredentials(creds) {
35
+ const credentialsPath = getCredentialsPath();
36
+ await mkdir(dirname(credentialsPath), { recursive: true });
37
+ const payload = `${JSON.stringify(creds, null, 2)}\n`;
38
+ await writeFile(credentialsPath, payload, { encoding: "utf8", mode: CREDENTIALS_MODE });
39
+ await chmod(credentialsPath, CREDENTIALS_MODE);
40
+ }
41
+ export async function deleteCredentials() {
42
+ try {
43
+ await unlink(getCredentialsPath());
44
+ }
45
+ catch (err) {
46
+ if (err.code !== "ENOENT") {
47
+ throw err;
48
+ }
49
+ }
50
+ }
@@ -0,0 +1,14 @@
1
+ export declare class ApiError extends Error {
2
+ readonly status: number;
3
+ readonly body?: unknown | undefined;
4
+ constructor(message: string, status: number, body?: unknown | undefined);
5
+ }
6
+ type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
7
+ export interface RequestOptions {
8
+ method?: HttpMethod;
9
+ path: string;
10
+ query?: Record<string, string>;
11
+ body?: unknown;
12
+ }
13
+ export declare function cawplanRequest(options: RequestOptions): Promise<unknown>;
14
+ export {};