@atlasauth/cli 0.1.0 → 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.
- package/README.md +34 -0
- package/dist/args.d.ts +15 -0
- package/dist/args.js +7 -0
- package/dist/args.js.map +1 -1
- package/dist/commands/actions.d.ts +11 -0
- package/dist/commands/actions.js +120 -0
- package/dist/commands/actions.js.map +1 -0
- package/dist/commands/config.d.ts +4 -0
- package/dist/commands/config.js +716 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/config-http.d.ts +27 -0
- package/dist/config-http.js +63 -0
- package/dist/config-http.js.map +1 -0
- package/dist/context.d.ts +17 -1
- package/dist/context.js +4 -0
- package/dist/context.js.map +1 -1
- package/dist/help.d.ts +1 -1
- package/dist/help.js +35 -0
- package/dist/help.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/run.js +4 -0
- package/dist/run.js.map +1 -1
- package/dist/serialize.d.ts +31 -0
- package/dist/serialize.js +248 -0
- package/dist/serialize.js.map +1 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -42,6 +42,8 @@ atlas orgs list | get <id> | members <id>
|
|
|
42
42
|
atlas api-keys list | create --subject-type <t> --subject-id <id> | revoke <id>
|
|
43
43
|
atlas webhooks list
|
|
44
44
|
atlas sessions revoke <id>
|
|
45
|
+
atlas config export [--dir <path>] [--format json|yaml]
|
|
46
|
+
atlas config import [--dir <path>] [--format json|yaml] [--dry-run] [--prune]
|
|
45
47
|
```
|
|
46
48
|
|
|
47
49
|
Every command takes `--json` for raw JSON (otherwise a human table). Paginated
|
|
@@ -56,3 +58,35 @@ atlas api-keys create --subject-type user --subject-id user_123 --name ci
|
|
|
56
58
|
|
|
57
59
|
Run `atlas --help` or `atlas <command> --help` for details, `atlas --version`
|
|
58
60
|
for the version.
|
|
61
|
+
|
|
62
|
+
## Config-as-code (`atlas config`)
|
|
63
|
+
|
|
64
|
+
The Auth0 `deploy-cli` equivalent: round-trip an instance's configuration to a
|
|
65
|
+
deterministic directory tree you keep in Git. `export` writes one file per
|
|
66
|
+
resource type with sorted keys and **secrets omitted**; `import` diffs the
|
|
67
|
+
directory against the live instance and applies creates/updates idempotently.
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
atlas config export --dir ./atlas-config # snapshot the instance
|
|
71
|
+
atlas config import --dir ./atlas-config --dry-run # preview the plan
|
|
72
|
+
atlas config import --dir ./atlas-config # apply creates/updates
|
|
73
|
+
atlas config import --dir ./atlas-config --prune # also delete removed resources
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Managed resource types (the same set the Terraform provider manages):
|
|
77
|
+
`instance` (auth config + allowed origins), `oauth_clients`, `oauth_providers`,
|
|
78
|
+
`sso_connections`, `resource_servers`, `jwt_templates`, `roles`,
|
|
79
|
+
`webhook_endpoints`, `billing_plans`, `redirect_urls`, `org_settings_schema`,
|
|
80
|
+
`notification_templates`, `email_templates`, `organization_policies`.
|
|
81
|
+
|
|
82
|
+
Rules that make it safe and repeatable:
|
|
83
|
+
|
|
84
|
+
- **Deterministic.** Keys are sorted, so re-exporting an unchanged instance is a
|
|
85
|
+
byte-for-byte no-op and a round-trip (`export` then `import`) is an empty diff.
|
|
86
|
+
- **No secrets on disk.** The management API never returns a secret on a read,
|
|
87
|
+
so none is ever written. To (re)write a credential at import, put a
|
|
88
|
+
`${ENV_VAR}` placeholder in the file; it is resolved from the environment.
|
|
89
|
+
- **Non-destructive.** `import` never deletes without `--prune`, and a resource
|
|
90
|
+
type with no file is left untouched (only committed types are managed).
|
|
91
|
+
|
|
92
|
+
Ship it on push with the [`atlas-deploy` GitHub Action](../../actions/atlas-deploy).
|
package/dist/args.d.ts
CHANGED
|
@@ -52,6 +52,21 @@ declare const OPTIONS: {
|
|
|
52
52
|
readonly name: {
|
|
53
53
|
readonly type: "string";
|
|
54
54
|
};
|
|
55
|
+
readonly dir: {
|
|
56
|
+
readonly type: "string";
|
|
57
|
+
};
|
|
58
|
+
readonly format: {
|
|
59
|
+
readonly type: "string";
|
|
60
|
+
};
|
|
61
|
+
readonly 'dry-run': {
|
|
62
|
+
readonly type: "boolean";
|
|
63
|
+
};
|
|
64
|
+
readonly prune: {
|
|
65
|
+
readonly type: "boolean";
|
|
66
|
+
};
|
|
67
|
+
readonly trigger: {
|
|
68
|
+
readonly type: "string";
|
|
69
|
+
};
|
|
55
70
|
};
|
|
56
71
|
export type Values = {
|
|
57
72
|
[K in keyof typeof OPTIONS]?: (typeof OPTIONS)[K]['type'] extends 'boolean' ? boolean : string;
|
package/dist/args.js
CHANGED
|
@@ -31,6 +31,13 @@ const OPTIONS = {
|
|
|
31
31
|
'subject-type': { type: 'string' },
|
|
32
32
|
'subject-id': { type: 'string' },
|
|
33
33
|
name: { type: 'string' },
|
|
34
|
+
// config export / import.
|
|
35
|
+
dir: { type: 'string' },
|
|
36
|
+
format: { type: 'string' },
|
|
37
|
+
'dry-run': { type: 'boolean' },
|
|
38
|
+
prune: { type: 'boolean' },
|
|
39
|
+
// actions.
|
|
40
|
+
trigger: { type: 'string' },
|
|
34
41
|
};
|
|
35
42
|
/** Parse argv, turning parseArgs' own errors (unknown/invalid flag) into clean CliErrors. */
|
|
36
43
|
function parse(argv) {
|
package/dist/args.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ParsedArgs } from '../args';
|
|
2
|
+
import type { RunContext } from '../context';
|
|
3
|
+
/**
|
|
4
|
+
* `atlas actions` — manage tenant Actions (code run in the auth pipeline).
|
|
5
|
+
*
|
|
6
|
+
* list the instance's actions
|
|
7
|
+
* deploy <file> --trigger <t> upload a file's code as a new action
|
|
8
|
+
* test <file> [--trigger <t>] dry-run the file OFFLINE through @atlasauth/actions
|
|
9
|
+
* logs <id> where to find an action's execution history
|
|
10
|
+
*/
|
|
11
|
+
export declare function actions(ctx: RunContext, args: ParsedArgs): Promise<number>;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.actions = actions;
|
|
4
|
+
const node_path_1 = require("node:path");
|
|
5
|
+
const actions_1 = require("@atlasauth/actions");
|
|
6
|
+
const args_1 = require("../args");
|
|
7
|
+
const errors_1 = require("../errors");
|
|
8
|
+
const output_1 = require("../output");
|
|
9
|
+
const shared_1 = require("./shared");
|
|
10
|
+
const COLUMNS = [
|
|
11
|
+
{ header: 'ID', get: (a) => a.id },
|
|
12
|
+
{ header: 'NAME', get: (a) => a.name },
|
|
13
|
+
{ header: 'TRIGGER', get: (a) => a.trigger },
|
|
14
|
+
{ header: 'ENABLED', get: (a) => a.enabled },
|
|
15
|
+
{ header: 'SECRETS', get: (a) => a.secret_names },
|
|
16
|
+
{ header: 'UPDATED', get: (a) => (0, output_1.fmtTime)(a.updated_at) },
|
|
17
|
+
];
|
|
18
|
+
/** Validate a `--trigger` value against the known set, with a clean error. */
|
|
19
|
+
function parseTrigger(raw) {
|
|
20
|
+
if (!raw) {
|
|
21
|
+
throw new errors_1.CliError(`--trigger is required (one of: ${actions_1.ACTION_TRIGGERS.join(', ')}).`);
|
|
22
|
+
}
|
|
23
|
+
if (!actions_1.ACTION_TRIGGERS.includes(raw)) {
|
|
24
|
+
throw new errors_1.CliError(`Unknown trigger '${raw}'. Expected one of: ${actions_1.ACTION_TRIGGERS.join(', ')}.`);
|
|
25
|
+
}
|
|
26
|
+
return raw;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* `atlas actions` — manage tenant Actions (code run in the auth pipeline).
|
|
30
|
+
*
|
|
31
|
+
* list the instance's actions
|
|
32
|
+
* deploy <file> --trigger <t> upload a file's code as a new action
|
|
33
|
+
* test <file> [--trigger <t>] dry-run the file OFFLINE through @atlasauth/actions
|
|
34
|
+
* logs <id> where to find an action's execution history
|
|
35
|
+
*/
|
|
36
|
+
async function actions(ctx, args) {
|
|
37
|
+
const sub = args.positionals[1];
|
|
38
|
+
const json = (0, shared_1.wantsJson)(args.values);
|
|
39
|
+
switch (sub) {
|
|
40
|
+
case 'list': {
|
|
41
|
+
const { client } = (0, shared_1.requireClient)(ctx, args.values);
|
|
42
|
+
const page = await client.actions.list();
|
|
43
|
+
if (json)
|
|
44
|
+
(0, output_1.printJson)(ctx.io, page);
|
|
45
|
+
else
|
|
46
|
+
ctx.io.out((0, output_1.renderTable)(COLUMNS, page.data));
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
case 'deploy': {
|
|
50
|
+
const file = (0, shared_1.requireArg)(args.positionals, 2, 'file');
|
|
51
|
+
const trigger = parseTrigger((0, args_1.str)(args.values, 'trigger'));
|
|
52
|
+
const code = ctx.readFile(file);
|
|
53
|
+
if (!code.trim())
|
|
54
|
+
throw new errors_1.CliError(`'${file}' is empty — nothing to deploy.`);
|
|
55
|
+
const name = (0, args_1.str)(args.values, 'name') || (0, node_path_1.basename)(file).replace(/\.[^.]+$/, '');
|
|
56
|
+
const { client } = (0, shared_1.requireClient)(ctx, args.values);
|
|
57
|
+
const action = await client.actions.create({ name, trigger, code });
|
|
58
|
+
if (json)
|
|
59
|
+
(0, output_1.printJson)(ctx.io, action);
|
|
60
|
+
else {
|
|
61
|
+
ctx.io.out(`Deployed action ${action.id} (${action.name}) for ${action.trigger}.`);
|
|
62
|
+
ctx.io.err(`It is created but NOT yet bound to the ${action.trigger} flow — bind it to run it.`);
|
|
63
|
+
}
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
case 'test': {
|
|
67
|
+
const file = (0, shared_1.requireArg)(args.positionals, 2, 'file');
|
|
68
|
+
// Default to post_login's sample event; --trigger picks another shape.
|
|
69
|
+
const trigger = (0, args_1.str)(args.values, 'trigger')
|
|
70
|
+
? parseTrigger((0, args_1.str)(args.values, 'trigger'))
|
|
71
|
+
: 'post_login';
|
|
72
|
+
const code = ctx.readFile(file);
|
|
73
|
+
if (!code.trim())
|
|
74
|
+
throw new errors_1.CliError(`'${file}' is empty — nothing to test.`);
|
|
75
|
+
// OFFLINE: no network, no client — the local harness mirrors the isolate.
|
|
76
|
+
const result = await (0, actions_1.runScript)(code, (0, actions_1.createTestEvent)(trigger));
|
|
77
|
+
if (json) {
|
|
78
|
+
(0, output_1.printJson)(ctx.io, result);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
ctx.io.out(`Trigger: ${trigger}`);
|
|
82
|
+
ctx.io.out(`Denied: ${result.denied}${result.denyReason ? ` (${result.denyReason})` : ''}`);
|
|
83
|
+
ctx.io.out(`ID claims: ${JSON.stringify(result.idTokenClaims)}`);
|
|
84
|
+
ctx.io.out(`AT claims: ${JSON.stringify(result.accessTokenClaims)}`);
|
|
85
|
+
ctx.io.out(`Metadata: ${JSON.stringify(result.appMetadata)}`);
|
|
86
|
+
if (result.logs.length)
|
|
87
|
+
ctx.io.out(`Logs:\n ${result.logs.join('\n ')}`);
|
|
88
|
+
if (result.error)
|
|
89
|
+
ctx.io.err(`Error: ${result.error}`);
|
|
90
|
+
}
|
|
91
|
+
// A thrown error in the action is a failed dry-run → non-zero so CI catches it.
|
|
92
|
+
return result.error ? 1 : 0;
|
|
93
|
+
}
|
|
94
|
+
case 'logs': {
|
|
95
|
+
const id = (0, shared_1.requireArg)(args.positionals, 2, 'action-id');
|
|
96
|
+
// The Backend API does not expose a per-action execution-log endpoint:
|
|
97
|
+
// each run is written as an audit event (`action.<trigger>`) carrying the
|
|
98
|
+
// outcome, duration and captured logs. Point the user at where to read it
|
|
99
|
+
// rather than pretend an endpoint exists.
|
|
100
|
+
const lines = [
|
|
101
|
+
`Atlas does not expose a live log stream for action ${id}.`,
|
|
102
|
+
'Each execution is recorded as an audit event named `action.<trigger>`',
|
|
103
|
+
'(outcome, duration, deny reason / error, and the action\'s console logs).',
|
|
104
|
+
'Read them in the dashboard audit log, or stream them via a configured',
|
|
105
|
+
'log stream. To see what an action WOULD do right now, dry-run it:',
|
|
106
|
+
` atlas actions test <file> --trigger <trigger>`,
|
|
107
|
+
];
|
|
108
|
+
if (json)
|
|
109
|
+
(0, output_1.printJson)(ctx.io, { object: 'action_logs_info', action_id: id, message: lines.join(' ') });
|
|
110
|
+
else
|
|
111
|
+
ctx.io.out(lines.join('\n'));
|
|
112
|
+
return 0;
|
|
113
|
+
}
|
|
114
|
+
default:
|
|
115
|
+
throw new errors_1.CliError(sub
|
|
116
|
+
? `Unknown subcommand 'actions ${sub}'. Try: list, deploy, test, logs.`
|
|
117
|
+
: 'actions needs a subcommand: list, deploy, test, logs.');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/commands/actions.ts"],"names":[],"mappings":"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"}
|