@atlasauth/cli 0.6.0 → 0.8.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 (48) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +5 -0
  3. package/dist/args.d.ts +34 -0
  4. package/dist/args.js +14 -0
  5. package/dist/args.js.map +1 -1
  6. package/dist/commands/actions-gallery.d.ts +8 -0
  7. package/dist/commands/actions-gallery.js +197 -0
  8. package/dist/commands/actions-gallery.js.map +1 -0
  9. package/dist/commands/actions.d.ts +2 -0
  10. package/dist/commands/actions.js +17 -2
  11. package/dist/commands/actions.js.map +1 -1
  12. package/dist/commands/config.d.ts +41 -1
  13. package/dist/commands/config.js +115 -26
  14. package/dist/commands/config.js.map +1 -1
  15. package/dist/commands/import-better-auth.d.ts +3 -0
  16. package/dist/commands/import-better-auth.js +164 -0
  17. package/dist/commands/import-better-auth.js.map +1 -0
  18. package/dist/commands/import.js +7 -0
  19. package/dist/commands/import.js.map +1 -1
  20. package/dist/commands/info.d.ts +75 -0
  21. package/dist/commands/info.js +362 -0
  22. package/dist/commands/info.js.map +1 -0
  23. package/dist/commands/migrate.d.ts +12 -0
  24. package/dist/commands/migrate.js +104 -0
  25. package/dist/commands/migrate.js.map +1 -0
  26. package/dist/context.d.ts +9 -1
  27. package/dist/context.js.map +1 -1
  28. package/dist/help.d.ts +1 -1
  29. package/dist/help.js +102 -2
  30. package/dist/help.js.map +1 -1
  31. package/dist/index.d.ts +4 -0
  32. package/dist/index.js +10 -1
  33. package/dist/index.js.map +1 -1
  34. package/dist/migrate/better-auth/integration.d.ts +59 -0
  35. package/dist/migrate/better-auth/integration.js +81 -0
  36. package/dist/migrate/better-auth/integration.js.map +1 -0
  37. package/dist/migrate/better-auth/orchestrator.d.ts +43 -0
  38. package/dist/migrate/better-auth/orchestrator.js +525 -0
  39. package/dist/migrate/better-auth/orchestrator.js.map +1 -0
  40. package/dist/migrate/better-auth/output.d.ts +20 -0
  41. package/dist/migrate/better-auth/output.js +146 -0
  42. package/dist/migrate/better-auth/output.js.map +1 -0
  43. package/dist/migrate/better-auth/translate.d.ts +77 -0
  44. package/dist/migrate/better-auth/translate.js +1989 -0
  45. package/dist/migrate/better-auth/translate.js.map +1 -0
  46. package/dist/run.js +4 -0
  47. package/dist/run.js.map +1 -1
  48. package/package.json +4 -3
package/dist/help.js CHANGED
@@ -20,7 +20,7 @@ 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
@@ -30,6 +30,16 @@ Commands:
30
30
  import --from <vendor> <file>
31
31
  Move users from Auth0, Clerk, Supabase, Firebase, Cognito,
32
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
+ migrate better-auth [path] Move a Better Auth app to Atlas end to end: config, users,
37
+ sessions and code, resumable (--dry-run, --resume, --yes)
38
+ migrate better-auth config [path]
39
+ Translate the app's betterAuth({...}) options into Atlas
40
+ config files plus a report (offline)
41
+ info [path] Print the environment for a support ticket (versions, SDKs,
42
+ instance, API latency, preflight); secrets redacted
33
43
  mcp install Add the Atlas MCP server (docs search) to Cursor, Claude Code,
34
44
  Codex or VS Code
35
45
 
@@ -54,10 +64,78 @@ Secrets: a command that receives a secret writes it to a 0600 file under
54
64
  Run 'atlas <command> --help' for command-specific help.`;
55
65
  /** Per-command help, keyed by the resource word. */
56
66
  exports.COMMAND_HELP = {
67
+ migrate: `atlas migrate — move an app's auth onto Atlas
68
+
69
+ Usage:
70
+ atlas migrate code --from <vendor> [path] [--yes] [--json]
71
+ atlas migrate better-auth config [path] [--dir <dir>] [--format json|yaml] [--entry <file>] [--json]
72
+ atlas migrate better-auth [path] [--dry-run] [--yes] [--resume] [--force] [--json]
73
+ [--dir <dir>] [--state-file <file>] [--entry <file>] [--bundle <file>] [--run-export]
74
+ [--confirm-conflicts] [--bridge-days <n>] [--skip <step,...>]
75
+
76
+ migrate better-auth config reads your betterAuth({...}) setup statically (it
77
+ follows imports and resolves env vars by NAME, never their values) and writes
78
+ Atlas config-as-code files (the 'atlas config import' format) plus
79
+ better-auth-report.md: what maps 1:1, what maps with a difference, and what
80
+ needs a manual step, each with file:line. Default --dir: atlas-migrate/config.
81
+
82
+ migrate better-auth runs the whole program, checkpointing each step in
83
+ atlas-migrate/state.json (--state-file):
84
+ preflight instance and key, CLI version, the betterAuth() call
85
+ translate the config files and report (as above)
86
+ apply review the diff, confirm, push the config (env placeholders are
87
+ filled from the environment and the app's .env files)
88
+ export run the exporter in the app (prints the command; --run-export runs it)
89
+ import upload the bundle, dry-run report, confirm, import (conflicts with
90
+ existing Atlas users need --confirm-conflicts; a stopped import resumes)
91
+ bridge accept Better Auth sessions for --bridge-days (default 30): no forced logout
92
+ code atlas migrate code --from better-auth, after a confirmation
93
+ verify counts, preflight and a sign-in checklist
94
+ --dry-run walks every step without changing the instance or the code. --yes
95
+ answers every confirmation. --resume continues a stopped run. --json prints the
96
+ step summary (with --json and no --yes it stops at the first confirmation).
97
+
98
+ Code rewrite (migrate code):
99
+
100
+ Vendors:
101
+ clerk @clerk/* SDKs
102
+ authjs Auth.js / NextAuth (next-auth v4 and v5, @auth/*)
103
+ supabase Supabase Auth (supabase.auth.*, auth-helpers, auth-ui); the
104
+ Supabase client itself stays for your database
105
+ auth0 @auth0/auth0-react, @auth0/nextjs-auth0 (v3 and v4), @auth0/auth0-spa-js
106
+ better-auth better-auth (client, server, Next.js handler, cookies)
107
+
108
+ What it rewrites: imports, providers, hooks, server session helpers, middleware,
109
+ sign-in/out calls and env var names, onto native Atlas APIs and the drop-in
110
+ compat helpers in @atlasauth/react/compat and @atlasauth/nextjs/compat that keep the
111
+ old shapes. Everything it cannot rewrite is listed with file:line and marked in
112
+ code with TODO(atlas-migrate).
113
+
114
+ Options:
115
+ --yes Write the changes (without it: a dry run printing the diff)
116
+ --dry-run Force a dry run even with --yes
117
+ --json Machine-readable result (diffs, report, packages, env)
118
+
119
+ Safe to re-run: migrated code is left as it is. Move your users with
120
+ 'atlas import --from <vendor> <export-file>'.`,
121
+ info: `atlas info — the environment, for support tickets
122
+
123
+ Usage:
124
+ atlas info [path] [--json] [--product <name> | --instance <id>]
125
+
126
+ Prints the CLI, Node and OS versions; the project's framework and Atlas SDK
127
+ packages with the installed version and whether npm has a newer one; the
128
+ configured instance (key prefixes only, never a key) and whether the app's
129
+ publishable key belongs to it; API reachability and latency; and the
130
+ instance's preflight summary. Network steps time out after 5 s and are
131
+ reported, not fatal. Anything shaped like a secret is redacted.`,
57
132
  import: `atlas import — move users from another auth provider
58
133
 
59
134
  Usage:
60
135
  atlas import --from <vendor> <export-file> [--dry-run]
136
+ atlas import --from better-auth --bundle <file> [--dry-run] [--yes]
137
+ atlas import --from better-auth --import <id> [--confirm-conflicts]
138
+ atlas import --from better-auth (prints the import key and export command)
61
139
 
62
140
  Vendors and the file each one reads:
63
141
  auth0 the user export job (NDJSON/JSON); --hashes <file> merges the password export
@@ -78,6 +156,13 @@ Options:
78
156
  --create-orgs Create organizations that memberships name but that do not exist yet
79
157
  --json Machine-readable summary
80
158
 
159
+ Better Auth bundle (npx atlas-better-auth-export --out <file> --public-key <key>):
160
+ --bundle <file> Upload the sealed bundle, show the dry run, then apply
161
+ --import <id> Continue an uploaded import (apply it, or resume a failed one)
162
+ --confirm-conflicts Apply although the dry run found conflicts with existing users
163
+ --options <json|@file> Import options, e.g. '{"import_sessions":false}'
164
+ --yes Apply without asking
165
+
81
166
  Batches are sent with upsert, so a resumed or repeated run never duplicates a
82
167
  user or a membership. Exit code 2 means some rows were reported as issues.`,
83
168
  mcp: `atlas mcp — connect AI coding agents to Atlas
@@ -258,9 +343,24 @@ Usage:
258
343
  atlas actions test <file> [--trigger <t>] [--json]
259
344
  atlas actions logs <action-id> [--json]
260
345
 
346
+ atlas actions gallery [query] [--trigger <t>] [--json]
347
+ atlas actions show <slug> [--json]
348
+ atlas actions install <slug> [--name <n>] [--secrets-file <dotenv>] [--json]
349
+ atlas actions installs [--json]
350
+ atlas actions update <action-id> [--secrets-file <dotenv>] [--json]
351
+ atlas actions publish <template.json> [--draft] [--json]
352
+
261
353
  deploy uploads the file's code verbatim as a new action (created, not yet bound).
262
354
  test runs the file OFFLINE through the @atlasauth/actions harness — no network,
263
355
  no real users — and exits non-zero if the action throws. logs explains where an
264
- action's execution history is recorded (Atlas has no live log-stream endpoint).`,
356
+ action's execution history is recorded (Atlas has no live log-stream endpoint).
357
+
358
+ The gallery: gallery lists first-party and community templates; install copies
359
+ one into the instance as a DISABLED, unbound action (secret values come from a
360
+ dotenv file, never argv); installs shows which actions came from the gallery
361
+ and whether a newer version exists; update moves one to the latest version.
362
+ publish reads a manifest {slug, name, author_name, summary, description,
363
+ category, tags, trigger, license, version, code_file, secrets, changelog},
364
+ creates the template or adds the version, and submits it for review.`,
265
365
  };
266
366
  //# 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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wDA6CgC,CAAC;AAEzD,oDAAoD;AACvC,QAAA,YAAY,GAA2B;IAClD,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;;;;;;;;;;;gFAWqE;CAC/E,CAAC"}
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEU,QAAA,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wDAuDgC,CAAC;AAEzD,oDAAoD;AACvC,QAAA,YAAY,GAA2B;IAClD,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8CAqDmC;IAC5C,IAAI,EAAE;;;;;;;;;;gEAUwD;IAC9D,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2EAmCiE;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"}
package/dist/index.d.ts CHANGED
@@ -25,3 +25,7 @@ export { preflight, envCommand, client } from './commands/project-commands';
25
25
  export { referrals } from './commands/referrals';
26
26
  export { writeSecretFile, readEnvFile, parseDotenv, renderDotenv, productDir, deliverSecret, } from './secrets';
27
27
  export { readManifest, writeManifest, manifestPath, type ProjectManifest, type ProjectInstance, type InstanceEnv, } from './project';
28
+ export { migrate } from './commands/migrate';
29
+ export { planConfigImport, type ConfigPlan, type PlannedChange } from './commands/config';
30
+ export { translateBetterAuth, type Translation, type ReportEntry, type ConfigDocument } from './migrate/better-auth/translate';
31
+ export { migrateBetterAuth, STEPS as BETTER_AUTH_MIGRATION_STEPS } from './migrate/better-auth/orchestrator';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.manifestPath = exports.writeManifest = exports.readManifest = exports.deliverSecret = exports.productDir = exports.renderDotenv = exports.parseDotenv = exports.readEnvFile = exports.writeSecretFile = exports.referrals = exports.client = exports.envCommand = exports.preflight = exports.init = 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;
3
+ exports.BETTER_AUTH_MIGRATION_STEPS = exports.migrateBetterAuth = exports.translateBetterAuth = exports.planConfigImport = exports.migrate = exports.manifestPath = exports.writeManifest = exports.readManifest = exports.deliverSecret = exports.productDir = exports.renderDotenv = exports.parseDotenv = exports.readEnvFile = exports.writeSecretFile = exports.referrals = exports.client = exports.envCommand = exports.preflight = exports.init = 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
4
  /**
5
5
  * Library surface of `@atlasauth/cli`. The package ships a bin (`atlas`), but
6
6
  * exporting the pieces lets the handlers be unit-tested with injected deps and
@@ -65,4 +65,13 @@ var project_1 = require("./project");
65
65
  Object.defineProperty(exports, "readManifest", { enumerable: true, get: function () { return project_1.readManifest; } });
66
66
  Object.defineProperty(exports, "writeManifest", { enumerable: true, get: function () { return project_1.writeManifest; } });
67
67
  Object.defineProperty(exports, "manifestPath", { enumerable: true, get: function () { return project_1.manifestPath; } });
68
+ var migrate_1 = require("./commands/migrate");
69
+ Object.defineProperty(exports, "migrate", { enumerable: true, get: function () { return migrate_1.migrate; } });
70
+ var config_3 = require("./commands/config");
71
+ Object.defineProperty(exports, "planConfigImport", { enumerable: true, get: function () { return config_3.planConfigImport; } });
72
+ var translate_1 = require("./migrate/better-auth/translate");
73
+ Object.defineProperty(exports, "translateBetterAuth", { enumerable: true, get: function () { return translate_1.translateBetterAuth; } });
74
+ var orchestrator_1 = require("./migrate/better-auth/orchestrator");
75
+ Object.defineProperty(exports, "migrateBetterAuth", { enumerable: true, get: function () { return orchestrator_1.migrateBetterAuth; } });
76
+ Object.defineProperty(exports, "BETTER_AUTH_MIGRATION_STEPS", { enumerable: true, get: function () { return orchestrator_1.STEPS; } });
68
77
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +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;AAChB,wCAAuC;AAA9B,4FAAA,IAAI,OAAA;AACb,gEAA4E;AAAnE,6GAAA,SAAS,OAAA;AAAE,8GAAA,UAAU,OAAA;AAAE,0GAAA,MAAM,OAAA;AACtC,kDAAiD;AAAxC,sGAAA,SAAS,OAAA;AAClB,qCAOmB;AANjB,0GAAA,eAAe,OAAA;AACf,sGAAA,WAAW,OAAA;AACX,sGAAA,WAAW,OAAA;AACX,uGAAA,YAAY,OAAA;AACZ,qGAAA,UAAU,OAAA;AACV,wGAAA,aAAa,OAAA;AAEf,qCAOmB;AANjB,uGAAA,YAAY,OAAA;AACZ,wGAAA,aAAa,OAAA;AACb,uGAAA,YAAY,OAAA"}
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;AAChB,wCAAuC;AAA9B,4FAAA,IAAI,OAAA;AACb,gEAA4E;AAAnE,6GAAA,SAAS,OAAA;AAAE,8GAAA,UAAU,OAAA;AAAE,0GAAA,MAAM,OAAA;AACtC,kDAAiD;AAAxC,sGAAA,SAAS,OAAA;AAClB,qCAOmB;AANjB,0GAAA,eAAe,OAAA;AACf,sGAAA,WAAW,OAAA;AACX,sGAAA,WAAW,OAAA;AACX,uGAAA,YAAY,OAAA;AACZ,qGAAA,UAAU,OAAA;AACV,wGAAA,aAAa,OAAA;AAEf,qCAOmB;AANjB,uGAAA,YAAY,OAAA;AACZ,wGAAA,aAAa,OAAA;AACb,uGAAA,YAAY,OAAA;AAKd,8CAA6C;AAApC,kGAAA,OAAO,OAAA;AAChB,4CAA0F;AAAjF,0GAAA,gBAAgB,OAAA;AACzB,6DAA+H;AAAtH,gHAAA,mBAAmB,OAAA;AAC5B,mEAA6G;AAApG,iHAAA,iBAAiB,OAAA;AAAE,2HAAA,KAAK,OAA+B"}
@@ -0,0 +1,59 @@
1
+ import { type BetterAuthImport, type BetterAuthImportOptions } from '@atlasauth/backend';
2
+ import type { ConfigHttp } from '../../config-http';
3
+ /**
4
+ * Every call the Better Auth migration makes into the import and session-bridge
5
+ * APIs lives in this one module:
6
+ *
7
+ * - the export/import pair: the `@atlasauth/better-auth-migrate` exporter seals
8
+ * a bundle to the instance's import key (`GET /v1/better_auth_imports/public_key`),
9
+ * which is uploaded in line-split parts, finalized (which runs the dry run)
10
+ * and applied under `/v1/better_auth_imports`, and
11
+ * - the session bridge (`/v1/migrations/better_auth/bridge`), which lets a live
12
+ * Better Auth session become an Atlas session during the cutover window.
13
+ */
14
+ /** The exporter's documented command line. */
15
+ export declare const EXPORTER_BIN = "atlas-better-auth-export";
16
+ export declare const EXPORTER_PACKAGE = "@atlasauth/better-auth-migrate";
17
+ /** `publicKey` is the key's compact `kid:public_key` form. */
18
+ export declare function exporterCommand(opts: {
19
+ out: string;
20
+ publicKey: string;
21
+ }): {
22
+ cmd: string;
23
+ args: string[];
24
+ display: string;
25
+ };
26
+ /** The import key the exporter seals the bundle to (the private half stays with Atlas), as `kid:public_key`. */
27
+ export declare function getImportPublicKey(http: ConfigHttp): Promise<string>;
28
+ export type ImportJob = BetterAuthImport;
29
+ /** Statuses an import rests in; anything else is still being worked on. */
30
+ export declare const RESTING_STATUSES: readonly string[];
31
+ /**
32
+ * Upload a sealed bundle: create the import, send it in line-split parts of at
33
+ * most 8 MiB, then finalize (which checks the parts and the key and runs the
34
+ * dry run; a large bundle comes back `analyzing` and finishes in the background).
35
+ */
36
+ export declare function uploadBundle(http: ConfigHttp, opts: {
37
+ bundle: string;
38
+ options?: BetterAuthImportOptions;
39
+ onPart?: (n: number, of: number) => void;
40
+ }): Promise<ImportJob>;
41
+ export declare function getImport(http: ConfigHttp, id: string): Promise<ImportJob>;
42
+ /** Finalize an import whose upload finished but was never finalized. */
43
+ export declare function finalizeImport(http: ConfigHttp, id: string): Promise<ImportJob>;
44
+ /** Apply a dry-run-ready import, or resume a failed one from where it stopped. */
45
+ export declare function applyImport(http: ConfigHttp, id: string, opts: {
46
+ confirmConflicts: boolean;
47
+ }): Promise<ImportJob>;
48
+ export interface BridgeSettings {
49
+ /** Better Auth's `advanced.cookiePrefix` (default `better-auth`). */
50
+ cookiePrefix: string;
51
+ /** When the bridge stops accepting Better Auth sessions (epoch ms). */
52
+ endsAt: number;
53
+ }
54
+ /**
55
+ * Turn the Better Auth session bridge on for a window. The old app's Better
56
+ * Auth secret is stored write-only so Atlas can check the cookie signature
57
+ * (the live fallback to the old app stays off unless set up separately).
58
+ */
59
+ export declare function enableSessionBridge(http: ConfigHttp, settings: BridgeSettings, secret: string): Promise<void>;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RESTING_STATUSES = exports.EXPORTER_PACKAGE = exports.EXPORTER_BIN = void 0;
4
+ exports.exporterCommand = exporterCommand;
5
+ exports.getImportPublicKey = getImportPublicKey;
6
+ exports.uploadBundle = uploadBundle;
7
+ exports.getImport = getImport;
8
+ exports.finalizeImport = finalizeImport;
9
+ exports.applyImport = applyImport;
10
+ exports.enableSessionBridge = enableSessionBridge;
11
+ const backend_1 = require("@atlasauth/backend");
12
+ /**
13
+ * Every call the Better Auth migration makes into the import and session-bridge
14
+ * APIs lives in this one module:
15
+ *
16
+ * - the export/import pair: the `@atlasauth/better-auth-migrate` exporter seals
17
+ * a bundle to the instance's import key (`GET /v1/better_auth_imports/public_key`),
18
+ * which is uploaded in line-split parts, finalized (which runs the dry run)
19
+ * and applied under `/v1/better_auth_imports`, and
20
+ * - the session bridge (`/v1/migrations/better_auth/bridge`), which lets a live
21
+ * Better Auth session become an Atlas session during the cutover window.
22
+ */
23
+ /** The exporter's documented command line. */
24
+ exports.EXPORTER_BIN = 'atlas-better-auth-export';
25
+ exports.EXPORTER_PACKAGE = '@atlasauth/better-auth-migrate';
26
+ /** `publicKey` is the key's compact `kid:public_key` form. */
27
+ function exporterCommand(opts) {
28
+ const args = ['--yes', exports.EXPORTER_BIN, '--out', opts.out, '--public-key', opts.publicKey];
29
+ return { cmd: 'npx', args, display: `npx ${exports.EXPORTER_BIN} --out ${opts.out} --public-key ${opts.publicKey}` };
30
+ }
31
+ /** The import key the exporter seals the bundle to (the private half stays with Atlas), as `kid:public_key`. */
32
+ async function getImportPublicKey(http) {
33
+ const key = await http.get('/v1/better_auth_imports/public_key');
34
+ if (!key?.compact)
35
+ throw new Error('The instance did not return an import key.');
36
+ return key.compact;
37
+ }
38
+ /** Statuses an import rests in; anything else is still being worked on. */
39
+ exports.RESTING_STATUSES = ['uploading', 'ready', 'invalid', 'completed', 'failed'];
40
+ const importPath = (id, sub = '') => `/v1/better_auth_imports/${encodeURIComponent(id)}${sub}`;
41
+ /**
42
+ * Upload a sealed bundle: create the import, send it in line-split parts of at
43
+ * most 8 MiB, then finalize (which checks the parts and the key and runs the
44
+ * dry run; a large bundle comes back `analyzing` and finishes in the background).
45
+ */
46
+ async function uploadBundle(http, opts) {
47
+ const parts = (0, backend_1.splitBundleParts)(opts.bundle);
48
+ if (parts.length === 0)
49
+ throw new Error('The bundle is empty.');
50
+ const created = await http.post('/v1/better_auth_imports', opts.options ? { options: opts.options } : {});
51
+ for (let i = 0; i < parts.length; i++) {
52
+ await http.put(importPath(created.id, `/parts/${i + 1}`), { data: parts[i] });
53
+ opts.onPart?.(i + 1, parts.length);
54
+ }
55
+ return http.post(importPath(created.id, '/finalize'), {});
56
+ }
57
+ async function getImport(http, id) {
58
+ return http.get(importPath(id));
59
+ }
60
+ /** Finalize an import whose upload finished but was never finalized. */
61
+ async function finalizeImport(http, id) {
62
+ return http.post(importPath(id, '/finalize'), {});
63
+ }
64
+ /** Apply a dry-run-ready import, or resume a failed one from where it stopped. */
65
+ async function applyImport(http, id, opts) {
66
+ return http.post(importPath(id, '/apply'), opts.confirmConflicts ? { confirm_conflicts: true } : {});
67
+ }
68
+ /**
69
+ * Turn the Better Auth session bridge on for a window. The old app's Better
70
+ * Auth secret is stored write-only so Atlas can check the cookie signature
71
+ * (the live fallback to the old app stays off unless set up separately).
72
+ */
73
+ async function enableSessionBridge(http, settings, secret) {
74
+ await http.put('/v1/migrations/better_auth/bridge', {
75
+ enabled: true,
76
+ ends_at: settings.endsAt,
77
+ cookie_prefix: settings.cookiePrefix,
78
+ live_fallback: { secret },
79
+ });
80
+ }
81
+ //# sourceMappingURL=integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.js","sourceRoot":"","sources":["../../../src/migrate/better-auth/integration.ts"],"names":[],"mappings":";;;AAoBA,0CAGC;AAGD,gDAIC;AAcD,oCAYC;AAED,8BAEC;AAGD,wCAEC;AAGD,kCAEC;AAcD,kDAOC;AA3FD,gDAAqI;AAGrI;;;;;;;;;;GAUG;AAEH,8CAA8C;AACjC,QAAA,YAAY,GAAG,0BAA0B,CAAC;AAC1C,QAAA,gBAAgB,GAAG,gCAAgC,CAAC;AAEjE,8DAA8D;AAC9D,SAAgB,eAAe,CAAC,IAAwC;IACtE,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,oBAAY,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACxF,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,oBAAY,UAAU,IAAI,CAAC,GAAG,iBAAiB,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;AAC/G,CAAC;AAED,gHAAgH;AACzG,KAAK,UAAU,kBAAkB,CAAC,IAAgB;IACvD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAsB,oCAAoC,CAAC,CAAC;IACtF,IAAI,CAAC,GAAG,EAAE,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IACjF,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC;AAID,2EAA2E;AAC9D,QAAA,gBAAgB,GAAsB,CAAC,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;AAE5G,MAAM,UAAU,GAAG,CAAC,EAAU,EAAE,GAAG,GAAG,EAAE,EAAE,EAAE,CAAC,2BAA2B,kBAAkB,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC;AAEvG;;;;GAIG;AACI,KAAK,UAAU,YAAY,CAChC,IAAgB,EAChB,IAAqG;IAErG,MAAM,KAAK,GAAG,IAAA,0BAAgB,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAChE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAY,yBAAyB,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACrH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9E,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAY,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC;AACvE,CAAC;AAEM,KAAK,UAAU,SAAS,CAAC,IAAgB,EAAE,EAAU;IAC1D,OAAO,IAAI,CAAC,GAAG,CAAY,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,wEAAwE;AACjE,KAAK,UAAU,cAAc,CAAC,IAAgB,EAAE,EAAU;IAC/D,OAAO,IAAI,CAAC,IAAI,CAAY,UAAU,CAAC,EAAE,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED,kFAAkF;AAC3E,KAAK,UAAU,WAAW,CAAC,IAAgB,EAAE,EAAU,EAAE,IAAmC;IACjG,OAAO,IAAI,CAAC,IAAI,CAAY,UAAU,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAClH,CAAC;AASD;;;;GAIG;AACI,KAAK,UAAU,mBAAmB,CAAC,IAAgB,EAAE,QAAwB,EAAE,MAAc;IAClG,MAAM,IAAI,CAAC,GAAG,CAAC,mCAAmC,EAAE;QAClD,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,QAAQ,CAAC,MAAM;QACxB,aAAa,EAAE,QAAQ,CAAC,YAAY;QACpC,aAAa,EAAE,EAAE,MAAM,EAAE;KAC1B,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { type ParsedArgs } from '../../args';
2
+ import type { RunContext } from '../../context';
3
+ import { type Json } from '../../serialize';
4
+ /**
5
+ * `atlas migrate better-auth [path]` — the whole Better Auth → Atlas program as
6
+ * one resumable run:
7
+ *
8
+ * preflight → translate → apply (review the diff, confirm, config push) →
9
+ * export (the exporter runs in the app) → import (dry run, confirm, apply) →
10
+ * bridge (no forced logout) → code (the codemod) → verify (checklist).
11
+ *
12
+ * Each finished step is checkpointed in the state file, so `--resume` carries
13
+ * on where a run stopped (a confirmation declined, an env var missing, the
14
+ * export not run yet). `--dry-run` walks every step without changing the
15
+ * instance or the code; `--yes` answers every confirmation.
16
+ */
17
+ export declare const STEPS: readonly ["preflight", "translate", "apply", "export", "import", "bridge", "code", "verify"];
18
+ export type StepId = (typeof STEPS)[number];
19
+ type StepStatus = 'done' | 'skipped' | 'planned' | 'action_needed' | 'awaiting_confirmation' | 'blocked';
20
+ interface StepRecord {
21
+ status: StepStatus;
22
+ at?: number;
23
+ detail?: Record<string, unknown>;
24
+ message?: string;
25
+ }
26
+ export interface MigrationState {
27
+ version: 1;
28
+ project: string;
29
+ instance_id: string | null;
30
+ environment: string | null;
31
+ started_at: number;
32
+ steps: Partial<Record<StepId, StepRecord>>;
33
+ }
34
+ /** `${NAME}` placeholders in the config files that the environment does not set. */
35
+ export declare function missingPlaceholders(dir: string, env: NodeJS.ProcessEnv): Set<string>;
36
+ /** Leaves of `desired` that differ from `live` (arrays compare as a whole). */
37
+ export declare function leafDiff(desired: Json, live: Json, prefix?: string): Array<{
38
+ path: string;
39
+ from: Json | undefined;
40
+ to: Json;
41
+ }>;
42
+ export declare function migrateBetterAuth(ctx: RunContext, args: ParsedArgs, projectArg: string | undefined): Promise<number>;
43
+ export {};