@getpilfer/cli 0.1.1 → 0.1.3
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 +13 -1
- package/SKILL.md +17 -1
- package/dist/build-program.js +2 -2
- package/dist/{chunk-QH2MMA3M.js → chunk-CXNVJZ4C.js} +173 -72
- package/dist/chunk-CXNVJZ4C.js.map +1 -0
- package/dist/chunk-NFFHTNJE.js +1161 -0
- package/dist/chunk-NFFHTNJE.js.map +1 -0
- package/dist/{generated-IFLUY7PB.js → generated-7QDIZ5V5.js} +656 -66
- package/dist/generated-7QDIZ5V5.js.map +1 -0
- package/dist/index.js +2 -2
- package/package.json +2 -2
- package/dist/chunk-2QYZ5OEW.js +0 -407
- package/dist/chunk-2QYZ5OEW.js.map +0 -1
- package/dist/chunk-QH2MMA3M.js.map +0 -1
- package/dist/generated-IFLUY7PB.js.map +0 -1
package/README.md
CHANGED
|
@@ -54,11 +54,23 @@ Nested scout sources:
|
|
|
54
54
|
|
|
55
55
|
```bash
|
|
56
56
|
pilfer sources list --scout-id <id>
|
|
57
|
-
pilfer sources create --scout-id <id> --url <url> --
|
|
57
|
+
pilfer sources create --scout-id <id> --url <url> --name "Vendor" --price 49
|
|
58
58
|
pilfer sources update --scout-id <id> <source-id> --starred true
|
|
59
59
|
pilfer sources delete --scout-id <id> <source-id>
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
+
Agent workflow helpers:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pilfer scouts shortlist
|
|
66
|
+
pilfer scouts pipeline
|
|
67
|
+
pilfer scouts purchase <scout-id> --cost 120
|
|
68
|
+
pilfer reports scouting
|
|
69
|
+
pilfer reports assets
|
|
70
|
+
pilfer reports balance --project-id <id>
|
|
71
|
+
pilfer reports balance --space-id <id>
|
|
72
|
+
```
|
|
73
|
+
|
|
62
74
|
Top-level helpers:
|
|
63
75
|
|
|
64
76
|
```bash
|
package/SKILL.md
CHANGED
|
@@ -19,11 +19,27 @@ Scout sources are nested and use custom commands:
|
|
|
19
19
|
```bash
|
|
20
20
|
pilfer sources list --scout-id <id>
|
|
21
21
|
pilfer sources get --scout-id <id> <source-id>
|
|
22
|
-
pilfer sources create --scout-id <id> --url <url> --
|
|
22
|
+
pilfer sources create --scout-id <id> --url <url> --name <name> --price <n>
|
|
23
23
|
pilfer sources update --scout-id <id> <source-id> --price <n>
|
|
24
24
|
pilfer sources delete --scout-id <id> <source-id>
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
## Agent Workflows
|
|
28
|
+
|
|
29
|
+
Use workflow helpers before composing raw CRUD:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pilfer scouts shortlist
|
|
33
|
+
pilfer scouts pipeline
|
|
34
|
+
pilfer scouts purchase <scout-id> --cost <n>
|
|
35
|
+
pilfer reports scouting
|
|
36
|
+
pilfer reports assets
|
|
37
|
+
pilfer reports balance [--project-id <id> | --space-id <id>]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`scouts purchase` creates an asset linked to the scout, then marks the scout `Purchased`.
|
|
41
|
+
`reports balance` compares owned asset value with active scouting value; if scoped relation data is unavailable from REST payloads it returns a `scopeWarning`.
|
|
42
|
+
|
|
27
43
|
## Auth
|
|
28
44
|
|
|
29
45
|
Resolution order:
|
package/dist/build-program.js
CHANGED
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
createProgramForCLI,
|
|
5
5
|
getProgramForDocs,
|
|
6
6
|
syncRootOptsFromCommand
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-NFFHTNJE.js";
|
|
8
|
+
import "./chunk-CXNVJZ4C.js";
|
|
9
9
|
import "./chunk-GZ4DXDQM.js";
|
|
10
10
|
export {
|
|
11
11
|
createProgram,
|
|
@@ -91,77 +91,22 @@ function extractErrorMessage(data) {
|
|
|
91
91
|
return baseMessage;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
// src/lib/flag-coercion.ts
|
|
95
|
-
function fail(exitWithError, message) {
|
|
96
|
-
return exitWithError(400, message);
|
|
97
|
-
}
|
|
98
|
-
function parseBoolean(raw, config, exitWithError) {
|
|
99
|
-
const value = raw.trim().toLowerCase();
|
|
100
|
-
if (["true", "1", "yes", "y", "on"].includes(value)) return true;
|
|
101
|
-
if (["false", "0", "no", "n", "off"].includes(value)) return false;
|
|
102
|
-
return fail(
|
|
103
|
-
exitWithError,
|
|
104
|
-
`Invalid value for ${config.flag} (${config.field}): expected boolean but got "${raw}"`
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
function parseNumber(raw, config, exitWithError) {
|
|
108
|
-
const trimmed = raw.trim();
|
|
109
|
-
const asNumber = Number(trimmed);
|
|
110
|
-
if (Number.isFinite(asNumber)) return asNumber;
|
|
111
|
-
if (config.allowDateTime) {
|
|
112
|
-
const asDate = Date.parse(trimmed);
|
|
113
|
-
if (Number.isFinite(asDate)) return asDate;
|
|
114
|
-
}
|
|
115
|
-
return fail(
|
|
116
|
-
exitWithError,
|
|
117
|
-
`Invalid value for ${config.flag} (${config.field}): expected number${config.allowDateTime ? " or ISO datetime" : ""} but got "${raw}"`
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
function coerceBodyFlag(raw, config, exitWithError) {
|
|
121
|
-
if (raw == null) return void 0;
|
|
122
|
-
const value = String(raw);
|
|
123
|
-
const trimmed = value.trim();
|
|
124
|
-
if (config.allowNull && trimmed.toLowerCase() === "null") {
|
|
125
|
-
return null;
|
|
126
|
-
}
|
|
127
|
-
if (config.kind === "string") return value;
|
|
128
|
-
if (config.kind === "boolean") return parseBoolean(value, config, exitWithError);
|
|
129
|
-
return parseNumber(value, config, exitWithError);
|
|
130
|
-
}
|
|
131
|
-
function coerceQueryFlag(raw, config, exitWithError) {
|
|
132
|
-
if (raw == null) {
|
|
133
|
-
return fail(
|
|
134
|
-
exitWithError,
|
|
135
|
-
`Missing value for ${config.flag} (${config.field})`
|
|
136
|
-
);
|
|
137
|
-
}
|
|
138
|
-
const value = String(raw);
|
|
139
|
-
if (config.kind === "string") return value;
|
|
140
|
-
if (config.kind === "boolean") {
|
|
141
|
-
return parseBoolean(value, config, exitWithError) ? "true" : "false";
|
|
142
|
-
}
|
|
143
|
-
return parseNumber(value, config, exitWithError);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// src/lib/merge-body.ts
|
|
147
|
-
function mergeBody(bodyFromFlags, bodyOption) {
|
|
148
|
-
let base = {};
|
|
149
|
-
if (bodyOption?.trim()) {
|
|
150
|
-
try {
|
|
151
|
-
base = JSON.parse(bodyOption);
|
|
152
|
-
} catch {
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return { ...base, ...bodyFromFlags };
|
|
156
|
-
}
|
|
157
|
-
|
|
158
94
|
// src/lib/output.ts
|
|
159
95
|
function getDefaultOutputFormat() {
|
|
160
96
|
return process.stdout.isTTY ? "table" : "json";
|
|
161
97
|
}
|
|
162
|
-
function formatErrorPayload(status, message) {
|
|
98
|
+
function formatErrorPayload(status, message, meta = {}) {
|
|
163
99
|
const code = statusToCode(status);
|
|
164
|
-
|
|
100
|
+
const requestId = meta.requestId ?? extractRequestId(message);
|
|
101
|
+
return {
|
|
102
|
+
error: true,
|
|
103
|
+
status,
|
|
104
|
+
code,
|
|
105
|
+
message,
|
|
106
|
+
...requestId ? { requestId } : {},
|
|
107
|
+
...meta.method ? { method: meta.method } : {},
|
|
108
|
+
...meta.path ? { path: meta.path } : {}
|
|
109
|
+
};
|
|
165
110
|
}
|
|
166
111
|
function statusToCode(status) {
|
|
167
112
|
if (status === 401) return "UNAUTHORIZED";
|
|
@@ -261,21 +206,177 @@ function printCsv(data) {
|
|
|
261
206
|
}
|
|
262
207
|
function printStructuredError(format, payload) {
|
|
263
208
|
if (format === "json") {
|
|
264
|
-
console.
|
|
209
|
+
console.error(JSON.stringify(payload));
|
|
265
210
|
return;
|
|
266
211
|
}
|
|
267
212
|
console.error(`Error ${payload.status} (${payload.code}): ${payload.message}`);
|
|
268
213
|
}
|
|
214
|
+
function extractRequestId(message) {
|
|
215
|
+
const match = message.match(/\(requestId: ([^)]+)\)/);
|
|
216
|
+
return match?.[1];
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// src/lib/list-controls.ts
|
|
220
|
+
var DEFAULT_PAGE_LIMIT = 100;
|
|
221
|
+
async function fetchList(options) {
|
|
222
|
+
if (!options.all) {
|
|
223
|
+
return options.request({
|
|
224
|
+
method: "GET",
|
|
225
|
+
path: options.path,
|
|
226
|
+
token: options.token,
|
|
227
|
+
baseUrl: options.baseUrl,
|
|
228
|
+
query: options.query
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
const limit = parsePositiveInt(options.query.limit, DEFAULT_PAGE_LIMIT);
|
|
232
|
+
let offset = parsePositiveInt(options.query.offset, 0);
|
|
233
|
+
const data = [];
|
|
234
|
+
for (; ; ) {
|
|
235
|
+
const res = await options.request({
|
|
236
|
+
method: "GET",
|
|
237
|
+
path: options.path,
|
|
238
|
+
token: options.token,
|
|
239
|
+
baseUrl: options.baseUrl,
|
|
240
|
+
query: { ...options.query, limit, offset }
|
|
241
|
+
});
|
|
242
|
+
if (!res.ok) return res;
|
|
243
|
+
const batch = Array.isArray(res.data?.data) ? res.data.data : [];
|
|
244
|
+
data.push(...batch);
|
|
245
|
+
if (batch.length < limit || batch.length === 0) break;
|
|
246
|
+
offset += limit;
|
|
247
|
+
}
|
|
248
|
+
return { ok: true, status: 200, data: { data } };
|
|
249
|
+
}
|
|
250
|
+
function printList(options) {
|
|
251
|
+
const rows = projectRows(filterRows(options.data, options.where), options.fields);
|
|
252
|
+
if (options.jsonl) {
|
|
253
|
+
for (const row of rows) console.log(JSON.stringify(row));
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
printOutput(options.format, rows, false);
|
|
257
|
+
}
|
|
258
|
+
function filterRows(data, where) {
|
|
259
|
+
const rows = data.filter(isRecord);
|
|
260
|
+
const filters = parseWhere(where);
|
|
261
|
+
if (filters.length === 0) return rows;
|
|
262
|
+
return rows.filter(
|
|
263
|
+
(row) => filters.every(({ field, value }) => equalValue(row[field], value))
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
function projectRows(rows, fields) {
|
|
267
|
+
const selected = parseFields(fields);
|
|
268
|
+
if (selected.length === 0) return rows;
|
|
269
|
+
return rows.map((row) => {
|
|
270
|
+
const projected = {};
|
|
271
|
+
for (const field of selected) projected[field] = row[field];
|
|
272
|
+
return projected;
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
function parseWhere(where) {
|
|
276
|
+
if (!where?.trim()) return [];
|
|
277
|
+
return where.split(",").map((part) => part.trim()).filter(Boolean).map((part) => {
|
|
278
|
+
const eq = part.indexOf("=");
|
|
279
|
+
if (eq === -1) return null;
|
|
280
|
+
const field = part.slice(0, eq).trim();
|
|
281
|
+
const value = part.slice(eq + 1).trim();
|
|
282
|
+
return field ? { field, value } : null;
|
|
283
|
+
}).filter((entry) => entry !== null);
|
|
284
|
+
}
|
|
285
|
+
function parseFields(fields) {
|
|
286
|
+
if (!fields?.trim()) return [];
|
|
287
|
+
return fields.split(",").map((field) => field.trim()).filter(Boolean);
|
|
288
|
+
}
|
|
289
|
+
function equalValue(actual, expected) {
|
|
290
|
+
if (actual == null) return expected === "";
|
|
291
|
+
if (typeof actual === "string") {
|
|
292
|
+
return actual.trim().toLowerCase() === expected.trim().toLowerCase();
|
|
293
|
+
}
|
|
294
|
+
return String(actual) === expected;
|
|
295
|
+
}
|
|
296
|
+
function parsePositiveInt(value, fallback) {
|
|
297
|
+
const parsed = Number(value);
|
|
298
|
+
if (!Number.isInteger(parsed) || parsed < 1) return fallback;
|
|
299
|
+
return parsed;
|
|
300
|
+
}
|
|
301
|
+
function isRecord(value) {
|
|
302
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// src/lib/flag-coercion.ts
|
|
306
|
+
function fail(exitWithError, message) {
|
|
307
|
+
return exitWithError(400, message);
|
|
308
|
+
}
|
|
309
|
+
function parseBoolean(raw, config, exitWithError) {
|
|
310
|
+
const value = raw.trim().toLowerCase();
|
|
311
|
+
if (["true", "1", "yes", "y", "on"].includes(value)) return true;
|
|
312
|
+
if (["false", "0", "no", "n", "off"].includes(value)) return false;
|
|
313
|
+
return fail(
|
|
314
|
+
exitWithError,
|
|
315
|
+
`Invalid value for ${config.flag} (${config.field}): expected boolean but got "${raw}"`
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
function parseNumber(raw, config, exitWithError) {
|
|
319
|
+
const trimmed = raw.trim();
|
|
320
|
+
const asNumber = Number(trimmed);
|
|
321
|
+
if (Number.isFinite(asNumber)) return asNumber;
|
|
322
|
+
if (config.allowDateTime) {
|
|
323
|
+
const asDate = Date.parse(trimmed);
|
|
324
|
+
if (Number.isFinite(asDate)) return asDate;
|
|
325
|
+
}
|
|
326
|
+
return fail(
|
|
327
|
+
exitWithError,
|
|
328
|
+
`Invalid value for ${config.flag} (${config.field}): expected number${config.allowDateTime ? " or ISO datetime" : ""} but got "${raw}"`
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
function coerceBodyFlag(raw, config, exitWithError) {
|
|
332
|
+
if (raw == null) return void 0;
|
|
333
|
+
const value = String(raw);
|
|
334
|
+
const trimmed = value.trim();
|
|
335
|
+
if (config.allowNull && trimmed.toLowerCase() === "null") {
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
if (config.kind === "string") return value;
|
|
339
|
+
if (config.kind === "boolean") return parseBoolean(value, config, exitWithError);
|
|
340
|
+
return parseNumber(value, config, exitWithError);
|
|
341
|
+
}
|
|
342
|
+
function coerceQueryFlag(raw, config, exitWithError) {
|
|
343
|
+
if (raw == null) {
|
|
344
|
+
return fail(
|
|
345
|
+
exitWithError,
|
|
346
|
+
`Missing value for ${config.flag} (${config.field})`
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
const value = String(raw);
|
|
350
|
+
if (config.kind === "string") return value;
|
|
351
|
+
if (config.kind === "boolean") {
|
|
352
|
+
return parseBoolean(value, config, exitWithError) ? "true" : "false";
|
|
353
|
+
}
|
|
354
|
+
return parseNumber(value, config, exitWithError);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// src/lib/merge-body.ts
|
|
358
|
+
function mergeBody(bodyFromFlags, bodyOption) {
|
|
359
|
+
let base = {};
|
|
360
|
+
if (bodyOption?.trim()) {
|
|
361
|
+
try {
|
|
362
|
+
base = JSON.parse(bodyOption);
|
|
363
|
+
} catch {
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return { ...base, ...bodyFromFlags };
|
|
367
|
+
}
|
|
269
368
|
|
|
270
369
|
export {
|
|
271
370
|
getBaseUrl,
|
|
272
371
|
apiRequest,
|
|
273
|
-
coerceBodyFlag,
|
|
274
|
-
coerceQueryFlag,
|
|
275
|
-
mergeBody,
|
|
276
372
|
getDefaultOutputFormat,
|
|
277
373
|
formatErrorPayload,
|
|
278
374
|
printOutput,
|
|
279
|
-
printStructuredError
|
|
375
|
+
printStructuredError,
|
|
376
|
+
fetchList,
|
|
377
|
+
printList,
|
|
378
|
+
coerceBodyFlag,
|
|
379
|
+
coerceQueryFlag,
|
|
380
|
+
mergeBody
|
|
280
381
|
};
|
|
281
|
-
//# sourceMappingURL=chunk-
|
|
382
|
+
//# sourceMappingURL=chunk-CXNVJZ4C.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/client.ts","../src/lib/output.ts","../src/lib/list-controls.ts","../src/lib/flag-coercion.ts","../src/lib/merge-body.ts"],"sourcesContent":["import { resolveStoredBaseUrl } from \"./auth.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.getpilfer.com\";\n\nexport function getBaseUrl(override?: string): string {\n const env = process.env.PILFER_API_BASE_URL;\n const stored = resolveStoredBaseUrl();\n const base = override ?? env ?? stored ?? DEFAULT_BASE_URL;\n return base.replace(/\\/$/, \"\");\n}\n\nexport interface RequestOptions {\n method: \"GET\" | \"POST\" | \"PATCH\" | \"PUT\" | \"DELETE\";\n path: string;\n token: string | null;\n baseUrl?: string;\n query?: Record<string, string | number | undefined>;\n body?: unknown;\n}\n\nexport interface ApiResponse<T = unknown> {\n ok: boolean;\n status: number;\n data?: T;\n error?: string;\n headers?: Headers;\n}\n\nconst RETRYABLE_STATUSES = new Set([502, 503, 504]);\nconst GET_MAX_ATTEMPTS = 3;\nconst GET_RETRY_BASE_DELAY_MS = 150;\n\nfunction shouldRetryRequest(method: RequestOptions[\"method\"], response: ApiResponse<unknown>, attempt: number): boolean {\n if (method !== \"GET\") return false;\n if (attempt >= GET_MAX_ATTEMPTS) return false;\n if (response.status === 0) return true;\n return RETRYABLE_STATUSES.has(response.status);\n}\n\nfunction getRetryDelayMs(attempt: number): number {\n const exp = GET_RETRY_BASE_DELAY_MS * Math.pow(2, Math.max(0, attempt - 1));\n const jitter = Math.floor(Math.random() * 50);\n return exp + jitter;\n}\n\nasync function sleep(ms: number): Promise<void> {\n await new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Call the Pilfer REST API. Path should be relative to /api/v1 (e.g. \"me\", \"projects\", \"projects/123\").\n */\nexport async function apiRequest<T = unknown>(\n options: RequestOptions,\n): Promise<ApiResponse<T>> {\n const base = getBaseUrl(options.baseUrl);\n const url = new URL(`/api/v1/${options.path.replace(/^\\//, \"\")}`, base);\n if (options.query) {\n for (const [k, v] of Object.entries(options.query)) {\n if (v !== undefined && v !== \"\") url.searchParams.set(k, String(v));\n }\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${options.token ?? \"\"}`,\n \"Content-Type\": \"application/json\",\n };\n\n const init: RequestInit = {\n method: options.method,\n headers,\n };\n if (\n options.body !== undefined &&\n options.method !== \"GET\"\n ) {\n init.body = JSON.stringify(options.body);\n }\n\n for (let attempt = 1; ; attempt++) {\n const response = await doRequest<T>(url.toString(), init);\n if (!shouldRetryRequest(options.method, response, attempt)) {\n return response;\n }\n await sleep(getRetryDelayMs(attempt));\n }\n}\n\nasync function doRequest<T>(url: string, init: RequestInit): Promise<ApiResponse<T>> {\n let res: Response;\n try {\n res = await fetch(url, init);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return { ok: false, status: 0, error: message };\n }\n\n let data: T | undefined;\n const text = await res.text();\n if (text) {\n try {\n data = JSON.parse(text) as T;\n } catch {\n data = undefined;\n }\n }\n\n return {\n ok: res.ok,\n status: res.status,\n data,\n error: !res.ok\n ? extractErrorMessage(data)\n : undefined,\n headers: res.headers,\n };\n}\n\nfunction extractErrorMessage(data: unknown): string | undefined {\n if (data == null || typeof data !== \"object\") return undefined;\n\n const body = data as {\n error?: unknown;\n message?: unknown;\n requestId?: unknown;\n };\n\n const baseMessage =\n typeof body.error === \"string\"\n ? body.error\n : typeof body.message === \"string\"\n ? body.message\n : undefined;\n if (baseMessage == null) return undefined;\n\n if (typeof body.requestId === \"string\" && body.requestId.trim() !== \"\") {\n return `${baseMessage} (requestId: ${body.requestId})`;\n }\n return baseMessage;\n}\n","export type OutputFormat = \"json\" | \"table\" | \"csv\";\n\nexport function getDefaultOutputFormat(): OutputFormat {\n return process.stdout.isTTY ? \"table\" : \"json\";\n}\n\nexport interface ErrorPayload {\n error: true;\n status: number;\n code: string;\n message: string;\n requestId?: string;\n method?: string;\n path?: string;\n}\n\nexport function formatErrorPayload(\n status: number,\n message: string,\n meta: { requestId?: string; method?: string; path?: string } = {},\n): ErrorPayload {\n const code = statusToCode(status);\n const requestId = meta.requestId ?? extractRequestId(message);\n return {\n error: true,\n status,\n code,\n message,\n ...(requestId ? { requestId } : {}),\n ...(meta.method ? { method: meta.method } : {}),\n ...(meta.path ? { path: meta.path } : {}),\n };\n}\n\nfunction statusToCode(status: number): string {\n if (status === 401) return \"UNAUTHORIZED\";\n if (status === 403) return \"FORBIDDEN\";\n if (status === 404) return \"NOT_FOUND\";\n if (status === 400) return \"BAD_REQUEST\";\n if (status === 429) return \"TOO_MANY_REQUESTS\";\n if (status >= 500) return \"SERVER_ERROR\";\n return \"ERROR\";\n}\n\n/**\n * Print result to stdout according to format. For list responses, pass the data array.\n * For single resource, pass the data object.\n */\nexport function printOutput(\n format: OutputFormat,\n data: unknown,\n isError = false,\n): void {\n if (format === \"json\") {\n const out = Array.isArray(data)\n ? { data }\n : typeof data === \"object\" && data !== null && \"data\" in data\n ? data\n : { data };\n console.log(JSON.stringify(out, null, 0));\n return;\n }\n if (format === \"table\") {\n printTable(data);\n return;\n }\n if (format === \"csv\") {\n printCsv(data);\n return;\n }\n console.log(JSON.stringify(data));\n}\n\nfunction getRows(data: unknown): Record<string, unknown>[] {\n if (Array.isArray(data)) return data as Record<string, unknown>[];\n if (typeof data === \"object\" && data !== null && \"data\" in data) {\n const d = (data as { data: unknown }).data;\n if (Array.isArray(d)) return d as Record<string, unknown>[];\n if (typeof d === \"object\" && d !== null) return [d as Record<string, unknown>];\n }\n if (typeof data === \"object\" && data !== null && !Array.isArray(data)) {\n return [data as Record<string, unknown>];\n }\n return [];\n}\n\nfunction getColumns(rows: Record<string, unknown>[]): string[] {\n const set = new Set<string>();\n for (const row of rows) {\n for (const k of Object.keys(row)) set.add(k);\n }\n return [...set].sort((a, b) => {\n const aIsId = a === \"_id\" || a === \"id\" || a.endsWith(\"Id\");\n const bIsId = b === \"_id\" || b === \"id\" || b.endsWith(\"Id\");\n if (aIsId !== bIsId) return aIsId ? 1 : -1;\n return a.localeCompare(b);\n });\n}\n\nfunction printTable(data: unknown): void {\n const rows = getRows(data);\n if (rows.length === 0) {\n console.log(\"(no data)\");\n return;\n }\n const cols = getColumns(rows);\n const widths = cols.map((c) => Math.max(c.length, 8));\n for (const row of rows) {\n for (let i = 0; i < cols.length; i++) {\n const col = cols[i]!;\n const val = row[col];\n const s = val === null || val === undefined ? \"\" : String(val);\n if (s.length > widths[i]!) widths[i] = Math.min(s.length, 40);\n }\n }\n const header = cols.map((c, i) => c.padEnd(widths[i]!)).join(\" \");\n console.log(header);\n console.log(cols.map((_, i) => \"-\".repeat(widths[i]!)).join(\" \"));\n for (const row of rows) {\n const line = cols\n .map((c, i) => {\n const val = row[c];\n const s = val === null || val === undefined ? \"\" : String(val);\n return s.slice(0, widths[i]!).padEnd(widths[i]!);\n })\n .join(\" \");\n console.log(line);\n }\n}\n\nfunction printCsv(data: unknown): void {\n const rows = getRows(data);\n if (rows.length === 0) {\n console.log(\"\");\n return;\n }\n const cols = getColumns(rows);\n const escape = (v: unknown): string => {\n const s = v === null || v === undefined ? \"\" : String(v);\n if (s.includes(\",\") || s.includes('\"') || s.includes(\"\\n\")) {\n return `\"${s.replace(/\"/g, '\"\"')}\"`;\n }\n return s;\n };\n console.log(cols.join(\",\"));\n for (const row of rows) {\n console.log(cols.map((c) => escape(row[c])).join(\",\"));\n }\n}\n\nexport function printStructuredError(format: OutputFormat, payload: ErrorPayload): void {\n if (format === \"json\") {\n console.error(JSON.stringify(payload));\n return;\n }\n console.error(`Error ${payload.status} (${payload.code}): ${payload.message}`);\n}\n\nfunction extractRequestId(message: string): string | undefined {\n const match = message.match(/\\(requestId: ([^)]+)\\)/);\n return match?.[1];\n}\n","import type { ApiResponse, RequestOptions } from \"./client.js\";\nimport { printOutput, type OutputFormat } from \"./output.js\";\n\nconst DEFAULT_PAGE_LIMIT = 100;\n\nexport interface FetchListOptions {\n path: string;\n token: string | null;\n baseUrl: string;\n query: Record<string, string | number | undefined>;\n all: boolean;\n request: <T = unknown>(options: RequestOptions) => Promise<ApiResponse<T>>;\n}\n\nexport interface PrintListOptions {\n format: OutputFormat;\n data: unknown[];\n fields?: string;\n where?: string;\n jsonl?: boolean;\n}\n\nexport async function fetchList(options: FetchListOptions): Promise<ApiResponse<{ data?: unknown[] }>> {\n if (!options.all) {\n return options.request<{ data?: unknown[] }>({\n method: \"GET\",\n path: options.path,\n token: options.token,\n baseUrl: options.baseUrl,\n query: options.query,\n });\n }\n\n const limit = parsePositiveInt(options.query.limit, DEFAULT_PAGE_LIMIT);\n let offset = parsePositiveInt(options.query.offset, 0);\n const data: unknown[] = [];\n\n for (;;) {\n const res = await options.request<{ data?: unknown[] }>({\n method: \"GET\",\n path: options.path,\n token: options.token,\n baseUrl: options.baseUrl,\n query: { ...options.query, limit, offset },\n });\n if (!res.ok) return res;\n\n const batch = Array.isArray(res.data?.data) ? res.data.data : [];\n data.push(...batch);\n if (batch.length < limit || batch.length === 0) break;\n offset += limit;\n }\n\n return { ok: true, status: 200, data: { data } };\n}\n\nexport function printList(options: PrintListOptions): void {\n const rows = projectRows(filterRows(options.data, options.where), options.fields);\n if (options.jsonl) {\n for (const row of rows) console.log(JSON.stringify(row));\n return;\n }\n printOutput(options.format, rows, false);\n}\n\nexport function filterRows(data: unknown[], where?: string): Record<string, unknown>[] {\n const rows = data.filter(isRecord);\n const filters = parseWhere(where);\n if (filters.length === 0) return rows;\n return rows.filter((row) =>\n filters.every(({ field, value }) => equalValue(row[field], value)),\n );\n}\n\nexport function projectRows(\n rows: Record<string, unknown>[],\n fields?: string,\n): Record<string, unknown>[] {\n const selected = parseFields(fields);\n if (selected.length === 0) return rows;\n return rows.map((row) => {\n const projected: Record<string, unknown> = {};\n for (const field of selected) projected[field] = row[field];\n return projected;\n });\n}\n\nfunction parseWhere(where?: string): Array<{ field: string; value: string }> {\n if (!where?.trim()) return [];\n return where\n .split(\",\")\n .map((part) => part.trim())\n .filter(Boolean)\n .map((part) => {\n const eq = part.indexOf(\"=\");\n if (eq === -1) return null;\n const field = part.slice(0, eq).trim();\n const value = part.slice(eq + 1).trim();\n return field ? { field, value } : null;\n })\n .filter((entry): entry is { field: string; value: string } => entry !== null);\n}\n\nfunction parseFields(fields?: string): string[] {\n if (!fields?.trim()) return [];\n return fields.split(\",\").map((field) => field.trim()).filter(Boolean);\n}\n\nfunction equalValue(actual: unknown, expected: string): boolean {\n if (actual == null) return expected === \"\";\n if (typeof actual === \"string\") {\n return actual.trim().toLowerCase() === expected.trim().toLowerCase();\n }\n return String(actual) === expected;\n}\n\nfunction parsePositiveInt(value: unknown, fallback: number): number {\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed < 1) return fallback;\n return parsed;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","type ExitWithError = (status: number, message: string) => never;\n\ntype PrimitiveKind = \"string\" | \"number\" | \"boolean\";\n\ninterface CoerceConfig {\n field: string;\n flag: string;\n kind: PrimitiveKind;\n allowNull?: boolean;\n allowDateTime?: boolean;\n}\n\nfunction fail(exitWithError: ExitWithError, message: string): never {\n return exitWithError(400, message);\n}\n\nfunction parseBoolean(\n raw: string,\n config: CoerceConfig,\n exitWithError: ExitWithError,\n): boolean {\n const value = raw.trim().toLowerCase();\n if ([\"true\", \"1\", \"yes\", \"y\", \"on\"].includes(value)) return true;\n if ([\"false\", \"0\", \"no\", \"n\", \"off\"].includes(value)) return false;\n return fail(\n exitWithError,\n `Invalid value for ${config.flag} (${config.field}): expected boolean but got \"${raw}\"`,\n );\n}\n\nfunction parseNumber(\n raw: string,\n config: CoerceConfig,\n exitWithError: ExitWithError,\n): number {\n const trimmed = raw.trim();\n const asNumber = Number(trimmed);\n if (Number.isFinite(asNumber)) return asNumber;\n\n if (config.allowDateTime) {\n const asDate = Date.parse(trimmed);\n if (Number.isFinite(asDate)) return asDate;\n }\n\n return fail(\n exitWithError,\n `Invalid value for ${config.flag} (${config.field}): expected number${config.allowDateTime ? \" or ISO datetime\" : \"\"} but got \"${raw}\"`,\n );\n}\n\nexport function coerceBodyFlag(\n raw: unknown,\n config: CoerceConfig,\n exitWithError: ExitWithError,\n): unknown {\n if (raw == null) return undefined;\n const value = String(raw);\n const trimmed = value.trim();\n\n if (config.allowNull && trimmed.toLowerCase() === \"null\") {\n return null;\n }\n\n if (config.kind === \"string\") return value;\n if (config.kind === \"boolean\") return parseBoolean(value, config, exitWithError);\n return parseNumber(value, config, exitWithError);\n}\n\nexport function coerceQueryFlag(\n raw: unknown,\n config: CoerceConfig,\n exitWithError: ExitWithError,\n): string | number {\n if (raw == null) {\n return fail(\n exitWithError,\n `Missing value for ${config.flag} (${config.field})`,\n );\n }\n\n const value = String(raw);\n if (config.kind === \"string\") return value;\n if (config.kind === \"boolean\") {\n return parseBoolean(value, config, exitWithError) ? \"true\" : \"false\";\n }\n return parseNumber(value, config, exitWithError);\n}\n","/**\n * Merge optional JSON body (from --body) with object built from flags.\n * Flags override keys in body when both are provided.\n */\nexport function mergeBody(\n bodyFromFlags: Record<string, unknown>,\n bodyOption: string | undefined,\n): Record<string, unknown> {\n let base: Record<string, unknown> = {};\n if (bodyOption?.trim()) {\n try {\n base = JSON.parse(bodyOption) as Record<string, unknown>;\n } catch {\n // ignore invalid JSON\n }\n }\n return { ...base, ...bodyFromFlags };\n}\n"],"mappings":"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","names":[]}
|