@signaliz/cli 1.0.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/README.md +29 -0
- package/dist/bin.js +139 -0
- package/package.json +25 -0
package/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# @signaliz/cli
|
|
2
|
+
|
|
3
|
+
Command-line interface for Signaliz — deploy Ops, stream logs, manage API keys.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @signaliz/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Configure
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
export SIGNALIZ_API_KEY=sk_...
|
|
15
|
+
export SIGNALIZ_WORKSPACE_ID=00000000-0000-0000-0000-000000000000
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
signaliz --help
|
|
22
|
+
signaliz logs <run_id>
|
|
23
|
+
signaliz deploy signaliz.yaml # plan
|
|
24
|
+
signaliz deploy signaliz.yaml --apply # apply
|
|
25
|
+
signaliz keys list
|
|
26
|
+
signaliz keys create --name=ci --scopes=read:ops,write:ops --expires=90d
|
|
27
|
+
signaliz keys rotate <key_id>
|
|
28
|
+
signaliz keys revoke <key_id>
|
|
29
|
+
```
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
// src/bin.ts
|
|
5
|
+
var import_node_fs = require("fs");
|
|
6
|
+
var HELP = `signaliz <command> [args]
|
|
7
|
+
|
|
8
|
+
Commands:
|
|
9
|
+
logs <run_id> [--since=ISO] [--filter=type1,type2]
|
|
10
|
+
Stream run events (SSE) until the run ends.
|
|
11
|
+
deploy <file.yaml> [--apply] Plan (default) or apply a signaliz.yaml.
|
|
12
|
+
keys list List API keys for the current workspace.
|
|
13
|
+
keys create --name=NAME --scopes=read:ops,write:ops [--expires=30d|90d|1y|never]
|
|
14
|
+
keys rotate <key_id>
|
|
15
|
+
keys revoke <key_id>
|
|
16
|
+
|
|
17
|
+
Environment:
|
|
18
|
+
SIGNALIZ_API_KEY sk_... key (required)
|
|
19
|
+
SIGNALIZ_API_URL override base URL (default: https://api.signaliz.com)
|
|
20
|
+
SIGNALIZ_WORKSPACE_ID workspace UUID for keys/deploy commands
|
|
21
|
+
`;
|
|
22
|
+
function arg(name) {
|
|
23
|
+
const found = process.argv.find((a) => a.startsWith(`--${name}=`));
|
|
24
|
+
return found?.split("=").slice(1).join("=");
|
|
25
|
+
}
|
|
26
|
+
function requireKey() {
|
|
27
|
+
const key = process.env.SIGNALIZ_API_KEY;
|
|
28
|
+
if (!key) {
|
|
29
|
+
console.error("error: SIGNALIZ_API_KEY env var required");
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
return key;
|
|
33
|
+
}
|
|
34
|
+
function baseUrl() {
|
|
35
|
+
return process.env.SIGNALIZ_API_URL?.replace(/\/$/, "") || "https://api.signaliz.com";
|
|
36
|
+
}
|
|
37
|
+
async function streamLogs(runId) {
|
|
38
|
+
const key = requireKey();
|
|
39
|
+
const url = new URL(`${baseUrl()}/functions/v1/cli-log-stream`);
|
|
40
|
+
url.searchParams.set("run_id", runId);
|
|
41
|
+
const since = arg("since");
|
|
42
|
+
const filter = arg("filter");
|
|
43
|
+
if (since) url.searchParams.set("since", since);
|
|
44
|
+
if (filter) url.searchParams.set("filter", filter);
|
|
45
|
+
const res = await fetch(url, { headers: { Authorization: `Bearer ${key}` } });
|
|
46
|
+
if (!res.ok) {
|
|
47
|
+
console.error(`error: ${res.status} ${await res.text()}`);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
if (!res.body) {
|
|
51
|
+
console.error("error: no response body");
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
const reader = res.body.getReader();
|
|
55
|
+
const decoder = new TextDecoder();
|
|
56
|
+
while (true) {
|
|
57
|
+
const { value, done } = await reader.read();
|
|
58
|
+
if (done) break;
|
|
59
|
+
process.stdout.write(decoder.decode(value));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async function deploy(file, applyMode) {
|
|
63
|
+
const key = requireKey();
|
|
64
|
+
const workspace_id = process.env.SIGNALIZ_WORKSPACE_ID;
|
|
65
|
+
if (!workspace_id) {
|
|
66
|
+
console.error("error: SIGNALIZ_WORKSPACE_ID env var required");
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
const yaml_text = (0, import_node_fs.readFileSync)(file, "utf8");
|
|
70
|
+
const fn = applyMode ? "yaml-apply" : "yaml-plan";
|
|
71
|
+
const res = await fetch(`${baseUrl()}/functions/v1/${fn}`, {
|
|
72
|
+
method: "POST",
|
|
73
|
+
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
|
|
74
|
+
body: JSON.stringify({ yaml_text, workspace_id, confirm: applyMode })
|
|
75
|
+
});
|
|
76
|
+
const data = await res.json();
|
|
77
|
+
console.log(JSON.stringify(data, null, 2));
|
|
78
|
+
if (!res.ok || data?.success === false) process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
async function keys(sub, rest) {
|
|
81
|
+
const key = requireKey();
|
|
82
|
+
const workspace_id = process.env.SIGNALIZ_WORKSPACE_ID;
|
|
83
|
+
if (!workspace_id) {
|
|
84
|
+
console.error("error: SIGNALIZ_WORKSPACE_ID env var required");
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
const body = { action: sub, workspace_id };
|
|
88
|
+
if (sub === "create") {
|
|
89
|
+
body.name = arg("name");
|
|
90
|
+
body.scopes = (arg("scopes") || "").split(",").filter(Boolean);
|
|
91
|
+
body.expires_in = arg("expires") || "never";
|
|
92
|
+
} else if (sub === "rotate" || sub === "revoke") {
|
|
93
|
+
body.key_id = rest[0];
|
|
94
|
+
}
|
|
95
|
+
const res = await fetch(`${baseUrl()}/functions/v1/api-keys`, {
|
|
96
|
+
method: "POST",
|
|
97
|
+
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
|
|
98
|
+
body: JSON.stringify(body)
|
|
99
|
+
});
|
|
100
|
+
console.log(JSON.stringify(await res.json(), null, 2));
|
|
101
|
+
if (!res.ok) process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
async function main() {
|
|
104
|
+
const [, , cmd, ...rest] = process.argv;
|
|
105
|
+
if (!cmd || cmd === "--help" || cmd === "-h") {
|
|
106
|
+
process.stdout.write(HELP);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
switch (cmd) {
|
|
110
|
+
case "logs":
|
|
111
|
+
if (!rest[0]) {
|
|
112
|
+
console.error("usage: signaliz logs <run_id>");
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
return streamLogs(rest[0]);
|
|
116
|
+
case "deploy":
|
|
117
|
+
if (!rest[0]) {
|
|
118
|
+
console.error("usage: signaliz deploy <file.yaml> [--apply]");
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
return deploy(rest[0], rest.includes("--apply"));
|
|
122
|
+
case "keys": {
|
|
123
|
+
const sub = rest[0];
|
|
124
|
+
if (!["list", "create", "rotate", "revoke"].includes(sub)) {
|
|
125
|
+
console.error("usage: signaliz keys <list|create|rotate|revoke> ...");
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
return keys(sub, rest.slice(1));
|
|
129
|
+
}
|
|
130
|
+
default:
|
|
131
|
+
console.error(`unknown command: ${cmd}`);
|
|
132
|
+
process.stdout.write(HELP);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
main().catch((err) => {
|
|
137
|
+
console.error(err);
|
|
138
|
+
process.exit(1);
|
|
139
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@signaliz/cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Signaliz CLI — deploy Ops, stream logs, manage API keys.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"signaliz": "./dist/bin.js"
|
|
7
|
+
},
|
|
8
|
+
"files": ["dist", "README.md"],
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsup src/bin.ts --format cjs --clean",
|
|
11
|
+
"prepublishOnly": "npm run build"
|
|
12
|
+
},
|
|
13
|
+
"keywords": ["signaliz", "cli", "gtm", "ops"],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=18"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@signaliz/sdk": "^1.0.0"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"tsup": "^8.0.0",
|
|
23
|
+
"typescript": "^5.3.0"
|
|
24
|
+
}
|
|
25
|
+
}
|