@atlasauth/cli 0.0.0-stage → 0.2.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 (71) hide show
  1. package/README.md +91 -2
  2. package/dist/args.d.ts +84 -0
  3. package/dist/args.js +76 -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/actions.d.ts +11 -0
  9. package/dist/commands/actions.js +120 -0
  10. package/dist/commands/actions.js.map +1 -0
  11. package/dist/commands/api-keys.d.ts +4 -0
  12. package/dist/commands/api-keys.js +81 -0
  13. package/dist/commands/api-keys.js.map +1 -0
  14. package/dist/commands/auth.d.ts +25 -0
  15. package/dist/commands/auth.js +94 -0
  16. package/dist/commands/auth.js.map +1 -0
  17. package/dist/commands/config.d.ts +4 -0
  18. package/dist/commands/config.js +716 -0
  19. package/dist/commands/config.js.map +1 -0
  20. package/dist/commands/orgs.d.ts +4 -0
  21. package/dist/commands/orgs.js +72 -0
  22. package/dist/commands/orgs.js.map +1 -0
  23. package/dist/commands/sessions.d.ts +4 -0
  24. package/dist/commands/sessions.js +28 -0
  25. package/dist/commands/sessions.js.map +1 -0
  26. package/dist/commands/shared.d.ts +32 -0
  27. package/dist/commands/shared.js +60 -0
  28. package/dist/commands/shared.js.map +1 -0
  29. package/dist/commands/users.d.ts +4 -0
  30. package/dist/commands/users.js +87 -0
  31. package/dist/commands/users.js.map +1 -0
  32. package/dist/commands/webhooks.d.ts +4 -0
  33. package/dist/commands/webhooks.js +34 -0
  34. package/dist/commands/webhooks.js.map +1 -0
  35. package/dist/config-http.d.ts +27 -0
  36. package/dist/config-http.js +63 -0
  37. package/dist/config-http.js.map +1 -0
  38. package/dist/config.d.ts +48 -0
  39. package/dist/config.js +69 -0
  40. package/dist/config.js.map +1 -0
  41. package/dist/context.d.ts +51 -0
  42. package/dist/context.js +27 -0
  43. package/dist/context.js.map +1 -0
  44. package/dist/errors.d.ts +15 -0
  45. package/dist/errors.js +25 -0
  46. package/dist/errors.js.map +1 -0
  47. package/dist/help.d.ts +8 -0
  48. package/dist/help.js +114 -0
  49. package/dist/help.js.map +1 -0
  50. package/dist/index.d.ts +22 -0
  51. package/dist/index.js +49 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/io.d.ts +21 -0
  54. package/dist/io.js +28 -0
  55. package/dist/io.js.map +1 -0
  56. package/dist/output.d.ts +41 -0
  57. package/dist/output.js +72 -0
  58. package/dist/output.js.map +1 -0
  59. package/dist/prompt.d.ts +15 -0
  60. package/dist/prompt.js +46 -0
  61. package/dist/prompt.js.map +1 -0
  62. package/dist/run.d.ts +12 -0
  63. package/dist/run.js +94 -0
  64. package/dist/run.js.map +1 -0
  65. package/dist/serialize.d.ts +31 -0
  66. package/dist/serialize.js +248 -0
  67. package/dist/serialize.js.map +1 -0
  68. package/dist/version.d.ts +7 -0
  69. package/dist/version.js +21 -0
  70. package/dist/version.js.map +1 -0
  71. package/package.json +35 -3
package/dist/config.js ADDED
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MemoryConfigStore = exports.FileConfigStore = void 0;
4
+ exports.defaultConfigPath = defaultConfigPath;
5
+ const node_fs_1 = require("node:fs");
6
+ const node_os_1 = require("node:os");
7
+ const node_path_1 = require("node:path");
8
+ const errors_1 = require("./errors");
9
+ const EMPTY = { profiles: {} };
10
+ /**
11
+ * Resolve the default config path: `$XDG_CONFIG_HOME/atlasauth/config.json`,
12
+ * falling back to `~/.config/atlasauth/config.json`. Honoring XDG keeps the CLI
13
+ * a good citizen on Linux while still working on macOS, where `~/.config` is
14
+ * the de-facto convention CLIs use.
15
+ */
16
+ function defaultConfigPath(env = process.env) {
17
+ const base = env.XDG_CONFIG_HOME?.trim() || (0, node_path_1.join)((0, node_os_1.homedir)(), '.config');
18
+ return (0, node_path_1.join)(base, 'atlasauth', 'config.json');
19
+ }
20
+ /** The real store: a JSON file written with 0600 perms and a 0700 parent dir. */
21
+ class FileConfigStore {
22
+ path;
23
+ constructor(path) {
24
+ this.path = path;
25
+ }
26
+ load() {
27
+ let text;
28
+ try {
29
+ text = (0, node_fs_1.readFileSync)(this.path, 'utf8');
30
+ }
31
+ catch {
32
+ // Missing file is the first-run state, not an error.
33
+ return { profiles: {} };
34
+ }
35
+ try {
36
+ const parsed = JSON.parse(text);
37
+ // Guard against a hand-corrupted file so every later `.profiles[...]` is safe.
38
+ return { active_profile: parsed.active_profile, profiles: parsed.profiles ?? {} };
39
+ }
40
+ catch {
41
+ throw new errors_1.CliError(`Config file at ${this.path} is not valid JSON. Fix or remove it, then run 'atlas login' again.`);
42
+ }
43
+ }
44
+ save(config) {
45
+ (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(this.path), { recursive: true, mode: 0o700 });
46
+ // Write THEN chmod: `mode` on writeFile is masked by umask and skipped
47
+ // entirely if the file already exists, so an explicit chmod is the only
48
+ // way to guarantee 0600 on every save.
49
+ (0, node_fs_1.writeFileSync)(this.path, JSON.stringify(config, null, 2) + '\n', { mode: 0o600 });
50
+ (0, node_fs_1.chmodSync)(this.path, 0o600);
51
+ }
52
+ }
53
+ exports.FileConfigStore = FileConfigStore;
54
+ /** An in-memory store for tests that still want to exercise the resolve logic. */
55
+ class MemoryConfigStore {
56
+ path = '<memory>';
57
+ data;
58
+ constructor(initial = EMPTY) {
59
+ this.data = structuredClone(initial);
60
+ }
61
+ load() {
62
+ return structuredClone(this.data);
63
+ }
64
+ save(config) {
65
+ this.data = structuredClone(config);
66
+ }
67
+ }
68
+ exports.MemoryConfigStore = MemoryConfigStore;
69
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;AA0CA,8CAGC;AA7CD,qCAA4E;AAC5E,qCAAkC;AAClC,yCAA0C;AAC1C,qCAAoC;AA+BpC,MAAM,KAAK,GAAe,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AAE3C;;;;;GAKG;AACH,SAAgB,iBAAiB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACpE,MAAM,IAAI,GAAG,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,IAAA,gBAAI,EAAC,IAAA,iBAAO,GAAE,EAAE,SAAS,CAAC,CAAC;IACvE,OAAO,IAAA,gBAAI,EAAC,IAAI,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;AAChD,CAAC;AAED,iFAAiF;AACjF,MAAa,eAAe;IACL;IAArB,YAAqB,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;IAErC,IAAI;QACF,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,GAAG,IAAA,sBAAY,EAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,qDAAqD;YACrD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAe,CAAC;YAC9C,+EAA+E;YAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACpF,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,iBAAQ,CAChB,kBAAkB,IAAI,CAAC,IAAI,qEAAqE,CACjG,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,CAAC,MAAkB;QACrB,IAAA,mBAAS,EAAC,IAAA,mBAAO,EAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAChE,uEAAuE;QACvE,wEAAwE;QACxE,uCAAuC;QACvC,IAAA,uBAAa,EAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAClF,IAAA,mBAAS,EAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC9B,CAAC;CACF;AA9BD,0CA8BC;AAED,kFAAkF;AAClF,MAAa,iBAAiB;IACnB,IAAI,GAAG,UAAU,CAAC;IACnB,IAAI,CAAa;IACzB,YAAY,UAAsB,KAAK;QACrC,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IACD,IAAI;QACF,OAAO,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,CAAC,MAAkB;QACrB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;CACF;AAZD,8CAYC"}
@@ -0,0 +1,51 @@
1
+ import { type AtlasClient } from '@atlasauth/backend';
2
+ import { type ConfigStore } from './config';
3
+ import { type ConfigHttp } from './config-http';
4
+ import { type IO } from './io';
5
+ import { type Prompter } from './prompt';
6
+ /**
7
+ * The exact slice of the Backend API client this CLI drives. Narrowed from the
8
+ * full {@link AtlasClient} on purpose: it documents — and the typechecker
9
+ * enforces — that the command set maps only onto namespaces that really exist,
10
+ * and it keeps the fake a test injects small (five namespaces, not forty).
11
+ */
12
+ export type ManagementClient = Pick<AtlasClient, 'users' | 'organizations' | 'apiKeys' | 'webhooks' | 'sessions' | 'actions'>;
13
+ /**
14
+ * Everything a command touches the outside world through, in one injectable
15
+ * bag. Production wires the real IO/config/prompt/client; every test builds
16
+ * this with fakes so a handler runs with no network, no TTY and no real
17
+ * `~/.config` file.
18
+ */
19
+ export interface RunContext {
20
+ io: IO;
21
+ /** Process environment — read for `ATLAS_SECRET_KEY` / `ATLAS_API_URL`. */
22
+ env: NodeJS.ProcessEnv;
23
+ config: ConfigStore;
24
+ prompt: Prompter;
25
+ /** Builds the Backend API client from a resolved credential. */
26
+ makeClient: (opts: {
27
+ secretKey: string;
28
+ apiUrl: string;
29
+ }) => ManagementClient;
30
+ /**
31
+ * Builds the raw management-API HTTP client used by `atlas config` (the
32
+ * config-only `/v1` endpoints the typed client omits). Optional so existing
33
+ * contexts stay valid; the config command falls back to the real one.
34
+ */
35
+ makeHttp?: (opts: {
36
+ secretKey: string;
37
+ apiUrl: string;
38
+ }) => ConfigHttp;
39
+ /**
40
+ * Read a file's text, for commands that take a path (`atlas actions deploy`
41
+ * / `test`). Injectable so a test drives them with an in-memory file instead
42
+ * of touching the disk. Defaults to reading UTF-8 off the real filesystem.
43
+ */
44
+ readFile: (path: string) => string;
45
+ }
46
+ /**
47
+ * The production context, with any piece overridable. Tests call this with a
48
+ * `config` pointed at a temp path and a `makeClient` returning a stub, so the
49
+ * same `run()` path is exercised end to end without side effects.
50
+ */
51
+ export declare function defaultContext(overrides?: Partial<RunContext>): RunContext;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultContext = defaultContext;
4
+ const node_fs_1 = require("node:fs");
5
+ const backend_1 = require("@atlasauth/backend");
6
+ const config_1 = require("./config");
7
+ const config_http_1 = require("./config-http");
8
+ const io_1 = require("./io");
9
+ const prompt_1 = require("./prompt");
10
+ /**
11
+ * The production context, with any piece overridable. Tests call this with a
12
+ * `config` pointed at a temp path and a `makeClient` returning a stub, so the
13
+ * same `run()` path is exercised end to end without side effects.
14
+ */
15
+ function defaultContext(overrides = {}) {
16
+ return {
17
+ io: (0, io_1.defaultIO)(),
18
+ env: process.env,
19
+ config: new config_1.FileConfigStore((0, config_1.defaultConfigPath)()),
20
+ prompt: (0, prompt_1.defaultPrompter)(),
21
+ makeClient: ({ secretKey, apiUrl }) => (0, backend_1.createAtlasClient)({ secretKey, apiUrl }),
22
+ makeHttp: ({ secretKey, apiUrl }) => (0, config_http_1.createConfigHttp)({ secretKey, apiUrl }),
23
+ readFile: (path) => (0, node_fs_1.readFileSync)(path, 'utf8'),
24
+ ...overrides,
25
+ };
26
+ }
27
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":";;AAmDA,wCAWC;AA9DD,qCAAuC;AACvC,gDAAyE;AACzE,qCAAgF;AAChF,+CAAkE;AAClE,6BAA0C;AAC1C,qCAA0D;AAyC1D;;;;GAIG;AACH,SAAgB,cAAc,CAAC,YAAiC,EAAE;IAChE,OAAO;QACL,EAAE,EAAE,IAAA,cAAS,GAAE;QACf,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,MAAM,EAAE,IAAI,wBAAe,CAAC,IAAA,0BAAiB,GAAE,CAAC;QAChD,MAAM,EAAE,IAAA,wBAAe,GAAE;QACzB,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,IAAA,2BAAiB,EAAC,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QAC/E,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,IAAA,8BAAgB,EAAC,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QAC5E,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,sBAAY,EAAC,IAAI,EAAE,MAAM,CAAC;QAC9C,GAAG,SAAS;KACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The one error a command handler throws to abort with a clean, user-facing
3
+ * message and a chosen exit code. {@link run} catches it, prints `message` to
4
+ * stderr (no stack), and returns `exitCode` — so a bad flag or a missing key
5
+ * never dumps a stack trace at the terminal the way an uncaught throw would.
6
+ *
7
+ * API failures are NOT CliErrors: they arrive as `AtlasApiError` from
8
+ * `@atlasauth/backend` and {@link run} formats those separately so the stable
9
+ * error `code` and HTTP status survive to the user.
10
+ */
11
+ export declare class CliError extends Error {
12
+ readonly name = "CliError";
13
+ readonly exitCode: number;
14
+ constructor(message: string, exitCode?: number);
15
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CliError = void 0;
4
+ /**
5
+ * The one error a command handler throws to abort with a clean, user-facing
6
+ * message and a chosen exit code. {@link run} catches it, prints `message` to
7
+ * stderr (no stack), and returns `exitCode` — so a bad flag or a missing key
8
+ * never dumps a stack trace at the terminal the way an uncaught throw would.
9
+ *
10
+ * API failures are NOT CliErrors: they arrive as `AtlasApiError` from
11
+ * `@atlasauth/backend` and {@link run} formats those separately so the stable
12
+ * error `code` and HTTP status survive to the user.
13
+ */
14
+ class CliError extends Error {
15
+ name = 'CliError';
16
+ exitCode;
17
+ constructor(message, exitCode = 1) {
18
+ super(message);
19
+ this.exitCode = exitCode;
20
+ // Keep `instanceof CliError` working under down-level compile targets.
21
+ Object.setPrototypeOf(this, CliError.prototype);
22
+ }
23
+ }
24
+ exports.CliError = CliError;
25
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;GASG;AACH,MAAa,QAAS,SAAQ,KAAK;IACf,IAAI,GAAG,UAAU,CAAC;IAC3B,QAAQ,CAAS;IAE1B,YAAY,OAAe,EAAE,QAAQ,GAAG,CAAC;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,uEAAuE;QACvE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IAClD,CAAC;CACF;AAVD,4BAUC"}
package/dist/help.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * All help text lives here as plain strings — the CLI's "docs" surface. Kept
3
+ * out of the handlers so the dispatch code stays about control flow and the
4
+ * copy can be read (and kept consistent) in one place.
5
+ */
6
+ export declare const TOP_HELP = "atlas \u2014 manage an Atlas instance from the terminal\n\nUsage: atlas <command> [subcommand] [arguments] [options]\n\nCommands:\n login Authenticate and store a profile credential\n logout Remove a stored profile credential\n whoami Show the active profile and instance\n users list|get|create|delete\n orgs list|get|members\n api-keys list|create|revoke\n webhooks list\n sessions revoke\n config export|import Config-as-code: round-trip the instance's config\n actions list|deploy|test|logs\n\nGlobal options:\n --profile <name> Use a named profile (default: active, else \"default\")\n --json Emit raw JSON instead of a human table\n --limit <n> Page size for list commands that paginate\n --starting-after <cursor> Pagination cursor (from a prior page's hint)\n -h, --help Show this help, or help for a command\n -v, --version Print the version\n\nEnvironment overrides:\n ATLAS_SECRET_KEY Secret key to use instead of the stored one\n ATLAS_API_URL API URL to use instead of the stored one\n\nRun 'atlas <command> --help' for command-specific help.";
7
+ /** Per-command help, keyed by the resource word. */
8
+ export declare const COMMAND_HELP: Record<string, string>;
package/dist/help.js ADDED
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ /**
3
+ * All help text lives here as plain strings — the CLI's "docs" surface. Kept
4
+ * out of the handlers so the dispatch code stays about control flow and the
5
+ * copy can be read (and kept consistent) in one place.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.COMMAND_HELP = exports.TOP_HELP = void 0;
9
+ exports.TOP_HELP = `atlas — manage an Atlas instance from the terminal
10
+
11
+ Usage: atlas <command> [subcommand] [arguments] [options]
12
+
13
+ Commands:
14
+ login Authenticate and store a profile credential
15
+ logout Remove a stored profile credential
16
+ whoami Show the active profile and instance
17
+ users list|get|create|delete
18
+ orgs list|get|members
19
+ api-keys list|create|revoke
20
+ webhooks list
21
+ sessions revoke
22
+ config export|import Config-as-code: round-trip the instance's config
23
+ actions list|deploy|test|logs
24
+
25
+ Global options:
26
+ --profile <name> Use a named profile (default: active, else "default")
27
+ --json Emit raw JSON instead of a human table
28
+ --limit <n> Page size for list commands that paginate
29
+ --starting-after <cursor> Pagination cursor (from a prior page's hint)
30
+ -h, --help Show this help, or help for a command
31
+ -v, --version Print the version
32
+
33
+ Environment overrides:
34
+ ATLAS_SECRET_KEY Secret key to use instead of the stored one
35
+ ATLAS_API_URL API URL to use instead of the stored one
36
+
37
+ Run 'atlas <command> --help' for command-specific help.`;
38
+ /** Per-command help, keyed by the resource word. */
39
+ exports.COMMAND_HELP = {
40
+ login: `atlas login — authenticate and store a profile credential
41
+
42
+ Usage: atlas login [--profile <name>] [--url <api-url>] [--secret-key <sk_...>]
43
+
44
+ Prompts for an API URL and a secret key, validates the key with one Backend
45
+ call, then stores it (0600) under the profile. --url / --secret-key skip the
46
+ prompts for non-interactive setup.`,
47
+ logout: `atlas logout — remove a stored profile credential
48
+
49
+ Usage: atlas logout [--profile <name>]`,
50
+ whoami: `atlas whoami — show the active profile and instance
51
+
52
+ Usage: atlas whoami [--profile <name>] [--json]`,
53
+ users: `atlas users — manage users
54
+
55
+ Usage:
56
+ atlas users list [--limit <n>] [--starting-after <cursor>] [--json]
57
+ atlas users get <user-id> [--json]
58
+ atlas users create --email <address> [--first-name <n>] [--last-name <n>] [--password <p>] [--json]
59
+ atlas users delete <user-id> [--json]`,
60
+ orgs: `atlas orgs — manage organizations
61
+
62
+ Usage:
63
+ atlas orgs list [--limit <n>] [--starting-after <cursor>] [--json]
64
+ atlas orgs get <org-id> [--json]
65
+ atlas orgs members <org-id> [--json]`,
66
+ 'api-keys': `atlas api-keys — manage end-user API keys
67
+
68
+ Usage:
69
+ atlas api-keys list [--subject-type <user|organization>] [--subject-id <id>] [--json]
70
+ atlas api-keys create --subject-type <user|organization> --subject-id <id> [--name <n>] [--json]
71
+ atlas api-keys revoke <api-key-id> [--json]`,
72
+ webhooks: `atlas webhooks — inspect webhook endpoints
73
+
74
+ Usage:
75
+ atlas webhooks list [--json]`,
76
+ sessions: `atlas sessions — manage sessions
77
+
78
+ Usage:
79
+ atlas sessions revoke <session-id> [--json]`,
80
+ config: `atlas config — config-as-code for an Atlas instance (the Auth0 deploy-cli peer)
81
+
82
+ Usage:
83
+ atlas config export [--dir <path>] [--format json|yaml]
84
+ atlas config import [--dir <path>] [--format json|yaml] [--dry-run] [--prune]
85
+
86
+ export Read the instance's current config (instance/auth config, OAuth clients
87
+ and providers, SSO connections, resource servers, JWT templates, roles,
88
+ webhook endpoints, billing plans, redirect URLs, org settings schema,
89
+ notification and email templates, org policies) and write a deterministic
90
+ directory tree — one file per resource type, keys sorted, SECRETS OMITTED.
91
+
92
+ import Diff the directory against live config and apply creates/updates
93
+ idempotently. A resource type with no file is left untouched.
94
+ --dry-run print the plan and apply nothing
95
+ --prune also delete live resources absent from the config
96
+ --dir config directory (default: ./atlas-config)
97
+ --format json (default) or yaml
98
+
99
+ Secrets never live on disk. Inject a credential at import with a \${ENV_VAR}
100
+ placeholder in a file (e.g. a provider "client_secret": "\${GOOGLE_SECRET}").`,
101
+ actions: `atlas actions — manage Actions (tenant code run in the auth pipeline)
102
+
103
+ Usage:
104
+ atlas actions list [--json]
105
+ atlas actions deploy <file> --trigger <post_login|pre_user_registration|post_user_registration> [--name <n>] [--json]
106
+ atlas actions test <file> [--trigger <t>] [--json]
107
+ atlas actions logs <action-id> [--json]
108
+
109
+ deploy uploads the file's code verbatim as a new action (created, not yet bound).
110
+ test runs the file OFFLINE through the @atlasauth/actions harness — no network,
111
+ no real users — and exits non-zero if the action throws. logs explains where an
112
+ action's execution history is recorded (Atlas has no live log-stream endpoint).`,
113
+ };
114
+ //# sourceMappingURL=help.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEU,QAAA,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;wDA4BgC,CAAC;AAEzD,oDAAoD;AACvC,QAAA,YAAY,GAA2B;IAClD,KAAK,EAAE;;;;;;mCAM0B;IAEjC,MAAM,EAAE;;uCAE6B;IAErC,MAAM,EAAE;;gDAEsC;IAE9C,KAAK,EAAE;;;;;;wCAM+B;IAEtC,IAAI,EAAE;;;;;uCAK+B;IAErC,UAAU,EAAE;;;;;8CAKgC;IAE5C,QAAQ,EAAE;;;+BAGmB;IAE7B,QAAQ,EAAE;;;8CAGkC;IAE5C,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;8EAoBoE;IAC5E,OAAO,EAAE;;;;;;;;;;;gFAWqE;CAC/E,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Library surface of `@atlasauth/cli`. The package ships a bin (`atlas`), but
3
+ * exporting the pieces lets the handlers be unit-tested with injected deps and
4
+ * lets another tool embed the CLI (e.g. `create-atlas-app`) without spawning a
5
+ * child process.
6
+ */
7
+ export { run, type Handler } from './run';
8
+ export { defaultContext, type RunContext, type ManagementClient } from './context';
9
+ export { createConfigHttp, isNotFound, type ConfigHttp } from './config-http';
10
+ export { CliError } from './errors';
11
+ export { defaultIO, captureIO, type IO, type CaptureIO } from './io';
12
+ export { FileConfigStore, MemoryConfigStore, defaultConfigPath, type ConfigStore, type ConfigFile, type Profile, } from './config';
13
+ export { defaultPrompter, type Prompter } from './prompt';
14
+ export { getVersion } from './version';
15
+ export { login, logout, whoami } from './commands/auth';
16
+ export { users } from './commands/users';
17
+ export { orgs } from './commands/orgs';
18
+ export { apiKeys } from './commands/api-keys';
19
+ export { webhooks } from './commands/webhooks';
20
+ export { sessions } from './commands/sessions';
21
+ export { config } from './commands/config';
22
+ export { actions } from './commands/actions';
package/dist/index.js ADDED
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.actions = exports.config = exports.sessions = exports.webhooks = exports.apiKeys = exports.orgs = exports.users = exports.whoami = exports.logout = exports.login = exports.getVersion = exports.defaultPrompter = exports.defaultConfigPath = exports.MemoryConfigStore = exports.FileConfigStore = exports.captureIO = exports.defaultIO = exports.CliError = exports.isNotFound = exports.createConfigHttp = exports.defaultContext = exports.run = void 0;
4
+ /**
5
+ * Library surface of `@atlasauth/cli`. The package ships a bin (`atlas`), but
6
+ * exporting the pieces lets the handlers be unit-tested with injected deps and
7
+ * lets another tool embed the CLI (e.g. `create-atlas-app`) without spawning a
8
+ * child process.
9
+ */
10
+ var run_1 = require("./run");
11
+ Object.defineProperty(exports, "run", { enumerable: true, get: function () { return run_1.run; } });
12
+ var context_1 = require("./context");
13
+ Object.defineProperty(exports, "defaultContext", { enumerable: true, get: function () { return context_1.defaultContext; } });
14
+ var config_http_1 = require("./config-http");
15
+ Object.defineProperty(exports, "createConfigHttp", { enumerable: true, get: function () { return config_http_1.createConfigHttp; } });
16
+ Object.defineProperty(exports, "isNotFound", { enumerable: true, get: function () { return config_http_1.isNotFound; } });
17
+ var errors_1 = require("./errors");
18
+ Object.defineProperty(exports, "CliError", { enumerable: true, get: function () { return errors_1.CliError; } });
19
+ var io_1 = require("./io");
20
+ Object.defineProperty(exports, "defaultIO", { enumerable: true, get: function () { return io_1.defaultIO; } });
21
+ Object.defineProperty(exports, "captureIO", { enumerable: true, get: function () { return io_1.captureIO; } });
22
+ var config_1 = require("./config");
23
+ Object.defineProperty(exports, "FileConfigStore", { enumerable: true, get: function () { return config_1.FileConfigStore; } });
24
+ Object.defineProperty(exports, "MemoryConfigStore", { enumerable: true, get: function () { return config_1.MemoryConfigStore; } });
25
+ Object.defineProperty(exports, "defaultConfigPath", { enumerable: true, get: function () { return config_1.defaultConfigPath; } });
26
+ var prompt_1 = require("./prompt");
27
+ Object.defineProperty(exports, "defaultPrompter", { enumerable: true, get: function () { return prompt_1.defaultPrompter; } });
28
+ var version_1 = require("./version");
29
+ Object.defineProperty(exports, "getVersion", { enumerable: true, get: function () { return version_1.getVersion; } });
30
+ // The individual command handlers, exported for direct testing/embedding.
31
+ var auth_1 = require("./commands/auth");
32
+ Object.defineProperty(exports, "login", { enumerable: true, get: function () { return auth_1.login; } });
33
+ Object.defineProperty(exports, "logout", { enumerable: true, get: function () { return auth_1.logout; } });
34
+ Object.defineProperty(exports, "whoami", { enumerable: true, get: function () { return auth_1.whoami; } });
35
+ var users_1 = require("./commands/users");
36
+ Object.defineProperty(exports, "users", { enumerable: true, get: function () { return users_1.users; } });
37
+ var orgs_1 = require("./commands/orgs");
38
+ Object.defineProperty(exports, "orgs", { enumerable: true, get: function () { return orgs_1.orgs; } });
39
+ var api_keys_1 = require("./commands/api-keys");
40
+ Object.defineProperty(exports, "apiKeys", { enumerable: true, get: function () { return api_keys_1.apiKeys; } });
41
+ var webhooks_1 = require("./commands/webhooks");
42
+ Object.defineProperty(exports, "webhooks", { enumerable: true, get: function () { return webhooks_1.webhooks; } });
43
+ var sessions_1 = require("./commands/sessions");
44
+ Object.defineProperty(exports, "sessions", { enumerable: true, get: function () { return sessions_1.sessions; } });
45
+ var config_2 = require("./commands/config");
46
+ Object.defineProperty(exports, "config", { enumerable: true, get: function () { return config_2.config; } });
47
+ var actions_1 = require("./commands/actions");
48
+ Object.defineProperty(exports, "actions", { enumerable: true, get: function () { return actions_1.actions; } });
49
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH,6BAA0C;AAAjC,0FAAA,GAAG,OAAA;AACZ,qCAAmF;AAA1E,yGAAA,cAAc,OAAA;AACvB,6CAA8E;AAArE,+GAAA,gBAAgB,OAAA;AAAE,yGAAA,UAAU,OAAA;AACrC,mCAAoC;AAA3B,kGAAA,QAAQ,OAAA;AACjB,2BAAqE;AAA5D,+FAAA,SAAS,OAAA;AAAE,+FAAA,SAAS,OAAA;AAC7B,mCAOkB;AANhB,yGAAA,eAAe,OAAA;AACf,2GAAA,iBAAiB,OAAA;AACjB,2GAAA,iBAAiB,OAAA;AAKnB,mCAA0D;AAAjD,yGAAA,eAAe,OAAA;AACxB,qCAAuC;AAA9B,qGAAA,UAAU,OAAA;AAEnB,0EAA0E;AAC1E,wCAAwD;AAA/C,6FAAA,KAAK,OAAA;AAAE,8FAAA,MAAM,OAAA;AAAE,8FAAA,MAAM,OAAA;AAC9B,0CAAyC;AAAhC,8FAAA,KAAK,OAAA;AACd,wCAAuC;AAA9B,4FAAA,IAAI,OAAA;AACb,gDAA8C;AAArC,mGAAA,OAAO,OAAA;AAChB,gDAA+C;AAAtC,oGAAA,QAAQ,OAAA;AACjB,gDAA+C;AAAtC,oGAAA,QAAQ,OAAA;AACjB,4CAA2C;AAAlC,gGAAA,MAAM,OAAA;AACf,8CAA6C;AAApC,kGAAA,OAAO,OAAA"}
package/dist/io.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The two sinks every command writes through, named so tests can capture
3
+ * output instead of spying on `console`. `out` is the data channel (tables,
4
+ * JSON, the answer a script would pipe); `err` is for diagnostics, prompts'
5
+ * echoes and error messages — exactly the stdout/stderr split a `--json`
6
+ * consumer relies on to parse stdout cleanly.
7
+ */
8
+ export interface IO {
9
+ out(text: string): void;
10
+ err(text: string): void;
11
+ }
12
+ /** The real IO: a trailing newline is added so callers pass bare lines. */
13
+ export declare function defaultIO(stdout?: NodeJS.WriteStream, stderr?: NodeJS.WriteStream): IO;
14
+ /** An in-memory IO for tests, exposing the captured lines plus joined views. */
15
+ export interface CaptureIO extends IO {
16
+ readonly outLines: string[];
17
+ readonly errLines: string[];
18
+ stdout(): string;
19
+ stderr(): string;
20
+ }
21
+ export declare function captureIO(): CaptureIO;
package/dist/io.js ADDED
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultIO = defaultIO;
4
+ exports.captureIO = captureIO;
5
+ /** The real IO: a trailing newline is added so callers pass bare lines. */
6
+ function defaultIO(stdout = process.stdout, stderr = process.stderr) {
7
+ return {
8
+ out(text) {
9
+ stdout.write(text + '\n');
10
+ },
11
+ err(text) {
12
+ stderr.write(text + '\n');
13
+ },
14
+ };
15
+ }
16
+ function captureIO() {
17
+ const outLines = [];
18
+ const errLines = [];
19
+ return {
20
+ outLines,
21
+ errLines,
22
+ out: (text) => void outLines.push(text),
23
+ err: (text) => void errLines.push(text),
24
+ stdout: () => outLines.join('\n'),
25
+ stderr: () => errLines.join('\n'),
26
+ };
27
+ }
28
+ //# sourceMappingURL=io.js.map
package/dist/io.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io.js","sourceRoot":"","sources":["../src/io.ts"],"names":[],"mappings":";;AAaA,8BAYC;AAUD,8BAWC;AAlCD,2EAA2E;AAC3E,SAAgB,SAAS,CACvB,SAA6B,OAAO,CAAC,MAAM,EAC3C,SAA6B,OAAO,CAAC,MAAM;IAE3C,OAAO;QACL,GAAG,CAAC,IAAI;YACN,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QAC5B,CAAC;QACD,GAAG,CAAC,IAAI;YACN,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QAC5B,CAAC;KACF,CAAC;AACJ,CAAC;AAUD,SAAgB,SAAS;IACvB,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,OAAO;QACL,QAAQ;QACR,QAAQ;QACR,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QACvC,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QACvC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QACjC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;KAClC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { IO } from './io';
2
+ /**
3
+ * A single rendered column: a header plus a getter that pulls the raw value off
4
+ * a row. Getters (not keys) because a few columns are derived — a user's name
5
+ * joins first + last, a webhook's events join an array — and a getter keeps that
6
+ * shaping next to the column instead of forcing a pre-massaged row.
7
+ */
8
+ export interface Column<T> {
9
+ header: string;
10
+ get: (row: T) => unknown;
11
+ }
12
+ /**
13
+ * Epoch-millisecond timestamp → ISO-8601, the form every Atlas `*_at` field
14
+ * takes on the wire. Blank for null (e.g. a user who never signed in) so the
15
+ * column stays readable rather than printing `1970-...`.
16
+ */
17
+ export declare function fmtTime(value: unknown): string;
18
+ /**
19
+ * Hand-rolled fixed-width table — the only "formatting library" this CLI has.
20
+ * Columns are padded to the widest cell (header included); a dashed rule sits
21
+ * under the header; trailing padding on the last column is trimmed so lines
22
+ * don't carry invisible whitespace. Empty input prints a friendly placeholder
23
+ * rather than a bare header with no rows.
24
+ */
25
+ export declare function renderTable<T>(columns: Column<T>[], rows: T[]): string;
26
+ /** Pretty-print any value as the `--json` output on stdout. */
27
+ export declare function printJson(io: IO, value: unknown): void;
28
+ /**
29
+ * Print a cursor-paginated list as either raw JSON or a table, and — in table
30
+ * mode, when there is another page — a footer naming the exact flag to fetch
31
+ * it. Keeping the hint next to the data is what makes `--starting-after`
32
+ * discoverable without the user reading `--help`.
33
+ */
34
+ export declare function printList<T>(io: IO, opts: {
35
+ json: boolean;
36
+ columns: Column<T>[];
37
+ }, page: {
38
+ data: T[];
39
+ has_more?: boolean;
40
+ next_cursor?: string | null;
41
+ }, raw?: unknown): void;
package/dist/output.js ADDED
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fmtTime = fmtTime;
4
+ exports.renderTable = renderTable;
5
+ exports.printJson = printJson;
6
+ exports.printList = printList;
7
+ /** Render a value as a table cell: null/undefined blank, arrays joined, objects JSON. */
8
+ function cell(value) {
9
+ if (value === null || value === undefined)
10
+ return '';
11
+ if (Array.isArray(value))
12
+ return value.map((v) => cell(v)).join(', ');
13
+ if (typeof value === 'object')
14
+ return JSON.stringify(value);
15
+ return String(value);
16
+ }
17
+ /**
18
+ * Epoch-millisecond timestamp → ISO-8601, the form every Atlas `*_at` field
19
+ * takes on the wire. Blank for null (e.g. a user who never signed in) so the
20
+ * column stays readable rather than printing `1970-...`.
21
+ */
22
+ function fmtTime(value) {
23
+ if (value === null || value === undefined)
24
+ return '';
25
+ const n = Number(value);
26
+ if (!Number.isFinite(n))
27
+ return '';
28
+ return new Date(n).toISOString();
29
+ }
30
+ /**
31
+ * Hand-rolled fixed-width table — the only "formatting library" this CLI has.
32
+ * Columns are padded to the widest cell (header included); a dashed rule sits
33
+ * under the header; trailing padding on the last column is trimmed so lines
34
+ * don't carry invisible whitespace. Empty input prints a friendly placeholder
35
+ * rather than a bare header with no rows.
36
+ */
37
+ function renderTable(columns, rows) {
38
+ if (rows.length === 0)
39
+ return '(no results)';
40
+ const matrix = rows.map((row) => columns.map((col) => cell(col.get(row))));
41
+ const widths = columns.map((col, i) => Math.max(col.header.length, ...matrix.map((r) => r[i].length)));
42
+ const pad = (text, width) => text.padEnd(width);
43
+ const line = (fields) => fields.map((f, i) => pad(f, widths[i])).join(' ').replace(/\s+$/, '');
44
+ const lines = [
45
+ line(columns.map((c) => c.header)),
46
+ line(widths.map((w) => '-'.repeat(w))),
47
+ ...matrix.map((r) => line(r)),
48
+ ];
49
+ return lines.join('\n');
50
+ }
51
+ /** Pretty-print any value as the `--json` output on stdout. */
52
+ function printJson(io, value) {
53
+ io.out(JSON.stringify(value, null, 2));
54
+ }
55
+ /**
56
+ * Print a cursor-paginated list as either raw JSON or a table, and — in table
57
+ * mode, when there is another page — a footer naming the exact flag to fetch
58
+ * it. Keeping the hint next to the data is what makes `--starting-after`
59
+ * discoverable without the user reading `--help`.
60
+ */
61
+ function printList(io, opts, page, raw = page) {
62
+ if (opts.json) {
63
+ printJson(io, raw);
64
+ return;
65
+ }
66
+ io.out(renderTable(opts.columns, page.data));
67
+ if (page.has_more && page.next_cursor) {
68
+ io.out('');
69
+ io.out(`More results — fetch the next page with: --starting-after ${page.next_cursor}`);
70
+ }
71
+ }
72
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The interactive input seam for `atlas login`. An interface (not a direct
3
+ * `readline` call) so tests script answers without a TTY, and so `secret()`
4
+ * can hide the key no matter where it's wired.
5
+ */
6
+ export interface Prompter {
7
+ /** A visible line of input, with an optional default shown in brackets. */
8
+ text(query: string, opts?: {
9
+ default?: string;
10
+ }): Promise<string>;
11
+ /** A hidden line of input — the terminal never echoes what's typed. */
12
+ secret(query: string): Promise<string>;
13
+ }
14
+ /** The real prompter, reading the TTY. Not exercised by unit tests (they inject). */
15
+ export declare function defaultPrompter(input?: NodeJS.ReadableStream, output?: NodeJS.WritableStream): Prompter;