@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.
Files changed (59) hide show
  1. package/README.md +57 -2
  2. package/dist/args.d.ts +69 -0
  3. package/dist/args.js +69 -0
  4. package/dist/args.js.map +1 -0
  5. package/dist/cli.d.ts +2 -0
  6. package/dist/cli.js +19 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/commands/api-keys.d.ts +4 -0
  9. package/dist/commands/api-keys.js +81 -0
  10. package/dist/commands/api-keys.js.map +1 -0
  11. package/dist/commands/auth.d.ts +25 -0
  12. package/dist/commands/auth.js +94 -0
  13. package/dist/commands/auth.js.map +1 -0
  14. package/dist/commands/orgs.d.ts +4 -0
  15. package/dist/commands/orgs.js +72 -0
  16. package/dist/commands/orgs.js.map +1 -0
  17. package/dist/commands/sessions.d.ts +4 -0
  18. package/dist/commands/sessions.js +28 -0
  19. package/dist/commands/sessions.js.map +1 -0
  20. package/dist/commands/shared.d.ts +32 -0
  21. package/dist/commands/shared.js +60 -0
  22. package/dist/commands/shared.js.map +1 -0
  23. package/dist/commands/users.d.ts +4 -0
  24. package/dist/commands/users.js +87 -0
  25. package/dist/commands/users.js.map +1 -0
  26. package/dist/commands/webhooks.d.ts +4 -0
  27. package/dist/commands/webhooks.js +34 -0
  28. package/dist/commands/webhooks.js.map +1 -0
  29. package/dist/config.d.ts +48 -0
  30. package/dist/config.js +69 -0
  31. package/dist/config.js.map +1 -0
  32. package/dist/context.d.ts +35 -0
  33. package/dist/context.js +23 -0
  34. package/dist/context.js.map +1 -0
  35. package/dist/errors.d.ts +15 -0
  36. package/dist/errors.js +25 -0
  37. package/dist/errors.js.map +1 -0
  38. package/dist/help.d.ts +8 -0
  39. package/dist/help.js +79 -0
  40. package/dist/help.js.map +1 -0
  41. package/dist/index.d.ts +19 -0
  42. package/dist/index.js +42 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/io.d.ts +21 -0
  45. package/dist/io.js +28 -0
  46. package/dist/io.js.map +1 -0
  47. package/dist/output.d.ts +41 -0
  48. package/dist/output.js +72 -0
  49. package/dist/output.js.map +1 -0
  50. package/dist/prompt.d.ts +15 -0
  51. package/dist/prompt.js +46 -0
  52. package/dist/prompt.js.map +1 -0
  53. package/dist/run.d.ts +12 -0
  54. package/dist/run.js +90 -0
  55. package/dist/run.js.map +1 -0
  56. package/dist/version.d.ts +7 -0
  57. package/dist/version.js +21 -0
  58. package/dist/version.js.map +1 -0
  59. package/package.json +34 -3
package/README.md CHANGED
@@ -1,3 +1,58 @@
1
- # Temporary Holding Version
1
+ # @atlasauth/cli
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
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
@@ -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
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
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
@@ -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,4 @@
1
+ import { type ParsedArgs } from '../args';
2
+ import type { RunContext } from '../context';
3
+ /** `atlas api-keys <list|create|revoke>` — maps onto `client.apiKeys.*`. */
4
+ export declare function apiKeys(ctx: RunContext, args: ParsedArgs): Promise<number>;
@@ -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":";;AA2BA,0BAsDC;AAhFD,kCAA+C;AAE/C,sCAAqC;AACrC,sCAAyE;AACzE,qCAAgE;AAEhE,MAAM,OAAO,GAAqB;IAChC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;IAClC,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,EAAE;IACtD,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE;IAClD,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE;IACtC,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE;IAC1C,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,gBAAO,EAAC,CAAC,CAAC,UAAU,CAAC,EAAE;CACzD,CAAC;AAEF,MAAM,aAAa,GAAiC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAE7E,SAAS,gBAAgB,CAAC,KAAyB,EAAE,IAAY;IAC/D,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,iBAAQ,CAAC,4BAA4B,IAAI,uBAAuB,CAAC,CAAC;IACxF,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,KAA0B,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,iBAAQ,CAAC,GAAG,IAAI,oBAAoB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,CAAC;IAC9F,CAAC;IACD,OAAO,KAA0B,CAAC;AACpC,CAAC;AAED,4EAA4E;AACrE,KAAK,UAAU,OAAO,CAAC,GAAe,EAAE,IAAgB;IAC7D,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,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,sBAAa,EAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACnD,2EAA2E;YAC3E,MAAM,WAAW,GAAG,IAAA,UAAG,EAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;YACrD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;gBACrC,YAAY,EAAE,WAAW,CAAC,CAAC,CAAC,gBAAgB,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,SAAS;gBACvF,UAAU,EAAE,IAAA,UAAG,EAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC;aAC3C,CAAC,CAAC;YACH,IAAI,IAAI;gBAAE,IAAA,kBAAS,EAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;;gBAC7B,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAA,oBAAW,EAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACjD,OAAO,CAAC,CAAC;QACX,CAAC;QAED,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAA,UAAG,EAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,gBAAgB,CAAC,CAAC;YACzF,MAAM,SAAS,GAAG,IAAA,UAAG,EAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;YACjD,IAAI,CAAC,SAAS;gBAAE,MAAM,IAAI,iBAAQ,CAAC,6CAA6C,CAAC,CAAC;YAClF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,sBAAa,EAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACnD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;gBACtC,YAAY,EAAE,WAAW;gBACzB,UAAU,EAAE,SAAS;gBACrB,IAAI,EAAE,IAAA,UAAG,EAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;aAC/B,CAAC,CAAC;YACH,IAAI,IAAI,EAAE,CAAC;gBACT,IAAA,kBAAS,EAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACN,8DAA8D;gBAC9D,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,mBAAmB,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;gBACzC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,wBAAwB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YACnD,CAAC;YACD,OAAO,CAAC,CAAC;QACX,CAAC;QAED,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,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC/C,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,GAAG,CAAC,CAAC;YACjD,OAAO,CAAC,CAAC;QACX,CAAC;QAED;YACE,MAAM,IAAI,iBAAQ,CAChB,GAAG;gBACD,CAAC,CAAC,gCAAgC,GAAG,+BAA+B;gBACpE,CAAC,CAAC,oDAAoD,CACzD,CAAC;IACN,CAAC;AACH,CAAC"}
@@ -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,4 @@
1
+ import { type ParsedArgs } from '../args';
2
+ import type { RunContext } from '../context';
3
+ /** `atlas orgs <list|get|members>` — maps onto `client.organizations.*`. */
4
+ export declare function orgs(ctx: RunContext, args: ParsedArgs): Promise<number>;
@@ -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,4 @@
1
+ import type { ParsedArgs } from '../args';
2
+ import type { RunContext } from '../context';
3
+ /** `atlas sessions revoke <id>` — the one mutation `client.sessions` exposes by id. */
4
+ export declare function sessions(ctx: RunContext, args: ParsedArgs): Promise<number>;
@@ -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;