@semilayer/cli 1.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/auth-config-3MWVCUTJ.js +117 -0
- package/dist/auth-config-3MWVCUTJ.js.map +1 -0
- package/dist/billing-OY5GJP5X.js +265 -0
- package/dist/billing-OY5GJP5X.js.map +1 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +49 -0
- package/dist/bin.js.map +1 -0
- package/dist/chunk-7TA63VHV.js +38 -0
- package/dist/chunk-7TA63VHV.js.map +1 -0
- package/dist/chunk-ALA4X7UU.js +19 -0
- package/dist/chunk-ALA4X7UU.js.map +1 -0
- package/dist/chunk-NIDLPHWY.js +53 -0
- package/dist/chunk-NIDLPHWY.js.map +1 -0
- package/dist/chunk-QMF7LD67.js +39 -0
- package/dist/chunk-QMF7LD67.js.map +1 -0
- package/dist/chunk-QXIVJY7K.js +56 -0
- package/dist/chunk-QXIVJY7K.js.map +1 -0
- package/dist/chunk-T3UROBMA.js +169 -0
- package/dist/chunk-T3UROBMA.js.map +1 -0
- package/dist/chunk-WZYOSGN3.js +88 -0
- package/dist/chunk-WZYOSGN3.js.map +1 -0
- package/dist/config-DACYO7JC.js +103 -0
- package/dist/config-DACYO7JC.js.map +1 -0
- package/dist/dev-R3AZSONQ.js +57 -0
- package/dist/dev-R3AZSONQ.js.map +1 -0
- package/dist/envs-RNZQ3OQP.js +105 -0
- package/dist/envs-RNZQ3OQP.js.map +1 -0
- package/dist/export-YRFR3JH2.js +81 -0
- package/dist/export-YRFR3JH2.js.map +1 -0
- package/dist/generate-QUETX3TN.js +41 -0
- package/dist/generate-QUETX3TN.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/init-TWJAGUN3.js +187 -0
- package/dist/init-TWJAGUN3.js.map +1 -0
- package/dist/keys-JBKCYKJU.js +111 -0
- package/dist/keys-JBKCYKJU.js.map +1 -0
- package/dist/lenses-VZSDFH3D.js +51 -0
- package/dist/lenses-VZSDFH3D.js.map +1 -0
- package/dist/login-BZ6ZPFHC.js +119 -0
- package/dist/login-BZ6ZPFHC.js.map +1 -0
- package/dist/logout-VMPRV62T.js +38 -0
- package/dist/logout-VMPRV62T.js.map +1 -0
- package/dist/members-DVE5FDLZ.js +110 -0
- package/dist/members-DVE5FDLZ.js.map +1 -0
- package/dist/observe-W346RZBX.js +149 -0
- package/dist/observe-W346RZBX.js.map +1 -0
- package/dist/orgs-YA3TVA3T.js +67 -0
- package/dist/orgs-YA3TVA3T.js.map +1 -0
- package/dist/pause-GQ6PKBUA.js +50 -0
- package/dist/pause-GQ6PKBUA.js.map +1 -0
- package/dist/projects-DMA2AXH3.js +107 -0
- package/dist/projects-DMA2AXH3.js.map +1 -0
- package/dist/push-3ZK3W2AC.js +145 -0
- package/dist/push-3ZK3W2AC.js.map +1 -0
- package/dist/resume-KVRPLXZZ.js +50 -0
- package/dist/resume-KVRPLXZZ.js.map +1 -0
- package/dist/run-IR5B4AE3.js +375 -0
- package/dist/run-IR5B4AE3.js.map +1 -0
- package/dist/sources-S52HUWRK.js +170 -0
- package/dist/sources-S52HUWRK.js.map +1 -0
- package/dist/status-AUECH6RX.js +130 -0
- package/dist/status-AUECH6RX.js.map +1 -0
- package/dist/stream-V7RGHTPR.js +344 -0
- package/dist/stream-V7RGHTPR.js.map +1 -0
- package/dist/sync-NRTC3WX4.js +68 -0
- package/dist/sync-NRTC3WX4.js.map +1 -0
- package/dist/whoami-EQGW6V5D.js +50 -0
- package/dist/whoami-EQGW6V5D.js.map +1 -0
- package/dist/wizard-QLAR33T2.js +306 -0
- package/dist/wizard-QLAR33T2.js.map +1 -0
- package/package.json +40 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
loadContext
|
|
4
|
+
} from "./chunk-QMF7LD67.js";
|
|
5
|
+
import {
|
|
6
|
+
createApiClient
|
|
7
|
+
} from "./chunk-T3UROBMA.js";
|
|
8
|
+
import "./chunk-7TA63VHV.js";
|
|
9
|
+
import {
|
|
10
|
+
bold,
|
|
11
|
+
dim,
|
|
12
|
+
error,
|
|
13
|
+
label,
|
|
14
|
+
newline,
|
|
15
|
+
table,
|
|
16
|
+
usageBar
|
|
17
|
+
} from "./chunk-WZYOSGN3.js";
|
|
18
|
+
|
|
19
|
+
// src/commands/status.ts
|
|
20
|
+
import { defineCommand } from "citty";
|
|
21
|
+
function formatCount(n) {
|
|
22
|
+
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
23
|
+
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}k`;
|
|
24
|
+
return String(n);
|
|
25
|
+
}
|
|
26
|
+
var status_default = defineCommand({
|
|
27
|
+
meta: { name: "status", description: "Show lens statuses and queue info" },
|
|
28
|
+
async run() {
|
|
29
|
+
try {
|
|
30
|
+
const ctx = await loadContext();
|
|
31
|
+
if (!ctx) {
|
|
32
|
+
error("No .semilayerrc found. Run `semilayer init` first.");
|
|
33
|
+
process.exitCode = 1;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const api = await createApiClient();
|
|
37
|
+
const params = new URLSearchParams({
|
|
38
|
+
orgSlug: ctx.orgSlug,
|
|
39
|
+
projectSlug: ctx.projectSlug,
|
|
40
|
+
envSlug: ctx.envSlug
|
|
41
|
+
});
|
|
42
|
+
const data = await api.get(`/v1/status?${params}`);
|
|
43
|
+
newline();
|
|
44
|
+
label(
|
|
45
|
+
"Environment",
|
|
46
|
+
`${data.environment.slug} ${dim(`(${data.environment.project} / ${data.environment.org})`)}`
|
|
47
|
+
);
|
|
48
|
+
newline();
|
|
49
|
+
if (data.lenses.length > 0) {
|
|
50
|
+
console.log(` ${bold("Lenses:")}`);
|
|
51
|
+
table(
|
|
52
|
+
data.lenses.map((l) => [
|
|
53
|
+
` ${l.name ?? "?"}`,
|
|
54
|
+
statusBadge(l.status),
|
|
55
|
+
`${formatCount(l.vectorCount)} vectors`,
|
|
56
|
+
l.errorCount > 0 ? `${l.errorCount} errors` : ""
|
|
57
|
+
])
|
|
58
|
+
);
|
|
59
|
+
} else {
|
|
60
|
+
console.log(` ${dim("No lenses configured")}`);
|
|
61
|
+
}
|
|
62
|
+
newline();
|
|
63
|
+
const q = data.queue;
|
|
64
|
+
console.log(` ${bold("Queue:")}`);
|
|
65
|
+
console.log(
|
|
66
|
+
` Active: ${q.active} Pending: ${q.pending} Failed: ${q.failed} Completed (24h): ${q.completed24h}`
|
|
67
|
+
);
|
|
68
|
+
newline();
|
|
69
|
+
try {
|
|
70
|
+
const me = await api.get("/auth/me");
|
|
71
|
+
if (me.deploymentMode === "saas") {
|
|
72
|
+
const billing = await api.get(
|
|
73
|
+
`/v1/orgs/${ctx.orgSlug}/billing`
|
|
74
|
+
);
|
|
75
|
+
console.log(` ${bold("Quotas:")} ${dim(`(${billing.plan?.tierName ?? "Free"})`)}`);
|
|
76
|
+
const order = [
|
|
77
|
+
["embedding_tokens", "Embedding tokens"],
|
|
78
|
+
["api_requests", "API requests"],
|
|
79
|
+
["vectors_stored", "Vectors stored"],
|
|
80
|
+
["ingest_jobs", "Ingest jobs"]
|
|
81
|
+
];
|
|
82
|
+
for (const [key, label_] of order) {
|
|
83
|
+
const m = billing.usage[key];
|
|
84
|
+
if (!m) continue;
|
|
85
|
+
console.log(` ${label_.padEnd(18)} ${usageBar(m.current, m.limit, 24)}`);
|
|
86
|
+
}
|
|
87
|
+
newline();
|
|
88
|
+
const streamingOrder = [
|
|
89
|
+
["concurrent_ws_connections", "WS connections"],
|
|
90
|
+
["ws_live_subscriptions", "Live subs"],
|
|
91
|
+
["ws_rows_per_hour", "Rows / hr"],
|
|
92
|
+
["ws_ops_per_minute", "Ops / min"]
|
|
93
|
+
];
|
|
94
|
+
const hasStreaming = streamingOrder.some(([k]) => billing.usage[k]);
|
|
95
|
+
if (hasStreaming) {
|
|
96
|
+
console.log(` ${bold("Streaming:")} ${dim("(per-pod snapshot)")}`);
|
|
97
|
+
for (const [key, label_] of streamingOrder) {
|
|
98
|
+
const m = billing.usage[key];
|
|
99
|
+
if (!m) continue;
|
|
100
|
+
console.log(` ${label_.padEnd(18)} ${usageBar(m.current, m.limit, 24)}`);
|
|
101
|
+
}
|
|
102
|
+
newline();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
} catch {
|
|
106
|
+
}
|
|
107
|
+
} catch (err) {
|
|
108
|
+
error(err.message);
|
|
109
|
+
process.exitCode = 1;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
function statusBadge(status) {
|
|
114
|
+
switch (status) {
|
|
115
|
+
case "ready":
|
|
116
|
+
return "\x1B[32mready\x1B[39m";
|
|
117
|
+
case "indexing":
|
|
118
|
+
return "\x1B[34mindexing\x1B[39m";
|
|
119
|
+
case "paused":
|
|
120
|
+
return "\x1B[33mpaused\x1B[39m";
|
|
121
|
+
case "error":
|
|
122
|
+
return "\x1B[31merror\x1B[39m";
|
|
123
|
+
default:
|
|
124
|
+
return status;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
export {
|
|
128
|
+
status_default as default
|
|
129
|
+
};
|
|
130
|
+
//# sourceMappingURL=status-AUECH6RX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/status.ts"],"sourcesContent":["import { defineCommand } from 'citty'\nimport type { StatusResponse, BillingSnapshot, MeResponse } from '@semilayer/core'\nimport { loadContext } from '../lib/context.js'\nimport { createApiClient } from '../lib/api.js'\nimport { error, bold, dim, newline, table, label, usageBar } from '../lib/output.js'\n\nfunction formatCount(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`\n if (n >= 1_000) return `${(n / 1_000).toFixed(1)}k`\n return String(n)\n}\n\nexport default defineCommand({\n meta: { name: 'status', description: 'Show lens statuses and queue info' },\n async run() {\n try {\n const ctx = await loadContext()\n if (!ctx) {\n error('No .semilayerrc found. Run `semilayer init` first.')\n process.exitCode = 1\n return\n }\n\n const api = await createApiClient()\n const params = new URLSearchParams({\n orgSlug: ctx.orgSlug,\n projectSlug: ctx.projectSlug,\n envSlug: ctx.envSlug,\n })\n const data = await api.get<StatusResponse>(`/v1/status?${params}`)\n\n newline()\n label(\n 'Environment',\n `${data.environment.slug} ${dim(`(${data.environment.project} / ${data.environment.org})`)}`,\n )\n newline()\n\n // Lenses table\n if (data.lenses.length > 0) {\n console.log(` ${bold('Lenses:')}`)\n table(\n data.lenses.map((l) => [\n ` ${l.name ?? '?'}`,\n statusBadge(l.status),\n `${formatCount(l.vectorCount)} vectors`,\n l.errorCount > 0 ? `${l.errorCount} errors` : '',\n ]),\n )\n } else {\n console.log(` ${dim('No lenses configured')}`)\n }\n\n newline()\n\n // Queue summary\n const q = data.queue\n console.log(` ${bold('Queue:')}`)\n console.log(\n ` Active: ${q.active} Pending: ${q.pending} Failed: ${q.failed} Completed (24h): ${q.completed24h}`,\n )\n newline()\n\n // Step 12 — Quotas (SaaS only). Best-effort: skip silently in\n // enterprise mode or when the billing endpoint isn't reachable.\n try {\n const me = await api.get<MeResponse>('/auth/me')\n if (me.deploymentMode === 'saas') {\n const billing = await api.get<BillingSnapshot>(\n `/v1/orgs/${ctx.orgSlug}/billing`,\n )\n console.log(` ${bold('Quotas:')} ${dim(`(${billing.plan?.tierName ?? 'Free'})`)}`)\n const order: Array<[string, string]> = [\n ['embedding_tokens', 'Embedding tokens'],\n ['api_requests', 'API requests'],\n ['vectors_stored', 'Vectors stored'],\n ['ingest_jobs', 'Ingest jobs'],\n ]\n for (const [key, label_] of order) {\n const m = billing.usage[key]\n if (!m) continue\n console.log(` ${label_.padEnd(18)} ${usageBar(m.current, m.limit, 24)}`)\n }\n newline()\n\n // Streaming — only show if at least one streaming metric exists in\n // the snapshot. Per-pod values from this pod, so they're a rough\n // \"current load\" rather than a cluster-wide total.\n const streamingOrder: Array<[string, string]> = [\n ['concurrent_ws_connections', 'WS connections'],\n ['ws_live_subscriptions', 'Live subs'],\n ['ws_rows_per_hour', 'Rows / hr'],\n ['ws_ops_per_minute', 'Ops / min'],\n ]\n const hasStreaming = streamingOrder.some(([k]) => billing.usage[k])\n if (hasStreaming) {\n console.log(` ${bold('Streaming:')} ${dim('(per-pod snapshot)')}`)\n for (const [key, label_] of streamingOrder) {\n const m = billing.usage[key]\n if (!m) continue\n console.log(` ${label_.padEnd(18)} ${usageBar(m.current, m.limit, 24)}`)\n }\n newline()\n }\n }\n } catch {\n // ignore — quota display is non-essential\n }\n } catch (err) {\n error((err as Error).message)\n process.exitCode = 1\n }\n },\n})\n\nfunction statusBadge(status: string): string {\n switch (status) {\n case 'ready':\n return '\\x1b[32mready\\x1b[39m'\n case 'indexing':\n return '\\x1b[34mindexing\\x1b[39m'\n case 'paused':\n return '\\x1b[33mpaused\\x1b[39m'\n case 'error':\n return '\\x1b[31merror\\x1b[39m'\n default:\n return status\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA,SAAS,qBAAqB;AAM9B,SAAS,YAAY,GAAmB;AACtC,MAAI,KAAK,IAAW,QAAO,IAAI,IAAI,KAAW,QAAQ,CAAC,CAAC;AACxD,MAAI,KAAK,IAAO,QAAO,IAAI,IAAI,KAAO,QAAQ,CAAC,CAAC;AAChD,SAAO,OAAO,CAAC;AACjB;AAEA,IAAO,iBAAQ,cAAc;AAAA,EAC3B,MAAM,EAAE,MAAM,UAAU,aAAa,oCAAoC;AAAA,EACzE,MAAM,MAAM;AACV,QAAI;AACF,YAAM,MAAM,MAAM,YAAY;AAC9B,UAAI,CAAC,KAAK;AACR,cAAM,oDAAoD;AAC1D,gBAAQ,WAAW;AACnB;AAAA,MACF;AAEA,YAAM,MAAM,MAAM,gBAAgB;AAClC,YAAM,SAAS,IAAI,gBAAgB;AAAA,QACjC,SAAS,IAAI;AAAA,QACb,aAAa,IAAI;AAAA,QACjB,SAAS,IAAI;AAAA,MACf,CAAC;AACD,YAAM,OAAO,MAAM,IAAI,IAAoB,cAAc,MAAM,EAAE;AAEjE,cAAQ;AACR;AAAA,QACE;AAAA,QACA,GAAG,KAAK,YAAY,IAAI,IAAI,IAAI,IAAI,KAAK,YAAY,OAAO,MAAM,KAAK,YAAY,GAAG,GAAG,CAAC;AAAA,MAC5F;AACA,cAAQ;AAGR,UAAI,KAAK,OAAO,SAAS,GAAG;AAC1B,gBAAQ,IAAI,KAAK,KAAK,SAAS,CAAC,EAAE;AAClC;AAAA,UACE,KAAK,OAAO,IAAI,CAAC,MAAM;AAAA,YACrB,OAAO,EAAE,QAAQ,GAAG;AAAA,YACpB,YAAY,EAAE,MAAM;AAAA,YACpB,GAAG,YAAY,EAAE,WAAW,CAAC;AAAA,YAC7B,EAAE,aAAa,IAAI,GAAG,EAAE,UAAU,YAAY;AAAA,UAChD,CAAC;AAAA,QACH;AAAA,MACF,OAAO;AACL,gBAAQ,IAAI,KAAK,IAAI,sBAAsB,CAAC,EAAE;AAAA,MAChD;AAEA,cAAQ;AAGR,YAAM,IAAI,KAAK;AACf,cAAQ,IAAI,KAAK,KAAK,QAAQ,CAAC,EAAE;AACjC,cAAQ;AAAA,QACN,eAAe,EAAE,MAAM,cAAc,EAAE,OAAO,aAAa,EAAE,MAAM,sBAAsB,EAAE,YAAY;AAAA,MACzG;AACA,cAAQ;AAIR,UAAI;AACF,cAAM,KAAK,MAAM,IAAI,IAAgB,UAAU;AAC/C,YAAI,GAAG,mBAAmB,QAAQ;AAChC,gBAAM,UAAU,MAAM,IAAI;AAAA,YACxB,YAAY,IAAI,OAAO;AAAA,UACzB;AACA,kBAAQ,IAAI,KAAK,KAAK,SAAS,CAAC,KAAK,IAAI,IAAI,QAAQ,MAAM,YAAY,MAAM,GAAG,CAAC,EAAE;AACnF,gBAAM,QAAiC;AAAA,YACrC,CAAC,oBAAoB,kBAAkB;AAAA,YACvC,CAAC,gBAAgB,cAAc;AAAA,YAC/B,CAAC,kBAAkB,gBAAgB;AAAA,YACnC,CAAC,eAAe,aAAa;AAAA,UAC/B;AACA,qBAAW,CAAC,KAAK,MAAM,KAAK,OAAO;AACjC,kBAAM,IAAI,QAAQ,MAAM,GAAG;AAC3B,gBAAI,CAAC,EAAG;AACR,oBAAQ,IAAI,OAAO,OAAO,OAAO,EAAE,CAAC,IAAI,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;AAAA,UAC5E;AACA,kBAAQ;AAKR,gBAAM,iBAA0C;AAAA,YAC9C,CAAC,6BAA6B,gBAAgB;AAAA,YAC9C,CAAC,yBAAyB,WAAW;AAAA,YACrC,CAAC,oBAAoB,WAAW;AAAA,YAChC,CAAC,qBAAqB,WAAW;AAAA,UACnC;AACA,gBAAM,eAAe,eAAe,KAAK,CAAC,CAAC,CAAC,MAAM,QAAQ,MAAM,CAAC,CAAC;AAClE,cAAI,cAAc;AAChB,oBAAQ,IAAI,KAAK,KAAK,YAAY,CAAC,KAAK,IAAI,oBAAoB,CAAC,EAAE;AACnE,uBAAW,CAAC,KAAK,MAAM,KAAK,gBAAgB;AAC1C,oBAAM,IAAI,QAAQ,MAAM,GAAG;AAC3B,kBAAI,CAAC,EAAG;AACR,sBAAQ,IAAI,OAAO,OAAO,OAAO,EAAE,CAAC,IAAI,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;AAAA,YAC5E;AACA,oBAAQ;AAAA,UACV;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF,SAAS,KAAK;AACZ,YAAO,IAAc,OAAO;AAC5B,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF;AACF,CAAC;AAED,SAAS,YAAY,QAAwB;AAC3C,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;","names":[]}
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
loadContext
|
|
4
|
+
} from "./chunk-QMF7LD67.js";
|
|
5
|
+
import {
|
|
6
|
+
bold,
|
|
7
|
+
dim,
|
|
8
|
+
error,
|
|
9
|
+
info,
|
|
10
|
+
label,
|
|
11
|
+
newline
|
|
12
|
+
} from "./chunk-WZYOSGN3.js";
|
|
13
|
+
|
|
14
|
+
// src/commands/stream.ts
|
|
15
|
+
import { defineCommand } from "citty";
|
|
16
|
+
import { BeamClient, BeamStreamError, BeamStreamRateLimitError, BeamStreamClosedError } from "@semilayer/client";
|
|
17
|
+
function isApiKey(value) {
|
|
18
|
+
return value.startsWith("sk_") || value.startsWith("pk_") || value.startsWith("ik_");
|
|
19
|
+
}
|
|
20
|
+
async function buildClient(apiKeyFlag, userTokenFlag) {
|
|
21
|
+
if (!apiKeyFlag) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
"Streaming commands require --api-key (sk_* or pk_*). JWT mode via Console is a future feature."
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
if (!isApiKey(apiKeyFlag)) {
|
|
27
|
+
throw new Error("--api-key must be an API key (sk_* or pk_*)");
|
|
28
|
+
}
|
|
29
|
+
if (apiKeyFlag.startsWith("ik_")) {
|
|
30
|
+
throw new Error("Ingest keys (ik_*) cannot open stream connections \u2014 use sk_* or pk_*");
|
|
31
|
+
}
|
|
32
|
+
const ctx = await loadContext();
|
|
33
|
+
const baseUrl = ctx?.serviceUrl ?? "https://api.semilayer.com";
|
|
34
|
+
return new BeamClient({
|
|
35
|
+
baseUrl,
|
|
36
|
+
apiKey: apiKeyFlag,
|
|
37
|
+
userToken: userTokenFlag
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function outputMode(flag) {
|
|
41
|
+
if (flag === "ndjson") return "ndjson";
|
|
42
|
+
if (flag === "pretty") return "pretty";
|
|
43
|
+
return process.stdout.isTTY ? "pretty" : "ndjson";
|
|
44
|
+
}
|
|
45
|
+
function printRowPretty(row, count) {
|
|
46
|
+
const prefix = dim(`[${count}]`);
|
|
47
|
+
if (typeof row === "object" && row !== null) {
|
|
48
|
+
console.log(`${prefix} ${JSON.stringify(row)}`);
|
|
49
|
+
} else {
|
|
50
|
+
console.log(`${prefix} ${String(row)}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function printRowNdjson(row) {
|
|
54
|
+
console.log(JSON.stringify(row));
|
|
55
|
+
}
|
|
56
|
+
function handleStreamError(err, lens) {
|
|
57
|
+
if (err instanceof BeamStreamRateLimitError) {
|
|
58
|
+
error(`Rate limited: ${err.detail}`);
|
|
59
|
+
info(dim("Back off and retry. Paid plans have much higher limits."));
|
|
60
|
+
process.exitCode = 1;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (err instanceof BeamStreamClosedError) {
|
|
64
|
+
if (err.closeCode === 4290) {
|
|
65
|
+
error("Concurrent connection limit reached for your org. Close an existing stream or upgrade.");
|
|
66
|
+
} else if (err.closeCode === 4291) {
|
|
67
|
+
error("Hourly rows-streamed quota exhausted. Back off or upgrade.");
|
|
68
|
+
} else if (err.closeCode === 4401) {
|
|
69
|
+
error("Auth failed on the stream upgrade. Check your --api-key.");
|
|
70
|
+
} else if (err.closeCode === 4403) {
|
|
71
|
+
error(`Streaming is disabled for lens '${lens}'.`);
|
|
72
|
+
} else {
|
|
73
|
+
error(`Stream closed: ${err.closeCode} ${err.reason}`);
|
|
74
|
+
}
|
|
75
|
+
process.exitCode = 1;
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (err instanceof BeamStreamError) {
|
|
79
|
+
error(`Stream error (${err.code}): ${err.detail}`);
|
|
80
|
+
process.exitCode = 1;
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
error(err.message);
|
|
84
|
+
process.exitCode = 1;
|
|
85
|
+
}
|
|
86
|
+
var streamSearchCommand = defineCommand({
|
|
87
|
+
meta: { name: "search", description: "Chunked streaming search (rows arrive incrementally)" },
|
|
88
|
+
args: {
|
|
89
|
+
lens: {
|
|
90
|
+
type: "positional",
|
|
91
|
+
description: "Lens name",
|
|
92
|
+
required: true
|
|
93
|
+
},
|
|
94
|
+
query: {
|
|
95
|
+
type: "string",
|
|
96
|
+
description: "Search query text",
|
|
97
|
+
required: true,
|
|
98
|
+
alias: "q"
|
|
99
|
+
},
|
|
100
|
+
limit: {
|
|
101
|
+
type: "string",
|
|
102
|
+
description: "Max rows before server emits `done` (default: 50)",
|
|
103
|
+
alias: "l"
|
|
104
|
+
},
|
|
105
|
+
"api-key": {
|
|
106
|
+
type: "string",
|
|
107
|
+
description: "API key (sk_* or pk_*)",
|
|
108
|
+
required: true
|
|
109
|
+
},
|
|
110
|
+
"user-token": {
|
|
111
|
+
type: "string",
|
|
112
|
+
description: "End-user JWT (passed through as ?userToken for row-level access rules)"
|
|
113
|
+
},
|
|
114
|
+
output: {
|
|
115
|
+
type: "string",
|
|
116
|
+
description: "Output format: ndjson | pretty (default: auto \u2014 ndjson when piping)",
|
|
117
|
+
alias: "o"
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
async run({ args }) {
|
|
121
|
+
try {
|
|
122
|
+
const client = await buildClient(args["api-key"], args["user-token"]);
|
|
123
|
+
const mode = outputMode(args.output);
|
|
124
|
+
const params = { query: args.query };
|
|
125
|
+
if (args.limit) params.limit = parseInt(args.limit, 10);
|
|
126
|
+
if (mode === "pretty") {
|
|
127
|
+
newline();
|
|
128
|
+
label("Stream search", `${bold(args.lens)} \u2192 "${args.query}"`);
|
|
129
|
+
newline();
|
|
130
|
+
}
|
|
131
|
+
const iter = client.stream.search(args.lens, params);
|
|
132
|
+
let count = 0;
|
|
133
|
+
const start = Date.now();
|
|
134
|
+
const reader = iter[Symbol.asyncIterator]();
|
|
135
|
+
const onSigint = () => {
|
|
136
|
+
if (reader.return) void reader.return(void 0);
|
|
137
|
+
};
|
|
138
|
+
process.on("SIGINT", onSigint);
|
|
139
|
+
try {
|
|
140
|
+
while (true) {
|
|
141
|
+
const { value, done } = await reader.next();
|
|
142
|
+
if (done) break;
|
|
143
|
+
count += 1;
|
|
144
|
+
if (mode === "ndjson") printRowNdjson(value);
|
|
145
|
+
else printRowPretty(value, count);
|
|
146
|
+
}
|
|
147
|
+
} finally {
|
|
148
|
+
process.off("SIGINT", onSigint);
|
|
149
|
+
}
|
|
150
|
+
if (mode === "pretty") {
|
|
151
|
+
newline();
|
|
152
|
+
info(dim(`${count} row${count === 1 ? "" : "s"} \xB7 ${Date.now() - start}ms`));
|
|
153
|
+
}
|
|
154
|
+
} catch (err) {
|
|
155
|
+
handleStreamError(err, args.lens);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
var streamQueryCommand = defineCommand({
|
|
160
|
+
meta: { name: "query", description: "Chunked streaming query (rows arrive page by page)" },
|
|
161
|
+
args: {
|
|
162
|
+
lens: {
|
|
163
|
+
type: "positional",
|
|
164
|
+
description: "Lens name",
|
|
165
|
+
required: true
|
|
166
|
+
},
|
|
167
|
+
where: {
|
|
168
|
+
type: "string",
|
|
169
|
+
description: `WHERE filter as JSON (e.g. '{"active":true}')`,
|
|
170
|
+
alias: "w"
|
|
171
|
+
},
|
|
172
|
+
limit: {
|
|
173
|
+
type: "string",
|
|
174
|
+
description: "Max total rows before stopping (default: unlimited)",
|
|
175
|
+
alias: "l"
|
|
176
|
+
},
|
|
177
|
+
"batch-size": {
|
|
178
|
+
type: "string",
|
|
179
|
+
description: "Rows per page (default: 100)"
|
|
180
|
+
},
|
|
181
|
+
"api-key": {
|
|
182
|
+
type: "string",
|
|
183
|
+
description: "API key (sk_* or pk_*)",
|
|
184
|
+
required: true
|
|
185
|
+
},
|
|
186
|
+
"user-token": {
|
|
187
|
+
type: "string",
|
|
188
|
+
description: "End-user JWT (passed through as ?userToken for row-level access rules)"
|
|
189
|
+
},
|
|
190
|
+
output: {
|
|
191
|
+
type: "string",
|
|
192
|
+
description: "Output format: ndjson | pretty (default: auto \u2014 ndjson when piping)",
|
|
193
|
+
alias: "o"
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
async run({ args }) {
|
|
197
|
+
try {
|
|
198
|
+
const client = await buildClient(args["api-key"], args["user-token"]);
|
|
199
|
+
const mode = outputMode(args.output);
|
|
200
|
+
let where;
|
|
201
|
+
if (args.where) {
|
|
202
|
+
try {
|
|
203
|
+
where = JSON.parse(args.where);
|
|
204
|
+
} catch {
|
|
205
|
+
throw new Error("--where must be valid JSON");
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
const params = {};
|
|
209
|
+
if (where) params.where = where;
|
|
210
|
+
if (args.limit) params.limit = parseInt(args.limit, 10);
|
|
211
|
+
if (args["batch-size"]) params.batchSize = parseInt(args["batch-size"], 10);
|
|
212
|
+
if (mode === "pretty") {
|
|
213
|
+
newline();
|
|
214
|
+
const parts = [bold(args.lens)];
|
|
215
|
+
if (args.where) parts.push(dim(`where: ${args.where}`));
|
|
216
|
+
label("Stream query", parts.join(" "));
|
|
217
|
+
newline();
|
|
218
|
+
}
|
|
219
|
+
const iter = client.stream.query(args.lens, params);
|
|
220
|
+
let count = 0;
|
|
221
|
+
const start = Date.now();
|
|
222
|
+
const reader = iter[Symbol.asyncIterator]();
|
|
223
|
+
const onSigint = () => {
|
|
224
|
+
if (reader.return) void reader.return(void 0);
|
|
225
|
+
};
|
|
226
|
+
process.on("SIGINT", onSigint);
|
|
227
|
+
try {
|
|
228
|
+
while (true) {
|
|
229
|
+
const { value, done } = await reader.next();
|
|
230
|
+
if (done) break;
|
|
231
|
+
count += 1;
|
|
232
|
+
if (mode === "ndjson") printRowNdjson(value);
|
|
233
|
+
else printRowPretty(value, count);
|
|
234
|
+
}
|
|
235
|
+
} finally {
|
|
236
|
+
process.off("SIGINT", onSigint);
|
|
237
|
+
}
|
|
238
|
+
if (mode === "pretty") {
|
|
239
|
+
newline();
|
|
240
|
+
info(dim(`${count} row${count === 1 ? "" : "s"} \xB7 ${Date.now() - start}ms`));
|
|
241
|
+
}
|
|
242
|
+
} catch (err) {
|
|
243
|
+
handleStreamError(err, args.lens);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
var streamSubscribeCommand = defineCommand({
|
|
248
|
+
meta: {
|
|
249
|
+
name: "subscribe",
|
|
250
|
+
description: "Subscribe to live tail events \u2014 runs until Ctrl-C or the socket closes"
|
|
251
|
+
},
|
|
252
|
+
args: {
|
|
253
|
+
lens: {
|
|
254
|
+
type: "positional",
|
|
255
|
+
description: "Lens name",
|
|
256
|
+
required: true
|
|
257
|
+
},
|
|
258
|
+
filter: {
|
|
259
|
+
type: "string",
|
|
260
|
+
description: `Filter as JSON (e.g. '{"category":"shoes"}')`,
|
|
261
|
+
alias: "f"
|
|
262
|
+
},
|
|
263
|
+
"api-key": {
|
|
264
|
+
type: "string",
|
|
265
|
+
description: "API key (sk_* or pk_*)",
|
|
266
|
+
required: true
|
|
267
|
+
},
|
|
268
|
+
"user-token": {
|
|
269
|
+
type: "string",
|
|
270
|
+
description: "End-user JWT (passed through as ?userToken for row-level access rules)"
|
|
271
|
+
},
|
|
272
|
+
output: {
|
|
273
|
+
type: "string",
|
|
274
|
+
description: "Output format: ndjson | pretty (default: auto \u2014 ndjson when piping)",
|
|
275
|
+
alias: "o"
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
async run({ args }) {
|
|
279
|
+
try {
|
|
280
|
+
const client = await buildClient(args["api-key"], args["user-token"]);
|
|
281
|
+
const mode = outputMode(args.output);
|
|
282
|
+
let filter;
|
|
283
|
+
if (args.filter) {
|
|
284
|
+
try {
|
|
285
|
+
filter = JSON.parse(args.filter);
|
|
286
|
+
} catch {
|
|
287
|
+
throw new Error("--filter must be valid JSON");
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
if (mode === "pretty") {
|
|
291
|
+
newline();
|
|
292
|
+
const parts = [bold(args.lens)];
|
|
293
|
+
if (args.filter) parts.push(dim(`filter: ${args.filter}`));
|
|
294
|
+
label("Subscribe", parts.join(" "));
|
|
295
|
+
info(dim("Waiting for events\u2026 (Ctrl-C to stop)"));
|
|
296
|
+
newline();
|
|
297
|
+
}
|
|
298
|
+
const iter = client.stream.subscribe(args.lens, filter ? { filter } : void 0);
|
|
299
|
+
let count = 0;
|
|
300
|
+
const reader = iter[Symbol.asyncIterator]();
|
|
301
|
+
const onSigint = () => {
|
|
302
|
+
if (reader.return) void reader.return(void 0);
|
|
303
|
+
};
|
|
304
|
+
process.on("SIGINT", onSigint);
|
|
305
|
+
try {
|
|
306
|
+
while (true) {
|
|
307
|
+
const { value, done } = await reader.next();
|
|
308
|
+
if (done) break;
|
|
309
|
+
count += 1;
|
|
310
|
+
if (mode === "ndjson") {
|
|
311
|
+
printRowNdjson(value);
|
|
312
|
+
} else {
|
|
313
|
+
const event = value;
|
|
314
|
+
const kind = event.kind === "delete" ? dim("del") : event.kind;
|
|
315
|
+
console.log(`${dim(`[${count}]`)} ${bold(kind.padEnd(6))} ${JSON.stringify(event.record)}`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
} finally {
|
|
319
|
+
process.off("SIGINT", onSigint);
|
|
320
|
+
}
|
|
321
|
+
if (mode === "pretty") {
|
|
322
|
+
newline();
|
|
323
|
+
info(dim(`${count} event${count === 1 ? "" : "s"}`));
|
|
324
|
+
}
|
|
325
|
+
} catch (err) {
|
|
326
|
+
handleStreamError(err, args.lens);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
var stream_default = defineCommand({
|
|
331
|
+
meta: {
|
|
332
|
+
name: "stream",
|
|
333
|
+
description: "Stream results from a lens over WebSocket (chunked search/query or live subscribe)"
|
|
334
|
+
},
|
|
335
|
+
subCommands: {
|
|
336
|
+
search: streamSearchCommand,
|
|
337
|
+
query: streamQueryCommand,
|
|
338
|
+
subscribe: streamSubscribeCommand
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
export {
|
|
342
|
+
stream_default as default
|
|
343
|
+
};
|
|
344
|
+
//# sourceMappingURL=stream-V7RGHTPR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/stream.ts"],"sourcesContent":["import { defineCommand } from 'citty'\nimport { BeamClient, BeamStreamError, BeamStreamRateLimitError, BeamStreamClosedError } from '@semilayer/client'\nimport { loadContext } from '../lib/context.js'\nimport { error, info, dim, bold, newline, label } from '../lib/output.js'\n\n// ── Shared helpers ─────────────────────────────────────────\n\nfunction isApiKey(value: string): boolean {\n return value.startsWith('sk_') || value.startsWith('pk_') || value.startsWith('ik_')\n}\n\n/**\n * Build a BeamClient for streaming. v0.1 requires an API key (sk_ or pk_) —\n * the JWT-via-Console-proxy path is a Phase 10 feature that needs the\n * run-route slug resolution to land first. ik_ keys are rejected (ingest only).\n */\nasync function buildClient(apiKeyFlag: string | undefined, userTokenFlag: string | undefined): Promise<BeamClient> {\n if (!apiKeyFlag) {\n throw new Error(\n 'Streaming commands require --api-key (sk_* or pk_*). JWT mode via Console is a future feature.',\n )\n }\n if (!isApiKey(apiKeyFlag)) {\n throw new Error('--api-key must be an API key (sk_* or pk_*)')\n }\n if (apiKeyFlag.startsWith('ik_')) {\n throw new Error('Ingest keys (ik_*) cannot open stream connections — use sk_* or pk_*')\n }\n\n const ctx = await loadContext()\n const baseUrl = ctx?.serviceUrl ?? 'https://api.semilayer.com'\n\n return new BeamClient({\n baseUrl,\n apiKey: apiKeyFlag,\n userToken: userTokenFlag,\n })\n}\n\n/** Default to NDJSON when piping (no TTY), otherwise pretty-print. */\nfunction outputMode(flag: string | undefined): 'ndjson' | 'pretty' {\n if (flag === 'ndjson') return 'ndjson'\n if (flag === 'pretty') return 'pretty'\n return process.stdout.isTTY ? 'pretty' : 'ndjson'\n}\n\nfunction printRowPretty(row: unknown, count: number): void {\n const prefix = dim(`[${count}]`)\n if (typeof row === 'object' && row !== null) {\n console.log(`${prefix} ${JSON.stringify(row)}`)\n } else {\n console.log(`${prefix} ${String(row)}`)\n }\n}\n\nfunction printRowNdjson(row: unknown): void {\n console.log(JSON.stringify(row))\n}\n\n/** Handle terminal streaming errors with typed branches. */\nfunction handleStreamError(err: unknown, lens: string): void {\n if (err instanceof BeamStreamRateLimitError) {\n error(`Rate limited: ${err.detail}`)\n info(dim('Back off and retry. Paid plans have much higher limits.'))\n process.exitCode = 1\n return\n }\n if (err instanceof BeamStreamClosedError) {\n if (err.closeCode === 4290) {\n error('Concurrent connection limit reached for your org. Close an existing stream or upgrade.')\n } else if (err.closeCode === 4291) {\n error('Hourly rows-streamed quota exhausted. Back off or upgrade.')\n } else if (err.closeCode === 4401) {\n error('Auth failed on the stream upgrade. Check your --api-key.')\n } else if (err.closeCode === 4403) {\n error(`Streaming is disabled for lens '${lens}'.`)\n } else {\n error(`Stream closed: ${err.closeCode} ${err.reason}`)\n }\n process.exitCode = 1\n return\n }\n if (err instanceof BeamStreamError) {\n error(`Stream error (${err.code}): ${err.detail}`)\n process.exitCode = 1\n return\n }\n error((err as Error).message)\n process.exitCode = 1\n}\n\n// ── Subcommands ────────────────────────────────────────────\n\nconst streamSearchCommand = defineCommand({\n meta: { name: 'search', description: 'Chunked streaming search (rows arrive incrementally)' },\n args: {\n lens: {\n type: 'positional',\n description: 'Lens name',\n required: true,\n },\n query: {\n type: 'string',\n description: 'Search query text',\n required: true,\n alias: 'q',\n },\n limit: {\n type: 'string',\n description: 'Max rows before server emits `done` (default: 50)',\n alias: 'l',\n },\n 'api-key': {\n type: 'string',\n description: 'API key (sk_* or pk_*)',\n required: true,\n },\n 'user-token': {\n type: 'string',\n description: 'End-user JWT (passed through as ?userToken for row-level access rules)',\n },\n output: {\n type: 'string',\n description: 'Output format: ndjson | pretty (default: auto — ndjson when piping)',\n alias: 'o',\n },\n },\n async run({ args }) {\n try {\n const client = await buildClient(args['api-key'], args['user-token'])\n const mode = outputMode(args.output)\n const params: { query: string; limit?: number } = { query: args.query }\n if (args.limit) params.limit = parseInt(args.limit, 10)\n\n if (mode === 'pretty') {\n newline()\n label('Stream search', `${bold(args.lens)} → \"${args.query}\"`)\n newline()\n }\n\n const iter = client.stream.search(args.lens, params)\n let count = 0\n const start = Date.now()\n\n // Graceful ctrl-C — call .return() on the iterator to tear down the WS\n const reader = iter[Symbol.asyncIterator]()\n const onSigint = () => {\n if (reader.return) void reader.return(undefined as never)\n }\n process.on('SIGINT', onSigint)\n\n try {\n while (true) {\n const { value, done } = await reader.next()\n if (done) break\n count += 1\n if (mode === 'ndjson') printRowNdjson(value)\n else printRowPretty(value, count)\n }\n } finally {\n process.off('SIGINT', onSigint)\n }\n\n if (mode === 'pretty') {\n newline()\n info(dim(`${count} row${count === 1 ? '' : 's'} · ${Date.now() - start}ms`))\n }\n } catch (err) {\n handleStreamError(err, args.lens)\n }\n },\n})\n\nconst streamQueryCommand = defineCommand({\n meta: { name: 'query', description: 'Chunked streaming query (rows arrive page by page)' },\n args: {\n lens: {\n type: 'positional',\n description: 'Lens name',\n required: true,\n },\n where: {\n type: 'string',\n description: 'WHERE filter as JSON (e.g. \\'{\"active\":true}\\')',\n alias: 'w',\n },\n limit: {\n type: 'string',\n description: 'Max total rows before stopping (default: unlimited)',\n alias: 'l',\n },\n 'batch-size': {\n type: 'string',\n description: 'Rows per page (default: 100)',\n },\n 'api-key': {\n type: 'string',\n description: 'API key (sk_* or pk_*)',\n required: true,\n },\n 'user-token': {\n type: 'string',\n description: 'End-user JWT (passed through as ?userToken for row-level access rules)',\n },\n output: {\n type: 'string',\n description: 'Output format: ndjson | pretty (default: auto — ndjson when piping)',\n alias: 'o',\n },\n },\n async run({ args }) {\n try {\n const client = await buildClient(args['api-key'], args['user-token'])\n const mode = outputMode(args.output)\n\n let where: Record<string, unknown> | undefined\n if (args.where) {\n try {\n where = JSON.parse(args.where)\n } catch {\n throw new Error('--where must be valid JSON')\n }\n }\n\n const params: { where?: Record<string, unknown>; limit?: number; batchSize?: number } = {}\n if (where) params.where = where\n if (args.limit) params.limit = parseInt(args.limit, 10)\n if (args['batch-size']) params.batchSize = parseInt(args['batch-size'], 10)\n\n if (mode === 'pretty') {\n newline()\n const parts = [bold(args.lens)]\n if (args.where) parts.push(dim(`where: ${args.where}`))\n label('Stream query', parts.join(' '))\n newline()\n }\n\n const iter = client.stream.query(args.lens, params)\n let count = 0\n const start = Date.now()\n const reader = iter[Symbol.asyncIterator]()\n const onSigint = () => {\n if (reader.return) void reader.return(undefined as never)\n }\n process.on('SIGINT', onSigint)\n\n try {\n while (true) {\n const { value, done } = await reader.next()\n if (done) break\n count += 1\n if (mode === 'ndjson') printRowNdjson(value)\n else printRowPretty(value, count)\n }\n } finally {\n process.off('SIGINT', onSigint)\n }\n\n if (mode === 'pretty') {\n newline()\n info(dim(`${count} row${count === 1 ? '' : 's'} · ${Date.now() - start}ms`))\n }\n } catch (err) {\n handleStreamError(err, args.lens)\n }\n },\n})\n\nconst streamSubscribeCommand = defineCommand({\n meta: {\n name: 'subscribe',\n description: 'Subscribe to live tail events — runs until Ctrl-C or the socket closes',\n },\n args: {\n lens: {\n type: 'positional',\n description: 'Lens name',\n required: true,\n },\n filter: {\n type: 'string',\n description: 'Filter as JSON (e.g. \\'{\"category\":\"shoes\"}\\')',\n alias: 'f',\n },\n 'api-key': {\n type: 'string',\n description: 'API key (sk_* or pk_*)',\n required: true,\n },\n 'user-token': {\n type: 'string',\n description: 'End-user JWT (passed through as ?userToken for row-level access rules)',\n },\n output: {\n type: 'string',\n description: 'Output format: ndjson | pretty (default: auto — ndjson when piping)',\n alias: 'o',\n },\n },\n async run({ args }) {\n try {\n const client = await buildClient(args['api-key'], args['user-token'])\n const mode = outputMode(args.output)\n\n let filter: Record<string, unknown> | undefined\n if (args.filter) {\n try {\n filter = JSON.parse(args.filter)\n } catch {\n throw new Error('--filter must be valid JSON')\n }\n }\n\n if (mode === 'pretty') {\n newline()\n const parts = [bold(args.lens)]\n if (args.filter) parts.push(dim(`filter: ${args.filter}`))\n label('Subscribe', parts.join(' '))\n info(dim('Waiting for events… (Ctrl-C to stop)'))\n newline()\n }\n\n const iter = client.stream.subscribe(args.lens, filter ? { filter } : undefined)\n let count = 0\n const reader = iter[Symbol.asyncIterator]()\n const onSigint = () => {\n if (reader.return) void reader.return(undefined as never)\n }\n process.on('SIGINT', onSigint)\n\n try {\n while (true) {\n const { value, done } = await reader.next()\n if (done) break\n count += 1\n if (mode === 'ndjson') {\n printRowNdjson(value)\n } else {\n const event = value as { kind: string; record: unknown }\n const kind = event.kind === 'delete' ? dim('del') : event.kind\n console.log(`${dim(`[${count}]`)} ${bold(kind.padEnd(6))} ${JSON.stringify(event.record)}`)\n }\n }\n } finally {\n process.off('SIGINT', onSigint)\n }\n\n if (mode === 'pretty') {\n newline()\n info(dim(`${count} event${count === 1 ? '' : 's'}`))\n }\n } catch (err) {\n handleStreamError(err, args.lens)\n }\n },\n})\n\n// ── Parent command ─────────────────────────────────────────\n\nexport default defineCommand({\n meta: {\n name: 'stream',\n description: 'Stream results from a lens over WebSocket (chunked search/query or live subscribe)',\n },\n subCommands: {\n search: streamSearchCommand,\n query: streamQueryCommand,\n subscribe: streamSubscribeCommand,\n },\n})\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
envPath
|
|
4
|
+
} from "./chunk-ALA4X7UU.js";
|
|
5
|
+
import {
|
|
6
|
+
loadContext
|
|
7
|
+
} from "./chunk-QMF7LD67.js";
|
|
8
|
+
import {
|
|
9
|
+
createApiClient
|
|
10
|
+
} from "./chunk-T3UROBMA.js";
|
|
11
|
+
import "./chunk-7TA63VHV.js";
|
|
12
|
+
import {
|
|
13
|
+
error,
|
|
14
|
+
info,
|
|
15
|
+
success
|
|
16
|
+
} from "./chunk-WZYOSGN3.js";
|
|
17
|
+
|
|
18
|
+
// src/commands/sync.ts
|
|
19
|
+
import { defineCommand } from "citty";
|
|
20
|
+
var sync_default = defineCommand({
|
|
21
|
+
meta: {
|
|
22
|
+
name: "sync",
|
|
23
|
+
description: "Smart sync a lens \u2014 full scan with hash dedup + tombstone deletes"
|
|
24
|
+
},
|
|
25
|
+
args: {
|
|
26
|
+
lens: {
|
|
27
|
+
type: "positional",
|
|
28
|
+
description: "Lens name",
|
|
29
|
+
required: true
|
|
30
|
+
},
|
|
31
|
+
rebuild: {
|
|
32
|
+
type: "boolean",
|
|
33
|
+
description: "Wipe the partition first and re-embed every row (destructive)",
|
|
34
|
+
default: false
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
async run({ args }) {
|
|
38
|
+
const ctx = await loadContext();
|
|
39
|
+
if (!ctx) {
|
|
40
|
+
error("No .semilayerrc found. Run `semilayer init` first.");
|
|
41
|
+
process.exitCode = 1;
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const api = await createApiClient();
|
|
45
|
+
const { lenses } = await api.get(`${envPath(ctx)}/lenses`);
|
|
46
|
+
const lens = lenses.find((l) => l.name === args.lens);
|
|
47
|
+
if (!lens) {
|
|
48
|
+
error(`Lens "${args.lens}" not found`);
|
|
49
|
+
process.exitCode = 1;
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (args.rebuild) {
|
|
53
|
+
info(`Rebuilding "${args.lens}" \u2014 partition will be wiped first`);
|
|
54
|
+
} else {
|
|
55
|
+
info(`Smart syncing "${args.lens}" \u2014 only changed rows will be embedded`);
|
|
56
|
+
}
|
|
57
|
+
const res = await api.post(
|
|
58
|
+
`${envPath(ctx)}/lenses/${lens.id}/sync`,
|
|
59
|
+
{ rebuild: args.rebuild === true }
|
|
60
|
+
);
|
|
61
|
+
success(`Sync queued for "${args.lens}" (job ${res.jobId}).`);
|
|
62
|
+
info("Watch progress with: semilayer status");
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
export {
|
|
66
|
+
sync_default as default
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=sync-NRTC3WX4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/sync.ts"],"sourcesContent":["import { defineCommand } from 'citty'\nimport type { Lens } from '@semilayer/core'\nimport { createApiClient } from '../lib/api.js'\nimport { loadContext } from '../lib/context.js'\nimport { envPath } from '../lib/env-path.js'\nimport { success, error, info } from '../lib/output.js'\n\n/**\n * Smart sync — full source scan with content-hash dedup and tombstone deletes.\n *\n * - Cheaper than `semilayer ingest --rebuild` for routine refreshes (only\n * re-embeds rows whose mapped content actually changed)\n * - Catches deletes (rows that disappeared from the source get tombstoned)\n * - Unlike incremental polling, doesn't depend on `updated_at` discipline\n *\n * Use `--rebuild` when you want a clean wipe + re-embed (e.g. after a\n * mapping change). The default is the smart path.\n */\nexport default defineCommand({\n meta: {\n name: 'sync',\n description: 'Smart sync a lens — full scan with hash dedup + tombstone deletes',\n },\n args: {\n lens: {\n type: 'positional',\n description: 'Lens name',\n required: true,\n },\n rebuild: {\n type: 'boolean',\n description: 'Wipe the partition first and re-embed every row (destructive)',\n default: false,\n },\n },\n async run({ args }) {\n const ctx = await loadContext()\n if (!ctx) {\n error('No .semilayerrc found. Run `semilayer init` first.')\n process.exitCode = 1\n return\n }\n const api = await createApiClient()\n const { lenses } = await api.get<{ lenses: Lens[] }>(`${envPath(ctx)}/lenses`)\n const lens = lenses.find((l) => l.name === args.lens)\n if (!lens) {\n error(`Lens \"${args.lens}\" not found`)\n process.exitCode = 1\n return\n }\n\n if (args.rebuild) {\n info(`Rebuilding \"${args.lens}\" — partition will be wiped first`)\n } else {\n info(`Smart syncing \"${args.lens}\" — only changed rows will be embedded`)\n }\n\n const res = await api.post<{ jobId: string; lensName: string; status: string }>(\n `${envPath(ctx)}/lenses/${lens.id}/sync`,\n { rebuild: args.rebuild === true },\n )\n\n success(`Sync queued for \"${args.lens}\" (job ${res.jobId}).`)\n info('Watch progress with: semilayer status')\n },\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA,SAAS,qBAAqB;AAkB9B,IAAO,eAAQ,cAAc;AAAA,EAC3B,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,UAAM,MAAM,MAAM,YAAY;AAC9B,QAAI,CAAC,KAAK;AACR,YAAM,oDAAoD;AAC1D,cAAQ,WAAW;AACnB;AAAA,IACF;AACA,UAAM,MAAM,MAAM,gBAAgB;AAClC,UAAM,EAAE,OAAO,IAAI,MAAM,IAAI,IAAwB,GAAG,QAAQ,GAAG,CAAC,SAAS;AAC7E,UAAM,OAAO,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI;AACpD,QAAI,CAAC,MAAM;AACT,YAAM,SAAS,KAAK,IAAI,aAAa;AACrC,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,QAAI,KAAK,SAAS;AAChB,WAAK,eAAe,KAAK,IAAI,wCAAmC;AAAA,IAClE,OAAO;AACL,WAAK,kBAAkB,KAAK,IAAI,6CAAwC;AAAA,IAC1E;AAEA,UAAM,MAAM,MAAM,IAAI;AAAA,MACpB,GAAG,QAAQ,GAAG,CAAC,WAAW,KAAK,EAAE;AAAA,MACjC,EAAE,SAAS,KAAK,YAAY,KAAK;AAAA,IACnC;AAEA,YAAQ,oBAAoB,KAAK,IAAI,UAAU,IAAI,KAAK,IAAI;AAC5D,SAAK,uCAAuC;AAAA,EAC9C;AACF,CAAC;","names":[]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
createApiClient
|
|
4
|
+
} from "./chunk-T3UROBMA.js";
|
|
5
|
+
import "./chunk-7TA63VHV.js";
|
|
6
|
+
import {
|
|
7
|
+
bold,
|
|
8
|
+
dim,
|
|
9
|
+
error,
|
|
10
|
+
label,
|
|
11
|
+
newline,
|
|
12
|
+
table
|
|
13
|
+
} from "./chunk-WZYOSGN3.js";
|
|
14
|
+
|
|
15
|
+
// src/commands/whoami.ts
|
|
16
|
+
import { defineCommand } from "citty";
|
|
17
|
+
var whoami_default = defineCommand({
|
|
18
|
+
meta: { name: "whoami", description: "Show current authenticated identity" },
|
|
19
|
+
async run() {
|
|
20
|
+
try {
|
|
21
|
+
const api = await createApiClient();
|
|
22
|
+
const me = await api.get("/auth/me");
|
|
23
|
+
newline();
|
|
24
|
+
label("User", me.user.email);
|
|
25
|
+
if (me.user.name) {
|
|
26
|
+
label("Name", me.user.name);
|
|
27
|
+
}
|
|
28
|
+
newline();
|
|
29
|
+
if (me.orgs.length > 0) {
|
|
30
|
+
console.log(` ${bold("Organizations:")}`);
|
|
31
|
+
table(
|
|
32
|
+
me.orgs.map((o) => [
|
|
33
|
+
` ${o.slug}`,
|
|
34
|
+
dim(`(${o.role})`)
|
|
35
|
+
])
|
|
36
|
+
);
|
|
37
|
+
} else {
|
|
38
|
+
console.log(` ${dim("No organizations")}`);
|
|
39
|
+
}
|
|
40
|
+
newline();
|
|
41
|
+
} catch (err) {
|
|
42
|
+
error(err.message);
|
|
43
|
+
process.exitCode = 1;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
export {
|
|
48
|
+
whoami_default as default
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=whoami-EQGW6V5D.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/whoami.ts"],"sourcesContent":["import { defineCommand } from 'citty'\nimport type { MeResponse } from '@semilayer/core'\nimport { createApiClient } from '../lib/api.js'\nimport { error, label, newline, table, bold, dim } from '../lib/output.js'\n\nexport default defineCommand({\n meta: { name: 'whoami', description: 'Show current authenticated identity' },\n async run() {\n try {\n const api = await createApiClient()\n const me = await api.get<MeResponse>('/auth/me')\n\n newline()\n label('User', me.user.email)\n if (me.user.name) {\n label('Name', me.user.name)\n }\n newline()\n\n if (me.orgs.length > 0) {\n console.log(` ${bold('Organizations:')}`)\n table(\n me.orgs.map((o) => [\n ` ${o.slug}`,\n dim(`(${o.role})`),\n ]),\n )\n } else {\n console.log(` ${dim('No organizations')}`)\n }\n newline()\n } catch (err) {\n error((err as Error).message)\n process.exitCode = 1\n }\n },\n})\n"],"mappings":";;;;;;;;;;;;;;;AAAA,SAAS,qBAAqB;AAK9B,IAAO,iBAAQ,cAAc;AAAA,EAC3B,MAAM,EAAE,MAAM,UAAU,aAAa,sCAAsC;AAAA,EAC3E,MAAM,MAAM;AACV,QAAI;AACF,YAAM,MAAM,MAAM,gBAAgB;AAClC,YAAM,KAAK,MAAM,IAAI,IAAgB,UAAU;AAE/C,cAAQ;AACR,YAAM,QAAQ,GAAG,KAAK,KAAK;AAC3B,UAAI,GAAG,KAAK,MAAM;AAChB,cAAM,QAAQ,GAAG,KAAK,IAAI;AAAA,MAC5B;AACA,cAAQ;AAER,UAAI,GAAG,KAAK,SAAS,GAAG;AACtB,gBAAQ,IAAI,KAAK,KAAK,gBAAgB,CAAC,EAAE;AACzC;AAAA,UACE,GAAG,KAAK,IAAI,CAAC,MAAM;AAAA,YACjB,OAAO,EAAE,IAAI;AAAA,YACb,IAAI,IAAI,EAAE,IAAI,GAAG;AAAA,UACnB,CAAC;AAAA,QACH;AAAA,MACF,OAAO;AACL,gBAAQ,IAAI,KAAK,IAAI,kBAAkB,CAAC,EAAE;AAAA,MAC5C;AACA,cAAQ;AAAA,IACV,SAAS,KAAK;AACZ,YAAO,IAAc,OAAO;AAC5B,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF;AACF,CAAC;","names":[]}
|