@scalepad/sdk-lm 0.1.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/dist/catalog.d.ts +14 -0
- package/dist/catalog.js +1147 -0
- package/dist/catalog.js.map +1 -0
- package/dist/generated.d.ts +445 -0
- package/dist/generated.js +668 -0
- package/dist/generated.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime.d.ts +37 -0
- package/dist/runtime.js +88 -0
- package/dist/runtime.js.map +1 -0
- package/dist/schema.d.ts +8767 -0
- package/dist/schema.js +2 -0
- package/dist/schema.js.map +1 -0
- package/package.json +17 -0
- package/src/catalog.ts +1161 -0
- package/src/generated.ts +1288 -0
- package/src/index.ts +63 -0
- package/src/runtime.ts +132 -0
- package/src/schema.ts +8768 -0
- package/tsconfig.json +9 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GeneratedLifecycleManagerClient,
|
|
3
|
+
type GetactionitemsbyidResponse as GetActionItemResponse,
|
|
4
|
+
type ListactionitemsQuery as ListActionItemsQuery,
|
|
5
|
+
type ListactionitemsResponse as ListActionItemsResponse
|
|
6
|
+
} from "./generated.js";
|
|
7
|
+
import type { BaseClientConfig } from "./runtime.js";
|
|
8
|
+
|
|
9
|
+
export { lifecycleManagerOperations, type GeneratedOperation as GeneratedLifecycleManagerOperation } from "./catalog.js";
|
|
10
|
+
export { GeneratedLifecycleManagerClient } from "./generated.js";
|
|
11
|
+
export { BaseApiError as ScalepadLmApiError, type FetchLike, type JsonArray, type JsonObject, type JsonPrimitive, type JsonValue } from "./runtime.js";
|
|
12
|
+
export type { paths } from "./schema.js";
|
|
13
|
+
|
|
14
|
+
export interface ListQuery {
|
|
15
|
+
cursor?: string;
|
|
16
|
+
pageSize?: number;
|
|
17
|
+
filters?: Record<string, string>;
|
|
18
|
+
sort?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface LifecycleManagerClientConfig extends BaseClientConfig {}
|
|
22
|
+
|
|
23
|
+
function buildListQuery(query: ListQuery = {}): Record<string, string> {
|
|
24
|
+
const params: Record<string, string> = {};
|
|
25
|
+
|
|
26
|
+
if (query.pageSize != null) {
|
|
27
|
+
params.page_size = String(query.pageSize);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (query.cursor) {
|
|
31
|
+
params.cursor = query.cursor;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (query.sort) {
|
|
35
|
+
params.sort = query.sort;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
for (const [field, expression] of Object.entries(query.filters ?? {})) {
|
|
39
|
+
params[`filter[${field}]`] = expression;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return params;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export class ScalepadLifecycleManagerClient {
|
|
46
|
+
private readonly generated: GeneratedLifecycleManagerClient;
|
|
47
|
+
|
|
48
|
+
public constructor(config: LifecycleManagerClientConfig) {
|
|
49
|
+
this.generated = new GeneratedLifecycleManagerClient(config);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public listActionItems(query: ListQuery = {}): Promise<ListActionItemsResponse> {
|
|
53
|
+
return this.generated.listActionItems(buildListQuery(query) as ListActionItemsQuery);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public getActionItem(id: string): Promise<GetActionItemResponse> {
|
|
57
|
+
return this.generated.getActionItemsById({ id });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function createLifecycleManagerClient(config: LifecycleManagerClientConfig): ScalepadLifecycleManagerClient {
|
|
62
|
+
return new ScalepadLifecycleManagerClient(config);
|
|
63
|
+
}
|
package/src/runtime.ts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
export type JsonPrimitive = string | number | boolean | null;
|
|
2
|
+
export interface JsonObject {
|
|
3
|
+
[key: string]: JsonValue;
|
|
4
|
+
}
|
|
5
|
+
export interface JsonArray extends Array<JsonValue> {}
|
|
6
|
+
export type JsonValue = JsonPrimitive | JsonObject | JsonArray;
|
|
7
|
+
export type FetchLike = typeof fetch;
|
|
8
|
+
export type QueryArrayValue = string | number | boolean;
|
|
9
|
+
export type QueryValue = string | number | boolean | null | undefined | ReadonlyArray<QueryArrayValue>;
|
|
10
|
+
export type QueryParams = Record<string, QueryValue>;
|
|
11
|
+
|
|
12
|
+
export class BaseApiError extends Error {
|
|
13
|
+
public readonly status: number;
|
|
14
|
+
public readonly payload: unknown;
|
|
15
|
+
|
|
16
|
+
public constructor(message: string, status: number, payload: unknown) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = "BaseApiError";
|
|
19
|
+
this.status = status;
|
|
20
|
+
this.payload = payload;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface BaseClientConfig {
|
|
25
|
+
apiKey: string;
|
|
26
|
+
baseUrl?: string;
|
|
27
|
+
fetchImpl?: FetchLike;
|
|
28
|
+
userAgent?: string;
|
|
29
|
+
maxRetries?: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const DEFAULT_BASE_URL = "https://api.scalepad.com";
|
|
33
|
+
|
|
34
|
+
function delay(ms: number): Promise<void> {
|
|
35
|
+
return new Promise((resolve) => {
|
|
36
|
+
setTimeout(resolve, ms);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function parseResponseBody(response: Response): Promise<unknown> {
|
|
41
|
+
if (response.status === 204 || response.status === 205) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
46
|
+
if (contentType.includes("application/json")) {
|
|
47
|
+
return response.json();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const text = await response.text();
|
|
51
|
+
return text.length === 0 ? null : text;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function appendQuery(url: URL, query?: QueryParams): void {
|
|
55
|
+
if (!query) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
for (const [key, value] of Object.entries(query)) {
|
|
60
|
+
if (value == null) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (Array.isArray(value)) {
|
|
65
|
+
url.searchParams.set(key, value.join(","));
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
url.searchParams.set(key, String(value));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export class BaseApiClient {
|
|
74
|
+
private readonly apiKey: string;
|
|
75
|
+
private readonly baseUrl: string;
|
|
76
|
+
private readonly fetchImpl: FetchLike;
|
|
77
|
+
private readonly userAgent: string;
|
|
78
|
+
private readonly maxRetries: number;
|
|
79
|
+
|
|
80
|
+
public constructor(config: BaseClientConfig) {
|
|
81
|
+
this.apiKey = config.apiKey;
|
|
82
|
+
this.baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
|
|
83
|
+
this.fetchImpl = config.fetchImpl ?? fetch;
|
|
84
|
+
this.userAgent = config.userAgent ?? "@scalepad/cli";
|
|
85
|
+
this.maxRetries = config.maxRetries ?? 3;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
protected async requestJson(request: {
|
|
89
|
+
method: string;
|
|
90
|
+
path: string;
|
|
91
|
+
query?: QueryParams;
|
|
92
|
+
body?: JsonValue;
|
|
93
|
+
}): Promise<unknown> {
|
|
94
|
+
const url = new URL(request.path, this.baseUrl);
|
|
95
|
+
appendQuery(url, request.query);
|
|
96
|
+
|
|
97
|
+
let attempt = 0;
|
|
98
|
+
while (true) {
|
|
99
|
+
const response = await this.fetchImpl(url, {
|
|
100
|
+
method: request.method,
|
|
101
|
+
headers: {
|
|
102
|
+
accept: "application/json",
|
|
103
|
+
...(request.body != null ? { "content-type": "application/json" } : {}),
|
|
104
|
+
"x-api-key": this.apiKey,
|
|
105
|
+
"user-agent": this.userAgent
|
|
106
|
+
},
|
|
107
|
+
body: request.body != null ? JSON.stringify(request.body) : undefined
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
if (response.ok) {
|
|
111
|
+
return parseResponseBody(response);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (response.status === 429 && attempt < this.maxRetries) {
|
|
115
|
+
attempt += 1;
|
|
116
|
+
const retryAfterSeconds = Number(response.headers.get("retry-after"));
|
|
117
|
+
const waitMs = Number.isFinite(retryAfterSeconds) && retryAfterSeconds > 0
|
|
118
|
+
? retryAfterSeconds * 1000
|
|
119
|
+
: 500 * (2 ** (attempt - 1));
|
|
120
|
+
await delay(waitMs);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const payload = await parseResponseBody(response);
|
|
125
|
+
throw new BaseApiError(
|
|
126
|
+
`API request failed with status ${response.status}`,
|
|
127
|
+
response.status,
|
|
128
|
+
payload
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|