local-expo-build 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/LICENSE +21 -0
  3. package/README.md +372 -0
  4. package/bin/local-expo-build.js +2 -0
  5. package/dist/cli.js +33 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/build.js +121 -0
  8. package/dist/commands/build.js.map +1 -0
  9. package/dist/commands/doctor.js +606 -0
  10. package/dist/commands/doctor.js.map +1 -0
  11. package/dist/commands/init.js +125 -0
  12. package/dist/commands/init.js.map +1 -0
  13. package/dist/commands/keystore.js +47 -0
  14. package/dist/commands/keystore.js.map +1 -0
  15. package/dist/core/bumpVersion.js +70 -0
  16. package/dist/core/bumpVersion.js.map +1 -0
  17. package/dist/core/easLink.js +64 -0
  18. package/dist/core/easLink.js.map +1 -0
  19. package/dist/core/expoConfig.js +71 -0
  20. package/dist/core/expoConfig.js.map +1 -0
  21. package/dist/core/gradleRun.js +31 -0
  22. package/dist/core/gradleRun.js.map +1 -0
  23. package/dist/core/keystore/easFetch.js +109 -0
  24. package/dist/core/keystore/easFetch.js.map +1 -0
  25. package/dist/core/keystore/existing.js +135 -0
  26. package/dist/core/keystore/existing.js.map +1 -0
  27. package/dist/core/keystore/generate.js +72 -0
  28. package/dist/core/keystore/generate.js.map +1 -0
  29. package/dist/core/keystore/index.js +62 -0
  30. package/dist/core/keystore/index.js.map +1 -0
  31. package/dist/core/keystore/rehydrate.js +88 -0
  32. package/dist/core/keystore/rehydrate.js.map +1 -0
  33. package/dist/core/pinGradle.js +50 -0
  34. package/dist/core/pinGradle.js.map +1 -0
  35. package/dist/core/prebuild.js +16 -0
  36. package/dist/core/prebuild.js.map +1 -0
  37. package/dist/core/sdkDetect.js +26 -0
  38. package/dist/core/sdkDetect.js.map +1 -0
  39. package/dist/core/setupSigning.js +168 -0
  40. package/dist/core/setupSigning.js.map +1 -0
  41. package/dist/core/syncEasVersion.js +97 -0
  42. package/dist/core/syncEasVersion.js.map +1 -0
  43. package/dist/core/writeCredentialsJson.js +51 -0
  44. package/dist/core/writeCredentialsJson.js.map +1 -0
  45. package/dist/util/ctx.js +17 -0
  46. package/dist/util/ctx.js.map +1 -0
  47. package/dist/util/gitignore.js +23 -0
  48. package/dist/util/gitignore.js.map +1 -0
  49. package/dist/util/log.js +16 -0
  50. package/dist/util/log.js.map +1 -0
  51. package/package.json +64 -0
  52. package/templates/keystore.properties.example +4 -0
  53. package/templates/scripts/build.js +79 -0
  54. package/templates/scripts/bump-version.js +65 -0
  55. package/templates/scripts/pin-gradle.js +45 -0
  56. package/templates/scripts/print-artifact.js +36 -0
  57. package/templates/scripts/setup-signing.js +137 -0
  58. package/templates/scripts/sync-eas-version.js +59 -0
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerInitCommand = registerInitCommand;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const prompts_1 = require("@inquirer/prompts");
10
+ const ctx_1 = require("../util/ctx");
11
+ const log_1 = require("../util/log");
12
+ const sdkDetect_1 = require("../core/sdkDetect");
13
+ const pinGradle_1 = require("../core/pinGradle");
14
+ const keystore_1 = require("../core/keystore");
15
+ const gitignore_1 = require("../util/gitignore");
16
+ const doctor_1 = require("./doctor");
17
+ const TEMPLATE_SCRIPTS = [
18
+ 'pin-gradle.js',
19
+ 'bump-version.js',
20
+ 'setup-signing.js',
21
+ 'sync-eas-version.js',
22
+ 'print-artifact.js',
23
+ 'build.js',
24
+ ];
25
+ const APK_CHAIN = 'node scripts/build.js apk';
26
+ const AAB_CHAIN = 'node scripts/build.js aab';
27
+ function templatesDir() {
28
+ // dist/commands -> ../../templates
29
+ return path_1.default.resolve(__dirname, '..', '..', 'templates');
30
+ }
31
+ function registerInitCommand(program) {
32
+ program
33
+ .command('init')
34
+ .description('Scaffold local-build scripts + package.json entries into an Expo project')
35
+ .option('--force', 'overwrite existing scripts/*.js files')
36
+ .option('--no-keystore', 'skip interactive keystore setup')
37
+ .option('--no-doctor', 'skip the pre-flight `doctor` run')
38
+ .action(async (opts, cmd) => {
39
+ const { cwd, dryRun } = (0, ctx_1.getCtx)(cmd);
40
+ log_1.log.step('local-expo-build init');
41
+ log_1.log.dim('One-time setup for local Expo Android builds · you keep full signing control');
42
+ log_1.log.dim(`Target: ${cwd}`);
43
+ // Pre-flight: run `doctor` so the environment is verified (and any missing
44
+ // pieces auto-fixed) before we scaffold anything into the project.
45
+ if (opts.doctor !== false) {
46
+ const { failedCount } = await (0, doctor_1.runDoctor)({
47
+ cwd,
48
+ dryRun,
49
+ title: 'local-expo-build init › pre-flight checks',
50
+ });
51
+ if (failedCount > 0) {
52
+ const proceed = await (0, prompts_1.confirm)({
53
+ message: `${failedCount} check(s) still failing. Continue with init anyway?`,
54
+ default: false,
55
+ });
56
+ if (!proceed) {
57
+ log_1.log.dim('Aborted. Fix the issues above and re-run, or pass --no-doctor to skip.');
58
+ return;
59
+ }
60
+ }
61
+ console.log('');
62
+ }
63
+ const sdk = (0, sdkDetect_1.detectExpoSdk)(cwd);
64
+ log_1.log.ok(`Detected Expo SDK ${sdk.major} (${sdk.raw})`);
65
+ if (!(sdk.major in pinGradle_1.GRADLE_PIN)) {
66
+ log_1.log.warn(`SDK ${sdk.major} is not in the supported table. pin-gradle will be a no-op. ` +
67
+ `If you hit a Gradle plugin error, update GRADLE_PIN.`);
68
+ }
69
+ const tplDir = templatesDir();
70
+ const scriptsDir = path_1.default.join(cwd, 'scripts');
71
+ fs_1.default.mkdirSync(scriptsDir, { recursive: true });
72
+ for (const file of TEMPLATE_SCRIPTS) {
73
+ const src = path_1.default.join(tplDir, 'scripts', file);
74
+ const dest = path_1.default.join(scriptsDir, file);
75
+ if (fs_1.default.existsSync(dest) && !opts.force) {
76
+ log_1.log.warn(`Exists, skipped (use --force): ${path_1.default.relative(cwd, dest)}`);
77
+ continue;
78
+ }
79
+ fs_1.default.copyFileSync(src, dest);
80
+ log_1.log.ok(`Wrote ${path_1.default.relative(cwd, dest)}`);
81
+ }
82
+ const examplePath = path_1.default.join(cwd, 'keystore.properties.example');
83
+ if (!fs_1.default.existsSync(examplePath)) {
84
+ fs_1.default.copyFileSync(path_1.default.join(tplDir, 'keystore.properties.example'), examplePath);
85
+ log_1.log.ok('Wrote keystore.properties.example');
86
+ }
87
+ const pkgPath = path_1.default.join(cwd, 'package.json');
88
+ const pkg = JSON.parse(fs_1.default.readFileSync(pkgPath, 'utf8'));
89
+ pkg.scripts = pkg.scripts || {};
90
+ let modified = false;
91
+ for (const [name, value] of [
92
+ ['build:android:apk', APK_CHAIN],
93
+ ['build:android:aab', AAB_CHAIN],
94
+ ]) {
95
+ if (pkg.scripts[name] && pkg.scripts[name] !== value && !opts.force) {
96
+ log_1.log.warn(`Script "${name}" already exists; not overwriting. Use --force to replace.`);
97
+ continue;
98
+ }
99
+ pkg.scripts[name] = value;
100
+ modified = true;
101
+ log_1.log.ok(`package.json: ${name}`);
102
+ }
103
+ if (modified)
104
+ fs_1.default.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
105
+ (0, gitignore_1.ensureGitignoreEntries)(cwd, ['keystore.properties', '*.jks', 'credentials.json']);
106
+ if (opts.keystore !== false) {
107
+ const wantsKs = await (0, prompts_1.confirm)({
108
+ message: 'Set up the Android signing keystore now?',
109
+ default: true,
110
+ });
111
+ if (wantsKs) {
112
+ await (0, keystore_1.ensureKeystore)(cwd);
113
+ }
114
+ else {
115
+ log_1.log.dim('Skipping keystore setup. Run later: npx local-expo-build keystore setup');
116
+ }
117
+ }
118
+ log_1.log.step('Init complete');
119
+ log_1.log.info('Next steps:');
120
+ log_1.log.dim(' npm run build:android:aab # build a release AAB');
121
+ log_1.log.dim(' npm run build:android:apk # build a release APK');
122
+ log_1.log.dim(' npx local-expo-build doctor # re-run env checks any time');
123
+ });
124
+ }
125
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerKeystoreCommand = registerKeystoreCommand;
4
+ const ctx_1 = require("../util/ctx");
5
+ const keystore_1 = require("../core/keystore");
6
+ const existing_1 = require("../core/keystore/existing");
7
+ const generate_1 = require("../core/keystore/generate");
8
+ const easFetch_1 = require("../core/keystore/easFetch");
9
+ function registerKeystoreCommand(program) {
10
+ const ks = program.command('keystore').description('Manage Android signing keystore');
11
+ ks.command('setup')
12
+ .description('Interactive: choose existing/generate/EAS')
13
+ .action(async (_opts, cmd) => {
14
+ const { cwd } = (0, ctx_1.getCtx)(cmd);
15
+ await (0, keystore_1.ensureKeystore)(cwd);
16
+ });
17
+ ks.command('import')
18
+ .description('Register an existing .jks file')
19
+ .action(async (_opts, cmd) => {
20
+ const { cwd } = (0, ctx_1.getCtx)(cmd);
21
+ await (0, keystore_1.ensureKeystore)(cwd, 'existing');
22
+ });
23
+ ks.command('create')
24
+ .description('Generate a new keystore via keytool')
25
+ .action(async (_opts, cmd) => {
26
+ const { cwd } = (0, ctx_1.getCtx)(cmd);
27
+ await (0, keystore_1.ensureKeystore)(cwd, 'generate');
28
+ });
29
+ ks.command('fetch')
30
+ .description('Fetch keystore via `eas credentials` (interactive)')
31
+ .action(async (_opts, cmd) => {
32
+ const { cwd } = (0, ctx_1.getCtx)(cmd);
33
+ await (0, keystore_1.ensureKeystore)(cwd, 'eas');
34
+ });
35
+ ks.command('rehydrate')
36
+ .description('Recreate keystore.properties (and copy .jks into android/app/) from credentials.json')
37
+ .option('--move', 'delete the source .jks after copying into android/app/')
38
+ .action(async (opts, cmd) => {
39
+ const { cwd } = (0, ctx_1.getCtx)(cmd);
40
+ await (0, keystore_1.ensureKeystore)(cwd, 'rehydrate', { rehydrate: { move: Boolean(opts.move) } });
41
+ });
42
+ // Silence unused warnings — providers referenced by ensureKeystore
43
+ void existing_1.importExistingKeystore;
44
+ void generate_1.generateKeystore;
45
+ void easFetch_1.fetchKeystoreFromEas;
46
+ }
47
+ //# sourceMappingURL=keystore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keystore.js","sourceRoot":"","sources":["../../src/commands/keystore.ts"],"names":[],"mappings":";;AAOA,0DA2CC;AAjDD,qCAAqC;AACrC,+CAAkD;AAClD,wDAAmE;AACnE,wDAA6D;AAC7D,wDAAiE;AAEjE,SAAgB,uBAAuB,CAAC,OAAgB;IACtD,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC,iCAAiC,CAAC,CAAC;IAEtF,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,2CAA2C,CAAC;SACxD,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC3B,MAAM,EAAE,GAAG,EAAE,GAAG,IAAA,YAAM,EAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,IAAA,yBAAc,EAAC,GAAG,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEL,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,gCAAgC,CAAC;SAC7C,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC3B,MAAM,EAAE,GAAG,EAAE,GAAG,IAAA,YAAM,EAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,IAAA,yBAAc,EAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEL,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,qCAAqC,CAAC;SAClD,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC3B,MAAM,EAAE,GAAG,EAAE,GAAG,IAAA,YAAM,EAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,IAAA,yBAAc,EAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEL,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,oDAAoD,CAAC;SACjE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC3B,MAAM,EAAE,GAAG,EAAE,GAAG,IAAA,YAAM,EAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,IAAA,yBAAc,EAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEL,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,sFAAsF,CAAC;SACnG,MAAM,CAAC,QAAQ,EAAE,wDAAwD,CAAC;SAC1E,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC1B,MAAM,EAAE,GAAG,EAAE,GAAG,IAAA,YAAM,EAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,IAAA,yBAAc,EAAC,GAAG,EAAE,WAAW,EAAE,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IAEL,mEAAmE;IACnE,KAAK,iCAAsB,CAAC;IAC5B,KAAK,2BAAgB,CAAC;IACtB,KAAK,+BAAoB,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.bumpVersion = bumpVersion;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const execa_1 = require("execa");
10
+ const log_1 = require("../util/log");
11
+ /**
12
+ * 1. Bump patch in app.json + package.json
13
+ * 2. Fetch versionCode from EAS (unless skipEas), increment, write into android/app/build.gradle
14
+ */
15
+ function bumpVersion({ cwd, profile = 'production', skipEas = false, }) {
16
+ const appJsonPath = path_1.default.join(cwd, 'app.json');
17
+ const pkgJsonPath = path_1.default.join(cwd, 'package.json');
18
+ const gradlePath = path_1.default.join(cwd, 'android', 'app', 'build.gradle');
19
+ if (!fs_1.default.existsSync(appJsonPath))
20
+ throw new Error(`app.json not found at ${appJsonPath}`);
21
+ if (!fs_1.default.existsSync(gradlePath))
22
+ throw new Error(`${gradlePath} not found — run prebuild first.`);
23
+ const appJson = JSON.parse(fs_1.default.readFileSync(appJsonPath, 'utf8'));
24
+ const currentVersion = appJson.expo?.version;
25
+ if (!currentVersion || currentVersion.split('.').length !== 3) {
26
+ throw new Error(`Unexpected version in app.json: "${currentVersion}"`);
27
+ }
28
+ const parts = currentVersion.split('.');
29
+ parts[2] = String(parseInt(parts[2], 10) + 1);
30
+ const nextVersion = parts.join('.');
31
+ appJson.expo.version = nextVersion;
32
+ fs_1.default.writeFileSync(appJsonPath, JSON.stringify(appJson, null, 2) + '\n', 'utf8');
33
+ log_1.log.ok(`app.json version: ${currentVersion} → ${nextVersion}`);
34
+ if (fs_1.default.existsSync(pkgJsonPath)) {
35
+ const pkg = JSON.parse(fs_1.default.readFileSync(pkgJsonPath, 'utf8'));
36
+ pkg.version = nextVersion;
37
+ fs_1.default.writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
38
+ log_1.log.ok(`package.json version: → ${nextVersion}`);
39
+ }
40
+ let nextCode = null;
41
+ if (!skipEas && appJson.expo?.extra?.eas?.projectId) {
42
+ log_1.log.info(`Fetching EAS versionCode (profile: ${profile})...`);
43
+ try {
44
+ const { stdout } = (0, execa_1.execaSync)('eas', ['build:version:get', '--platform', 'android', '--profile', profile, '--non-interactive'], { cwd, encoding: 'utf8', reject: false });
45
+ const match = stdout.match(/Android versionCode\s*[-–]\s*(\d+)/i);
46
+ if (match) {
47
+ nextCode = parseInt(match[1], 10) + 1;
48
+ log_1.log.ok(`EAS versionCode: ${match[1]} → ${nextCode}`);
49
+ }
50
+ else {
51
+ log_1.log.warn(`Could not parse EAS versionCode; falling back to local bump`);
52
+ }
53
+ }
54
+ catch (err) {
55
+ log_1.log.warn(`EAS version fetch failed: ${err?.message || err}`);
56
+ }
57
+ }
58
+ let gradle = fs_1.default.readFileSync(gradlePath, 'utf8');
59
+ if (nextCode == null) {
60
+ const cur = gradle.match(/\bversionCode\s+(\d+)/);
61
+ nextCode = cur ? parseInt(cur[1], 10) + 1 : 1;
62
+ log_1.log.dim(`Local versionCode bump: → ${nextCode}`);
63
+ }
64
+ gradle = gradle.replace(/(\bversionCode\s+)\d+/, `$1${nextCode}`);
65
+ gradle = gradle.replace(/(\bversionName\s+")[^"]*"/, `$1${nextVersion}"`);
66
+ fs_1.default.writeFileSync(gradlePath, gradle, 'utf8');
67
+ log_1.log.ok(`build.gradle: versionCode=${nextCode}, versionName="${nextVersion}"`);
68
+ return { versionName: nextVersion, versionCode: nextCode };
69
+ }
70
+ //# sourceMappingURL=bumpVersion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bumpVersion.js","sourceRoot":"","sources":["../../src/core/bumpVersion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.detectEasLink = detectEasLink;
7
+ exports.isEasReady = isEasReady;
8
+ exports.hasProjectId = hasProjectId;
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const expoConfig_1 = require("./expoConfig");
12
+ /**
13
+ * Statically classify whether an Expo project is linked to an EAS project.
14
+ *
15
+ * Uses `readExpoConfig` so this works for both `app.json` and dynamic
16
+ * `app.config.{js,ts}` configs. When a dynamic config exists but the Expo
17
+ * CLI can't resolve it (not installed, syntax error, etc.) we return
18
+ * `dynamic-unreadable` so the caller can warn instead of pretending.
19
+ */
20
+ function detectEasLink(cwd) {
21
+ const hasEasJson = fs_1.default.existsSync(path_1.default.join(cwd, 'eas.json'));
22
+ const hasAppJson = fs_1.default.existsSync(path_1.default.join(cwd, 'app.json'));
23
+ const hasDynamic = fs_1.default.existsSync(path_1.default.join(cwd, 'app.config.js')) ||
24
+ fs_1.default.existsSync(path_1.default.join(cwd, 'app.config.ts')) ||
25
+ fs_1.default.existsSync(path_1.default.join(cwd, 'app.config.cjs')) ||
26
+ fs_1.default.existsSync(path_1.default.join(cwd, 'app.config.mjs'));
27
+ const resolved = (0, expoConfig_1.readExpoConfig)(cwd);
28
+ if (resolved) {
29
+ const projectId = resolved.config?.extra?.eas?.projectId;
30
+ if (projectId) {
31
+ return { kind: 'linked', projectId, hasEasJson, source: resolved.source };
32
+ }
33
+ return {
34
+ kind: 'not-linked',
35
+ hasAppJson: resolved.source === 'app.json' ? true : hasAppJson,
36
+ hasEasJson,
37
+ source: resolved.source,
38
+ };
39
+ }
40
+ if (hasDynamic)
41
+ return { kind: 'dynamic-unreadable', hasEasJson };
42
+ if (hasEasJson) {
43
+ return { kind: 'not-linked', hasAppJson: false, hasEasJson: true, source: 'app.json' };
44
+ }
45
+ return { kind: 'no-expo-config' };
46
+ }
47
+ /**
48
+ * Returns true when the project has enough state for `eas credentials` and
49
+ * other project-scoped EAS commands to run. EAS requires BOTH a projectId
50
+ * (linked) AND an eas.json (build config). `eas init` writes the projectId;
51
+ * `eas build:configure` writes eas.json. They're independent.
52
+ */
53
+ function isEasReady(result) {
54
+ if (result.kind === 'linked')
55
+ return result.hasEasJson;
56
+ if (result.kind === 'dynamic-unreadable')
57
+ return result.hasEasJson;
58
+ return false;
59
+ }
60
+ /** True iff the project is linked (has a projectId we can statically see). */
61
+ function hasProjectId(result) {
62
+ return result.kind === 'linked';
63
+ }
64
+ //# sourceMappingURL=easLink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"easLink.js","sourceRoot":"","sources":["../../src/core/easLink.ts"],"names":[],"mappings":";;;;;AAkBA,sCA6BC;AAQD,gCAIC;AAGD,oCAEC;AAhED,4CAAoB;AACpB,gDAAwB;AACxB,6CAA8C;AAQ9C;;;;;;;GAOG;AACH,SAAgB,aAAa,CAAC,GAAW;IACvC,MAAM,UAAU,GAAG,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC;IAC7D,MAAM,UAAU,GAAG,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC;IAC7D,MAAM,UAAU,GACd,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAC9C,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAC9C,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;QAC/C,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAElD,MAAM,QAAQ,GAAG,IAAA,2BAAc,EAAC,GAAG,CAAC,CAAC;IAErC,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,SAAS,GAAuB,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,CAAC;QAC7E,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC5E,CAAC;QACD,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,UAAU,EAAE,QAAQ,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU;YAC9D,UAAU;YACV,MAAM,EAAE,QAAQ,CAAC,MAAM;SACxB,CAAC;IACJ,CAAC;IAED,IAAI,UAAU;QAAE,OAAO,EAAE,IAAI,EAAE,oBAAoB,EAAE,UAAU,EAAE,CAAC;IAClE,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IACzF,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,SAAgB,UAAU,CAAC,MAAqB;IAC9C,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,UAAU,CAAC;IACvD,IAAI,MAAM,CAAC,IAAI,KAAK,oBAAoB;QAAE,OAAO,MAAM,CAAC,UAAU,CAAC;IACnE,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8EAA8E;AAC9E,SAAgB,YAAY,CAAC,MAAqB;IAChD,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC;AAClC,CAAC"}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.readExpoConfig = readExpoConfig;
7
+ exports.invalidateExpoConfigCache = invalidateExpoConfigCache;
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const execa_1 = require("execa");
11
+ const cache = new Map();
12
+ function readExpoConfig(cwd) {
13
+ if (cache.has(cwd))
14
+ return cache.get(cwd) ?? null;
15
+ const hasDynamic = fs_1.default.existsSync(path_1.default.join(cwd, 'app.config.js')) ||
16
+ fs_1.default.existsSync(path_1.default.join(cwd, 'app.config.ts')) ||
17
+ fs_1.default.existsSync(path_1.default.join(cwd, 'app.config.cjs')) ||
18
+ fs_1.default.existsSync(path_1.default.join(cwd, 'app.config.mjs'));
19
+ if (hasDynamic) {
20
+ const fromDynamic = readDynamicConfig(cwd);
21
+ if (fromDynamic) {
22
+ cache.set(cwd, fromDynamic);
23
+ return fromDynamic;
24
+ }
25
+ // Fall through to app.json (some projects keep both; dynamic just augments).
26
+ }
27
+ const appJsonPath = path_1.default.join(cwd, 'app.json');
28
+ if (fs_1.default.existsSync(appJsonPath)) {
29
+ try {
30
+ const raw = JSON.parse(fs_1.default.readFileSync(appJsonPath, 'utf8'));
31
+ const inner = raw?.expo ?? raw ?? null;
32
+ if (inner && typeof inner === 'object') {
33
+ const result = { config: inner, source: 'app.json' };
34
+ cache.set(cwd, result);
35
+ return result;
36
+ }
37
+ }
38
+ catch {
39
+ // malformed app.json — fall through
40
+ }
41
+ }
42
+ cache.set(cwd, null);
43
+ return null;
44
+ }
45
+ function invalidateExpoConfigCache(cwd) {
46
+ if (cwd)
47
+ cache.delete(cwd);
48
+ else
49
+ cache.clear();
50
+ }
51
+ function readDynamicConfig(cwd) {
52
+ try {
53
+ const result = (0, execa_1.execaSync)('npx', ['--no-install', 'expo', 'config', '--json', '--type', 'public'], {
54
+ cwd,
55
+ reject: false,
56
+ timeout: 30_000,
57
+ stdio: ['ignore', 'pipe', 'pipe'],
58
+ });
59
+ if (result.exitCode !== 0 || !result.stdout)
60
+ return null;
61
+ const parsed = JSON.parse(result.stdout);
62
+ const inner = parsed?.expo ?? parsed;
63
+ if (!inner || typeof inner !== 'object')
64
+ return null;
65
+ return { config: inner, source: 'dynamic' };
66
+ }
67
+ catch {
68
+ return null;
69
+ }
70
+ }
71
+ //# sourceMappingURL=expoConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expoConfig.js","sourceRoot":"","sources":["../../src/core/expoConfig.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.gradleRun = gradleRun;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const execa_1 = require("execa");
10
+ const log_1 = require("../util/log");
11
+ async function gradleRun({ cwd, task }) {
12
+ const androidDir = path_1.default.join(cwd, 'android');
13
+ const isWin = process.platform === 'win32';
14
+ const wrapper = isWin ? 'gradlew.bat' : './gradlew';
15
+ if (!fs_1.default.existsSync(path_1.default.join(androidDir, isWin ? 'gradlew.bat' : 'gradlew'))) {
16
+ throw new Error(`Gradle wrapper not found in ${androidDir}. Run prebuild first.`);
17
+ }
18
+ log_1.log.info(`gradle ${task} (cwd: ${androidDir})`);
19
+ await (0, execa_1.execa)(wrapper, [task], { cwd: androidDir, stdio: 'inherit', shell: isWin });
20
+ const artifact = task === 'bundleRelease'
21
+ ? path_1.default.join(androidDir, 'app', 'build', 'outputs', 'bundle', 'release', 'app-release.aab')
22
+ : path_1.default.join(androidDir, 'app', 'build', 'outputs', 'apk', 'release', 'app-release.apk');
23
+ if (fs_1.default.existsSync(artifact)) {
24
+ log_1.log.ok(`Artifact: ${artifact}`);
25
+ }
26
+ else {
27
+ log_1.log.warn(`Expected artifact not found at ${artifact}`);
28
+ }
29
+ return artifact;
30
+ }
31
+ //# sourceMappingURL=gradleRun.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gradleRun.js","sourceRoot":"","sources":["../../src/core/gradleRun.ts"],"names":[],"mappings":";;;;;AAUA,8BAoBC;AA9BD,4CAAoB;AACpB,gDAAwB;AACxB,iCAA8B;AAC9B,qCAAkC;AAO3B,KAAK,UAAU,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,EAAiB;IAC1D,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC;IACpD,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QAC7E,MAAM,IAAI,KAAK,CAAC,+BAA+B,UAAU,uBAAuB,CAAC,CAAC;IACpF,CAAC;IACD,SAAG,CAAC,IAAI,CAAC,UAAU,IAAI,UAAU,UAAU,GAAG,CAAC,CAAC;IAChD,MAAM,IAAA,aAAK,EAAC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAElF,MAAM,QAAQ,GACZ,IAAI,KAAK,eAAe;QACtB,CAAC,CAAC,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,iBAAiB,CAAC;QAC1F,CAAC,CAAC,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC;IAC5F,IAAI,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,SAAG,CAAC,EAAE,CAAC,aAAa,QAAQ,EAAE,CAAC,CAAC;IAClC,CAAC;SAAM,CAAC;QACN,SAAG,CAAC,IAAI,CAAC,kCAAkC,QAAQ,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchKeystoreFromEas = fetchKeystoreFromEas;
4
+ const execa_1 = require("execa");
5
+ const prompts_1 = require("@inquirer/prompts");
6
+ const log_1 = require("../../util/log");
7
+ const easLink_1 = require("../easLink");
8
+ /**
9
+ * Fetches Android signing credentials from EAS.
10
+ *
11
+ * EAS CLI does not expose a stable non-interactive keystore export, so we run
12
+ * `eas credentials --platform android` interactively and ask the user to
13
+ * download the .jks via the menu. After download, they re-run
14
+ * `local-expo-build keystore import <path>`.
15
+ *
16
+ * Pre-flight: `eas credentials` requires BOTH a projectId (linked via
17
+ * `eas init`) AND `eas.json` (created via `eas build:configure`). We check
18
+ * each independently and offer to run the appropriate command so the user
19
+ * doesn't see a cryptic "credentials command failed".
20
+ */
21
+ async function fetchKeystoreFromEas(cwd) {
22
+ await ensureEasReady(cwd);
23
+ log_1.log.info('Launching EAS credentials manager. Choose "Download Keystore" to save the .jks locally.');
24
+ log_1.log.dim('When done, re-run: local-expo-build keystore import <path-to-downloaded.jks>');
25
+ try {
26
+ await (0, execa_1.execa)('eas', ['credentials', '--platform', 'android'], { cwd, stdio: 'inherit' });
27
+ }
28
+ catch (err) {
29
+ throw new Error(`eas credentials failed: ${err?.shortMessage || err?.message || err}. ` +
30
+ `Ensure EAS CLI is installed (npm i -g eas-cli) and you are logged in (eas login).`);
31
+ }
32
+ log_1.log.warn('EAS CLI does not provide a stable non-interactive keystore export. ' +
33
+ 'After downloading, run `local-expo-build keystore import <path>` to register it.');
34
+ }
35
+ async function ensureEasReady(cwd) {
36
+ let link = (0, easLink_1.detectEasLink)(cwd);
37
+ if ((0, easLink_1.isEasReady)(link))
38
+ return;
39
+ if (link.kind === 'no-expo-config') {
40
+ throw new Error(`This does not look like an Expo project (no app.json or app.config.*). ` +
41
+ `Run \`local-expo-build\` inside an Expo project root, or pass --cwd <path>.`);
42
+ }
43
+ const interactive = process.stdin.isTTY;
44
+ // Step 1: project not linked (no projectId in static config) — needs `eas init`.
45
+ if (link.kind === 'not-linked') {
46
+ const reason = link.hasAppJson
47
+ ? 'app.json has no expo.extra.eas.projectId'
48
+ : 'no app.json with an EAS projectId';
49
+ log_1.log.warn(`EAS project not linked: ${reason}.`);
50
+ log_1.log.dim('Running `eas init` will link this project to an EAS account and write the projectId.');
51
+ if (!interactive) {
52
+ throw new Error(`EAS project not linked. Run \`eas init\` in ${cwd}, then re-run this command.`);
53
+ }
54
+ const yes = await (0, prompts_1.confirm)({
55
+ message: 'Run `eas init` now to link this project?',
56
+ default: true,
57
+ });
58
+ if (!yes) {
59
+ throw new Error('Aborted. Run `eas init` manually, then re-run `local-expo-build keystore fetch`.');
60
+ }
61
+ await runEas(cwd, ['init'], 'eas init');
62
+ link = (0, easLink_1.detectEasLink)(cwd);
63
+ if ((0, easLink_1.isEasReady)(link)) {
64
+ log_1.log.ok('EAS link complete. Continuing with credentials fetch...');
65
+ return;
66
+ }
67
+ }
68
+ // Step 2: linked (or dynamic) but eas.json is missing — needs `eas build:configure`.
69
+ if (link.kind === 'no-expo-config') {
70
+ throw new Error('Lost track of Expo config after `eas init`. Please re-run `local-expo-build keystore fetch`.');
71
+ }
72
+ if (link.kind === 'dynamic-unreadable') {
73
+ throw new Error('app.config.* exists but could not be resolved. Install Expo CLI in your project ' +
74
+ '(`npm install`) and retry, or add `expo.extra.eas.projectId` + `eas.json` manually.');
75
+ }
76
+ if (!link.hasEasJson) {
77
+ log_1.log.warn('eas.json is missing — required by `eas credentials`.');
78
+ log_1.log.dim('Running `eas build:configure` will create eas.json with default build profiles.');
79
+ if (!interactive) {
80
+ throw new Error(`eas.json not found. Run \`eas build:configure --platform android\` in ${cwd}, ` +
81
+ `then re-run this command.`);
82
+ }
83
+ const yes = await (0, prompts_1.confirm)({
84
+ message: 'Run `eas build:configure --platform android` now to create eas.json?',
85
+ default: true,
86
+ });
87
+ if (!yes) {
88
+ throw new Error('Aborted. Run `eas build:configure --platform android` manually, ' +
89
+ 'then re-run `local-expo-build keystore fetch`.');
90
+ }
91
+ await runEas(cwd, ['build:configure', '--platform', 'android'], 'eas build:configure');
92
+ link = (0, easLink_1.detectEasLink)(cwd);
93
+ }
94
+ if (!(0, easLink_1.isEasReady)(link)) {
95
+ throw new Error('EAS setup finished but the project still does not appear ready. ' +
96
+ 'Verify eas.json exists and (for static configs) app.json has expo.extra.eas.projectId, then retry.');
97
+ }
98
+ log_1.log.ok('EAS is ready. Continuing with credentials fetch...');
99
+ }
100
+ async function runEas(cwd, args, label) {
101
+ try {
102
+ await (0, execa_1.execa)('eas', args, { cwd, stdio: 'inherit' });
103
+ }
104
+ catch (err) {
105
+ throw new Error(`${label} failed: ${err?.shortMessage || err?.message || err}. ` +
106
+ `Ensure EAS CLI is installed (npm i -g eas-cli) and you are logged in (eas login).`);
107
+ }
108
+ }
109
+ //# sourceMappingURL=easFetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"easFetch.js","sourceRoot":"","sources":["../../../src/core/keystore/easFetch.ts"],"names":[],"mappings":"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"}