devhelm 0.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/LICENSE +21 -0
- package/README.md +81 -0
- package/bin/dev.js +5 -0
- package/bin/run.js +5 -0
- package/dist/commands/monitors/list.d.ts +10 -0
- package/dist/commands/monitors/list.d.ts.map +1 -0
- package/dist/commands/monitors/list.js +34 -0
- package/dist/commands/monitors/list.js.map +1 -0
- package/dist/commands/version.d.ts +7 -0
- package/dist/commands/version.d.ts.map +1 -0
- package/dist/commands/version.js +15 -0
- package/dist/commands/version.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api-client.d.ts +12 -0
- package/dist/lib/api-client.d.ts.map +1 -0
- package/dist/lib/api-client.js +35 -0
- package/dist/lib/api-client.js.map +1 -0
- package/dist/lib/auth.d.ts +14 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +53 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/errors.d.ts +12 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +23 -0
- package/dist/lib/errors.js.map +1 -0
- package/oclif.manifest.json +60 -0
- package/package.json +72 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DevHelm
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# DevHelm CLI
|
|
2
|
+
|
|
3
|
+
The official command-line interface for [DevHelm](https://devhelm.io) — manage monitors, deployments, and infrastructure as code.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g devhelm
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Authenticate
|
|
15
|
+
devhelm auth login
|
|
16
|
+
|
|
17
|
+
# List monitors
|
|
18
|
+
devhelm monitors list
|
|
19
|
+
|
|
20
|
+
# Validate a configuration file
|
|
21
|
+
devhelm validate devhelm.yml
|
|
22
|
+
|
|
23
|
+
# Deploy monitors from config
|
|
24
|
+
devhelm deploy
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Authentication
|
|
28
|
+
|
|
29
|
+
The CLI resolves credentials in this order:
|
|
30
|
+
|
|
31
|
+
1. `DEVHELM_API_TOKEN` environment variable (highest priority)
|
|
32
|
+
2. Active auth context from `~/.devhelm/contexts.json`
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Interactive login (creates a "default" context)
|
|
36
|
+
devhelm auth login
|
|
37
|
+
|
|
38
|
+
# Manage multiple contexts
|
|
39
|
+
devhelm auth context create staging --api-url https://api.devhelm.io --token sk_...
|
|
40
|
+
devhelm auth context use staging
|
|
41
|
+
devhelm auth context list
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Commands
|
|
45
|
+
|
|
46
|
+
| Command | Description |
|
|
47
|
+
|---------|-------------|
|
|
48
|
+
| `devhelm version` | Print CLI version |
|
|
49
|
+
| `devhelm monitors list` | List all monitors |
|
|
50
|
+
| `devhelm monitors get <id>` | Get monitor details |
|
|
51
|
+
| `devhelm validate [file]` | Validate devhelm.yml |
|
|
52
|
+
| `devhelm deploy` | Deploy configuration |
|
|
53
|
+
| `devhelm status` | Show deployment status |
|
|
54
|
+
|
|
55
|
+
Run `devhelm --help` for the full command list.
|
|
56
|
+
|
|
57
|
+
## Development
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
git clone https://github.com/devhelmhq/cli.git
|
|
61
|
+
cd cli
|
|
62
|
+
npm install
|
|
63
|
+
npm run build
|
|
64
|
+
|
|
65
|
+
# Run in dev mode
|
|
66
|
+
node bin/dev.js version
|
|
67
|
+
node bin/dev.js monitors list
|
|
68
|
+
|
|
69
|
+
# Run tests
|
|
70
|
+
npm test
|
|
71
|
+
|
|
72
|
+
# Lint
|
|
73
|
+
npm run lint
|
|
74
|
+
|
|
75
|
+
# Type check
|
|
76
|
+
npm run typecheck
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## License
|
|
80
|
+
|
|
81
|
+
MIT
|
package/bin/dev.js
ADDED
package/bin/run.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class MonitorsList extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
};
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/monitors/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAQ,MAAM,aAAa,CAAA;AAK1C,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,OAAO;IAC/C,OAAgB,WAAW,SAAsB;IAEjD,OAAgB,QAAQ,WAGvB;IAED,OAAgB,KAAK;;MAEpB;IAEK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAyB3B"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import { ApiClient } from '../../lib/api-client.js';
|
|
3
|
+
import { resolveToken, resolveApiUrl } from '../../lib/auth.js';
|
|
4
|
+
import { AuthError } from '../../lib/errors.js';
|
|
5
|
+
export default class MonitorsList extends Command {
|
|
6
|
+
static description = 'List all monitors';
|
|
7
|
+
static examples = [
|
|
8
|
+
'<%= config.bin %> monitors list',
|
|
9
|
+
'<%= config.bin %> monitors list --json',
|
|
10
|
+
];
|
|
11
|
+
static flags = {
|
|
12
|
+
json: Flags.boolean({ description: 'Output as JSON', default: false }),
|
|
13
|
+
};
|
|
14
|
+
async run() {
|
|
15
|
+
const { flags } = await this.parse(MonitorsList);
|
|
16
|
+
const token = resolveToken();
|
|
17
|
+
if (!token)
|
|
18
|
+
throw new AuthError();
|
|
19
|
+
const client = new ApiClient({ baseUrl: resolveApiUrl(), token });
|
|
20
|
+
const monitors = await client.get('/platform/monitors?size=50');
|
|
21
|
+
if (flags.json) {
|
|
22
|
+
this.log(JSON.stringify(monitors.content, null, 2));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (monitors.content.length === 0) {
|
|
26
|
+
this.log('No monitors found.');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
for (const m of monitors.content) {
|
|
30
|
+
this.log(` ${m.id}\t${m.status}\t${m.type}\t${m.name}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/monitors/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAC,SAAS,EAAC,MAAM,yBAAyB,CAAA;AACjD,OAAO,EAAC,YAAY,EAAE,aAAa,EAAC,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAA;AAE7C,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,OAAO;IAC/C,MAAM,CAAU,WAAW,GAAG,mBAAmB,CAAA;IAEjD,MAAM,CAAU,QAAQ,GAAG;QACzB,iCAAiC;QACjC,wCAAwC;KACzC,CAAA;IAED,MAAM,CAAU,KAAK,GAAG;QACtB,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,EAAC,WAAW,EAAE,gBAAgB,EAAE,OAAO,EAAE,KAAK,EAAC,CAAC;KACrE,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,EAAC,KAAK,EAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;QAE9C,MAAM,KAAK,GAAG,YAAY,EAAE,CAAA;QAC5B,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,SAAS,EAAE,CAAA;QAEjC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAC,OAAO,EAAE,aAAa,EAAE,EAAE,KAAK,EAAC,CAAC,CAAA;QAC/D,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAC/B,4BAA4B,CAC7B,CAAA;QAED,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YACnD,OAAM;QACR,CAAC;QAED,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;YAC9B,OAAM;QACR,CAAC;QAED,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;QAC1D,CAAC;IACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/commands/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAA;AAKnC,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,OAAO;IAC1C,OAAgB,WAAW,SAA0B;IAErD,OAAgB,QAAQ,WAAgC;IAElD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAM3B"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
export default class Version extends Command {
|
|
6
|
+
static description = 'Print the CLI version';
|
|
7
|
+
static examples = ['<%= config.bin %> version'];
|
|
8
|
+
async run() {
|
|
9
|
+
await this.parse(Version);
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, '..', '..', 'package.json'), 'utf8'));
|
|
12
|
+
this.log(`devhelm/${pkg.version} ${process.platform}-${process.arch} node-${process.version}`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/commands/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAA;AACnC,OAAO,EAAC,YAAY,EAAC,MAAM,SAAS,CAAA;AACpC,OAAO,EAAC,aAAa,EAAC,MAAM,UAAU,CAAA;AACtC,OAAO,EAAC,OAAO,EAAE,IAAI,EAAC,MAAM,WAAW,CAAA;AAEvC,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,OAAO;IAC1C,MAAM,CAAU,WAAW,GAAG,uBAAuB,CAAA;IAErD,MAAM,CAAU,QAAQ,GAAG,CAAC,2BAA2B,CAAC,CAAA;IAExD,KAAK,CAAC,GAAG;QACP,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACzB,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QACzD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC,CAAA;QACzF,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,SAAS,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;IAChG,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,aAAa,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface ApiClientOptions {
|
|
2
|
+
baseUrl: string;
|
|
3
|
+
token: string;
|
|
4
|
+
}
|
|
5
|
+
export declare class ApiClient {
|
|
6
|
+
private baseUrl;
|
|
7
|
+
private token;
|
|
8
|
+
constructor(options: ApiClientOptions);
|
|
9
|
+
get<T>(path: string): Promise<T>;
|
|
10
|
+
post<T>(path: string, body: unknown): Promise<T>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,KAAK,CAAQ;gBAET,OAAO,EAAE,gBAAgB;IAK/B,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAehC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;CAgBvD"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export class ApiClient {
|
|
2
|
+
baseUrl;
|
|
3
|
+
token;
|
|
4
|
+
constructor(options) {
|
|
5
|
+
this.baseUrl = options.baseUrl.replace(/\/$/, '');
|
|
6
|
+
this.token = options.token;
|
|
7
|
+
}
|
|
8
|
+
async get(path) {
|
|
9
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
10
|
+
headers: {
|
|
11
|
+
Authorization: `Bearer ${this.token}`,
|
|
12
|
+
'Content-Type': 'application/json',
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
if (!response.ok) {
|
|
16
|
+
throw new Error(`API request failed: ${response.status} ${response.statusText}`);
|
|
17
|
+
}
|
|
18
|
+
return response.json();
|
|
19
|
+
}
|
|
20
|
+
async post(path, body) {
|
|
21
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
22
|
+
method: 'POST',
|
|
23
|
+
headers: {
|
|
24
|
+
Authorization: `Bearer ${this.token}`,
|
|
25
|
+
'Content-Type': 'application/json',
|
|
26
|
+
},
|
|
27
|
+
body: JSON.stringify(body),
|
|
28
|
+
});
|
|
29
|
+
if (!response.ok) {
|
|
30
|
+
throw new Error(`API request failed: ${response.status} ${response.statusText}`);
|
|
31
|
+
}
|
|
32
|
+
return response.json();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,SAAS;IACZ,OAAO,CAAQ;IACf,KAAK,CAAQ;IAErB,YAAY,OAAyB;QACnC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;QACjD,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,GAAG,CAAI,IAAY;QACvB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YACrD,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;gBACrC,cAAc,EAAE,kBAAkB;aACnC;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;QAClF,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAA;IACtC,CAAC;IAED,KAAK,CAAC,IAAI,CAAI,IAAY,EAAE,IAAa;QACvC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YACrD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;gBACrC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;QAClF,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAA;IACtC,CAAC;CACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface AuthContext {
|
|
2
|
+
name: string;
|
|
3
|
+
apiUrl: string;
|
|
4
|
+
token: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function resolveToken(): string | undefined;
|
|
7
|
+
export declare function resolveApiUrl(): string;
|
|
8
|
+
export declare function getCurrentContext(): AuthContext | undefined;
|
|
9
|
+
export declare function listContexts(): {
|
|
10
|
+
current: string;
|
|
11
|
+
contexts: AuthContext[];
|
|
12
|
+
};
|
|
13
|
+
export declare function saveContext(context: AuthContext, setCurrent?: boolean): void;
|
|
14
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACd;AAUD,wBAAgB,YAAY,IAAI,MAAM,GAAG,SAAS,CAOjD;AAED,wBAAgB,aAAa,IAAI,MAAM,CAOtC;AAED,wBAAgB,iBAAiB,IAAI,WAAW,GAAG,SAAS,CAI3D;AAED,wBAAgB,YAAY,IAAI;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,WAAW,EAAE,CAAA;CAAC,CAOzE;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,UAAO,GAAG,IAAI,CAKzE"}
|
package/dist/lib/auth.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
const CONFIG_DIR = join(homedir(), '.devhelm');
|
|
5
|
+
const CONTEXTS_PATH = join(CONFIG_DIR, 'contexts.json');
|
|
6
|
+
export function resolveToken() {
|
|
7
|
+
if (process.env.DEVHELM_API_TOKEN) {
|
|
8
|
+
return process.env.DEVHELM_API_TOKEN;
|
|
9
|
+
}
|
|
10
|
+
const ctx = getCurrentContext();
|
|
11
|
+
return ctx?.token;
|
|
12
|
+
}
|
|
13
|
+
export function resolveApiUrl() {
|
|
14
|
+
if (process.env.DEVHELM_API_URL) {
|
|
15
|
+
return process.env.DEVHELM_API_URL;
|
|
16
|
+
}
|
|
17
|
+
const ctx = getCurrentContext();
|
|
18
|
+
return ctx?.apiUrl ?? 'https://api.devhelm.io';
|
|
19
|
+
}
|
|
20
|
+
export function getCurrentContext() {
|
|
21
|
+
const file = readContextsFile();
|
|
22
|
+
if (!file)
|
|
23
|
+
return undefined;
|
|
24
|
+
return file.contexts[file.current];
|
|
25
|
+
}
|
|
26
|
+
export function listContexts() {
|
|
27
|
+
const file = readContextsFile();
|
|
28
|
+
if (!file)
|
|
29
|
+
return { current: '', contexts: [] };
|
|
30
|
+
return {
|
|
31
|
+
current: file.current,
|
|
32
|
+
contexts: Object.values(file.contexts),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export function saveContext(context, setCurrent = true) {
|
|
36
|
+
const file = readContextsFile() ?? { current: '', contexts: {} };
|
|
37
|
+
file.contexts[context.name] = context;
|
|
38
|
+
if (setCurrent)
|
|
39
|
+
file.current = context.name;
|
|
40
|
+
writeContextsFile(file);
|
|
41
|
+
}
|
|
42
|
+
function readContextsFile() {
|
|
43
|
+
if (!existsSync(CONTEXTS_PATH))
|
|
44
|
+
return undefined;
|
|
45
|
+
return JSON.parse(readFileSync(CONTEXTS_PATH, 'utf8'));
|
|
46
|
+
}
|
|
47
|
+
function writeContextsFile(file) {
|
|
48
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
49
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
50
|
+
}
|
|
51
|
+
writeFileSync(CONTEXTS_PATH, JSON.stringify(file, null, 2));
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAC,MAAM,SAAS,CAAA;AAC1E,OAAO,EAAC,OAAO,EAAC,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAa9B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAA;AAC9C,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,CAAA;AAEvD,MAAM,UAAU,YAAY;IAC1B,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAClC,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAA;IACtC,CAAC;IAED,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAA;IAC/B,OAAO,GAAG,EAAE,KAAK,CAAA;AACnB,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QAChC,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAA;IACpC,CAAC;IAED,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAA;IAC/B,OAAO,GAAG,EAAE,MAAM,IAAI,wBAAwB,CAAA;AAChD,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAA;IAC/B,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAA;IAC3B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;AACpC,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAA;IAC/B,IAAI,CAAC,IAAI;QAAE,OAAO,EAAC,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAC,CAAA;IAC7C,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;KACvC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAoB,EAAE,UAAU,GAAG,IAAI;IACjE,MAAM,IAAI,GAAG,gBAAgB,EAAE,IAAI,EAAC,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAC,CAAA;IAC9D,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAA;IACrC,IAAI,UAAU;QAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAA;IAC3C,iBAAiB,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED,SAAS,gBAAgB;IACvB,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;QAAE,OAAO,SAAS,CAAA;IAChD,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAA;AACxD,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAkB;IAC3C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAA;IAC1C,CAAC;IAED,aAAa,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;AAC7D,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class DevhelmError extends Error {
|
|
2
|
+
exitCode: number;
|
|
3
|
+
constructor(message: string, exitCode?: number);
|
|
4
|
+
}
|
|
5
|
+
export declare class AuthError extends DevhelmError {
|
|
6
|
+
constructor(message?: string);
|
|
7
|
+
}
|
|
8
|
+
export declare class ApiError extends DevhelmError {
|
|
9
|
+
status: number;
|
|
10
|
+
constructor(status: number, message: string);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAa,SAAQ,KAAK;IAG5B,QAAQ,EAAE,MAAM;gBADvB,OAAO,EAAE,MAAM,EACR,QAAQ,GAAE,MAAU;CAK9B;AAED,qBAAa,SAAU,SAAQ,YAAY;gBAC7B,OAAO,SAAuD;CAI3E;AAED,qBAAa,QAAS,SAAQ,YAAY;IAE/B,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM;CAKlB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export class DevhelmError extends Error {
|
|
2
|
+
exitCode;
|
|
3
|
+
constructor(message, exitCode = 1) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.exitCode = exitCode;
|
|
6
|
+
this.name = 'DevhelmError';
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export class AuthError extends DevhelmError {
|
|
10
|
+
constructor(message = 'Not authenticated. Run `devhelm auth login` first.') {
|
|
11
|
+
super(message, 2);
|
|
12
|
+
this.name = 'AuthError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export class ApiError extends DevhelmError {
|
|
16
|
+
status;
|
|
17
|
+
constructor(status, message) {
|
|
18
|
+
super(`API error (${status}): ${message}`, 3);
|
|
19
|
+
this.status = status;
|
|
20
|
+
this.name = 'ApiError';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,YAAa,SAAQ,KAAK;IAG5B;IAFT,YACE,OAAe,EACR,WAAmB,CAAC;QAE3B,KAAK,CAAC,OAAO,CAAC,CAAA;QAFP,aAAQ,GAAR,QAAQ,CAAY;QAG3B,IAAI,CAAC,IAAI,GAAG,cAAc,CAAA;IAC5B,CAAC;CACF;AAED,MAAM,OAAO,SAAU,SAAQ,YAAY;IACzC,YAAY,OAAO,GAAG,oDAAoD;QACxE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;QACjB,IAAI,CAAC,IAAI,GAAG,WAAW,CAAA;IACzB,CAAC;CACF;AAED,MAAM,OAAO,QAAS,SAAQ,YAAY;IAE/B;IADT,YACS,MAAc,EACrB,OAAe;QAEf,KAAK,CAAC,cAAc,MAAM,MAAM,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;QAHtC,WAAM,GAAN,MAAM,CAAQ;QAIrB,IAAI,CAAC,IAAI,GAAG,UAAU,CAAA;IACxB,CAAC;CACF"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"commands": {
|
|
3
|
+
"version": {
|
|
4
|
+
"aliases": [],
|
|
5
|
+
"args": {},
|
|
6
|
+
"description": "Print the CLI version",
|
|
7
|
+
"examples": [
|
|
8
|
+
"<%= config.bin %> version"
|
|
9
|
+
],
|
|
10
|
+
"flags": {},
|
|
11
|
+
"hasDynamicHelp": false,
|
|
12
|
+
"hiddenAliases": [],
|
|
13
|
+
"id": "version",
|
|
14
|
+
"pluginAlias": "devhelm",
|
|
15
|
+
"pluginName": "devhelm",
|
|
16
|
+
"pluginType": "core",
|
|
17
|
+
"strict": true,
|
|
18
|
+
"enableJsonFlag": false,
|
|
19
|
+
"isESM": true,
|
|
20
|
+
"relativePath": [
|
|
21
|
+
"dist",
|
|
22
|
+
"commands",
|
|
23
|
+
"version.js"
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
"monitors:list": {
|
|
27
|
+
"aliases": [],
|
|
28
|
+
"args": {},
|
|
29
|
+
"description": "List all monitors",
|
|
30
|
+
"examples": [
|
|
31
|
+
"<%= config.bin %> monitors list",
|
|
32
|
+
"<%= config.bin %> monitors list --json"
|
|
33
|
+
],
|
|
34
|
+
"flags": {
|
|
35
|
+
"json": {
|
|
36
|
+
"description": "Output as JSON",
|
|
37
|
+
"name": "json",
|
|
38
|
+
"allowNo": false,
|
|
39
|
+
"type": "boolean"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"hasDynamicHelp": false,
|
|
43
|
+
"hiddenAliases": [],
|
|
44
|
+
"id": "monitors:list",
|
|
45
|
+
"pluginAlias": "devhelm",
|
|
46
|
+
"pluginName": "devhelm",
|
|
47
|
+
"pluginType": "core",
|
|
48
|
+
"strict": true,
|
|
49
|
+
"enableJsonFlag": false,
|
|
50
|
+
"isESM": true,
|
|
51
|
+
"relativePath": [
|
|
52
|
+
"dist",
|
|
53
|
+
"commands",
|
|
54
|
+
"monitors",
|
|
55
|
+
"list.js"
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"version": "0.1.0"
|
|
60
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "devhelm",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "DevHelm CLI — manage monitors, deployments, and infrastructure as code",
|
|
5
|
+
"author": "DevHelm <hello@devhelm.io>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://github.com/devhelmhq/cli",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/devhelmhq/cli.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": "https://github.com/devhelmhq/cli/issues",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"bin": {
|
|
15
|
+
"devhelm": "./bin/run.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"bin",
|
|
19
|
+
"dist",
|
|
20
|
+
"oclif.manifest.json"
|
|
21
|
+
],
|
|
22
|
+
"main": "dist/index.js",
|
|
23
|
+
"types": "dist/index.d.ts",
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc -b && oclif manifest",
|
|
26
|
+
"lint": "eslint src/ test/",
|
|
27
|
+
"lint:fix": "eslint src/ test/ --fix",
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"test:watch": "vitest",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"postpack": "rm -f oclif.manifest.json",
|
|
32
|
+
"prepack": "npm run build"
|
|
33
|
+
},
|
|
34
|
+
"oclif": {
|
|
35
|
+
"bin": "devhelm",
|
|
36
|
+
"dirname": "devhelm",
|
|
37
|
+
"commands": {
|
|
38
|
+
"strategy": "pattern",
|
|
39
|
+
"target": "./dist/commands"
|
|
40
|
+
},
|
|
41
|
+
"plugins": [
|
|
42
|
+
"@oclif/plugin-help",
|
|
43
|
+
"@oclif/plugin-not-found"
|
|
44
|
+
],
|
|
45
|
+
"topicSeparator": " "
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18.0.0"
|
|
49
|
+
},
|
|
50
|
+
"keywords": [
|
|
51
|
+
"devhelm",
|
|
52
|
+
"monitoring",
|
|
53
|
+
"cli",
|
|
54
|
+
"uptime",
|
|
55
|
+
"infrastructure-as-code",
|
|
56
|
+
"devops"
|
|
57
|
+
],
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"@oclif/core": "^4.10.5",
|
|
60
|
+
"@oclif/plugin-help": "^6.2.43",
|
|
61
|
+
"@oclif/plugin-not-found": "^3.2.80"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@types/node": "^25.5.2",
|
|
65
|
+
"@typescript-eslint/eslint-plugin": "^8.58.1",
|
|
66
|
+
"@typescript-eslint/parser": "^8.58.1",
|
|
67
|
+
"eslint": "^10.2.0",
|
|
68
|
+
"oclif": "^4.23.0",
|
|
69
|
+
"typescript": "^6.0.2",
|
|
70
|
+
"vitest": "^4.1.4"
|
|
71
|
+
}
|
|
72
|
+
}
|