@atlasauth/cli 0.0.0-stage → 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/README.md +57 -2
- package/dist/args.d.ts +69 -0
- package/dist/args.js +69 -0
- package/dist/args.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +19 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/api-keys.d.ts +4 -0
- package/dist/commands/api-keys.js +81 -0
- package/dist/commands/api-keys.js.map +1 -0
- package/dist/commands/auth.d.ts +25 -0
- package/dist/commands/auth.js +94 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/orgs.d.ts +4 -0
- package/dist/commands/orgs.js +72 -0
- package/dist/commands/orgs.js.map +1 -0
- package/dist/commands/sessions.d.ts +4 -0
- package/dist/commands/sessions.js +28 -0
- package/dist/commands/sessions.js.map +1 -0
- package/dist/commands/shared.d.ts +32 -0
- package/dist/commands/shared.js +60 -0
- package/dist/commands/shared.js.map +1 -0
- package/dist/commands/users.d.ts +4 -0
- package/dist/commands/users.js +87 -0
- package/dist/commands/users.js.map +1 -0
- package/dist/commands/webhooks.d.ts +4 -0
- package/dist/commands/webhooks.js +34 -0
- package/dist/commands/webhooks.js.map +1 -0
- package/dist/config.d.ts +48 -0
- package/dist/config.js +69 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +35 -0
- package/dist/context.js +23 -0
- package/dist/context.js.map +1 -0
- package/dist/errors.d.ts +15 -0
- package/dist/errors.js +25 -0
- package/dist/errors.js.map +1 -0
- package/dist/help.d.ts +8 -0
- package/dist/help.js +79 -0
- package/dist/help.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/io.d.ts +21 -0
- package/dist/io.js +28 -0
- package/dist/io.js.map +1 -0
- package/dist/output.d.ts +41 -0
- package/dist/output.js +72 -0
- package/dist/output.js.map +1 -0
- package/dist/prompt.d.ts +15 -0
- package/dist/prompt.js +46 -0
- package/dist/prompt.js.map +1 -0
- package/dist/run.d.ts +12 -0
- package/dist/run.js +90 -0
- package/dist/run.js.map +1 -0
- package/dist/version.d.ts +7 -0
- package/dist/version.js +21 -0
- package/dist/version.js.map +1 -0
- package/package.json +34 -3
package/README.md
CHANGED
|
@@ -1,3 +1,58 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @atlasauth/cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`atlas` — manage an Atlas instance from the terminal, over the secret-key
|
|
4
|
+
Backend API. The peer of `auth0-cli` and Clerk's `cli`, built directly on
|
|
5
|
+
[`@atlasauth/backend`](../backend).
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm i -g @atlasauth/cli
|
|
11
|
+
# or run without installing:
|
|
12
|
+
npx @atlasauth/cli --help
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Authentication
|
|
16
|
+
|
|
17
|
+
The CLI is config-file + secret-key based, like `auth0-cli`'s token model — no
|
|
18
|
+
dashboard OAuth app to register against.
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
atlas login # prompts for an API URL + an sk_ key, validates it
|
|
22
|
+
atlas login --profile prod # store a second, named credential
|
|
23
|
+
atlas whoami # show the active profile + instance (key masked)
|
|
24
|
+
atlas logout # forget a stored credential
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`login` validates the key with one cheap Backend call before saving it to
|
|
28
|
+
`~/.config/atlasauth/config.json` (mode `0600`). `--url` / `--secret-key` skip
|
|
29
|
+
the prompts for CI.
|
|
30
|
+
|
|
31
|
+
Env overrides (win over the stored profile, like most cloud CLIs):
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
ATLAS_SECRET_KEY=sk_live_... ATLAS_API_URL=https://api.atlasauth.net atlas users list
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Commands
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
atlas users list | get <id> | create --email <e> | delete <id>
|
|
41
|
+
atlas orgs list | get <id> | members <id>
|
|
42
|
+
atlas api-keys list | create --subject-type <t> --subject-id <id> | revoke <id>
|
|
43
|
+
atlas webhooks list
|
|
44
|
+
atlas sessions revoke <id>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Every command takes `--json` for raw JSON (otherwise a human table). Paginated
|
|
48
|
+
lists (`users list`, `orgs list`) take `--limit <n>` and `--starting-after
|
|
49
|
+
<cursor>`; the table footer prints the exact cursor flag for the next page.
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
atlas users list --limit 20
|
|
53
|
+
atlas users list --json | jq '.data[].id'
|
|
54
|
+
atlas api-keys create --subject-type user --subject-id user_123 --name ci
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Run `atlas --help` or `atlas <command> --help` for details, `atlas --version`
|
|
58
|
+
for the version.
|
package/dist/args.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single option schema for the whole CLI. parseArgs in `strict` mode rejects
|
|
3
|
+
* an unknown flag for us (turned into a clean {@link CliError} below), so every
|
|
4
|
+
* flag any command accepts must appear here once. Per-command validation of
|
|
5
|
+
* which flags actually apply happens in the handler.
|
|
6
|
+
*/
|
|
7
|
+
declare const OPTIONS: {
|
|
8
|
+
readonly json: {
|
|
9
|
+
readonly type: "boolean";
|
|
10
|
+
};
|
|
11
|
+
readonly profile: {
|
|
12
|
+
readonly type: "string";
|
|
13
|
+
};
|
|
14
|
+
readonly limit: {
|
|
15
|
+
readonly type: "string";
|
|
16
|
+
};
|
|
17
|
+
readonly 'starting-after': {
|
|
18
|
+
readonly type: "string";
|
|
19
|
+
};
|
|
20
|
+
readonly help: {
|
|
21
|
+
readonly type: "boolean";
|
|
22
|
+
readonly short: "h";
|
|
23
|
+
};
|
|
24
|
+
readonly version: {
|
|
25
|
+
readonly type: "boolean";
|
|
26
|
+
readonly short: "v";
|
|
27
|
+
};
|
|
28
|
+
readonly url: {
|
|
29
|
+
readonly type: "string";
|
|
30
|
+
};
|
|
31
|
+
readonly 'secret-key': {
|
|
32
|
+
readonly type: "string";
|
|
33
|
+
};
|
|
34
|
+
readonly email: {
|
|
35
|
+
readonly type: "string";
|
|
36
|
+
};
|
|
37
|
+
readonly 'first-name': {
|
|
38
|
+
readonly type: "string";
|
|
39
|
+
};
|
|
40
|
+
readonly 'last-name': {
|
|
41
|
+
readonly type: "string";
|
|
42
|
+
};
|
|
43
|
+
readonly password: {
|
|
44
|
+
readonly type: "string";
|
|
45
|
+
};
|
|
46
|
+
readonly 'subject-type': {
|
|
47
|
+
readonly type: "string";
|
|
48
|
+
};
|
|
49
|
+
readonly 'subject-id': {
|
|
50
|
+
readonly type: "string";
|
|
51
|
+
};
|
|
52
|
+
readonly name: {
|
|
53
|
+
readonly type: "string";
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
export type Values = {
|
|
57
|
+
[K in keyof typeof OPTIONS]?: (typeof OPTIONS)[K]['type'] extends 'boolean' ? boolean : string;
|
|
58
|
+
};
|
|
59
|
+
export interface ParsedArgs {
|
|
60
|
+
positionals: string[];
|
|
61
|
+
values: Values;
|
|
62
|
+
}
|
|
63
|
+
/** Parse argv, turning parseArgs' own errors (unknown/invalid flag) into clean CliErrors. */
|
|
64
|
+
export declare function parse(argv: string[]): ParsedArgs;
|
|
65
|
+
/** A string flag's value, or undefined. */
|
|
66
|
+
export declare function str(values: Values, key: keyof Values): string | undefined;
|
|
67
|
+
/** `--limit` as a positive integer, or undefined. Rejects garbage with a clean error. */
|
|
68
|
+
export declare function limit(values: Values): number | undefined;
|
|
69
|
+
export {};
|
package/dist/args.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parse = parse;
|
|
4
|
+
exports.str = str;
|
|
5
|
+
exports.limit = limit;
|
|
6
|
+
const node_util_1 = require("node:util");
|
|
7
|
+
const errors_1 = require("./errors");
|
|
8
|
+
/**
|
|
9
|
+
* The single option schema for the whole CLI. parseArgs in `strict` mode rejects
|
|
10
|
+
* an unknown flag for us (turned into a clean {@link CliError} below), so every
|
|
11
|
+
* flag any command accepts must appear here once. Per-command validation of
|
|
12
|
+
* which flags actually apply happens in the handler.
|
|
13
|
+
*/
|
|
14
|
+
const OPTIONS = {
|
|
15
|
+
// Global.
|
|
16
|
+
json: { type: 'boolean' },
|
|
17
|
+
profile: { type: 'string' },
|
|
18
|
+
limit: { type: 'string' },
|
|
19
|
+
'starting-after': { type: 'string' },
|
|
20
|
+
help: { type: 'boolean', short: 'h' },
|
|
21
|
+
version: { type: 'boolean', short: 'v' },
|
|
22
|
+
// login (non-interactive overrides for the prompts).
|
|
23
|
+
url: { type: 'string' },
|
|
24
|
+
'secret-key': { type: 'string' },
|
|
25
|
+
// users create.
|
|
26
|
+
email: { type: 'string' },
|
|
27
|
+
'first-name': { type: 'string' },
|
|
28
|
+
'last-name': { type: 'string' },
|
|
29
|
+
password: { type: 'string' },
|
|
30
|
+
// api-keys.
|
|
31
|
+
'subject-type': { type: 'string' },
|
|
32
|
+
'subject-id': { type: 'string' },
|
|
33
|
+
name: { type: 'string' },
|
|
34
|
+
};
|
|
35
|
+
/** Parse argv, turning parseArgs' own errors (unknown/invalid flag) into clean CliErrors. */
|
|
36
|
+
function parse(argv) {
|
|
37
|
+
try {
|
|
38
|
+
const { values, positionals } = (0, node_util_1.parseArgs)({
|
|
39
|
+
args: argv,
|
|
40
|
+
options: OPTIONS,
|
|
41
|
+
allowPositionals: true,
|
|
42
|
+
strict: true,
|
|
43
|
+
});
|
|
44
|
+
return { values: values, positionals };
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
// parseArgs throws a TypeError with an ERR_PARSE_ARGS_* code; surface its
|
|
48
|
+
// message (e.g. "Unknown option '--frob'") without the stack.
|
|
49
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
50
|
+
throw new errors_1.CliError(message);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** A string flag's value, or undefined. */
|
|
54
|
+
function str(values, key) {
|
|
55
|
+
const v = values[key];
|
|
56
|
+
return typeof v === 'string' ? v : undefined;
|
|
57
|
+
}
|
|
58
|
+
/** `--limit` as a positive integer, or undefined. Rejects garbage with a clean error. */
|
|
59
|
+
function limit(values) {
|
|
60
|
+
const raw = str(values, 'limit');
|
|
61
|
+
if (raw === undefined)
|
|
62
|
+
return undefined;
|
|
63
|
+
const n = Number(raw);
|
|
64
|
+
if (!Number.isInteger(n) || n < 1) {
|
|
65
|
+
throw new errors_1.CliError(`--limit must be a positive integer, got '${raw}'.`);
|
|
66
|
+
}
|
|
67
|
+
return n;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=args.js.map
|
package/dist/args.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":";;AAyCA,sBAeC;AAGD,kBAGC;AAGD,sBAQC;AAzED,yCAAsC;AACtC,qCAAoC;AAEpC;;;;;GAKG;AACH,MAAM,OAAO,GAAG;IACd,UAAU;IACV,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;IACzB,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IAC3B,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACzB,gBAAgB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACpC,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE;IACrC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE;IACxC,qDAAqD;IACrD,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACvB,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IAChC,gBAAgB;IAChB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACzB,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IAChC,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IAC/B,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IAC5B,YAAY;IACZ,cAAc,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IAClC,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IAChC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;CAChB,CAAC;AAWX,6FAA6F;AAC7F,SAAgB,KAAK,CAAC,IAAc;IAClC,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,IAAA,qBAAS,EAAC;YACxC,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,OAAO;YAChB,gBAAgB,EAAE,IAAI;YACtB,MAAM,EAAE,IAAI;SACb,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,MAAgB,EAAE,WAAW,EAAE,CAAC;IACnD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,0EAA0E;QAC1E,8DAA8D;QAC9D,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,IAAI,iBAAQ,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAED,2CAA2C;AAC3C,SAAgB,GAAG,CAAC,MAAc,EAAE,GAAiB;IACnD,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/C,CAAC;AAED,yFAAyF;AACzF,SAAgB,KAAK,CAAC,MAAc;IAClC,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,iBAAQ,CAAC,4CAA4C,GAAG,IAAI,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const context_1 = require("./context");
|
|
5
|
+
const run_1 = require("./run");
|
|
6
|
+
/**
|
|
7
|
+
* The bin entry — the ONLY place that touches `process` for lifecycle. It wires
|
|
8
|
+
* the production context, runs, and exits with the returned code. `run` is
|
|
9
|
+
* designed to catch its own errors, so the `.catch` here is a last-resort guard
|
|
10
|
+
* against a genuine bug; even then it prints a line, never a raw stack.
|
|
11
|
+
*/
|
|
12
|
+
(0, run_1.run)(process.argv.slice(2), (0, context_1.defaultContext)())
|
|
13
|
+
.then((code) => process.exit(code))
|
|
14
|
+
.catch((err) => {
|
|
15
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
16
|
+
process.stderr.write(`atlas: unexpected error: ${message}\n`);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
});
|
|
19
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AACA,uCAA2C;AAC3C,+BAA4B;AAE5B;;;;;GAKG;AACH,IAAA,SAAG,EAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAA,wBAAc,GAAE,CAAC;KACzC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAClC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,OAAO,IAAI,CAAC,CAAC;IAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.apiKeys = apiKeys;
|
|
4
|
+
const args_1 = require("../args");
|
|
5
|
+
const errors_1 = require("../errors");
|
|
6
|
+
const output_1 = require("../output");
|
|
7
|
+
const shared_1 = require("./shared");
|
|
8
|
+
const COLUMNS = [
|
|
9
|
+
{ header: 'ID', get: (k) => k.id },
|
|
10
|
+
{ header: 'SUBJECT_TYPE', get: (k) => k.subject_type },
|
|
11
|
+
{ header: 'SUBJECT_ID', get: (k) => k.subject_id },
|
|
12
|
+
{ header: 'NAME', get: (k) => k.name },
|
|
13
|
+
{ header: 'PREFIX', get: (k) => k.prefix },
|
|
14
|
+
{ header: 'CREATED', get: (k) => (0, output_1.fmtTime)(k.created_at) },
|
|
15
|
+
];
|
|
16
|
+
const SUBJECT_TYPES = ['user', 'organization'];
|
|
17
|
+
function parseSubjectType(value, flag) {
|
|
18
|
+
if (!value)
|
|
19
|
+
throw new errors_1.CliError(`api-keys create requires ${flag} <user|organization>.`);
|
|
20
|
+
if (!SUBJECT_TYPES.includes(value)) {
|
|
21
|
+
throw new errors_1.CliError(`${flag} must be one of: ${SUBJECT_TYPES.join(', ')} (got '${value}').`);
|
|
22
|
+
}
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
/** `atlas api-keys <list|create|revoke>` — maps onto `client.apiKeys.*`. */
|
|
26
|
+
async function apiKeys(ctx, args) {
|
|
27
|
+
const sub = args.positionals[1];
|
|
28
|
+
const json = (0, shared_1.wantsJson)(args.values);
|
|
29
|
+
switch (sub) {
|
|
30
|
+
case 'list': {
|
|
31
|
+
const { client } = (0, shared_1.requireClient)(ctx, args.values);
|
|
32
|
+
// Optional narrowing to one subject; the route itself is not cursor-paged.
|
|
33
|
+
const subjectType = (0, args_1.str)(args.values, 'subject-type');
|
|
34
|
+
const page = await client.apiKeys.list({
|
|
35
|
+
subject_type: subjectType ? parseSubjectType(subjectType, '--subject-type') : undefined,
|
|
36
|
+
subject_id: (0, args_1.str)(args.values, 'subject-id'),
|
|
37
|
+
});
|
|
38
|
+
if (json)
|
|
39
|
+
(0, output_1.printJson)(ctx.io, page);
|
|
40
|
+
else
|
|
41
|
+
ctx.io.out((0, output_1.renderTable)(COLUMNS, page.data));
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
case 'create': {
|
|
45
|
+
const subjectType = parseSubjectType((0, args_1.str)(args.values, 'subject-type'), '--subject-type');
|
|
46
|
+
const subjectId = (0, args_1.str)(args.values, 'subject-id');
|
|
47
|
+
if (!subjectId)
|
|
48
|
+
throw new errors_1.CliError('api-keys create requires --subject-id <id>.');
|
|
49
|
+
const { client } = (0, shared_1.requireClient)(ctx, args.values);
|
|
50
|
+
const key = await client.apiKeys.create({
|
|
51
|
+
subject_type: subjectType,
|
|
52
|
+
subject_id: subjectId,
|
|
53
|
+
name: (0, args_1.str)(args.values, 'name'),
|
|
54
|
+
});
|
|
55
|
+
if (json) {
|
|
56
|
+
(0, output_1.printJson)(ctx.io, key);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// The secret is revealed exactly once — make that unmissable.
|
|
60
|
+
ctx.io.out(`Created API key ${key.id}.`);
|
|
61
|
+
ctx.io.out(`Secret (shown once): ${key.secret}`);
|
|
62
|
+
}
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
case 'revoke': {
|
|
66
|
+
const id = (0, shared_1.requireArg)(args.positionals, 2, 'api-key-id');
|
|
67
|
+
const { client } = (0, shared_1.requireClient)(ctx, args.values);
|
|
68
|
+
const result = await client.apiKeys.delete(id);
|
|
69
|
+
if (json)
|
|
70
|
+
(0, output_1.printJson)(ctx.io, result);
|
|
71
|
+
else
|
|
72
|
+
ctx.io.out(`Revoked API key ${result.id}.`);
|
|
73
|
+
return 0;
|
|
74
|
+
}
|
|
75
|
+
default:
|
|
76
|
+
throw new errors_1.CliError(sub
|
|
77
|
+
? `Unknown subcommand 'api-keys ${sub}'. Try: list, create, revoke.`
|
|
78
|
+
: 'api-keys needs a subcommand: list, create, revoke.');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=api-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-keys.js","sourceRoot":"","sources":["../../src/commands/api-keys.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ParsedArgs } from '../args';
|
|
2
|
+
import type { RunContext } from '../context';
|
|
3
|
+
/**
|
|
4
|
+
* `atlas login` — prompt for an API URL + a secret key, PROVE the key works
|
|
5
|
+
* with one cheap Backend call, then store it under a named profile (0600).
|
|
6
|
+
*
|
|
7
|
+
* Validating before saving is the point: a login that silently stored a typo'd
|
|
8
|
+
* key would surface only later as a baffling 401 on an unrelated command. We
|
|
9
|
+
* spend one `users.list({ limit: 1 })` round-trip here so every later command
|
|
10
|
+
* can trust the stored credential. `--url` / `--secret-key` skip the prompts
|
|
11
|
+
* for non-interactive setup (CI), mirroring the `ATLAS_*` env overrides.
|
|
12
|
+
*/
|
|
13
|
+
export declare function login(ctx: RunContext, args: ParsedArgs): Promise<number>;
|
|
14
|
+
/**
|
|
15
|
+
* `atlas logout` — forget one profile's stored credential. If it was the active
|
|
16
|
+
* profile, the active pointer falls back to any remaining profile so the CLI
|
|
17
|
+
* isn't left pointing at nothing.
|
|
18
|
+
*/
|
|
19
|
+
export declare function logout(ctx: RunContext, args: ParsedArgs): Promise<number>;
|
|
20
|
+
/**
|
|
21
|
+
* `atlas whoami` — report the active profile and instance without any network
|
|
22
|
+
* call. The secret is always masked; the per-field source tells a user whether
|
|
23
|
+
* an `ATLAS_*` env var is shadowing the stored profile.
|
|
24
|
+
*/
|
|
25
|
+
export declare function whoami(ctx: RunContext, args: ParsedArgs): Promise<number>;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.login = login;
|
|
4
|
+
exports.logout = logout;
|
|
5
|
+
exports.whoami = whoami;
|
|
6
|
+
const backend_1 = require("@atlasauth/backend");
|
|
7
|
+
const args_1 = require("../args");
|
|
8
|
+
const errors_1 = require("../errors");
|
|
9
|
+
const output_1 = require("../output");
|
|
10
|
+
const shared_1 = require("./shared");
|
|
11
|
+
/**
|
|
12
|
+
* `atlas login` — prompt for an API URL + a secret key, PROVE the key works
|
|
13
|
+
* with one cheap Backend call, then store it under a named profile (0600).
|
|
14
|
+
*
|
|
15
|
+
* Validating before saving is the point: a login that silently stored a typo'd
|
|
16
|
+
* key would surface only later as a baffling 401 on an unrelated command. We
|
|
17
|
+
* spend one `users.list({ limit: 1 })` round-trip here so every later command
|
|
18
|
+
* can trust the stored credential. `--url` / `--secret-key` skip the prompts
|
|
19
|
+
* for non-interactive setup (CI), mirroring the `ATLAS_*` env overrides.
|
|
20
|
+
*/
|
|
21
|
+
async function login(ctx, args) {
|
|
22
|
+
const { values } = args;
|
|
23
|
+
const profile = (0, args_1.str)(values, 'profile') || 'default';
|
|
24
|
+
const apiUrl = (0, args_1.str)(values, 'url') ||
|
|
25
|
+
(await ctx.prompt.text('Atlas API URL', { default: backend_1.DEFAULT_API_URL })) ||
|
|
26
|
+
backend_1.DEFAULT_API_URL;
|
|
27
|
+
const secretKey = (0, args_1.str)(values, 'secret-key') || (await ctx.prompt.secret('Atlas secret key (sk_...)'));
|
|
28
|
+
if (!secretKey)
|
|
29
|
+
throw new errors_1.CliError('A secret key is required to log in.');
|
|
30
|
+
// Prove the credential before persisting it.
|
|
31
|
+
const client = ctx.makeClient({ secretKey, apiUrl });
|
|
32
|
+
try {
|
|
33
|
+
await client.users.list({ limit: 1 });
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
if (err instanceof backend_1.AtlasApiError) {
|
|
37
|
+
throw new errors_1.CliError(`Secret key rejected by ${apiUrl} (HTTP ${err.status}${err.code ? `, ${err.code}` : ''}). Nothing was saved.`);
|
|
38
|
+
}
|
|
39
|
+
// A network/DNS failure, not a bad key — say so distinctly.
|
|
40
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
41
|
+
throw new errors_1.CliError(`Could not reach ${apiUrl}: ${detail}. Nothing was saved.`);
|
|
42
|
+
}
|
|
43
|
+
const file = ctx.config.load();
|
|
44
|
+
file.profiles[profile] = { api_url: apiUrl, secret_key: secretKey };
|
|
45
|
+
file.active_profile = profile;
|
|
46
|
+
ctx.config.save(file);
|
|
47
|
+
ctx.io.out(`Logged in to ${apiUrl} as profile '${profile}'.`);
|
|
48
|
+
ctx.io.out(`Credential stored at ${ctx.config.path} (mode 0600).`);
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* `atlas logout` — forget one profile's stored credential. If it was the active
|
|
53
|
+
* profile, the active pointer falls back to any remaining profile so the CLI
|
|
54
|
+
* isn't left pointing at nothing.
|
|
55
|
+
*/
|
|
56
|
+
async function logout(ctx, args) {
|
|
57
|
+
const { values } = args;
|
|
58
|
+
const file = ctx.config.load();
|
|
59
|
+
const profile = (0, args_1.str)(values, 'profile') || file.active_profile || 'default';
|
|
60
|
+
if (!file.profiles[profile]) {
|
|
61
|
+
ctx.io.out(`No stored credential for profile '${profile}'.`);
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
delete file.profiles[profile];
|
|
65
|
+
if (file.active_profile === profile) {
|
|
66
|
+
file.active_profile = Object.keys(file.profiles)[0];
|
|
67
|
+
}
|
|
68
|
+
ctx.config.save(file);
|
|
69
|
+
ctx.io.out(`Logged out of profile '${profile}'.`);
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* `atlas whoami` — report the active profile and instance without any network
|
|
74
|
+
* call. The secret is always masked; the per-field source tells a user whether
|
|
75
|
+
* an `ATLAS_*` env var is shadowing the stored profile.
|
|
76
|
+
*/
|
|
77
|
+
async function whoami(ctx, args) {
|
|
78
|
+
const auth = (0, shared_1.resolveAuth)(ctx, args.values);
|
|
79
|
+
if ((0, shared_1.wantsJson)(args.values)) {
|
|
80
|
+
(0, output_1.printJson)(ctx.io, {
|
|
81
|
+
profile: auth.profile,
|
|
82
|
+
api_url: auth.apiUrl,
|
|
83
|
+
secret_key: (0, shared_1.maskSecret)(auth.secretKey),
|
|
84
|
+
key_source: auth.keySource,
|
|
85
|
+
url_source: auth.urlSource,
|
|
86
|
+
});
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
89
|
+
ctx.io.out(`Profile: ${auth.profile}`);
|
|
90
|
+
ctx.io.out(`API URL: ${auth.apiUrl} (${auth.urlSource})`);
|
|
91
|
+
ctx.io.out(`Secret key: ${(0, shared_1.maskSecret)(auth.secretKey)} (${auth.keySource})`);
|
|
92
|
+
return 0;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.orgs = orgs;
|
|
4
|
+
const args_1 = require("../args");
|
|
5
|
+
const errors_1 = require("../errors");
|
|
6
|
+
const output_1 = require("../output");
|
|
7
|
+
const shared_1 = require("./shared");
|
|
8
|
+
const ORG_COLUMNS = [
|
|
9
|
+
{ header: 'ID', get: (o) => o.id },
|
|
10
|
+
{ header: 'NAME', get: (o) => o.name },
|
|
11
|
+
{ header: 'SLUG', get: (o) => o.slug },
|
|
12
|
+
{ header: 'MEMBERS_MAX', get: (o) => o.max_allowed_memberships },
|
|
13
|
+
{ header: 'CREATED', get: (o) => (0, output_1.fmtTime)(o.created_at) },
|
|
14
|
+
];
|
|
15
|
+
const MEMBER_COLUMNS = [
|
|
16
|
+
{ header: 'ID', get: (m) => m.id },
|
|
17
|
+
{ header: 'USER_ID', get: (m) => m.user_id },
|
|
18
|
+
{ header: 'ROLE', get: (m) => m.role },
|
|
19
|
+
{ header: 'CREATED', get: (m) => (0, output_1.fmtTime)(m.created_at) },
|
|
20
|
+
];
|
|
21
|
+
/** `atlas orgs <list|get|members>` — maps onto `client.organizations.*`. */
|
|
22
|
+
async function orgs(ctx, args) {
|
|
23
|
+
const sub = args.positionals[1];
|
|
24
|
+
const json = (0, shared_1.wantsJson)(args.values);
|
|
25
|
+
switch (sub) {
|
|
26
|
+
case 'list': {
|
|
27
|
+
const { client } = (0, shared_1.requireClient)(ctx, args.values);
|
|
28
|
+
const page = await client.organizations.list({
|
|
29
|
+
limit: (0, args_1.limit)(args.values),
|
|
30
|
+
starting_after: (0, args_1.str)(args.values, 'starting-after'),
|
|
31
|
+
});
|
|
32
|
+
(0, output_1.printList)(ctx.io, { json, columns: ORG_COLUMNS }, page);
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
case 'get': {
|
|
36
|
+
const id = (0, shared_1.requireArg)(args.positionals, 2, 'org-id');
|
|
37
|
+
const { client } = (0, shared_1.requireClient)(ctx, args.values);
|
|
38
|
+
const org = await client.organizations.get(id);
|
|
39
|
+
if (json)
|
|
40
|
+
(0, output_1.printJson)(ctx.io, org);
|
|
41
|
+
else
|
|
42
|
+
ctx.io.out(renderOrg(org));
|
|
43
|
+
return 0;
|
|
44
|
+
}
|
|
45
|
+
case 'members': {
|
|
46
|
+
const id = (0, shared_1.requireArg)(args.positionals, 2, 'org-id');
|
|
47
|
+
const { client } = (0, shared_1.requireClient)(ctx, args.values);
|
|
48
|
+
// memberships.list returns { data, has_more } — no cursor on this route.
|
|
49
|
+
const page = await client.organizations.memberships.list(id);
|
|
50
|
+
if (json)
|
|
51
|
+
(0, output_1.printJson)(ctx.io, page);
|
|
52
|
+
else
|
|
53
|
+
ctx.io.out((0, output_1.renderTable)(MEMBER_COLUMNS, page.data));
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
default:
|
|
57
|
+
throw new errors_1.CliError(sub
|
|
58
|
+
? `Unknown subcommand 'orgs ${sub}'. Try: list, get, members.`
|
|
59
|
+
: 'orgs needs a subcommand: list, get, members.');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function renderOrg(o) {
|
|
63
|
+
return [
|
|
64
|
+
`ID: ${o.id}`,
|
|
65
|
+
`Name: ${o.name}`,
|
|
66
|
+
`Slug: ${o.slug}`,
|
|
67
|
+
`Max members: ${o.max_allowed_memberships}`,
|
|
68
|
+
`Created by: ${o.created_by}`,
|
|
69
|
+
`Created: ${(0, output_1.fmtTime)(o.created_at)}`,
|
|
70
|
+
].join('\n');
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=orgs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orgs.js","sourceRoot":"","sources":["../../src/commands/orgs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sessions = sessions;
|
|
4
|
+
const errors_1 = require("../errors");
|
|
5
|
+
const output_1 = require("../output");
|
|
6
|
+
const shared_1 = require("./shared");
|
|
7
|
+
/** `atlas sessions revoke <id>` — the one mutation `client.sessions` exposes by id. */
|
|
8
|
+
async function sessions(ctx, args) {
|
|
9
|
+
const sub = args.positionals[1];
|
|
10
|
+
const json = (0, shared_1.wantsJson)(args.values);
|
|
11
|
+
switch (sub) {
|
|
12
|
+
case 'revoke': {
|
|
13
|
+
const id = (0, shared_1.requireArg)(args.positionals, 2, 'session-id');
|
|
14
|
+
const { client } = (0, shared_1.requireClient)(ctx, args.values);
|
|
15
|
+
const result = await client.sessions.revoke(id);
|
|
16
|
+
if (json)
|
|
17
|
+
(0, output_1.printJson)(ctx.io, result);
|
|
18
|
+
else
|
|
19
|
+
ctx.io.out(`Revoked session ${result.id} (status: ${result.status}).`);
|
|
20
|
+
return 0;
|
|
21
|
+
}
|
|
22
|
+
default:
|
|
23
|
+
throw new errors_1.CliError(sub
|
|
24
|
+
? `Unknown subcommand 'sessions ${sub}'. Try: revoke.`
|
|
25
|
+
: 'sessions needs a subcommand: revoke.');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/commands/sessions.ts"],"names":[],"mappings":";;AAOA,4BAqBC;AA1BD,sCAAqC;AACrC,sCAAsC;AACtC,qCAAgE;AAEhE,uFAAuF;AAChF,KAAK,UAAU,QAAQ,CAAC,GAAe,EAAE,IAAgB;IAC9D,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,IAAA,kBAAS,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEpC,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,EAAE,GAAG,IAAA,mBAAU,EAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;YACzD,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,sBAAa,EAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAChD,IAAI,IAAI;gBAAE,IAAA,kBAAS,EAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;;gBAC/B,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,EAAE,aAAa,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;YAC5E,OAAO,CAAC,CAAC;QACX,CAAC;QAED;YACE,MAAM,IAAI,iBAAQ,CAChB,GAAG;gBACD,CAAC,CAAC,gCAAgC,GAAG,iBAAiB;gBACtD,CAAC,CAAC,sCAAsC,CAC3C,CAAC;IACN,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type Values } from '../args';
|
|
2
|
+
import type { ManagementClient, RunContext } from '../context';
|
|
3
|
+
/**
|
|
4
|
+
* A credential resolved for one invocation, plus where each half came from —
|
|
5
|
+
* the source is what `whoami` reports so a user can tell a stored key from an
|
|
6
|
+
* env override.
|
|
7
|
+
*/
|
|
8
|
+
export interface ResolvedAuth {
|
|
9
|
+
profile: string;
|
|
10
|
+
apiUrl: string;
|
|
11
|
+
secretKey: string;
|
|
12
|
+
keySource: 'env' | 'config';
|
|
13
|
+
urlSource: 'env' | 'config' | 'default';
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Resolve which credential to use, with env overrides winning over the stored
|
|
17
|
+
* profile — the same precedence `auth0-cli` and most cloud CLIs use, so a CI
|
|
18
|
+
* job can set `ATLAS_SECRET_KEY` without a `login` step. Throws a clean error
|
|
19
|
+
* (not a stack) when nothing supplies a key.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveAuth(ctx: RunContext, values: Values): ResolvedAuth;
|
|
22
|
+
/** Resolve the credential and build the Backend API client bound to it. */
|
|
23
|
+
export declare function requireClient(ctx: RunContext, values: Values): {
|
|
24
|
+
client: ManagementClient;
|
|
25
|
+
auth: ResolvedAuth;
|
|
26
|
+
};
|
|
27
|
+
/** True when `--json` was passed. */
|
|
28
|
+
export declare function wantsJson(values: Values): boolean;
|
|
29
|
+
/** The first positional after the resource word — e.g. an id for `users get <id>`. */
|
|
30
|
+
export declare function requireArg(positionals: string[], index: number, name: string): string;
|
|
31
|
+
/** Mask a secret for display: keep the `sk_live_`-style prefix and the last 4. */
|
|
32
|
+
export declare function maskSecret(key: string): string;
|