@atlasauth/cli 0.5.0 → 0.7.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.
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.migrate = migrate;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ const upgrade_1 = require("@atlasauth/upgrade");
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 migrate code --from <vendor> [path]` — rewrite an app's auth code onto
13
+ * Atlas (Clerk, Auth.js/NextAuth, Supabase Auth, Auth0, Better Auth).
14
+ *
15
+ * Safe by default: without `--yes` it is a dry run that prints the diff of every
16
+ * file it would change plus a report of what it could not rewrite (file:line).
17
+ * `--yes` writes the changes. Running it again over migrated code changes nothing.
18
+ * Users move separately, with `atlas import --from <vendor>`.
19
+ */
20
+ async function migrate(ctx, args) {
21
+ const sub = args.positionals[1];
22
+ if (sub !== 'code') {
23
+ throw new errors_1.CliError(sub ? `Unknown subcommand 'migrate ${sub}'. Try: code.` : 'migrate needs a subcommand: code.');
24
+ }
25
+ const raw = (0, args_1.str)(args.values, 'from');
26
+ const vendor = (0, upgrade_1.resolveVendor)(raw);
27
+ if (!vendor) {
28
+ throw new errors_1.CliError(raw
29
+ ? `Unknown --from '${raw}'. Use one of: ${upgrade_1.MIGRATE_VENDORS.join(', ')}.`
30
+ : `migrate code needs --from <${upgrade_1.MIGRATE_VENDORS.join('|')}>.`);
31
+ }
32
+ const target = (0, node_path_1.resolve)(args.positionals[2] ?? process.cwd());
33
+ if (!(0, node_fs_1.existsSync)(target))
34
+ throw new errors_1.CliError(`Path not found: ${target}`);
35
+ const write = args.values.yes === true && args.values['dry-run'] !== true;
36
+ const result = (0, upgrade_1.runMigration)(target, { from: vendor, write });
37
+ if ((0, shared_1.wantsJson)(args.values)) {
38
+ (0, output_1.printJson)(ctx.io, {
39
+ object: 'code_migration',
40
+ vendor: result.vendor,
41
+ written: write,
42
+ env_style: result.envStyle,
43
+ files_scanned: result.filesScanned,
44
+ files_changed: result.filesChanged,
45
+ rewrites: result.rewrites,
46
+ changes: result.changes.map((c) => ({ path: c.path, diff: (0, upgrade_1.unifiedDiff)(c.before, c.after, c.path) })),
47
+ manual: result.manual,
48
+ packages: result.packages,
49
+ env_to_set: result.envToSet,
50
+ });
51
+ return 0;
52
+ }
53
+ for (const change of result.changes) {
54
+ if (write)
55
+ ctx.io.out(`updated ${change.path}`);
56
+ else {
57
+ ctx.io.out((0, upgrade_1.unifiedDiff)(change.before, change.after, change.path));
58
+ ctx.io.out('');
59
+ }
60
+ }
61
+ for (const line of (0, upgrade_1.formatMigration)(result, { written: write }))
62
+ ctx.io.out(line);
63
+ return 0;
64
+ }
65
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"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"}
@@ -4,12 +4,12 @@ import type { RunContext } from '../context';
4
4
  * `atlas referrals connect | backfill | status`: referral attribution from the
5
5
  * terminal.
6
6
  *
7
- * `connect --provider referally` is bring-your-own-key: the Referally merchant
8
- * key is used for one call (it creates the Atlas connection on Referally) and
9
- * is never stored or printed. The connection id and secret Referally returns
7
+ * `connect --provider referally` is bring-your-own-key: the Referalli merchant
8
+ * key is used for one call (it creates the Atlas connection on Referalli) and
9
+ * is never stored or printed. The connection id and secret Referalli returns
10
10
  * go straight onto the instance; the secret is never printed either.
11
11
  */
12
- /** The Referally API version pinned on every call. */
12
+ /** The Referalli API version pinned on every call. */
13
13
  export declare const REFERALLY_VERSION = "2026-10-21";
14
14
  interface PingRead {
15
15
  ok?: boolean;
@@ -36,12 +36,12 @@ export declare function pingSkewMs(ping: PingRead, receivedAt: number, latencyMs
36
36
  export declare function describeTestLines(test: TestRead, receivedAt: number): string[];
37
37
  /** A `customerRef,code` CSV → map; throws on a bad line. A header row is skipped. */
38
38
  export declare function parseCodeCsv(text: string): Record<string, string>;
39
- /** The Referally topics two-way sync subscribes to (changes to a referral after sign-up). */
39
+ /** The Referalli topics two-way sync subscribes to (changes to a referral after sign-up). */
40
40
  export declare const REFERALLY_SYNC_TOPICS: readonly ["referral.created", "referral.held", "referral.paused", "referral.resumed", "referral.approved", "referral.voided", "referral.reassigned"];
41
41
  /**
42
42
  * Whether the merchant key reaches live or test data: the org's `livemode`,
43
43
  * else the key prefix (rk_test_ = test; rk_live_ and older rk_ keys = live).
44
- * `known` is false when Referally reports no mode (no test mode there).
44
+ * `known` is false when Referalli reports no mode (no test mode there).
45
45
  */
46
46
  export declare function referallyKeyMode(ctx: RunContext, input: {
47
47
  baseUrl: string;
@@ -19,12 +19,12 @@ const shared_1 = require("./shared");
19
19
  * `atlas referrals connect | backfill | status`: referral attribution from the
20
20
  * terminal.
21
21
  *
22
- * `connect --provider referally` is bring-your-own-key: the Referally merchant
23
- * key is used for one call (it creates the Atlas connection on Referally) and
24
- * is never stored or printed. The connection id and secret Referally returns
22
+ * `connect --provider referally` is bring-your-own-key: the Referalli merchant
23
+ * key is used for one call (it creates the Atlas connection on Referalli) and
24
+ * is never stored or printed. The connection id and secret Referalli returns
25
25
  * go straight onto the instance; the secret is never printed either.
26
26
  */
27
- /** The Referally API version pinned on every call. */
27
+ /** The Referalli API version pinned on every call. */
28
28
  exports.REFERALLY_VERSION = '2026-10-21';
29
29
  const PROVIDERS = ['referally', 'webhook'];
30
30
  /** Read a key from a file, or stdin with '-'. A bare key or a dotenv line. Never printed. */
@@ -113,7 +113,7 @@ function parseCodeCsv(text) {
113
113
  });
114
114
  return out;
115
115
  }
116
- /** One call to the Referally merchant API with the merchant key. Throws a CliError naming `what` on failure. */
116
+ /** One call to the Referalli merchant API with the merchant key. Throws a CliError naming `what` on failure. */
117
117
  async function referallyRequest(ctx, input) {
118
118
  const fetchImpl = ctx.fetch ?? globalThis.fetch;
119
119
  let res;
@@ -130,7 +130,7 @@ async function referallyRequest(ctx, input) {
130
130
  });
131
131
  }
132
132
  catch (err) {
133
- throw new errors_1.CliError(`Could not reach Referally at ${input.baseUrl}: ${err instanceof Error ? err.message : String(err)}`);
133
+ throw new errors_1.CliError(`Could not reach Referalli at ${input.baseUrl}: ${err instanceof Error ? err.message : String(err)}`);
134
134
  }
135
135
  const text = await res.text();
136
136
  let json = {};
@@ -146,18 +146,18 @@ async function referallyRequest(ctx, input) {
146
146
  (Array.isArray(err) && err[0] && typeof err[0] === 'object' && 'message' in err[0] ? String(err[0].message) : null) ??
147
147
  (typeof json.message === 'string' ? json.message : null);
148
148
  const hint = res.status === 401 || res.status === 403 ? ' Check the merchant key.' : '';
149
- throw new errors_1.CliError(`Referally refused to ${input.what} (HTTP ${res.status})${msg ? `: ${msg}` : ''}.${hint}`);
149
+ throw new errors_1.CliError(`Referalli refused to ${input.what} (HTTP ${res.status})${msg ? `: ${msg}` : ''}.${hint}`);
150
150
  }
151
151
  return json;
152
152
  }
153
153
  async function referallyCreateConnection(ctx, input) {
154
154
  const json = await referallyRequest(ctx, { ...input, method: 'POST', path: '/v1/auth/connections', what: 'create the connection' });
155
155
  if (typeof json.id !== 'string' || typeof json.secret !== 'string') {
156
- throw new errors_1.CliError('Referally answered without a connection id and secret.');
156
+ throw new errors_1.CliError('Referalli answered without a connection id and secret.');
157
157
  }
158
158
  return json;
159
159
  }
160
- /** The Referally topics two-way sync subscribes to (changes to a referral after sign-up). */
160
+ /** The Referalli topics two-way sync subscribes to (changes to a referral after sign-up). */
161
161
  exports.REFERALLY_SYNC_TOPICS = [
162
162
  'referral.created',
163
163
  'referral.held',
@@ -170,7 +170,7 @@ exports.REFERALLY_SYNC_TOPICS = [
170
170
  /**
171
171
  * Whether the merchant key reaches live or test data: the org's `livemode`,
172
172
  * else the key prefix (rk_test_ = test; rk_live_ and older rk_ keys = live).
173
- * `known` is false when Referally reports no mode (no test mode there).
173
+ * `known` is false when Referalli reports no mode (no test mode there).
174
174
  */
175
175
  async function referallyKeyMode(ctx, input) {
176
176
  try {
@@ -206,12 +206,12 @@ async function connect(ctx, args) {
206
206
  throw new errors_1.CliError('referrals connect --provider referally needs --program <prg_…>.');
207
207
  const baseRaw = (0, args_1.str)(v, 'base-url') ?? ctx.env.REFERALLY_BASE_URL?.trim();
208
208
  if (!baseRaw)
209
- throw new errors_1.CliError('Pass --base-url <your Referally base URL> (or set REFERALLY_BASE_URL).');
209
+ throw new errors_1.CliError('Pass --base-url <your Referalli base URL> (or set REFERALLY_BASE_URL).');
210
210
  const baseUrl = httpsUrl(baseRaw, '--base-url');
211
211
  const keyFile = (0, args_1.str)(v, 'referally-key-file');
212
- const key = (0, args_1.str)(v, 'referally-key') ?? (keyFile ? readKeyFile(ctx, keyFile, 'the Referally key') : ctx.env.REFERALLY_API_KEY?.trim());
212
+ const key = (0, args_1.str)(v, 'referally-key') ?? (keyFile ? readKeyFile(ctx, keyFile, 'the Referalli key') : ctx.env.REFERALLY_API_KEY?.trim());
213
213
  if (!key) {
214
- throw new errors_1.CliError('Pass your Referally merchant key with --referally-key-file <path|-> (or --referally-key, or REFERALLY_API_KEY). It is used once and never stored.');
214
+ throw new errors_1.CliError('Pass your Referalli merchant key with --referally-key-file <path|-> (or --referally-key, or REFERALLY_API_KEY). It is used once and never stored.');
215
215
  }
216
216
  const destination = (0, args_1.str)(v, 'destination');
217
217
  if (destination)
@@ -222,7 +222,7 @@ async function connect(ctx, args) {
222
222
  const instanceLive = instance.environment === 'production';
223
223
  const mode = await referallyKeyMode(ctx, { baseUrl, key });
224
224
  if (mode.known && mode.live !== instanceLive) {
225
- const message = `the Referally key reaches ${mode.live ? 'live' : 'test'} data but instance ${instance.id} is ` +
225
+ const message = `the Referalli key reaches ${mode.live ? 'live' : 'test'} data but instance ${instance.id} is ` +
226
226
  `${instance.environment ?? 'not production'}. Use ${instanceLive ? 'a live (rk_live_…)' : 'a test (rk_test_…)'} key` +
227
227
  ` for it, or pass --allow-mode-mismatch.`;
228
228
  if (v['allow-mode-mismatch'] !== true)
@@ -230,7 +230,7 @@ async function connect(ctx, args) {
230
230
  ctx.io.err(`atlas: warning: ${message.replace(/, or pass --allow-mode-mismatch\.$/, '.')}`);
231
231
  }
232
232
  else if (!mode.known && !instanceLive) {
233
- ctx.io.err(`atlas: warning: Referally did not say whether this key reaches test data; instance ${instance.id} is ${instance.environment ?? 'not production'}.`);
233
+ ctx.io.err(`atlas: warning: Referalli did not say whether this key reaches test data; instance ${instance.id} is ${instance.environment ?? 'not production'}.`);
234
234
  }
235
235
  const created = await referallyCreateConnection(ctx, {
236
236
  baseUrl,
@@ -274,21 +274,21 @@ async function connect(ctx, args) {
274
274
  saved = await http.patch('/v1/instance/referrals', patch);
275
275
  }
276
276
  catch (err) {
277
- // The secret is shown once by Referally: keep it so the merchant can finish by hand.
277
+ // The secret is shown once by Referalli: keep it so the merchant can finish by hand.
278
278
  const saved = (0, secrets_1.deliverSecret)({
279
279
  io: out,
280
280
  env: ctx.env,
281
281
  product,
282
282
  fileName: `referally-connection-${created.id}.env`,
283
283
  entries: { REFERALLY_CONNECTION_ID: created.id, REFERALLY_CONNECTION_SECRET: created.secret },
284
- label: 'The Referally connection secret (not saved on Atlas)',
284
+ label: 'The Referalli connection secret (not saved on Atlas)',
285
285
  force: v.force === true,
286
- comment: `Referally connection ${created.id}: saving it on the Atlas instance failed. Paste it in Users → Referrals.`,
286
+ comment: `Referalli connection ${created.id}: saving it on the Atlas instance failed. Paste it in Users → Referrals.`,
287
287
  });
288
- ctx.io.err(`atlas: the connection ${created.id} was created on Referally, but saving it on the instance failed.${saved.path ? ` Its secret is in ${saved.path}.` : ''}`);
288
+ ctx.io.err(`atlas: the connection ${created.id} was created on Referalli, but saving it on the instance failed.${saved.path ? ` Its secret is in ${saved.path}.` : ''}`);
289
289
  throw err;
290
290
  }
291
- // Two-way sync: Referally's referral events go to the instance's inbound URL.
291
+ // Two-way sync: Referalli's referral events go to the instance's inbound URL.
292
292
  let syncEndpoint = null;
293
293
  const inboundUrl = saved?.inbound?.url ?? null;
294
294
  if (v['no-sync'] !== true && inboundUrl) {
@@ -302,7 +302,7 @@ async function connect(ctx, args) {
302
302
  what: 'register the referral event webhook',
303
303
  });
304
304
  if (typeof endpoint.id !== 'string' || typeof endpoint.secret !== 'string') {
305
- throw new errors_1.CliError('Referally answered without a webhook endpoint id and secret.');
305
+ throw new errors_1.CliError('Referalli answered without a webhook endpoint id and secret.');
306
306
  }
307
307
  try {
308
308
  await http.patch('/v1/instance/referrals', { inbound_secret: endpoint.secret, inbound_endpoint_id: endpoint.id });
@@ -315,17 +315,17 @@ async function connect(ctx, args) {
315
315
  product,
316
316
  fileName: `referally-webhook-${endpoint.id}.env`,
317
317
  entries: { REFERALLY_WEBHOOK_ENDPOINT_ID: endpoint.id, REFERALLY_WEBHOOK_SECRET: endpoint.secret },
318
- label: 'The Referally webhook secret (not saved on Atlas)',
318
+ label: 'The Referalli webhook secret (not saved on Atlas)',
319
319
  force: v.force === true,
320
- comment: `Referally webhook ${endpoint.id}: saving it on the Atlas instance failed. Paste it as the inbound secret in Users → Referrals.`,
320
+ comment: `Referalli webhook ${endpoint.id}: saving it on the Atlas instance failed. Paste it as the inbound secret in Users → Referrals.`,
321
321
  });
322
- ctx.io.err(`atlas: warning: the webhook ${endpoint.id} was registered on Referally, but saving its secret failed (${err instanceof Error ? err.message : String(err)}).${kept.path ? ` It is in ${kept.path}.` : ''}`);
322
+ ctx.io.err(`atlas: warning: the webhook ${endpoint.id} was registered on Referalli, but saving its secret failed (${err instanceof Error ? err.message : String(err)}).${kept.path ? ` It is in ${kept.path}.` : ''}`);
323
323
  }
324
324
  }
325
325
  catch (err) {
326
326
  if (!(err instanceof errors_1.CliError))
327
327
  throw err;
328
- ctx.io.err(`atlas: warning: ${err.message} Referral changes on Referally won't reach Atlas until it is registered (see the docs).`);
328
+ ctx.io.err(`atlas: warning: ${err.message} Referral changes on Referalli won't reach Atlas until it is registered (see the docs).`);
329
329
  }
330
330
  }
331
331
  summary = {
@@ -340,9 +340,9 @@ async function connect(ctx, args) {
340
340
  sync_endpoint_id: syncEndpoint,
341
341
  };
342
342
  if (!json) {
343
- out.out(`Created Referally connection ${created.id} for instance ${instance.id} and saved it (the secret was not printed).`);
343
+ out.out(`Created Referalli connection ${created.id} for instance ${instance.id} and saved it (the secret was not printed).`);
344
344
  if (syncEndpoint)
345
- out.out(`Referral changes on Referally sync back to Atlas (webhook ${syncEndpoint}).`);
345
+ out.out(`Referral changes on Referalli sync back to Atlas (webhook ${syncEndpoint}).`);
346
346
  }
347
347
  }
348
348
  else {
@@ -516,7 +516,7 @@ async function status(ctx, args) {
516
516
  lines.push(`Failed (7 days): ${c.failed_calls_7d ?? 0} Retrying: ${c.retrying_calls ?? 0}`);
517
517
  const inbound = settings.inbound;
518
518
  if (inbound?.url) {
519
- // Referally needs its own webhook secret; the Atlas protocol falls back to the signing secret.
519
+ // Referalli needs its own webhook secret; the Atlas protocol falls back to the signing secret.
520
520
  const syncing = inbound.secret_set || (settings.provider === 'webhook' && settings.signing_secret_set);
521
521
  lines.push(`Two-way sync: ${syncing ? 'on' : 'off (no inbound secret)'}${inbound.endpoint_id ? ` (webhook ${inbound.endpoint_id})` : ''}`);
522
522
  lines.push(`Inbound URL: ${inbound.url}`);
package/dist/context.d.ts CHANGED
@@ -9,7 +9,7 @@ import { type Prompter } from './prompt';
9
9
  * enforces — that the command set maps only onto namespaces that really exist,
10
10
  * and it keeps the fake a test injects small (five namespaces, not forty).
11
11
  */
12
- export type ManagementClient = Pick<AtlasClient, 'users' | 'organizations' | 'apiKeys' | 'webhooks' | 'sessions' | 'actions'>;
12
+ export type ManagementClient = Pick<AtlasClient, 'users' | 'organizations' | 'apiKeys' | 'webhooks' | 'sessions' | 'actions' | 'actionGallery' | 'actionTemplates'>;
13
13
  /**
14
14
  * Everything a command touches the outside world through, in one injectable
15
15
  * bag. Production wires the real IO/config/prompt/client; every test builds
package/dist/help.d.ts CHANGED
@@ -3,6 +3,6 @@
3
3
  * out of the handlers so the dispatch code stays about control flow and the
4
4
  * copy can be read (and kept consistent) in one place.
5
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|create\n sessions revoke\n config export|import Config-as-code: round-trip the instance's config\n actions list|deploy|test|logs\n init Create or complete an app's setup (idempotent); secrets to 0600 files\n preflight Check an instance's setup; non-zero exit on errors (for CI)\n env Print deploy variables: public values + secret file paths\n client rotate Rotate an OAuth client secret straight into its file\n referrals connect|backfill|status\n Connect a referral platform, backfill, check the connection\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 ATLAS_PLATFORM_KEY Platform key (psk_) for atlas init\n REFERALLY_BASE_URL Referally base URL for atlas referrals connect\n REFERALLY_API_KEY Referally merchant key for atlas referrals connect (never stored)\n\nSecrets: a command that receives a secret writes it to a 0600 file under\n~/.config/<product>/ and prints only the path. --print-secret prints it instead.\n\nRun 'atlas <command> --help' for command-specific help.";
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|create\n sessions revoke\n config export|import Config-as-code: round-trip the instance's config\n actions list|deploy|test|logs|gallery|show|install|installs|update|publish\n init Create or complete an app's setup (idempotent); secrets to 0600 files\n preflight Check an instance's setup; non-zero exit on errors (for CI)\n env Print deploy variables: public values + secret file paths\n client rotate Rotate an OAuth client secret straight into its file\n referrals connect|backfill|status\n Connect a referral platform, backfill, check the connection\n import --from <vendor> <file>\n Move users from Auth0, Clerk, Supabase, Firebase, Cognito,\n Auth.js, WorkOS or Better Auth (resumable; --dry-run first)\n migrate code --from <vendor> [path]\n Rewrite an app's auth code onto Atlas (Clerk, Auth.js,\n Supabase, Auth0, Better Auth); a dry run with a diff unless --yes\n info [path] Print the environment for a support ticket (versions, SDKs,\n instance, API latency, preflight); secrets redacted\n mcp install Add the Atlas MCP server (docs search) to Cursor, Claude Code,\n Codex or VS Code\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 ATLAS_PLATFORM_KEY Platform key (psk_) for atlas init\n REFERALLY_BASE_URL Referalli base URL for atlas referrals connect\n REFERALLY_API_KEY Referalli merchant key for atlas referrals connect (never stored)\n\nSecrets: a command that receives a secret writes it to a 0600 file under\n~/.config/<product>/ and prints only the path. --print-secret prints it instead.\n\nRun 'atlas <command> --help' for command-specific help.";
7
7
  /** Per-command help, keyed by the resource word. */
8
8
  export declare const COMMAND_HELP: Record<string, string>;
package/dist/help.js CHANGED
@@ -20,13 +20,23 @@ Commands:
20
20
  webhooks list|create
21
21
  sessions revoke
22
22
  config export|import Config-as-code: round-trip the instance's config
23
- actions list|deploy|test|logs
23
+ actions list|deploy|test|logs|gallery|show|install|installs|update|publish
24
24
  init Create or complete an app's setup (idempotent); secrets to 0600 files
25
25
  preflight Check an instance's setup; non-zero exit on errors (for CI)
26
26
  env Print deploy variables: public values + secret file paths
27
27
  client rotate Rotate an OAuth client secret straight into its file
28
28
  referrals connect|backfill|status
29
29
  Connect a referral platform, backfill, check the connection
30
+ import --from <vendor> <file>
31
+ Move users from Auth0, Clerk, Supabase, Firebase, Cognito,
32
+ Auth.js, WorkOS or Better Auth (resumable; --dry-run first)
33
+ migrate code --from <vendor> [path]
34
+ Rewrite an app's auth code onto Atlas (Clerk, Auth.js,
35
+ Supabase, Auth0, Better Auth); a dry run with a diff unless --yes
36
+ info [path] Print the environment for a support ticket (versions, SDKs,
37
+ instance, API latency, preflight); secrets redacted
38
+ mcp install Add the Atlas MCP server (docs search) to Cursor, Claude Code,
39
+ Codex or VS Code
30
40
 
31
41
  Global options:
32
42
  --profile <name> Use a named profile (default: active, else "default")
@@ -40,8 +50,8 @@ Environment overrides:
40
50
  ATLAS_SECRET_KEY Secret key to use instead of the stored one
41
51
  ATLAS_API_URL API URL to use instead of the stored one
42
52
  ATLAS_PLATFORM_KEY Platform key (psk_) for atlas init
43
- REFERALLY_BASE_URL Referally base URL for atlas referrals connect
44
- REFERALLY_API_KEY Referally merchant key for atlas referrals connect (never stored)
53
+ REFERALLY_BASE_URL Referalli base URL for atlas referrals connect
54
+ REFERALLY_API_KEY Referalli merchant key for atlas referrals connect (never stored)
45
55
 
46
56
  Secrets: a command that receives a secret writes it to a 0600 file under
47
57
  ~/.config/<product>/ and prints only the path. --print-secret prints it instead.
@@ -49,6 +59,85 @@ Secrets: a command that receives a secret writes it to a 0600 file under
49
59
  Run 'atlas <command> --help' for command-specific help.`;
50
60
  /** Per-command help, keyed by the resource word. */
51
61
  exports.COMMAND_HELP = {
62
+ migrate: `atlas migrate code — rewrite an app's auth code onto Atlas
63
+
64
+ Usage:
65
+ atlas migrate code --from <vendor> [path] [--yes] [--json]
66
+
67
+ Vendors:
68
+ clerk @clerk/* SDKs
69
+ authjs Auth.js / NextAuth (next-auth v4 and v5, @auth/*)
70
+ supabase Supabase Auth (supabase.auth.*, auth-helpers, auth-ui); the
71
+ Supabase client itself stays for your database
72
+ auth0 @auth0/auth0-react, @auth0/nextjs-auth0 (v3 and v4), @auth0/auth0-spa-js
73
+ better-auth better-auth (client, server, Next.js handler, cookies)
74
+
75
+ What it rewrites: imports, providers, hooks, server session helpers, middleware,
76
+ sign-in/out calls and env var names, onto native Atlas APIs and the drop-in
77
+ compat helpers in @atlasauth/react/compat and @atlasauth/nextjs/compat that keep the
78
+ old shapes. Everything it cannot rewrite is listed with file:line and marked in
79
+ code with TODO(atlas-migrate).
80
+
81
+ Options:
82
+ --yes Write the changes (without it: a dry run printing the diff)
83
+ --dry-run Force a dry run even with --yes
84
+ --json Machine-readable result (diffs, report, packages, env)
85
+
86
+ Safe to re-run: migrated code is left as it is. Move your users with
87
+ 'atlas import --from <vendor> <export-file>'.`,
88
+ info: `atlas info — the environment, for support tickets
89
+
90
+ Usage:
91
+ atlas info [path] [--json] [--product <name> | --instance <id>]
92
+
93
+ Prints the CLI, Node and OS versions; the project's framework and Atlas SDK
94
+ packages with the installed version and whether npm has a newer one; the
95
+ configured instance (key prefixes only, never a key) and whether the app's
96
+ publishable key belongs to it; API reachability and latency; and the
97
+ instance's preflight summary. Network steps time out after 5 s and are
98
+ reported, not fatal. Anything shaped like a secret is redacted.`,
99
+ import: `atlas import — move users from another auth provider
100
+
101
+ Usage:
102
+ atlas import --from <vendor> <export-file> [--dry-run]
103
+
104
+ Vendors and the file each one reads:
105
+ auth0 the user export job (NDJSON/JSON); --hashes <file> merges the password export
106
+ clerk the dashboard CSV export, or users JSON from the Backend API
107
+ supabase auth.users rows as CSV or JSON (with an identities array for social links)
108
+ firebase firebase auth:export --format=json; needs --hash-config <file>
109
+ cognito aws cognito-idp list-users JSON, or the user-pool CSV
110
+ authjs the adapter's users + accounts tables as JSON
111
+ workos User Management users JSON (+ organization_memberships)
112
+ better-auth JSON of the user, account, member and organization tables
113
+
114
+ Options:
115
+ --dry-run Map and summarise only; nothing is sent
116
+ --batch-size <n> Users per request, 1-100 (default 100)
117
+ --state-file <file> Progress file (default <export-file>.atlas-import.json); re-running resumes
118
+ --hash-config <file> Firebase hash parameters: {signer_key, salt_separator, rounds, mem_cost}
119
+ --hashes <file> Password hashes keyed by email, merged onto the users
120
+ --create-orgs Create organizations that memberships name but that do not exist yet
121
+ --json Machine-readable summary
122
+
123
+ Batches are sent with upsert, so a resumed or repeated run never duplicates a
124
+ user or a membership. Exit code 2 means some rows were reported as issues.`,
125
+ mcp: `atlas mcp — connect AI coding agents to Atlas
126
+
127
+ Usage:
128
+ atlas mcp install --cursor | --claude-code | --codex | --vscode [--dir <project>] [--global]
129
+
130
+ Adds the Atlas MCP server (npx -y @atlasauth/mcp) to the client's config so the
131
+ agent can search and read the Atlas docs. Servers already in the file are kept.
132
+
133
+ --cursor .cursor/mcp.json in the project (~/.cursor/mcp.json with --global)
134
+ --claude-code .mcp.json in the project
135
+ --codex ~/.codex/config.toml (or $CODEX_HOME/config.toml)
136
+ --vscode .vscode/mcp.json in the project
137
+ --dir <path> The project directory (default: the current directory)
138
+
139
+ No key is written. To also manage your instance from the agent, add
140
+ ATLAS_SECRET_KEY to the server's env yourself.`,
52
141
  referrals: `atlas referrals — referral attribution
53
142
 
54
143
  Usage:
@@ -62,15 +151,15 @@ Usage:
62
151
  [--metadata-path public_metadata.referral_code] [--wait]
63
152
  atlas referrals status
64
153
 
65
- connect --provider referally creates the Atlas connection on Referally with
154
+ connect --provider referally creates the Atlas connection on Referalli with
66
155
  your merchant key (bring your own key: used for this one call, never stored or
67
156
  printed), saves the connection id and secret on the instance, and runs a ping.
68
157
  It requires v2 signatures on the connection from the start and registers a
69
- Referally webhook that sends referral changes (voided, approved, reassigned…)
158
+ Referalli webhook that sends referral changes (voided, approved, reassigned…)
70
159
  back to Atlas; --no-sync skips the webhook. A test key (rk_test_) belongs with a
71
160
  development instance and a live key with production: a mismatch is refused
72
161
  unless --allow-mode-mismatch. --auto-enroll and --destination are passed to
73
- Referally. --enable turns referrals on when the ping passes. Prefer --referally-key-file (or
162
+ Referalli. --enable turns referrals on when the ping passes. Prefer --referally-key-file (or
74
163
  REFERALLY_API_KEY) to --referally-key: a key on the command line can end up in
75
164
  your shell history.
76
165
 
@@ -211,9 +300,24 @@ Usage:
211
300
  atlas actions test <file> [--trigger <t>] [--json]
212
301
  atlas actions logs <action-id> [--json]
213
302
 
303
+ atlas actions gallery [query] [--trigger <t>] [--json]
304
+ atlas actions show <slug> [--json]
305
+ atlas actions install <slug> [--name <n>] [--secrets-file <dotenv>] [--json]
306
+ atlas actions installs [--json]
307
+ atlas actions update <action-id> [--secrets-file <dotenv>] [--json]
308
+ atlas actions publish <template.json> [--draft] [--json]
309
+
214
310
  deploy uploads the file's code verbatim as a new action (created, not yet bound).
215
311
  test runs the file OFFLINE through the @atlasauth/actions harness — no network,
216
312
  no real users — and exits non-zero if the action throws. logs explains where an
217
- action's execution history is recorded (Atlas has no live log-stream endpoint).`,
313
+ action's execution history is recorded (Atlas has no live log-stream endpoint).
314
+
315
+ The gallery: gallery lists first-party and community templates; install copies
316
+ one into the instance as a DISABLED, unbound action (secret values come from a
317
+ dotenv file, never argv); installs shows which actions came from the gallery
318
+ and whether a newer version exists; update moves one to the latest version.
319
+ publish reads a manifest {slug, name, author_name, summary, description,
320
+ category, tags, trigger, license, version, code_file, secrets, changelog},
321
+ creates the template or adds the version, and submits it for review.`,
218
322
  };
219
323
  //# sourceMappingURL=help.js.map
package/dist/help.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEU,QAAA,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wDAwCgC,CAAC;AAEzD,oDAAoD;AACvC,QAAA,YAAY,GAA2B;IAClD,SAAS,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yEAmC4D;IAEvE,KAAK,EAAE;;;;;;mCAM0B;IAEjC,MAAM,EAAE;;uCAE6B;IAErC,MAAM,EAAE;;gDAEsC;IAE9C,KAAK,EAAE;;;;;;wCAM+B;IAEtC,IAAI,EAAE;;;;;uCAK+B;IAErC,UAAU,EAAE;;;;;;8CAMgC;IAE5C,QAAQ,EAAE;;;;;;0EAM8D;IAExE,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;yEA4BiE;IAEvE,SAAS,EAAE;;;;;;oDAMuC;IAElD,GAAG,EAAE;;;;;;;qDAO8C;IAEnD,MAAM,EAAE;;;;;;;;wDAQ8C;IAEtD,QAAQ,EAAE;;;8CAGkC;IAE5C,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;8EAoBoE;IAC5E,OAAO,EAAE;;;;;;;;;;;gFAWqE;CAC/E,CAAC"}
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEU,QAAA,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wDAkDgC,CAAC;AAEzD,oDAAoD;AACvC,QAAA,YAAY,GAA2B;IAClD,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;8CAyBmC;IAC5C,IAAI,EAAE;;;;;;;;;;gEAUwD;IAC9D,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;2EAyBiE;IACzE,GAAG,EAAE;;;;;;;;;;;;;;;+CAewC;IAC7C,SAAS,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yEAmC4D;IAEvE,KAAK,EAAE;;;;;;mCAM0B;IAEjC,MAAM,EAAE;;uCAE6B;IAErC,MAAM,EAAE;;gDAEsC;IAE9C,KAAK,EAAE;;;;;;wCAM+B;IAEtC,IAAI,EAAE;;;;;uCAK+B;IAErC,UAAU,EAAE;;;;;;8CAMgC;IAE5C,QAAQ,EAAE;;;;;;0EAM8D;IAExE,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;yEA4BiE;IAEvE,SAAS,EAAE;;;;;;oDAMuC;IAElD,GAAG,EAAE;;;;;;;qDAO8C;IAEnD,MAAM,EAAE;;;;;;;;wDAQ8C;IAEtD,QAAQ,EAAE;;;8CAGkC;IAE5C,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;8EAoBoE;IAC5E,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;qEA0B0D;CACpE,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * A small RFC 4180 CSV reader for vendor exports: quoted fields, doubled quotes,
3
+ * embedded commas and newlines, CRLF. Returns one object per data row keyed by
4
+ * the header row. No dependency, because the CLI ships none it does not need.
5
+ */
6
+ export declare function parseCsv(text: string): Array<Record<string, string>>;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseCsv = parseCsv;
4
+ /**
5
+ * A small RFC 4180 CSV reader for vendor exports: quoted fields, doubled quotes,
6
+ * embedded commas and newlines, CRLF. Returns one object per data row keyed by
7
+ * the header row. No dependency, because the CLI ships none it does not need.
8
+ */
9
+ function parseCsv(text) {
10
+ const rows = [];
11
+ let row = [];
12
+ let field = '';
13
+ let quoted = false;
14
+ const src = text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
15
+ for (let i = 0; i < src.length; i++) {
16
+ const c = src[i];
17
+ if (quoted) {
18
+ if (c === '"') {
19
+ if (src[i + 1] === '"') {
20
+ field += '"';
21
+ i++;
22
+ }
23
+ else
24
+ quoted = false;
25
+ }
26
+ else
27
+ field += c;
28
+ continue;
29
+ }
30
+ if (c === '"')
31
+ quoted = true;
32
+ else if (c === ',') {
33
+ row.push(field);
34
+ field = '';
35
+ }
36
+ else if (c === '\n' || c === '\r') {
37
+ if (c === '\r' && src[i + 1] === '\n')
38
+ i++;
39
+ row.push(field);
40
+ field = '';
41
+ if (row.some((v) => v !== ''))
42
+ rows.push(row);
43
+ row = [];
44
+ }
45
+ else
46
+ field += c;
47
+ }
48
+ row.push(field);
49
+ if (row.some((v) => v !== ''))
50
+ rows.push(row);
51
+ const [header, ...data] = rows;
52
+ if (!header)
53
+ return [];
54
+ const keys = header.map((h) => h.trim());
55
+ return data.map((cells) => {
56
+ const out = {};
57
+ keys.forEach((k, idx) => {
58
+ out[k] = cells[idx] ?? '';
59
+ });
60
+ return out;
61
+ });
62
+ }
63
+ //# sourceMappingURL=csv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv.js","sourceRoot":"","sources":["../../src/import/csv.ts"],"names":[],"mappings":";;AAKA,4BA2CC;AAhDD;;;;GAIG;AACH,SAAgB,QAAQ,CAAC,IAAY;IACnC,MAAM,IAAI,GAAe,EAAE,CAAC;IAC5B,IAAI,GAAG,GAAa,EAAE,CAAC;IACvB,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEjE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAE,CAAC;QAClB,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;gBACd,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;oBACvB,KAAK,IAAI,GAAG,CAAC;oBACb,CAAC,EAAE,CAAC;gBACN,CAAC;;oBAAM,MAAM,GAAG,KAAK,CAAC;YACxB,CAAC;;gBAAM,KAAK,IAAI,CAAC,CAAC;YAClB,SAAS;QACX,CAAC;QACD,IAAI,CAAC,KAAK,GAAG;YAAE,MAAM,GAAG,IAAI,CAAC;aACxB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YACnB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChB,KAAK,GAAG,EAAE,CAAC;QACb,CAAC;aAAM,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACpC,IAAI,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI;gBAAE,CAAC,EAAE,CAAC;YAC3C,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChB,KAAK,GAAG,EAAE,CAAC;YACX,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC9C,GAAG,GAAG,EAAE,CAAC;QACX,CAAC;;YAAM,KAAK,IAAI,CAAC,CAAC;IACpB,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChB,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;QAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE9C,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAC/B,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACxB,MAAM,GAAG,GAA2B,EAAE,CAAC;QACvC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;YACtB,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Vendor export → Atlas bulk-import rows. Each mapper reads the file format the
3
+ * vendor's own export produces and returns the rows `POST /v1/user_imports`
4
+ * accepts, plus warnings for what could not be carried over. Pure functions of
5
+ * the parsed file, so every mapping is tested from a fixture with no network.
6
+ */
7
+ export declare const VENDORS: readonly ["auth0", "clerk", "supabase", "firebase", "cognito", "authjs", "workos", "better-auth"];
8
+ export type Vendor = (typeof VENDORS)[number];
9
+ export interface ImportMembershipRow {
10
+ organization_id?: string;
11
+ organization_external_id?: string;
12
+ organization_slug?: string;
13
+ organization_name?: string;
14
+ role?: string;
15
+ }
16
+ /** One row of the Atlas import body. Only fields with a value are set. */
17
+ export interface ImportRow {
18
+ email_address: string;
19
+ email_verified?: boolean;
20
+ first_name?: string;
21
+ last_name?: string;
22
+ username?: string;
23
+ external_id?: string;
24
+ created_at?: string | number;
25
+ password_hash?: string;
26
+ password_salt?: string;
27
+ password_hasher?: string;
28
+ phone_numbers?: Array<{
29
+ phone_number: string;
30
+ verified?: boolean;
31
+ }>;
32
+ external_accounts?: Array<{
33
+ provider: string;
34
+ provider_user_id: string;
35
+ email?: string;
36
+ }>;
37
+ organization_memberships?: ImportMembershipRow[];
38
+ public_metadata?: Record<string, unknown>;
39
+ private_metadata?: Record<string, unknown>;
40
+ unsafe_metadata?: Record<string, unknown>;
41
+ }
42
+ export interface MappedExport {
43
+ rows: ImportRow[];
44
+ /** Human-readable notes: records skipped, data that cannot move, follow-ups. */
45
+ warnings: string[];
46
+ }
47
+ /** Parse the file text: a JSON document, newline-delimited JSON, or CSV. */
48
+ export declare function parseExport(text: string, fileName?: string): unknown;
49
+ export declare function atlasProvider(raw: string): string;
50
+ /**
51
+ * Map a parsed vendor export. `hashes` is an optional second file of password
52
+ * hashes keyed by email (Auth0's support export, WorkOS's, or any `{email,
53
+ * password_hash}` list), merged onto the rows.
54
+ */
55
+ export declare function mapExport(vendor: Vendor, doc: unknown, hashes?: unknown): MappedExport;
56
+ /** A one-screen summary of what an import would do (the dry run). */
57
+ export declare function summarize(rows: ImportRow[]): Record<string, number>;