@scalebun/cli 1.0.0 → 1.4.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 (57) hide show
  1. package/lib/api/client.d.ts +8 -0
  2. package/lib/api/client.d.ts.map +1 -1
  3. package/lib/api/client.js +70 -2
  4. package/lib/api/client.js.map +1 -1
  5. package/lib/commands/ci-init.d.ts +0 -6
  6. package/lib/commands/ci-init.d.ts.map +1 -1
  7. package/lib/commands/ci-init.js +172 -28
  8. package/lib/commands/ci-init.js.map +1 -1
  9. package/lib/commands/doctor.d.ts +8 -0
  10. package/lib/commands/doctor.d.ts.map +1 -0
  11. package/lib/commands/doctor.js +252 -0
  12. package/lib/commands/doctor.js.map +1 -0
  13. package/lib/commands/login.d.ts +28 -4
  14. package/lib/commands/login.d.ts.map +1 -1
  15. package/lib/commands/login.js +132 -51
  16. package/lib/commands/login.js.map +1 -1
  17. package/lib/commands/ota-bundle.d.ts.map +1 -1
  18. package/lib/commands/ota-bundle.js +2 -0
  19. package/lib/commands/ota-bundle.js.map +1 -1
  20. package/lib/commands/ota-delete-bundle.d.ts +8 -0
  21. package/lib/commands/ota-delete-bundle.d.ts.map +1 -1
  22. package/lib/commands/ota-delete-bundle.js +60 -0
  23. package/lib/commands/ota-delete-bundle.js.map +1 -1
  24. package/lib/commands/ota-keys.d.ts +14 -0
  25. package/lib/commands/ota-keys.d.ts.map +1 -0
  26. package/lib/commands/ota-keys.js +200 -0
  27. package/lib/commands/ota-keys.js.map +1 -0
  28. package/lib/commands/ota-publish.d.ts +10 -0
  29. package/lib/commands/ota-publish.d.ts.map +1 -1
  30. package/lib/commands/ota-publish.js +251 -34
  31. package/lib/commands/ota-publish.js.map +1 -1
  32. package/lib/commands/ota-rollout.d.ts +3 -0
  33. package/lib/commands/ota-rollout.d.ts.map +1 -0
  34. package/lib/commands/ota-rollout.js +235 -0
  35. package/lib/commands/ota-rollout.js.map +1 -0
  36. package/lib/commands/quickstart.d.ts +4 -0
  37. package/lib/commands/quickstart.d.ts.map +1 -0
  38. package/lib/commands/quickstart.js +274 -0
  39. package/lib/commands/quickstart.js.map +1 -0
  40. package/lib/index.js +20 -1
  41. package/lib/index.js.map +1 -1
  42. package/lib/utils/bundle.d.ts +86 -0
  43. package/lib/utils/bundle.d.ts.map +1 -1
  44. package/lib/utils/bundle.js +244 -14
  45. package/lib/utils/bundle.js.map +1 -1
  46. package/lib/utils/credentials.d.ts +12 -1
  47. package/lib/utils/credentials.d.ts.map +1 -1
  48. package/lib/utils/credentials.js +40 -1
  49. package/lib/utils/credentials.js.map +1 -1
  50. package/lib/utils/transportSecurity.d.ts +36 -0
  51. package/lib/utils/transportSecurity.d.ts.map +1 -0
  52. package/lib/utils/transportSecurity.js +74 -0
  53. package/lib/utils/transportSecurity.js.map +1 -0
  54. package/lib/utils/ui.d.ts.map +1 -1
  55. package/lib/utils/ui.js +2 -0
  56. package/lib/utils/ui.js.map +1 -1
  57. package/package.json +1 -1
@@ -0,0 +1,252 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.registerDoctorCommand = registerDoctorCommand;
37
+ exports.runDoctor = runDoctor;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const credentials_1 = require("../utils/credentials");
41
+ const client_1 = require("../api/client");
42
+ const bundle_1 = require("../utils/bundle");
43
+ const findings = [];
44
+ function report(level, title, detail) {
45
+ findings.push({ level, title, detail });
46
+ const icon = level === 'ok' ? '✅' : level === 'warn' ? '⚠️ ' : '❌';
47
+ console.log(`${icon} ${title}`);
48
+ if (detail)
49
+ console.log(` ${detail.split('\n').join('\n ')}`);
50
+ }
51
+ /** Find the first file matching `names` under `dir`, skipping heavy folders. */
52
+ function findFile(dir, names, maxDepth = 6) {
53
+ if (maxDepth < 0 || !fs.existsSync(dir))
54
+ return null;
55
+ let entries;
56
+ try {
57
+ entries = fs.readdirSync(dir, { withFileTypes: true });
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ for (const e of entries) {
63
+ if (e.isFile() && names.includes(e.name))
64
+ return path.join(dir, e.name);
65
+ }
66
+ for (const e of entries) {
67
+ if (!e.isDirectory())
68
+ continue;
69
+ if (['node_modules', 'Pods', 'build', '.git', '.gradle'].includes(e.name))
70
+ continue;
71
+ const hit = findFile(path.join(dir, e.name), names, maxDepth - 1);
72
+ if (hit)
73
+ return hit;
74
+ }
75
+ return null;
76
+ }
77
+ function parseMinor(version) {
78
+ if (!version)
79
+ return null;
80
+ const m = /^(\d+)\.(\d+)/.exec(version);
81
+ return m ? [Number(m[1]), Number(m[2])] : null;
82
+ }
83
+ function registerDoctorCommand(program) {
84
+ program
85
+ .command('doctor')
86
+ .description('Check that this project is correctly set up for OTA updates')
87
+ .action(() => runDoctor());
88
+ }
89
+ /**
90
+ * All doctor checks as a reusable step (`quickstart` runs it inline).
91
+ * Same contract as the command: exits the process on a blocking failure.
92
+ */
93
+ async function runDoctor() {
94
+ findings.length = 0; // reusable across calls in one process
95
+ {
96
+ const cwd = process.cwd();
97
+ console.log('\nScalebun doctor\n');
98
+ // ── 1. Credentials ─────────────────────────────────────────────────────
99
+ const creds = (0, credentials_1.readCredentials)();
100
+ if (!creds) {
101
+ report('fail', 'Not logged in', 'Run `scalebun login`, or set SCALEBUN_TOKEN + SCALEBUN_API_URL in CI.');
102
+ }
103
+ else {
104
+ const source = process.env.SCALEBUN_TOKEN ? 'environment variables' : '~/.scalebun/credentials.json';
105
+ if (creds.token.startsWith('scalebun_pat_')) {
106
+ report('ok', `Credentials found (${source}, durable access token)`);
107
+ }
108
+ else {
109
+ report('warn', `Credentials found (${source}) but the token is a session JWT`, 'Session tokens expire in ~15 minutes. Run `scalebun login` again — it now mints\n' +
110
+ 'a durable access token automatically.');
111
+ }
112
+ try {
113
+ const me = await new client_1.ApiClient(creds).get('/auth/me');
114
+ report('ok', `Token valid — authenticated as ${me.email}`);
115
+ }
116
+ catch (err) {
117
+ report('fail', 'Stored token no longer works', err.message);
118
+ }
119
+ }
120
+ // ── 2. Project shape ───────────────────────────────────────────────────
121
+ const rnVersion = (0, bundle_1.detectProjectRnVersion)(cwd);
122
+ const expo = (0, bundle_1.isExpoProject)(cwd);
123
+ if (!rnVersion) {
124
+ report('fail', 'React Native not found in node_modules', 'Run this from your app root, after installing dependencies.');
125
+ }
126
+ else {
127
+ report('ok', `React Native ${rnVersion} (${expo ? 'Expo' : 'bare'} project)`);
128
+ }
129
+ const hermesc = (0, bundle_1.resolveHermesc)(cwd);
130
+ if (hermesc) {
131
+ report('ok', 'hermesc found — `--hermes` publishes will compile bytecode');
132
+ }
133
+ else if (rnVersion) {
134
+ report('warn', 'hermesc not found under node_modules/react-native/sdks/hermesc', 'Publishes fall back to plain JS: they work, but cold start is ~20-30% slower\n' +
135
+ 'and Hermes-bytecode runtime gating cannot protect these bundles.');
136
+ }
137
+ // ── 3. Android wiring ──────────────────────────────────────────────────
138
+ const gradleProps = path.join(cwd, 'android', 'gradle.properties');
139
+ const mainApp = findFile(path.join(cwd, 'android', 'app', 'src', 'main'), [
140
+ 'MainApplication.kt',
141
+ 'MainApplication.java',
142
+ ]);
143
+ const minor = parseMinor(rnVersion);
144
+ if (!fs.existsSync(path.join(cwd, 'android'))) {
145
+ report('warn', 'No android/ directory — skipping Android checks');
146
+ }
147
+ else {
148
+ const newArch = fs.existsSync(gradleProps) &&
149
+ /newArchEnabled\s*=\s*true/.test(fs.readFileSync(gradleProps, 'utf-8'));
150
+ // The dead zone: bridgeless ignored getJSBundleFile() until RN 0.76.1.
151
+ // An update installs, reports INSTALLED, and the app keeps running the
152
+ // APK asset — the exact failure that killed CodePush on modern RN.
153
+ if (newArch && minor && (minor[1] === 74 || minor[1] === 75) && minor[0] === 0) {
154
+ report('fail', `New Architecture is ON with React Native ${rnVersion} — OTA updates CANNOT LOAD`, 'Bridgeless did not honour getJSBundleFile() until RN 0.76.1. Updates will\n' +
155
+ 'install and silently never run (the SDK detects this and disables itself).\n' +
156
+ 'Fix: upgrade to RN >= 0.76.1, or set newArchEnabled=false.');
157
+ }
158
+ else if (newArch && rnVersion?.startsWith('0.76.0')) {
159
+ report('fail', 'React Native 0.76.0 exactly — one patch release short of the bridgeless fix', 'Upgrade to 0.76.1 or later.');
160
+ }
161
+ if (!mainApp) {
162
+ report('warn', 'MainApplication.kt/.java not found — cannot verify Android wiring');
163
+ }
164
+ else {
165
+ const src = fs.readFileSync(mainApp, 'utf-8');
166
+ const wired = src.includes('ScaleBunOtaModule.getJSBundleFile');
167
+ const rel = path.relative(cwd, mainApp);
168
+ if (!wired) {
169
+ report('fail', `Android bundle resolution is NOT wired (${rel})`, 'Without it, updates download and install but the app keeps running the bundle\n' +
170
+ 'baked into the APK — every metric reports success and nothing changes.\n' +
171
+ (minor && (minor[0] > 0 || minor[1] >= 82)
172
+ ? 'RN >= 0.82 (ReactNativeHost was removed) — pass the path to the host:\n' +
173
+ ' override val reactHost: ReactHost by lazy {\n' +
174
+ ' getDefaultReactHost(context = applicationContext,\n' +
175
+ ' packageList = PackageList(this).packages,\n' +
176
+ ' jsBundleFilePath = ScaleBunOtaModule.getJSBundleFile(applicationContext))\n' +
177
+ ' }'
178
+ : 'Add inside your ReactNativeHost:\n' +
179
+ ' override fun getJSBundleFile(): String? =\n' +
180
+ ' ScaleBunOtaModule.getJSBundleFile(this@MainApplication) ?: super.getJSBundleFile()'));
181
+ }
182
+ else if (minor &&
183
+ (minor[0] > 0 || minor[1] >= 82) &&
184
+ !src.includes('jsBundleFilePath')) {
185
+ report('fail', `RN ${rnVersion} uses the removed ReactNativeHost override (${rel})`, 'RN 0.82 deleted ReactNativeHost — the getJSBundleFile() override no longer\n' +
186
+ 'compiles or runs. Pass jsBundleFilePath to getDefaultReactHost(...) instead.');
187
+ }
188
+ else {
189
+ report('ok', `Android bundle resolution wired (${rel})`);
190
+ }
191
+ }
192
+ }
193
+ // ── 4. iOS wiring ──────────────────────────────────────────────────────
194
+ if (!fs.existsSync(path.join(cwd, 'ios'))) {
195
+ report('warn', 'No ios/ directory — skipping iOS checks');
196
+ }
197
+ else {
198
+ const appDelegate = findFile(path.join(cwd, 'ios'), [
199
+ 'AppDelegate.swift',
200
+ 'AppDelegate.mm',
201
+ 'AppDelegate.m',
202
+ ]);
203
+ if (!appDelegate) {
204
+ report('warn', 'AppDelegate not found — cannot verify iOS wiring');
205
+ }
206
+ else {
207
+ const src = fs.readFileSync(appDelegate, 'utf-8');
208
+ const rel = path.relative(cwd, appDelegate);
209
+ if (src.includes('ScaleBunOtaModule.getBundleURL') || src.includes('getBundleURL()')) {
210
+ report('ok', `iOS bundle resolution wired (${rel})`);
211
+ }
212
+ else {
213
+ report('fail', `iOS bundle resolution is NOT wired (${rel})`, 'Override bundleURL to resolve the OTA slot:\n' +
214
+ ' override func bundleURL() -> URL? {\n' +
215
+ ' #if DEBUG\n' +
216
+ ' RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")\n' +
217
+ ' #else\n' +
218
+ ' ScaleBunOtaModule.getBundleURL()\n' +
219
+ ' #endif\n' +
220
+ ' }');
221
+ }
222
+ }
223
+ }
224
+ // ── 5. Signing ─────────────────────────────────────────────────────────
225
+ const keyPath = path.join(cwd, '.scalebun', 'ota-signing-key.pem');
226
+ if (fs.existsSync(keyPath)) {
227
+ report('ok', 'ed25519 signing key present — publishes are signed');
228
+ const gitignore = path.join(cwd, '.gitignore');
229
+ const ignored = fs.existsSync(gitignore) && /(^|\n)\s*\.scalebun\/?\s*(\n|$)/.test(fs.readFileSync(gitignore, 'utf-8'));
230
+ if (!ignored) {
231
+ report('fail', '.scalebun/ is NOT in .gitignore — the private signing key can be committed', 'Anyone with this key can sign bundles your users will trust.\n' +
232
+ 'Fix: echo ".scalebun/" >> .gitignore (and rotate the key if it was ever pushed)');
233
+ }
234
+ }
235
+ else {
236
+ report('warn', 'No signing key — bundles ship on SHA-256 integrity alone', 'Integrity proves bytes arrived intact; only a signature proves they came from you.\n' +
237
+ 'Set up: scalebun ota generate-key-pair --app-id <id> --name "release key"');
238
+ }
239
+ // ── Summary ────────────────────────────────────────────────────────────
240
+ const fails = findings.filter((f) => f.level === 'fail').length;
241
+ const warns = findings.filter((f) => f.level === 'warn').length;
242
+ console.log('');
243
+ if (fails > 0) {
244
+ console.log(`${fails} blocking issue(s), ${warns} warning(s). Fix the ❌ items before shipping OTA.`);
245
+ process.exit(1);
246
+ }
247
+ console.log(warns > 0
248
+ ? `No blocking issues (${warns} warning(s)). You can ship OTA updates.`
249
+ : 'All checks passed. You can ship OTA updates.');
250
+ }
251
+ }
252
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,34 @@
1
1
  import { Command } from 'commander';
2
2
  /**
3
- * `scalebun login` — authenticate via Personal Access Token (PAT).
3
+ * `scalebun login` — authenticate and store a DURABLE credential.
4
4
  *
5
- * 1. Prompt for backend URL and PAT
6
- * 2. Validate by calling GET /auth/me
7
- * 3. Store in ~/.scalebun/credentials.json
5
+ * ── Why the PAT exchange matters ────────────────────────────────────────────
6
+ *
7
+ * The backend's session JWTs expire in ~15 minutes. This command used to store
8
+ * that JWT directly, so every publish that started more than a few minutes
9
+ * after login failed with an opaque 401 — hit live during the first real
10
+ * device-test run. Meanwhile the backend has had a full personal-access-token
11
+ * system all along (`POST /auth/tokens`, hashed at rest, scoped, revocable)
12
+ * that the CLI never used.
13
+ *
14
+ * Now: email/password buys a short-lived JWT, which is immediately spent on
15
+ * minting a PAT named after this machine. The PAT is what gets stored — it
16
+ * survives for `--expires-days` (default 90) and is revocable from the
17
+ * dashboard (Settings → Access Tokens) if this machine is ever lost.
18
+ *
19
+ * Pasting an existing `scalebun_pat_…` still works and skips the exchange.
8
20
  */
9
21
  export declare function registerLoginCommand(program: Command): void;
22
+ export interface LoginOptions {
23
+ apiUrl?: string;
24
+ token?: string;
25
+ email?: string;
26
+ password?: string;
27
+ expiresDays: string;
28
+ }
29
+ /**
30
+ * The full interactive login flow as a reusable step (`quickstart` runs it
31
+ * inline when no credentials are stored). Exits the process on failure.
32
+ */
33
+ export declare function runLogin(opts: LoginOptions): Promise<void>;
10
34
  //# sourceMappingURL=login.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuE3D"}
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsB3D;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA8HhE"}
@@ -34,77 +34,158 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.registerLoginCommand = registerLoginCommand;
37
+ exports.runLogin = runLogin;
37
38
  const readline = __importStar(require("readline"));
39
+ const os = __importStar(require("os"));
38
40
  const credentials_1 = require("../utils/credentials");
39
41
  const client_1 = require("../api/client");
42
+ const transportSecurity_1 = require("../utils/transportSecurity");
40
43
  /**
41
- * `scalebun login` — authenticate via Personal Access Token (PAT).
44
+ * `scalebun login` — authenticate and store a DURABLE credential.
42
45
  *
43
- * 1. Prompt for backend URL and PAT
44
- * 2. Validate by calling GET /auth/me
45
- * 3. Store in ~/.scalebun/credentials.json
46
+ * ── Why the PAT exchange matters ────────────────────────────────────────────
47
+ *
48
+ * The backend's session JWTs expire in ~15 minutes. This command used to store
49
+ * that JWT directly, so every publish that started more than a few minutes
50
+ * after login failed with an opaque 401 — hit live during the first real
51
+ * device-test run. Meanwhile the backend has had a full personal-access-token
52
+ * system all along (`POST /auth/tokens`, hashed at rest, scoped, revocable)
53
+ * that the CLI never used.
54
+ *
55
+ * Now: email/password buys a short-lived JWT, which is immediately spent on
56
+ * minting a PAT named after this machine. The PAT is what gets stored — it
57
+ * survives for `--expires-days` (default 90) and is revocable from the
58
+ * dashboard (Settings → Access Tokens) if this machine is ever lost.
59
+ *
60
+ * Pasting an existing `scalebun_pat_…` still works and skips the exchange.
46
61
  */
47
62
  function registerLoginCommand(program) {
48
63
  program
49
64
  .command('login')
50
- .description('Authenticate with your Scalebun backend using a PAT')
65
+ .description('Authenticate with your Scalebun backend (stores a durable access token)')
51
66
  .option('--api-url <url>', 'Backend API URL (e.g. https://api.scalebun.com/api/v1)')
52
67
  .option('--token <pat>', 'Personal access token (scalebun_pat_…)')
53
- .action(async (opts) => {
54
- const rl = readline.createInterface({
55
- input: process.stdin,
56
- output: process.stdout,
57
- });
58
- const ask = (q) => new Promise((resolve) => rl.question(q, resolve));
59
- try {
60
- const existing = (0, credentials_1.readCredentials)();
61
- const apiUrl = opts.apiUrl ||
62
- (await ask(`API URL${existing?.apiUrl ? ` [${existing.apiUrl}]` : ''}: `)) ||
63
- existing?.apiUrl;
64
- if (!apiUrl) {
65
- console.error('❌ API URL is required');
66
- process.exit(1);
67
- }
68
- let token = opts.token;
69
- if (!token) {
70
- const input = await ask('Email or Token (scalebun_pat_…): ');
71
- if (!input) {
72
- console.error('❌ Email or Token is required');
68
+ .option('--email <email>', 'Account email (prompts for password unless --password is set)')
69
+ .option('--password <password>', 'Account password (prefer the prompt — flags leak into shell history)')
70
+ .option('--expires-days <n>', 'Lifetime of the minted CLI token in days (0 = never expires)', '90')
71
+ .action((opts) => runLogin(opts));
72
+ program
73
+ .command('logout')
74
+ .description('Remove stored credentials from this machine')
75
+ .action(() => {
76
+ (0, credentials_1.clearCredentials)();
77
+ console.log('✅ Logged out. (The token still exists server-side revoke it in the dashboard if this machine is compromised.)');
78
+ });
79
+ }
80
+ /**
81
+ * The full interactive login flow as a reusable step (`quickstart` runs it
82
+ * inline when no credentials are stored). Exits the process on failure.
83
+ */
84
+ async function runLogin(opts) {
85
+ {
86
+ {
87
+ const rl = readline.createInterface({
88
+ input: process.stdin,
89
+ output: process.stdout,
90
+ });
91
+ const ask = (q) => new Promise((resolve) => rl.question(q, resolve));
92
+ try {
93
+ const existing = (0, credentials_1.readCredentials)();
94
+ const apiUrl = opts.apiUrl ||
95
+ (await ask(`API URL${existing?.apiUrl ? ` [${existing.apiUrl}]` : ''}: `)) ||
96
+ existing?.apiUrl;
97
+ if (!apiUrl) {
98
+ console.error('❌ API URL is required');
73
99
  process.exit(1);
74
100
  }
75
- if (input.includes('@')) {
76
- const password = await ask('Password: ');
101
+ // Check the scheme HERE, before a password is prompted for. The API
102
+ // client enforces the same rule, but by then the user has already
103
+ // typed a password that we would only then refuse to send — and a
104
+ // password typed at a prompt is a password the user now has to
105
+ // consider changing. Fail before asking for it.
106
+ try {
107
+ (0, transportSecurity_1.assertSecureApiUrl)(apiUrl);
108
+ }
109
+ catch (err) {
110
+ console.error(`❌ ${err.message}`);
111
+ process.exit(1);
112
+ }
113
+ let token = opts.token;
114
+ let email = opts.email;
115
+ if (!token && !email) {
116
+ const input = await ask('Email or token (scalebun_pat_…): ');
117
+ if (!input) {
118
+ console.error('❌ Email or token is required');
119
+ process.exit(1);
120
+ }
121
+ if (input.includes('@'))
122
+ email = input;
123
+ else
124
+ token = input;
125
+ }
126
+ // ── Email/password → JWT → durable PAT ────────────────────────────
127
+ if (!token && email) {
128
+ const password = opts.password || (await ask('Password: '));
77
129
  if (!password) {
78
130
  console.error('❌ Password is required');
79
131
  process.exit(1);
80
132
  }
81
- console.log(' Logging in with credentials…');
133
+ console.log(' Signing in…');
82
134
  const unauthClient = new client_1.ApiClient({ apiUrl, token: '' });
83
- const loginRes = await unauthClient.post('/auth/login', {
84
- email: input,
85
- password,
86
- });
87
- token = loginRes.accessToken;
88
- }
89
- else {
90
- token = input;
135
+ const loginRes = await unauthClient.post('/auth/login', { email, password });
136
+ if (!loginRes.accessToken) {
137
+ if (loginRes.mfaRequired) {
138
+ console.error('❌ This account has MFA enabled, which the CLI cannot complete.\n' +
139
+ ' Create a token in the dashboard instead (Settings → Access Tokens)\n' +
140
+ ' and run: scalebun login --token scalebun_pat_…');
141
+ }
142
+ else {
143
+ console.error('❌ Sign-in did not return a token.');
144
+ }
145
+ process.exit(1);
146
+ }
147
+ // Spend the 15-minute JWT on something durable.
148
+ const expiresDays = Math.max(0, parseInt(opts.expiresDays, 10) || 0);
149
+ const jwtClient = new client_1.ApiClient({ apiUrl, token: loginRes.accessToken });
150
+ try {
151
+ const pat = await jwtClient.post('/auth/tokens', {
152
+ name: `Scalebun CLI on ${os.hostname()}`,
153
+ scopes: ['read', 'write'],
154
+ expiresInDays: expiresDays > 0 ? expiresDays : null,
155
+ });
156
+ token = pat.token;
157
+ console.log(` 🔑 Created CLI access token (…${pat.last4}, ` +
158
+ `${expiresDays > 0 ? `expires in ${expiresDays} days` : 'no expiry'}). ` +
159
+ 'Revocable from the dashboard.');
160
+ }
161
+ catch (patErr) {
162
+ // An older backend without /auth/tokens still logs in — but the
163
+ // session dies in minutes, and pretending otherwise reproduces
164
+ // the exact bug this exchange exists to fix. Say so.
165
+ token = loginRes.accessToken;
166
+ console.warn(` ⚠️ Could not create a durable token (${patErr.message}).\n` +
167
+ ' Falling back to the session token, which EXPIRES IN ~15 MINUTES.');
168
+ }
91
169
  }
170
+ // ── Validate whatever we ended up with ─────────────────────────────
171
+ console.log(' Validating token…');
172
+ const client = new client_1.ApiClient({ apiUrl, token: token });
173
+ const me = await client.get('/auth/me');
174
+ (0, credentials_1.writeCredentials)({ apiUrl, token: token });
175
+ console.log(`✅ Logged in as ${me.email} (${me.role ?? 'User'})`);
176
+ console.log(' Credentials saved to ~/.scalebun/credentials.json');
177
+ console.log('\nNext steps:');
178
+ console.log(' scalebun doctor # verify your project is OTA-ready');
179
+ console.log(' scalebun ota publish --app-id <id> # ship your first update');
180
+ }
181
+ catch (err) {
182
+ console.error(`❌ Login failed: ${err.message}`);
183
+ process.exit(1);
184
+ }
185
+ finally {
186
+ rl.close();
92
187
  }
93
- // Validate the token
94
- console.log(' Validating token…');
95
- const client = new client_1.ApiClient({ apiUrl, token });
96
- const me = await client.get('/auth/me');
97
- (0, credentials_1.writeCredentials)({ apiUrl, token });
98
- console.log(`✅ Logged in as ${me.email} (${me.role ?? 'User'})`);
99
- console.log(` Credentials saved to ~/.scalebun/credentials.json`);
100
- }
101
- catch (err) {
102
- console.error(`❌ Login failed: ${err.message}`);
103
- process.exit(1);
104
- }
105
- finally {
106
- rl.close();
107
188
  }
108
- });
189
+ }
109
190
  }
110
191
  //# sourceMappingURL=login.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ota-bundle.d.ts","sourceRoot":"","sources":["../../src/commands/ota-bundle.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAqD3D"}
1
+ {"version":3,"file":"ota-bundle.d.ts","sourceRoot":"","sources":["../../src/commands/ota-bundle.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAwD3D"}
@@ -52,6 +52,7 @@ function registerOtaBundleCommand(ota) {
52
52
  .option('--output <path>', 'Output bundle destination path', './index.android.bundle')
53
53
  .option('--hermes', 'Compile to Hermes bytecode (recommended for production)')
54
54
  .option('--hermes-disabled', 'Explicitly disable Hermes bytecode compilation')
55
+ .option('--allow-plain-js', 'Emit uncompiled JS if hermesc fails, instead of aborting')
55
56
  .option('--sourcemap', 'Generate sourcemap alongside the bundle')
56
57
  .action(async (opts) => {
57
58
  const platform = opts.platform;
@@ -63,6 +64,7 @@ function registerOtaBundleCommand(ota) {
63
64
  entryFile: opts.entryFile,
64
65
  dev: false,
65
66
  hermes: useHermes,
67
+ allowPlainJs: opts.allowPlainJs ?? false,
66
68
  sourcemap: opts.sourcemap,
67
69
  });
68
70
  const destPath = path.resolve(opts.output);
@@ -1 +1 @@
1
- {"version":3,"file":"ota-bundle.js","sourceRoot":"","sources":["../../src/commands/ota-bundle.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,4DAqDC;AAhED,uCAAyB;AACzB,2CAA6B;AAE7B,4CAA8C;AAE9C;;;;;GAKG;AACH,SAAgB,wBAAwB,CAAC,GAAY;IACnD,GAAG;SACA,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,gFAAgF,CAAC;SAC7F,MAAM,CAAC,uBAAuB,EAAE,gCAAgC,EAAE,SAAS,CAAC;SAC5E,MAAM,CAAC,qBAAqB,EAAE,eAAe,EAAE,UAAU,CAAC;SAC1D,MAAM,CAAC,iBAAiB,EAAE,gCAAgC,EAAE,wBAAwB,CAAC;SACrF,MAAM,CAAC,UAAU,EAAE,yDAAyD,CAAC;SAC7E,MAAM,CAAC,mBAAmB,EAAE,gDAAgD,CAAC;SAC7E,MAAM,CAAC,aAAa,EAAE,yCAAyC,CAAC;SAChE,MAAM,CACL,KAAK,EAAE,IAON,EAAE,EAAE;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,QAA6B,CAAC;QACpD,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QAE5D,OAAO,CAAC,GAAG,CAAC,eAAe,QAAQ,eAAe,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAE5F,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAA,oBAAW,EAAC;gBACzB,QAAQ;gBACR,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,GAAG,EAAE,KAAK;gBACV,MAAM,EAAE,SAAS;gBACjB,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5B,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7C,CAAC;YAED,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC7C,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACpC,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAEvD,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,QAAQ,KAAK,CAAC,IAAI,SAAS,CAAC,CAAC;YAClE,OAAO,CAAC,GAAG,CAAC,iGAAiG,CAAC,CAAC;QACjH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,CAAC,KAAK,CAAC,sBAAsB,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC;YAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CACF,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"ota-bundle.js","sourceRoot":"","sources":["../../src/commands/ota-bundle.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,4DAwDC;AAnED,uCAAyB;AACzB,2CAA6B;AAE7B,4CAA8C;AAE9C;;;;;GAKG;AACH,SAAgB,wBAAwB,CAAC,GAAY;IACnD,GAAG;SACA,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,gFAAgF,CAAC;SAC7F,MAAM,CAAC,uBAAuB,EAAE,gCAAgC,EAAE,SAAS,CAAC;SAC5E,MAAM,CAAC,qBAAqB,EAAE,eAAe,EAAE,UAAU,CAAC;SAC1D,MAAM,CAAC,iBAAiB,EAAE,gCAAgC,EAAE,wBAAwB,CAAC;SACrF,MAAM,CAAC,UAAU,EAAE,yDAAyD,CAAC;SAC7E,MAAM,CAAC,mBAAmB,EAAE,gDAAgD,CAAC;SAC7E,MAAM,CAAC,kBAAkB,EAAE,0DAA0D,CAAC;SACtF,MAAM,CAAC,aAAa,EAAE,yCAAyC,CAAC;SAChE,MAAM,CACL,KAAK,EAAE,IAQN,EAAE,EAAE;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,QAA6B,CAAC;QACpD,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QAE5D,OAAO,CAAC,GAAG,CAAC,eAAe,QAAQ,eAAe,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAE5F,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAA,oBAAW,EAAC;gBACzB,QAAQ;gBACR,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,GAAG,EAAE,KAAK;gBACV,MAAM,EAAE,SAAS;gBACjB,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,KAAK;gBACxC,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5B,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7C,CAAC;YAED,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC7C,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACpC,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAEvD,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,QAAQ,KAAK,CAAC,IAAI,SAAS,CAAC,CAAC;YAClE,OAAO,CAAC,GAAG,CAAC,iGAAiG,CAAC,CAAC;QACjH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,CAAC,KAAK,CAAC,sBAAsB,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC;YAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CACF,CAAC;AACN,CAAC"}
@@ -1,3 +1,11 @@
1
1
  import { Command } from 'commander';
2
+ /**
3
+ * `scalebun ota delete-bundle` — permanent, irreversible artifact deletion.
4
+ *
5
+ * It asks first. This used to delete on sight: one mis-pasted --bundle-id and
6
+ * the artifact was gone, with devices possibly still running it. `ota rollback`
7
+ * already had this shape (prompt on a TTY, explicit --yes off-TTY); a command
8
+ * whose own description says "permanently" needs it at least as much.
9
+ */
2
10
  export declare function registerOtaDeleteBundleCommand(ota: Command): void;
3
11
  //# sourceMappingURL=ota-delete-bundle.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ota-delete-bundle.d.ts","sourceRoot":"","sources":["../../src/commands/ota-delete-bundle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAwBjE"}
1
+ {"version":3,"file":"ota-delete-bundle.d.ts","sourceRoot":"","sources":["../../src/commands/ota-delete-bundle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAiDjE"}