@koda-sl/baker-cli 0.254.0 → 0.254.1
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 +9 -0
- package/dist/{chunk-5JHSX3ZB.js → chunk-6F52WYB7.js} +2 -2
- package/dist/{chunk-JKSMLAQN.js → chunk-GU7IWEBC.js} +7 -3
- package/dist/chunk-GU7IWEBC.js.map +1 -0
- package/dist/{chunk-6MAVG6LO.js → chunk-KSOGK7SJ.js} +3 -3
- package/dist/cli.js +48 -14
- package/dist/cli.js.map +1 -1
- package/dist/{client-3TNO43FO.js → client-VDCCDEHE.js} +4 -2
- package/dist/{output-B3OCLLS5.js → output-JBYI5IVX.js} +3 -3
- package/dist/{shared-J24NXBW4.js → shared-GWFXJXKJ.js} +4 -4
- package/package.json +1 -1
- package/dist/chunk-JKSMLAQN.js.map +0 -1
- /package/dist/{chunk-5JHSX3ZB.js.map → chunk-6F52WYB7.js.map} +0 -0
- /package/dist/{chunk-6MAVG6LO.js.map → chunk-KSOGK7SJ.js.map} +0 -0
- /package/dist/{client-3TNO43FO.js.map → client-VDCCDEHE.js.map} +0 -0
- /package/dist/{output-B3OCLLS5.js.map → output-JBYI5IVX.js.map} +0 -0
- /package/dist/{shared-J24NXBW4.js.map → shared-GWFXJXKJ.js.map} +0 -0
package/README.md
CHANGED
|
@@ -2735,6 +2735,15 @@ When `list` or `search` returns nothing, the envelope carries `meta.empty` expla
|
|
|
2735
2735
|
|
|
2736
2736
|
If the source check itself fails, `meta.empty` is omitted entirely and the hint says so — an unverified absence is never reported as one.
|
|
2737
2737
|
|
|
2738
|
+
`list` is paged. `--limit` is the page size (default 50); when the library continues past the page you got, the envelope carries `meta.next_cursor` and a hint, and `meta.empty` is omitted — a page that is not the last page establishes nothing about the corpus. Read on with the same filters plus `--cursor`:
|
|
2739
|
+
|
|
2740
|
+
```bash
|
|
2741
|
+
baker testimonials list --sentiment positive --limit 50
|
|
2742
|
+
baker testimonials list --sentiment positive --limit 50 --cursor <meta.next_cursor>
|
|
2743
|
+
```
|
|
2744
|
+
|
|
2745
|
+
No `meta.next_cursor` means the library ended there.
|
|
2746
|
+
|
|
2738
2747
|
### `baker testimonials tags`
|
|
2739
2748
|
|
|
2740
2749
|
List the available testimonial tag names — built-in defaults plus the company's custom tags. Use it before filtering with `--tags`. Defaults to a markdown list (`--output json` for the `{ ok, data }` envelope).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ApiError,
|
|
3
3
|
apiGet
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-GU7IWEBC.js";
|
|
5
5
|
import {
|
|
6
6
|
getEnv
|
|
7
7
|
} from "./chunk-DZUVUGEP.js";
|
|
@@ -295,4 +295,4 @@ export {
|
|
|
295
295
|
writeAdsOutput,
|
|
296
296
|
resolveCustomerId
|
|
297
297
|
};
|
|
298
|
-
//# sourceMappingURL=chunk-
|
|
298
|
+
//# sourceMappingURL=chunk-6F52WYB7.js.map
|
|
@@ -110,7 +110,7 @@ async function handleResponse(response) {
|
|
|
110
110
|
throw new ApiError("INTERNAL_ERROR", "Failed to parse API response as JSON");
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
|
-
async function
|
|
113
|
+
async function apiGetWithHeaders(path, params) {
|
|
114
114
|
const env = getEnv();
|
|
115
115
|
const url = new URL(path, env.BAKER_API_URL);
|
|
116
116
|
if (params) {
|
|
@@ -148,7 +148,10 @@ async function apiGet(path, params) {
|
|
|
148
148
|
responseBody: await readBodyForLog(response),
|
|
149
149
|
durationMs: Date.now() - startedAt
|
|
150
150
|
});
|
|
151
|
-
return handleResponse(response);
|
|
151
|
+
return { data: await handleResponse(response), headers: response.headers };
|
|
152
|
+
}
|
|
153
|
+
async function apiGet(path, params) {
|
|
154
|
+
return (await apiGetWithHeaders(path, params)).data;
|
|
152
155
|
}
|
|
153
156
|
async function apiPost(path, body, opts) {
|
|
154
157
|
const env = getEnv();
|
|
@@ -198,7 +201,8 @@ async function apiPost(path, body, opts) {
|
|
|
198
201
|
export {
|
|
199
202
|
ApiError,
|
|
200
203
|
validateConvexId,
|
|
204
|
+
apiGetWithHeaders,
|
|
201
205
|
apiGet,
|
|
202
206
|
apiPost
|
|
203
207
|
};
|
|
204
|
-
//# sourceMappingURL=chunk-
|
|
208
|
+
//# sourceMappingURL=chunk-GU7IWEBC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"sourcesContent":["import { debugLogHttp, readBodyForLog } from \"./debugLog.ts\";\nimport { getEnv } from \"./env.ts\";\n\nconst MAX_RATE_LIMIT_RETRIES = 3;\nconst MAX_TOTAL_WAIT_MS = 2 * 60 * 1000;\n\nasync function fetchWithRateLimitRetry(url: string, init: RequestInit): Promise<Response> {\n let totalWaited = 0;\n\n for (let attempt = 0; attempt <= MAX_RATE_LIMIT_RETRIES; attempt++) {\n const response = await fetch(url, init);\n\n if (response.status !== 429 || attempt >= MAX_RATE_LIMIT_RETRIES) {\n return response;\n }\n\n const retryAfterHeader = response.headers.get(\"Retry-After\");\n const waitMs = retryAfterHeader ? Number(retryAfterHeader) * 1000 : 2000 * 2 ** attempt;\n\n if (totalWaited + waitMs > MAX_TOTAL_WAIT_MS) {\n return response;\n }\n\n totalWaited += waitMs;\n await new Promise((resolve) => setTimeout(resolve, waitMs));\n }\n\n return fetch(url, init);\n}\n\ntype ErrorCode =\n | \"UNAUTHORIZED\"\n | \"FORBIDDEN\"\n | \"NOT_FOUND\"\n | \"CONFLICT\"\n | \"VALIDATION_ERROR\"\n | \"RATE_LIMITED\"\n | \"INTERNAL_ERROR\"\n | \"NETWORK_ERROR\"\n | \"TIMEOUT\"\n | \"IMAGE_PROCESSING_ERROR\";\n\nexport class ApiError extends Error {\n code: ErrorCode;\n\n constructor(code: ErrorCode, message: string) {\n super(message);\n this.name = \"ApiError\";\n this.code = code;\n }\n}\n\nconst CONVEX_ID_RE = /^[a-zA-Z0-9_]+$/;\n\nfunction hasControlCharacters(value: string): boolean {\n for (let i = 0; i < value.length; i++) {\n const code = value.charCodeAt(i);\n // Allow tab (9), newline (10), carriage return (13)\n if (code < 32 && code !== 9 && code !== 10 && code !== 13) {\n return true;\n }\n }\n return false;\n}\n\nfunction validateStringValue(value: string): void {\n if (hasControlCharacters(value)) {\n throw new ApiError(\"VALIDATION_ERROR\", \"String value contains invalid control characters\");\n }\n}\n\nexport function validateConvexId(id: string): void {\n if (!CONVEX_ID_RE.test(id)) {\n throw new ApiError(\"VALIDATION_ERROR\", `Invalid ID format: \"${id}\". Expected alphanumeric string.`);\n }\n}\n\nfunction sanitizeParams(params: Record<string, string>): Record<string, string> {\n const sanitized: Record<string, string> = {};\n for (const [key, value] of Object.entries(params)) {\n validateStringValue(value);\n sanitized[key] = value;\n }\n return sanitized;\n}\n\n/**\n * Sent on every call so the backend can attribute immediately-applied writes\n * (library images and videos, followed advertisers) to the Session they were\n * made from. Absent outside a chat-attached environment.\n */\nfunction chatHeader(): Record<string, string> {\n const chatId = getEnv().BAKER_CHAT_ID;\n return chatId ? { \"x-baker-chat-id\": chatId } : {};\n}\n\nfunction mapHttpError(status: number): ErrorCode {\n if (status === 401) {\n return \"UNAUTHORIZED\";\n }\n // 403 is never \"not connected\" — every backend `FORBIDDEN` means connected but\n // not allowed (an asset outside the granted scope, a capability the account\n // lacks). Folding it into UNAUTHORIZED sent agents down the reconnect path,\n // which cannot fix a permission gap and wastes the user's time.\n if (status === 403) {\n return \"FORBIDDEN\";\n }\n if (status === 404) {\n return \"NOT_FOUND\";\n }\n if (status === 422 || status === 400) {\n return \"VALIDATION_ERROR\";\n }\n // 409 is a state the caller has to change, never a fault to sit out. It is\n // what the backend returns for \"this workspace has not switched analytics on\n // yet\" and its siblings — folded into INTERNAL_ERROR, that reaches an agent\n // as a transient failure worth retrying, which it never is.\n if (status === 409) {\n return \"CONFLICT\";\n }\n if (status === 429) {\n return \"RATE_LIMITED\";\n }\n return \"INTERNAL_ERROR\";\n}\n\nasync function handleResponse<T>(response: Response): Promise<T> {\n const body = await response.text();\n\n if (!response.ok) {\n let message = `HTTP ${response.status}: ${response.statusText}`;\n try {\n const parsed = JSON.parse(body) as { error?: string | { message?: string }; message?: string };\n if (typeof parsed.error === \"string\") {\n message = parsed.error;\n } else if (parsed.error?.message) {\n message = parsed.error.message;\n } else if (parsed.message) {\n message = parsed.message;\n }\n } catch {\n // Use default message\n }\n throw new ApiError(mapHttpError(response.status), message);\n }\n\n try {\n return JSON.parse(body) as T;\n } catch {\n throw new ApiError(\"INTERNAL_ERROR\", \"Failed to parse API response as JSON\");\n }\n}\n\n/**\n * A GET that also hands back the response headers.\n *\n * Some endpoints have to say something *about* the answer that the answer has\n * no room for — `GET /api/testimonials` returns a bare array and sets\n * `X-Baker-Next-Cursor` when rows past this page remain unexamined, so the rows\n * alone cannot tell one page of a library from the whole of it.\n */\nexport async function apiGetWithHeaders<T>(\n path: string,\n params?: Record<string, string>,\n): Promise<{ data: T; headers: Headers }> {\n const env = getEnv();\n const url = new URL(path, env.BAKER_API_URL);\n if (params) {\n const clean = sanitizeParams(params);\n for (const [key, value] of Object.entries(clean)) {\n url.searchParams.set(key, value);\n }\n }\n\n const urlStr = url.toString();\n const startedAt = Date.now();\n let response: Response;\n try {\n response = await fetchWithRateLimitRetry(urlStr, {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${env.BAKER_API_KEY}`,\n Accept: \"application/json\",\n ...chatHeader(),\n },\n signal: AbortSignal.timeout(60_000),\n });\n } catch (err) {\n debugLogHttp({ source: \"cli\", method: \"GET\", url: urlStr, durationMs: Date.now() - startedAt, error: err });\n if (err instanceof Error && (err.name === \"TimeoutError\" || err.name === \"AbortError\")) {\n throw new ApiError(\"TIMEOUT\", \"Request timed out after 60 seconds\");\n }\n throw new ApiError(\"NETWORK_ERROR\", `Request failed: ${err instanceof Error ? err.message : \"Unknown error\"}`);\n }\n\n debugLogHttp({\n source: \"cli\",\n method: \"GET\",\n url: urlStr,\n status: response.status,\n ok: response.ok,\n responseBody: await readBodyForLog(response),\n durationMs: Date.now() - startedAt,\n });\n return { data: await handleResponse<T>(response), headers: response.headers };\n}\n\nexport async function apiGet<T>(path: string, params?: Record<string, string>): Promise<T> {\n return (await apiGetWithHeaders<T>(path, params)).data;\n}\n\nexport async function apiPost<T>(path: string, body: unknown, opts?: { timeoutMs?: number }): Promise<T> {\n const env = getEnv();\n const timeoutMs = opts?.timeoutMs ?? 60_000;\n const urlStr = new URL(path, env.BAKER_API_URL).toString();\n const startedAt = Date.now();\n let response: Response;\n try {\n response = await fetchWithRateLimitRetry(urlStr, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${env.BAKER_API_KEY}`,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...chatHeader(),\n },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(timeoutMs),\n });\n } catch (err) {\n debugLogHttp({\n source: \"cli\",\n method: \"POST\",\n url: urlStr,\n requestBody: body,\n durationMs: Date.now() - startedAt,\n error: err,\n });\n if (err instanceof Error && (err.name === \"TimeoutError\" || err.name === \"AbortError\")) {\n throw new ApiError(\"TIMEOUT\", `Request timed out after ${Math.round(timeoutMs / 1000)} seconds`);\n }\n throw new ApiError(\"NETWORK_ERROR\", `Request failed: ${err instanceof Error ? err.message : \"Unknown error\"}`);\n }\n\n debugLogHttp({\n source: \"cli\",\n method: \"POST\",\n url: urlStr,\n requestBody: body,\n status: response.status,\n ok: response.ok,\n responseBody: await readBodyForLog(response),\n durationMs: Date.now() - startedAt,\n });\n return handleResponse<T>(response);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
handleConnectionError,
|
|
3
3
|
needsConnectionFix,
|
|
4
4
|
writeAdsJson
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-6F52WYB7.js";
|
|
6
6
|
import {
|
|
7
7
|
ApiError
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-GU7IWEBC.js";
|
|
9
9
|
import {
|
|
10
10
|
getEnv
|
|
11
11
|
} from "./chunk-DZUVUGEP.js";
|
|
@@ -108,4 +108,4 @@ export {
|
|
|
108
108
|
csvOrJson,
|
|
109
109
|
resolveEffectiveStatus
|
|
110
110
|
};
|
|
111
|
-
//# sourceMappingURL=chunk-
|
|
111
|
+
//# sourceMappingURL=chunk-KSOGK7SJ.js.map
|
package/dist/cli.js
CHANGED
|
@@ -67,7 +67,7 @@ import {
|
|
|
67
67
|
resolveAccountIdArg,
|
|
68
68
|
resolveEffectiveStatus,
|
|
69
69
|
todayIso
|
|
70
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-KSOGK7SJ.js";
|
|
71
71
|
import {
|
|
72
72
|
buildQueryCacheKey,
|
|
73
73
|
cacheGet,
|
|
@@ -83,13 +83,14 @@ import {
|
|
|
83
83
|
writeAdsJson,
|
|
84
84
|
writeAdsOutput,
|
|
85
85
|
writeJsonEnvelope
|
|
86
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-6F52WYB7.js";
|
|
87
87
|
import {
|
|
88
88
|
ApiError,
|
|
89
89
|
apiGet,
|
|
90
|
+
apiGetWithHeaders,
|
|
90
91
|
apiPost,
|
|
91
92
|
validateConvexId
|
|
92
|
-
} from "./chunk-
|
|
93
|
+
} from "./chunk-GU7IWEBC.js";
|
|
93
94
|
import {
|
|
94
95
|
installStreamTaps,
|
|
95
96
|
logInvocation
|
|
@@ -6183,7 +6184,10 @@ var testimonialsListRequestSchema = z20.object({
|
|
|
6183
6184
|
status: testimonialStatusSchema.optional(),
|
|
6184
6185
|
sentiment: testimonialSentimentSchema.optional(),
|
|
6185
6186
|
language: z20.string().min(2).max(5).optional(),
|
|
6186
|
-
limit: z20.coerce.number().int().positive().max(200).optional()
|
|
6187
|
+
limit: z20.coerce.number().int().positive().max(200).optional(),
|
|
6188
|
+
// Opaque, from the previous response's `X-Baker-Next-Cursor`. Absent on the
|
|
6189
|
+
// first page; its absence on a response means the corpus is exhausted.
|
|
6190
|
+
cursor: z20.string().optional()
|
|
6187
6191
|
});
|
|
6188
6192
|
var testimonialsListResponseSchema = z20.array(testimonialDocSchema);
|
|
6189
6193
|
var testimonialsGetRequestSchema = z20.object({ id: z20.string().min(1, "Missing id parameter") });
|
|
@@ -21014,10 +21018,10 @@ function duplicateCommand2(entity, label) {
|
|
|
21014
21018
|
replace: { type: "boolean", description: "Pause the original once the copy publishes" }
|
|
21015
21019
|
},
|
|
21016
21020
|
run: async ({ args }) => {
|
|
21017
|
-
const { apiPost: apiPost2 } = await import("./client-
|
|
21021
|
+
const { apiPost: apiPost2 } = await import("./client-VDCCDEHE.js");
|
|
21018
21022
|
const { requireChatId: requireChatId2 } = await import("./env-FWMZXMQK.js");
|
|
21019
|
-
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-
|
|
21020
|
-
const { handleMetaError: handleMetaError2 } = await import("./shared-
|
|
21023
|
+
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-JBYI5IVX.js");
|
|
21024
|
+
const { handleMetaError: handleMetaError2 } = await import("./shared-GWFXJXKJ.js");
|
|
21021
21025
|
try {
|
|
21022
21026
|
const accountId = bareAccountId2(args);
|
|
21023
21027
|
const chatId = requireChatId2();
|
|
@@ -50105,14 +50109,30 @@ function emptyReasonDetail(reason, sourceCount, activeFilters) {
|
|
|
50105
50109
|
}
|
|
50106
50110
|
return `${sourceCount} review source${sourceCount === 1 ? " is" : "s are"} connected but hold no testimonials yet \u2014 the source is there, the rows are not. Ingestion may still be running.`;
|
|
50107
50111
|
}
|
|
50112
|
+
function morePagesHint(resultCount, cursor) {
|
|
50113
|
+
const found = resultCount === 0 ? "This page held no matches" : `This page held ${resultCount}`;
|
|
50114
|
+
return `${found}, and the library continues past it \u2014 so this is one page, not the client's whole set. Do not report it as the corpus and do not conclude anything is missing from it. Read the next page with \`baker testimonials list --cursor ${cursor}\` (same filters), or go straight at the rows you want with \`baker testimonials search <query>\`.`;
|
|
50115
|
+
}
|
|
50116
|
+
function endOfWalkHint(command) {
|
|
50117
|
+
const noun = command === "search" ? "results" : "rows";
|
|
50118
|
+
return `That was the end of the library \u2014 no more ${noun} past the page before this one. Nothing here says the corpus is empty (the earlier pages held it), so answer from what those pages returned rather than re-reading.`;
|
|
50119
|
+
}
|
|
50108
50120
|
async function measureEmptyCorpus({
|
|
50109
50121
|
command,
|
|
50110
50122
|
resultCount,
|
|
50111
|
-
activeFilters
|
|
50123
|
+
activeFilters,
|
|
50124
|
+
nextCursor = null,
|
|
50125
|
+
continued = false
|
|
50112
50126
|
}) {
|
|
50127
|
+
if (nextCursor) {
|
|
50128
|
+
return { hints: [morePagesHint(resultCount, nextCursor)] };
|
|
50129
|
+
}
|
|
50113
50130
|
if (resultCount > 0) {
|
|
50114
50131
|
return { hints: [] };
|
|
50115
50132
|
}
|
|
50133
|
+
if (continued) {
|
|
50134
|
+
return { hints: [endOfWalkHint(command)] };
|
|
50135
|
+
}
|
|
50116
50136
|
if (activeFilters.length > 0) {
|
|
50117
50137
|
const reason2 = "filtered_out";
|
|
50118
50138
|
return {
|
|
@@ -50191,7 +50211,12 @@ registerSchema({
|
|
|
50191
50211
|
},
|
|
50192
50212
|
language: { type: "string", description: "Filter by language code (e.g. en, es)", required: false },
|
|
50193
50213
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false },
|
|
50194
|
-
limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
|
|
50214
|
+
limit: { type: "number", description: "Max results per page (default 50)", required: false, default: 50 },
|
|
50215
|
+
cursor: {
|
|
50216
|
+
type: "string",
|
|
50217
|
+
description: "Read the next page: pass meta.next_cursor from the previous call, with the same filters.",
|
|
50218
|
+
required: false
|
|
50219
|
+
}
|
|
50195
50220
|
}
|
|
50196
50221
|
});
|
|
50197
50222
|
var PARAM_NAMES = {
|
|
@@ -50202,7 +50227,8 @@ var PARAM_NAMES = {
|
|
|
50202
50227
|
sentiment: "sentiment",
|
|
50203
50228
|
language: "language",
|
|
50204
50229
|
tags: "tags",
|
|
50205
|
-
limit: "limit"
|
|
50230
|
+
limit: "limit",
|
|
50231
|
+
cursor: "cursor"
|
|
50206
50232
|
};
|
|
50207
50233
|
function buildListParams(args) {
|
|
50208
50234
|
const params = {};
|
|
@@ -50227,22 +50253,30 @@ var listCommand18 = defineCommand205({
|
|
|
50227
50253
|
sentiment: { type: "string", description: "Filter: positive|neutral|negative", required: false },
|
|
50228
50254
|
language: { type: "string", description: "Filter by language code (e.g. en, es)", required: false },
|
|
50229
50255
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false },
|
|
50230
|
-
limit: { type: "string", description: "Max results (default 50)", required: false },
|
|
50256
|
+
limit: { type: "string", description: "Max results per page (default 50)", required: false },
|
|
50257
|
+
cursor: { type: "string", description: "meta.next_cursor from the previous page", required: false },
|
|
50231
50258
|
output: { type: "string", description: "Output format: json|files|md", required: false, default: "json" },
|
|
50232
50259
|
fields: { type: "string", description: "Comma-separated field names to include", required: false },
|
|
50233
50260
|
full: { type: "boolean", description: "Include full metadata", required: false, default: false }
|
|
50234
50261
|
},
|
|
50235
50262
|
run: async ({ args }) => {
|
|
50236
50263
|
try {
|
|
50237
|
-
const data = await
|
|
50264
|
+
const { data, headers } = await apiGetWithHeaders(
|
|
50265
|
+
"/api/testimonials",
|
|
50266
|
+
buildListParams(args)
|
|
50267
|
+
);
|
|
50268
|
+
const nextCursor = headers.get("x-baker-next-cursor");
|
|
50238
50269
|
const { hints: hints2, empty } = await measureEmptyCorpus({
|
|
50239
50270
|
command: "list",
|
|
50240
50271
|
resultCount: data.length,
|
|
50241
|
-
activeFilters: activeFilterFlags(args, FILTER_FLAGS)
|
|
50272
|
+
activeFilters: activeFilterFlags(args, FILTER_FLAGS),
|
|
50273
|
+
nextCursor,
|
|
50274
|
+
continued: Boolean(args.cursor)
|
|
50242
50275
|
});
|
|
50243
50276
|
const outputFormat = args.output || "json";
|
|
50277
|
+
const meta = { ...empty ? { empty } : {}, ...nextCursor ? { next_cursor: nextCursor } : {} };
|
|
50244
50278
|
writeOutput(
|
|
50245
|
-
{ ok: true, data, ...
|
|
50279
|
+
{ ok: true, data, ...Object.keys(meta).length > 0 ? { meta } : {}, ...hints2.length > 0 ? { hints: hints2 } : {} },
|
|
50246
50280
|
outputFormat,
|
|
50247
50281
|
args.fields ? args.fields.split(",") : void 0,
|
|
50248
50282
|
args.full,
|