@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,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
loadContext
|
|
4
|
+
} from "./chunk-QMF7LD67.js";
|
|
5
|
+
import {
|
|
6
|
+
saveCredentials
|
|
7
|
+
} from "./chunk-7TA63VHV.js";
|
|
8
|
+
import {
|
|
9
|
+
error,
|
|
10
|
+
info,
|
|
11
|
+
success
|
|
12
|
+
} from "./chunk-WZYOSGN3.js";
|
|
13
|
+
|
|
14
|
+
// src/commands/login.ts
|
|
15
|
+
import { defineCommand } from "citty";
|
|
16
|
+
|
|
17
|
+
// src/lib/server.ts
|
|
18
|
+
import { createServer } from "http";
|
|
19
|
+
import { URL } from "url";
|
|
20
|
+
function startCallbackServer(port, timeoutMs = 6e4) {
|
|
21
|
+
let resolve;
|
|
22
|
+
let reject;
|
|
23
|
+
const promise = new Promise((res, rej) => {
|
|
24
|
+
resolve = res;
|
|
25
|
+
reject = rej;
|
|
26
|
+
});
|
|
27
|
+
const server = createServer((req, res) => {
|
|
28
|
+
const url = new URL(req.url ?? "/", `http://localhost:${port}`);
|
|
29
|
+
if (url.pathname === "/callback") {
|
|
30
|
+
const accessToken = url.searchParams.get("access_token");
|
|
31
|
+
const refreshToken = url.searchParams.get("refresh_token");
|
|
32
|
+
if (accessToken && refreshToken) {
|
|
33
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
34
|
+
res.end(
|
|
35
|
+
"<html><body><h2>Logged in! You can close this tab.</h2></body></html>"
|
|
36
|
+
);
|
|
37
|
+
resolve({ accessToken, refreshToken });
|
|
38
|
+
} else {
|
|
39
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
40
|
+
res.end("<html><body><h2>Login failed \u2014 missing tokens.</h2></body></html>");
|
|
41
|
+
reject(new Error("Callback missing access_token or refresh_token"));
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
res.writeHead(404);
|
|
45
|
+
res.end();
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
const timeout = setTimeout(() => {
|
|
49
|
+
server.close();
|
|
50
|
+
reject(new Error("Login timed out. Try again."));
|
|
51
|
+
}, timeoutMs);
|
|
52
|
+
promise.finally(() => {
|
|
53
|
+
clearTimeout(timeout);
|
|
54
|
+
server.close();
|
|
55
|
+
});
|
|
56
|
+
server.listen(port, "127.0.0.1");
|
|
57
|
+
return { promise, server };
|
|
58
|
+
}
|
|
59
|
+
async function findAvailablePort() {
|
|
60
|
+
const { createServer: createNet } = await import("net");
|
|
61
|
+
for (let port = 9876; port <= 9899; port++) {
|
|
62
|
+
const available = await new Promise((resolve) => {
|
|
63
|
+
const srv = createNet();
|
|
64
|
+
srv.once("error", () => resolve(false));
|
|
65
|
+
srv.listen(port, "127.0.0.1", () => {
|
|
66
|
+
srv.close(() => resolve(true));
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
if (available) return port;
|
|
70
|
+
}
|
|
71
|
+
throw new Error("No available port found in range 9876-9899");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// src/commands/login.ts
|
|
75
|
+
var login_default = defineCommand({
|
|
76
|
+
meta: { name: "login", description: "Authenticate with the SemiLayer service" },
|
|
77
|
+
args: {
|
|
78
|
+
"service-url": {
|
|
79
|
+
type: "string",
|
|
80
|
+
description: "Service API URL"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
async run({ args }) {
|
|
84
|
+
const ctx = await loadContext();
|
|
85
|
+
const serviceUrl = args["service-url"] || ctx?.serviceUrl || "https://api.semilayer.com";
|
|
86
|
+
const port = await findAvailablePort();
|
|
87
|
+
const redirectUri = `http://localhost:${port}/callback`;
|
|
88
|
+
const loginUrl = `${serviceUrl}/auth/login?app=cli&redirect=${encodeURIComponent(redirectUri)}`;
|
|
89
|
+
info(`Opening browser for login...`);
|
|
90
|
+
info(`If it doesn't open, visit: ${loginUrl}`);
|
|
91
|
+
const { exec } = await import("child_process");
|
|
92
|
+
const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? 'start ""' : "xdg-open";
|
|
93
|
+
exec(`${cmd} "${loginUrl}"`);
|
|
94
|
+
const { promise } = startCallbackServer(port);
|
|
95
|
+
try {
|
|
96
|
+
const { accessToken, refreshToken } = await promise;
|
|
97
|
+
const payload = JSON.parse(
|
|
98
|
+
Buffer.from(accessToken.split(".")[1], "base64url").toString()
|
|
99
|
+
);
|
|
100
|
+
const email = payload.email ?? "unknown";
|
|
101
|
+
const expiresAt = new Date(payload.exp * 1e3).toISOString();
|
|
102
|
+
await saveCredentials({
|
|
103
|
+
accessToken,
|
|
104
|
+
refreshToken,
|
|
105
|
+
expiresAt,
|
|
106
|
+
email,
|
|
107
|
+
serviceUrl
|
|
108
|
+
});
|
|
109
|
+
success(`Logged in as ${email}`);
|
|
110
|
+
} catch (err) {
|
|
111
|
+
error(err.message);
|
|
112
|
+
process.exitCode = 1;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
export {
|
|
117
|
+
login_default as default
|
|
118
|
+
};
|
|
119
|
+
//# sourceMappingURL=login-BZ6ZPFHC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/login.ts","../src/lib/server.ts"],"sourcesContent":["import { defineCommand } from 'citty'\nimport { findAvailablePort, startCallbackServer } from '../lib/server.js'\nimport { saveCredentials } from '../lib/credentials.js'\nimport { loadContext } from '../lib/context.js'\nimport { success, error, info } from '../lib/output.js'\n\nexport default defineCommand({\n meta: { name: 'login', description: 'Authenticate with the SemiLayer service' },\n args: {\n 'service-url': {\n type: 'string',\n description: 'Service API URL',\n },\n },\n async run({ args }) {\n const ctx = await loadContext()\n const serviceUrl =\n args['service-url'] || ctx?.serviceUrl || 'https://api.semilayer.com'\n\n const port = await findAvailablePort()\n const redirectUri = `http://localhost:${port}/callback`\n\n const loginUrl = `${serviceUrl}/auth/login?app=cli&redirect=${encodeURIComponent(redirectUri)}`\n\n info(`Opening browser for login...`)\n info(`If it doesn't open, visit: ${loginUrl}`)\n\n // Open browser\n const { exec } = await import('node:child_process')\n const cmd =\n process.platform === 'darwin'\n ? 'open'\n : process.platform === 'win32'\n ? 'start \"\"'\n : 'xdg-open'\n exec(`${cmd} \"${loginUrl}\"`)\n\n // Wait for callback\n const { promise } = startCallbackServer(port)\n\n try {\n const { accessToken, refreshToken } = await promise\n\n // Decode JWT to get email and expiry\n const payload = JSON.parse(\n Buffer.from(accessToken.split('.')[1]!, 'base64url').toString(),\n )\n const email = payload.email ?? 'unknown'\n const expiresAt = new Date(payload.exp * 1000).toISOString()\n\n await saveCredentials({\n accessToken,\n refreshToken,\n expiresAt,\n email,\n serviceUrl,\n })\n\n success(`Logged in as ${email}`)\n } catch (err) {\n error((err as Error).message)\n process.exitCode = 1\n }\n },\n})\n","import { createServer, type Server } from 'node:http'\nimport { URL } from 'node:url'\n\nexport interface CallbackResult {\n accessToken: string\n refreshToken: string\n}\n\n/**\n * Start a temporary localhost HTTP server that waits for the OIDC callback.\n * Returns the tokens from the query params, then shuts down.\n */\nexport function startCallbackServer(\n port: number,\n timeoutMs = 60_000,\n): { promise: Promise<CallbackResult>; server: Server } {\n let resolve: (result: CallbackResult) => void\n let reject: (err: Error) => void\n\n const promise = new Promise<CallbackResult>((res, rej) => {\n resolve = res\n reject = rej\n })\n\n const server = createServer((req, res) => {\n const url = new URL(req.url ?? '/', `http://localhost:${port}`)\n\n if (url.pathname === '/callback') {\n const accessToken = url.searchParams.get('access_token')\n const refreshToken = url.searchParams.get('refresh_token')\n\n if (accessToken && refreshToken) {\n res.writeHead(200, { 'Content-Type': 'text/html' })\n res.end(\n '<html><body><h2>Logged in! You can close this tab.</h2></body></html>',\n )\n resolve!({ accessToken, refreshToken })\n } else {\n res.writeHead(400, { 'Content-Type': 'text/html' })\n res.end('<html><body><h2>Login failed — missing tokens.</h2></body></html>')\n reject!(new Error('Callback missing access_token or refresh_token'))\n }\n } else {\n res.writeHead(404)\n res.end()\n }\n })\n\n const timeout = setTimeout(() => {\n server.close()\n reject!(new Error('Login timed out. Try again.'))\n }, timeoutMs)\n\n // Clean up timeout when resolved\n promise.finally(() => {\n clearTimeout(timeout)\n server.close()\n })\n\n server.listen(port, '127.0.0.1')\n\n return { promise, server }\n}\n\n/** Find an available port in the 9876-9899 range */\nexport async function findAvailablePort(): Promise<number> {\n const { createServer: createNet } = await import('node:net')\n for (let port = 9876; port <= 9899; port++) {\n const available = await new Promise<boolean>((resolve) => {\n const srv = createNet()\n srv.once('error', () => resolve(false))\n srv.listen(port, '127.0.0.1', () => {\n srv.close(() => resolve(true))\n })\n })\n if (available) return port\n }\n throw new Error('No available port found in range 9876-9899')\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
clearCredentials,
|
|
4
|
+
loadCredentials
|
|
5
|
+
} from "./chunk-7TA63VHV.js";
|
|
6
|
+
import {
|
|
7
|
+
info,
|
|
8
|
+
success
|
|
9
|
+
} from "./chunk-WZYOSGN3.js";
|
|
10
|
+
|
|
11
|
+
// src/commands/logout.ts
|
|
12
|
+
import { defineCommand } from "citty";
|
|
13
|
+
var logout_default = defineCommand({
|
|
14
|
+
meta: { name: "logout", description: "Log out and clear local credentials" },
|
|
15
|
+
async run() {
|
|
16
|
+
const creds = await loadCredentials();
|
|
17
|
+
if (!creds) {
|
|
18
|
+
info("Already logged out.");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
await fetch(`${creds.serviceUrl}/auth/logout`, {
|
|
23
|
+
method: "POST",
|
|
24
|
+
headers: {
|
|
25
|
+
Authorization: `Bearer ${creds.refreshToken}`,
|
|
26
|
+
"Content-Type": "application/json"
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
} catch {
|
|
30
|
+
}
|
|
31
|
+
await clearCredentials();
|
|
32
|
+
success("Logged out.");
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
export {
|
|
36
|
+
logout_default as default
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=logout-VMPRV62T.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/logout.ts"],"sourcesContent":["import { defineCommand } from 'citty'\nimport { loadCredentials, clearCredentials } from '../lib/credentials.js'\nimport { success, info } from '../lib/output.js'\n\nexport default defineCommand({\n meta: { name: 'logout', description: 'Log out and clear local credentials' },\n async run() {\n const creds = await loadCredentials()\n\n if (!creds) {\n info('Already logged out.')\n return\n }\n\n // Revoke refresh token on the server (best-effort)\n try {\n await fetch(`${creds.serviceUrl}/auth/logout`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${creds.refreshToken}`,\n 'Content-Type': 'application/json',\n },\n })\n } catch {\n // Server unreachable — still clear local creds\n }\n\n await clearCredentials()\n success('Logged out.')\n },\n})\n"],"mappings":";;;;;;;;;;;AAAA,SAAS,qBAAqB;AAI9B,IAAO,iBAAQ,cAAc;AAAA,EAC3B,MAAM,EAAE,MAAM,UAAU,aAAa,sCAAsC;AAAA,EAC3E,MAAM,MAAM;AACV,UAAM,QAAQ,MAAM,gBAAgB;AAEpC,QAAI,CAAC,OAAO;AACV,WAAK,qBAAqB;AAC1B;AAAA,IACF;AAGA,QAAI;AACF,YAAM,MAAM,GAAG,MAAM,UAAU,gBAAgB;AAAA,QAC7C,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,eAAe,UAAU,MAAM,YAAY;AAAA,UAC3C,gBAAgB;AAAA,QAClB;AAAA,MACF,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AAEA,UAAM,iBAAiB;AACvB,YAAQ,aAAa;AAAA,EACvB;AACF,CAAC;","names":[]}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
orgPath
|
|
4
|
+
} from "./chunk-ALA4X7UU.js";
|
|
5
|
+
import {
|
|
6
|
+
loadContext
|
|
7
|
+
} from "./chunk-QMF7LD67.js";
|
|
8
|
+
import {
|
|
9
|
+
confirm
|
|
10
|
+
} from "./chunk-QXIVJY7K.js";
|
|
11
|
+
import {
|
|
12
|
+
createApiClient
|
|
13
|
+
} from "./chunk-T3UROBMA.js";
|
|
14
|
+
import "./chunk-7TA63VHV.js";
|
|
15
|
+
import {
|
|
16
|
+
bold,
|
|
17
|
+
error,
|
|
18
|
+
newline,
|
|
19
|
+
success,
|
|
20
|
+
table
|
|
21
|
+
} from "./chunk-WZYOSGN3.js";
|
|
22
|
+
|
|
23
|
+
// src/commands/members.ts
|
|
24
|
+
import { defineCommand } from "citty";
|
|
25
|
+
var members_default = defineCommand({
|
|
26
|
+
meta: { name: "members", description: "Manage organization members" },
|
|
27
|
+
subCommands: {
|
|
28
|
+
list: defineCommand({
|
|
29
|
+
meta: { name: "list", description: "List members in the current organization" },
|
|
30
|
+
async run() {
|
|
31
|
+
const ctx = await loadContext();
|
|
32
|
+
if (!ctx) {
|
|
33
|
+
error("No .semilayerrc found. Run `semilayer init` first.");
|
|
34
|
+
process.exitCode = 1;
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const api = await createApiClient();
|
|
38
|
+
const { members } = await api.get(`${orgPath(ctx)}/members`);
|
|
39
|
+
if (members.length === 0) {
|
|
40
|
+
newline();
|
|
41
|
+
bold("No members found.");
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
table(
|
|
45
|
+
["Email", "Role"],
|
|
46
|
+
members.map((m) => [m.email, m.role])
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
}),
|
|
50
|
+
invite: defineCommand({
|
|
51
|
+
meta: { name: "invite", description: "Invite a member to the organization" },
|
|
52
|
+
args: {
|
|
53
|
+
email: { type: "string", description: "Email address to invite", required: true },
|
|
54
|
+
role: { type: "string", description: "Role to assign", default: "developer" }
|
|
55
|
+
},
|
|
56
|
+
async run({ args }) {
|
|
57
|
+
const ctx = await loadContext();
|
|
58
|
+
if (!ctx) {
|
|
59
|
+
error("No .semilayerrc found. Run `semilayer init` first.");
|
|
60
|
+
process.exitCode = 1;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const api = await createApiClient();
|
|
64
|
+
await api.post(`${orgPath(ctx)}/members`, { email: args.email, role: args.role });
|
|
65
|
+
success(`Invitation sent to ${args.email} as ${args.role}.`);
|
|
66
|
+
}
|
|
67
|
+
}),
|
|
68
|
+
update: defineCommand({
|
|
69
|
+
meta: { name: "update", description: "Update a member's role" },
|
|
70
|
+
args: {
|
|
71
|
+
"member-id": { type: "string", description: "Member ID", required: true },
|
|
72
|
+
role: { type: "string", description: "New role", required: true }
|
|
73
|
+
},
|
|
74
|
+
async run({ args }) {
|
|
75
|
+
const ctx = await loadContext();
|
|
76
|
+
if (!ctx) {
|
|
77
|
+
error("No .semilayerrc found. Run `semilayer init` first.");
|
|
78
|
+
process.exitCode = 1;
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const api = await createApiClient();
|
|
82
|
+
await api.patch(`${orgPath(ctx)}/members/${args["member-id"]}`, { role: args.role });
|
|
83
|
+
success(`Member role updated to ${args.role}.`);
|
|
84
|
+
}
|
|
85
|
+
}),
|
|
86
|
+
remove: defineCommand({
|
|
87
|
+
meta: { name: "remove", description: "Remove a member from the organization" },
|
|
88
|
+
args: {
|
|
89
|
+
"member-id": { type: "string", description: "Member ID", required: true }
|
|
90
|
+
},
|
|
91
|
+
async run({ args }) {
|
|
92
|
+
const ctx = await loadContext();
|
|
93
|
+
if (!ctx) {
|
|
94
|
+
error("No .semilayerrc found. Run `semilayer init` first.");
|
|
95
|
+
process.exitCode = 1;
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const ok = await confirm(`Remove member ${args["member-id"]}? This cannot be undone.`);
|
|
99
|
+
if (!ok) return;
|
|
100
|
+
const api = await createApiClient();
|
|
101
|
+
await api.del(`${orgPath(ctx)}/members/${args["member-id"]}`);
|
|
102
|
+
success("Member removed.");
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
export {
|
|
108
|
+
members_default as default
|
|
109
|
+
};
|
|
110
|
+
//# sourceMappingURL=members-DVE5FDLZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/members.ts"],"sourcesContent":["import { defineCommand } from 'citty'\nimport type { Member } from '@semilayer/core'\nimport { createApiClient } from '../lib/api.js'\nimport { loadContext } from '../lib/context.js'\nimport { orgPath } from '../lib/env-path.js'\nimport { success, error, bold, table, newline } from '../lib/output.js'\nimport { confirm } from '../lib/prompt.js'\n\nexport default defineCommand({\n meta: { name: 'members', description: 'Manage organization members' },\n subCommands: {\n list: defineCommand({\n meta: { name: 'list', description: 'List members in the current organization' },\n async run() {\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 { members } = await api.get<{ members: Member[] }>(`${orgPath(ctx)}/members`)\n if (members.length === 0) {\n newline()\n bold('No members found.')\n return\n }\n table(\n ['Email', 'Role'],\n members.map((m) => [m.email, m.role]),\n )\n },\n }),\n\n invite: defineCommand({\n meta: { name: 'invite', description: 'Invite a member to the organization' },\n args: {\n email: { type: 'string', description: 'Email address to invite', required: true },\n role: { type: 'string', description: 'Role to assign', default: 'developer' },\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 await api.post(`${orgPath(ctx)}/members`, { email: args.email, role: args.role })\n success(`Invitation sent to ${args.email} as ${args.role}.`)\n },\n }),\n\n update: defineCommand({\n meta: { name: 'update', description: \"Update a member's role\" },\n args: {\n 'member-id': { type: 'string', description: 'Member ID', required: true },\n role: { type: 'string', description: 'New role', required: true },\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 await api.patch(`${orgPath(ctx)}/members/${args['member-id']}`, { role: args.role })\n success(`Member role updated to ${args.role}.`)\n },\n }),\n\n remove: defineCommand({\n meta: { name: 'remove', description: 'Remove a member from the organization' },\n args: {\n 'member-id': { type: 'string', description: 'Member ID', required: true },\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 ok = await confirm(`Remove member ${args['member-id']}? This cannot be undone.`)\n if (!ok) return\n const api = await createApiClient()\n await api.del(`${orgPath(ctx)}/members/${args['member-id']}`)\n success('Member removed.')\n },\n }),\n },\n})\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,149 @@
|
|
|
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/observe.ts
|
|
15
|
+
import { defineCommand } from "citty";
|
|
16
|
+
import {
|
|
17
|
+
BeamClient,
|
|
18
|
+
BeamStreamError,
|
|
19
|
+
BeamStreamRateLimitError,
|
|
20
|
+
BeamStreamClosedError
|
|
21
|
+
} from "@semilayer/client";
|
|
22
|
+
function isApiKey(value) {
|
|
23
|
+
return value.startsWith("sk_") || value.startsWith("pk_") || value.startsWith("ik_");
|
|
24
|
+
}
|
|
25
|
+
var observe_default = defineCommand({
|
|
26
|
+
meta: {
|
|
27
|
+
name: "observe",
|
|
28
|
+
description: "Observe a single record live \u2014 first yield is the current state, subsequent yields are deltas"
|
|
29
|
+
},
|
|
30
|
+
args: {
|
|
31
|
+
lens: {
|
|
32
|
+
type: "positional",
|
|
33
|
+
description: "Lens name",
|
|
34
|
+
required: true
|
|
35
|
+
},
|
|
36
|
+
"record-id": {
|
|
37
|
+
type: "positional",
|
|
38
|
+
description: "Record id to observe",
|
|
39
|
+
required: true
|
|
40
|
+
},
|
|
41
|
+
"api-key": {
|
|
42
|
+
type: "string",
|
|
43
|
+
description: "API key (sk_* or pk_*)",
|
|
44
|
+
required: true
|
|
45
|
+
},
|
|
46
|
+
"user-token": {
|
|
47
|
+
type: "string",
|
|
48
|
+
description: "End-user JWT (passed through as ?userToken for row-level access rules)"
|
|
49
|
+
},
|
|
50
|
+
output: {
|
|
51
|
+
type: "string",
|
|
52
|
+
description: "Output format: ndjson | pretty (default: auto \u2014 ndjson when piping)",
|
|
53
|
+
alias: "o"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
async run({ args }) {
|
|
57
|
+
try {
|
|
58
|
+
if (!args["api-key"]) {
|
|
59
|
+
throw new Error("observe requires --api-key (sk_* or pk_*)");
|
|
60
|
+
}
|
|
61
|
+
if (!isApiKey(args["api-key"])) {
|
|
62
|
+
throw new Error("--api-key must be an API key (sk_* or pk_*)");
|
|
63
|
+
}
|
|
64
|
+
if (args["api-key"].startsWith("ik_")) {
|
|
65
|
+
throw new Error("Ingest keys (ik_*) cannot open stream connections");
|
|
66
|
+
}
|
|
67
|
+
const ctx = await loadContext();
|
|
68
|
+
const baseUrl = ctx?.serviceUrl ?? "https://api.semilayer.com";
|
|
69
|
+
const client = new BeamClient({
|
|
70
|
+
baseUrl,
|
|
71
|
+
apiKey: args["api-key"],
|
|
72
|
+
userToken: args["user-token"]
|
|
73
|
+
});
|
|
74
|
+
const mode = process.stdout.isTTY && args.output !== "ndjson" ? "pretty" : "ndjson";
|
|
75
|
+
if (mode === "pretty") {
|
|
76
|
+
newline();
|
|
77
|
+
label("Observe", `${bold(args.lens)} \u2192 ${dim(args["record-id"])}`);
|
|
78
|
+
info(dim("Waiting for current state + deltas\u2026 (Ctrl-C to stop)"));
|
|
79
|
+
newline();
|
|
80
|
+
}
|
|
81
|
+
const iter = client.observe(args.lens, args["record-id"]);
|
|
82
|
+
let version = 0;
|
|
83
|
+
const reader = iter[Symbol.asyncIterator]();
|
|
84
|
+
const onSigint = () => {
|
|
85
|
+
if (reader.return) void reader.return(void 0);
|
|
86
|
+
};
|
|
87
|
+
process.on("SIGINT", onSigint);
|
|
88
|
+
try {
|
|
89
|
+
while (true) {
|
|
90
|
+
const { value, done } = await reader.next();
|
|
91
|
+
if (done) break;
|
|
92
|
+
version += 1;
|
|
93
|
+
if (mode === "ndjson") {
|
|
94
|
+
console.log(JSON.stringify(value));
|
|
95
|
+
} else {
|
|
96
|
+
const tag = version === 1 ? dim("current") : dim(`delta ${version - 1}`);
|
|
97
|
+
console.log(`${dim(`[v${version}]`)} ${tag} ${JSON.stringify(value)}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
} finally {
|
|
101
|
+
process.off("SIGINT", onSigint);
|
|
102
|
+
}
|
|
103
|
+
if (mode === "pretty") {
|
|
104
|
+
newline();
|
|
105
|
+
info(dim(`${version} version${version === 1 ? "" : "s"} seen`));
|
|
106
|
+
}
|
|
107
|
+
} catch (err) {
|
|
108
|
+
handleStreamError(err, args.lens);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
function handleStreamError(err, lens) {
|
|
113
|
+
if (err instanceof BeamStreamRateLimitError) {
|
|
114
|
+
error(`Rate limited: ${err.detail}`);
|
|
115
|
+
info(dim("Back off and retry. Paid plans have much higher limits."));
|
|
116
|
+
process.exitCode = 1;
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (err instanceof BeamStreamClosedError) {
|
|
120
|
+
if (err.closeCode === 4290) {
|
|
121
|
+
error("Concurrent connection limit reached for your org.");
|
|
122
|
+
} else if (err.closeCode === 4291) {
|
|
123
|
+
error("Hourly rows-streamed quota exhausted.");
|
|
124
|
+
} else if (err.closeCode === 4401) {
|
|
125
|
+
error("Auth failed on the stream upgrade.");
|
|
126
|
+
} else if (err.closeCode === 4403) {
|
|
127
|
+
error(`Live tail is disabled for lens '${lens}'.`);
|
|
128
|
+
} else {
|
|
129
|
+
error(`Stream closed: ${err.closeCode} ${err.reason}`);
|
|
130
|
+
}
|
|
131
|
+
process.exitCode = 1;
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (err instanceof BeamStreamError) {
|
|
135
|
+
if (err.code === "not_found") {
|
|
136
|
+
error(`Record not found: ${err.detail}`);
|
|
137
|
+
} else {
|
|
138
|
+
error(`Stream error (${err.code}): ${err.detail}`);
|
|
139
|
+
}
|
|
140
|
+
process.exitCode = 1;
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
error(err.message);
|
|
144
|
+
process.exitCode = 1;
|
|
145
|
+
}
|
|
146
|
+
export {
|
|
147
|
+
observe_default as default
|
|
148
|
+
};
|
|
149
|
+
//# sourceMappingURL=observe-W346RZBX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/observe.ts"],"sourcesContent":["import { defineCommand } from 'citty'\nimport {\n BeamClient,\n BeamStreamError,\n BeamStreamRateLimitError,\n BeamStreamClosedError,\n} from '@semilayer/client'\nimport { loadContext } from '../lib/context.js'\nimport { error, info, dim, bold, newline, label } from '../lib/output.js'\n\nfunction isApiKey(value: string): boolean {\n return value.startsWith('sk_') || value.startsWith('pk_') || value.startsWith('ik_')\n}\n\nexport default defineCommand({\n meta: {\n name: 'observe',\n description:\n 'Observe a single record live — first yield is the current state, subsequent yields are deltas',\n },\n args: {\n lens: {\n type: 'positional',\n description: 'Lens name',\n required: true,\n },\n 'record-id': {\n type: 'positional',\n description: 'Record id to observe',\n required: true,\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 if (!args['api-key']) {\n throw new Error('observe requires --api-key (sk_* or pk_*)')\n }\n if (!isApiKey(args['api-key'])) {\n throw new Error('--api-key must be an API key (sk_* or pk_*)')\n }\n if (args['api-key'].startsWith('ik_')) {\n throw new Error('Ingest keys (ik_*) cannot open stream connections')\n }\n\n const ctx = await loadContext()\n const baseUrl = ctx?.serviceUrl ?? 'https://api.semilayer.com'\n const client = new BeamClient({\n baseUrl,\n apiKey: args['api-key'],\n userToken: args['user-token'],\n })\n\n const mode = process.stdout.isTTY && args.output !== 'ndjson' ? 'pretty' : 'ndjson'\n\n if (mode === 'pretty') {\n newline()\n label('Observe', `${bold(args.lens)} → ${dim(args['record-id'])}`)\n info(dim('Waiting for current state + deltas… (Ctrl-C to stop)'))\n newline()\n }\n\n const iter = client.observe(args.lens, args['record-id'])\n let version = 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 version += 1\n if (mode === 'ndjson') {\n console.log(JSON.stringify(value))\n } else {\n const tag = version === 1 ? dim('current') : dim(`delta ${version - 1}`)\n console.log(`${dim(`[v${version}]`)} ${tag} ${JSON.stringify(value)}`)\n }\n }\n } finally {\n process.off('SIGINT', onSigint)\n }\n\n if (mode === 'pretty') {\n newline()\n info(dim(`${version} version${version === 1 ? '' : 's'} seen`))\n }\n } catch (err) {\n handleStreamError(err, args.lens)\n }\n },\n})\n\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.')\n } else if (err.closeCode === 4291) {\n error('Hourly rows-streamed quota exhausted.')\n } else if (err.closeCode === 4401) {\n error('Auth failed on the stream upgrade.')\n } else if (err.closeCode === 4403) {\n error(`Live tail 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 if (err.code === 'not_found') {\n error(`Record not found: ${err.detail}`)\n } else {\n error(`Stream error (${err.code}): ${err.detail}`)\n }\n process.exitCode = 1\n return\n }\n error((err as Error).message)\n process.exitCode = 1\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
confirm
|
|
4
|
+
} from "./chunk-QXIVJY7K.js";
|
|
5
|
+
import {
|
|
6
|
+
createApiClient
|
|
7
|
+
} from "./chunk-T3UROBMA.js";
|
|
8
|
+
import "./chunk-7TA63VHV.js";
|
|
9
|
+
import {
|
|
10
|
+
bold,
|
|
11
|
+
newline,
|
|
12
|
+
success,
|
|
13
|
+
table
|
|
14
|
+
} from "./chunk-WZYOSGN3.js";
|
|
15
|
+
|
|
16
|
+
// src/commands/orgs.ts
|
|
17
|
+
import { defineCommand } from "citty";
|
|
18
|
+
var orgs_default = defineCommand({
|
|
19
|
+
meta: { name: "orgs", description: "Manage organizations" },
|
|
20
|
+
subCommands: {
|
|
21
|
+
list: defineCommand({
|
|
22
|
+
meta: { name: "list", description: "List all organizations" },
|
|
23
|
+
async run() {
|
|
24
|
+
const api = await createApiClient();
|
|
25
|
+
const { orgs } = await api.get("/v1/orgs/");
|
|
26
|
+
if (orgs.length === 0) {
|
|
27
|
+
newline();
|
|
28
|
+
bold("No organizations found.");
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
table(
|
|
32
|
+
["Slug", "Name"],
|
|
33
|
+
orgs.map((o) => [o.slug, o.name])
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
}),
|
|
37
|
+
create: defineCommand({
|
|
38
|
+
meta: { name: "create", description: "Create a new organization" },
|
|
39
|
+
args: {
|
|
40
|
+
name: { type: "string", description: "Organization name", required: true },
|
|
41
|
+
slug: { type: "string", description: "Organization slug", required: true }
|
|
42
|
+
},
|
|
43
|
+
async run({ args }) {
|
|
44
|
+
const api = await createApiClient();
|
|
45
|
+
await api.post("/v1/orgs/", { name: args.name, slug: args.slug });
|
|
46
|
+
success(`Organization "${args.name}" (${args.slug}) created.`);
|
|
47
|
+
}
|
|
48
|
+
}),
|
|
49
|
+
delete: defineCommand({
|
|
50
|
+
meta: { name: "delete", description: "Delete an organization" },
|
|
51
|
+
args: {
|
|
52
|
+
org: { type: "string", description: "Organization slug to delete", required: true }
|
|
53
|
+
},
|
|
54
|
+
async run({ args }) {
|
|
55
|
+
const ok = await confirm(`Delete organization "${args.org}"? This cannot be undone.`);
|
|
56
|
+
if (!ok) return;
|
|
57
|
+
const api = await createApiClient();
|
|
58
|
+
await api.del(`/v1/orgs/${args.org}`);
|
|
59
|
+
success(`Organization "${args.org}" deleted.`);
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
export {
|
|
65
|
+
orgs_default as default
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=orgs-YA3TVA3T.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/orgs.ts"],"sourcesContent":["import { defineCommand } from 'citty'\nimport type { Org } from '@semilayer/core'\nimport { createApiClient } from '../lib/api.js'\nimport { success, bold, table, newline } from '../lib/output.js'\nimport { confirm } from '../lib/prompt.js'\n\nexport default defineCommand({\n meta: { name: 'orgs', description: 'Manage organizations' },\n subCommands: {\n list: defineCommand({\n meta: { name: 'list', description: 'List all organizations' },\n async run() {\n const api = await createApiClient()\n const { orgs } = await api.get<{ orgs: Org[] }>('/v1/orgs/')\n if (orgs.length === 0) {\n newline()\n bold('No organizations found.')\n return\n }\n table(\n ['Slug', 'Name'],\n orgs.map((o) => [o.slug, o.name]),\n )\n },\n }),\n\n create: defineCommand({\n meta: { name: 'create', description: 'Create a new organization' },\n args: {\n name: { type: 'string', description: 'Organization name', required: true },\n slug: { type: 'string', description: 'Organization slug', required: true },\n },\n async run({ args }) {\n const api = await createApiClient()\n await api.post('/v1/orgs/', { name: args.name, slug: args.slug })\n success(`Organization \"${args.name}\" (${args.slug}) created.`)\n },\n }),\n\n delete: defineCommand({\n meta: { name: 'delete', description: 'Delete an organization' },\n args: {\n org: { type: 'string', description: 'Organization slug to delete', required: true },\n },\n async run({ args }) {\n const ok = await confirm(`Delete organization \"${args.org}\"? This cannot be undone.`)\n if (!ok) return\n const api = await createApiClient()\n await api.del(`/v1/orgs/${args.org}`)\n success(`Organization \"${args.org}\" deleted.`)\n },\n }),\n },\n})\n"],"mappings":";;;;;;;;;;;;;;;;AAAA,SAAS,qBAAqB;AAM9B,IAAO,eAAQ,cAAc;AAAA,EAC3B,MAAM,EAAE,MAAM,QAAQ,aAAa,uBAAuB;AAAA,EAC1D,aAAa;AAAA,IACX,MAAM,cAAc;AAAA,MAClB,MAAM,EAAE,MAAM,QAAQ,aAAa,yBAAyB;AAAA,MAC5D,MAAM,MAAM;AACV,cAAM,MAAM,MAAM,gBAAgB;AAClC,cAAM,EAAE,KAAK,IAAI,MAAM,IAAI,IAAqB,WAAW;AAC3D,YAAI,KAAK,WAAW,GAAG;AACrB,kBAAQ;AACR,eAAK,yBAAyB;AAC9B;AAAA,QACF;AACA;AAAA,UACE,CAAC,QAAQ,MAAM;AAAA,UACf,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC;AAAA,QAClC;AAAA,MACF;AAAA,IACF,CAAC;AAAA,IAED,QAAQ,cAAc;AAAA,MACpB,MAAM,EAAE,MAAM,UAAU,aAAa,4BAA4B;AAAA,MACjE,MAAM;AAAA,QACJ,MAAM,EAAE,MAAM,UAAU,aAAa,qBAAqB,UAAU,KAAK;AAAA,QACzE,MAAM,EAAE,MAAM,UAAU,aAAa,qBAAqB,UAAU,KAAK;AAAA,MAC3E;AAAA,MACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,cAAM,MAAM,MAAM,gBAAgB;AAClC,cAAM,IAAI,KAAK,aAAa,EAAE,MAAM,KAAK,MAAM,MAAM,KAAK,KAAK,CAAC;AAChE,gBAAQ,iBAAiB,KAAK,IAAI,MAAM,KAAK,IAAI,YAAY;AAAA,MAC/D;AAAA,IACF,CAAC;AAAA,IAED,QAAQ,cAAc;AAAA,MACpB,MAAM,EAAE,MAAM,UAAU,aAAa,yBAAyB;AAAA,MAC9D,MAAM;AAAA,QACJ,KAAK,EAAE,MAAM,UAAU,aAAa,+BAA+B,UAAU,KAAK;AAAA,MACpF;AAAA,MACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,cAAM,KAAK,MAAM,QAAQ,wBAAwB,KAAK,GAAG,2BAA2B;AACpF,YAAI,CAAC,GAAI;AACT,cAAM,MAAM,MAAM,gBAAgB;AAClC,cAAM,IAAI,IAAI,YAAY,KAAK,GAAG,EAAE;AACpC,gBAAQ,iBAAiB,KAAK,GAAG,YAAY;AAAA,MAC/C;AAAA,IACF,CAAC;AAAA,EACH;AACF,CAAC;","names":[]}
|
|
@@ -0,0 +1,50 @@
|
|
|
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
|
+
success
|
|
15
|
+
} from "./chunk-WZYOSGN3.js";
|
|
16
|
+
|
|
17
|
+
// src/commands/pause.ts
|
|
18
|
+
import { defineCommand } from "citty";
|
|
19
|
+
var pause_default = defineCommand({
|
|
20
|
+
meta: { name: "pause", description: "Pause ingestion for a lens" },
|
|
21
|
+
args: {
|
|
22
|
+
lens: {
|
|
23
|
+
type: "positional",
|
|
24
|
+
description: "Lens name",
|
|
25
|
+
required: true
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
async run({ args }) {
|
|
29
|
+
const ctx = await loadContext();
|
|
30
|
+
if (!ctx) {
|
|
31
|
+
error("No .semilayerrc found. Run `semilayer init` first.");
|
|
32
|
+
process.exitCode = 1;
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const api = await createApiClient();
|
|
36
|
+
const { lenses } = await api.get(`${envPath(ctx)}/lenses`);
|
|
37
|
+
const lens = lenses.find((l) => l.name === args.lens);
|
|
38
|
+
if (!lens) {
|
|
39
|
+
error(`Lens "${args.lens}" not found`);
|
|
40
|
+
process.exitCode = 1;
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
await api.post(`${envPath(ctx)}/lenses/${lens.id}/pause`);
|
|
44
|
+
success(`Lens "${args.lens}" paused.`);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
export {
|
|
48
|
+
pause_default as default
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=pause-GQ6PKBUA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/pause.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 } from '../lib/output.js'\n\nexport default defineCommand({\n meta: { name: 'pause', description: 'Pause ingestion for a lens' },\n args: {\n lens: {\n type: 'positional',\n description: 'Lens name',\n required: true,\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 await api.post(`${envPath(ctx)}/lenses/${lens.id}/pause`)\n success(`Lens \"${args.lens}\" paused.`)\n },\n})\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA,SAAS,qBAAqB;AAO9B,IAAO,gBAAQ,cAAc;AAAA,EAC3B,MAAM,EAAE,MAAM,SAAS,aAAa,6BAA6B;AAAA,EACjE,MAAM;AAAA,IACJ,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;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;AACA,UAAM,IAAI,KAAK,GAAG,QAAQ,GAAG,CAAC,WAAW,KAAK,EAAE,QAAQ;AACxD,YAAQ,SAAS,KAAK,IAAI,WAAW;AAAA,EACvC;AACF,CAAC;","names":[]}
|