@makefully/adaptfully 3.16.1 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,243 @@
1
+ import { spawn } from 'node:child_process';
2
+ import fsp from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import {
5
+ defaultDeploymentCredentialPath,
6
+ ensureDeploymentManifest,
7
+ ensurePublishCredentialsGitignore,
8
+ parsePublishCredentialArgv,
9
+ promptConfirm,
10
+ promptRequired,
11
+ } from './publish-credentials.js';
12
+
13
+ const DEBUG_ALIAS = 'androiddebugkey';
14
+ const DEBUG_PASSWORD = 'android';
15
+ const DEBUG_DNAME = 'CN=Android Debug,O=Android,C=US';
16
+
17
+ /**
18
+ * @param {string} [projectRoot]
19
+ * @param {string} [deploymentKey='android']
20
+ */
21
+ export function defaultAndroidDeploymentDir(projectRoot = '.', deploymentKey = 'android') {
22
+ return path.dirname(defaultDeploymentCredentialPath(projectRoot, deploymentKey, 'build.json'));
23
+ }
24
+
25
+ /**
26
+ * @param {{
27
+ * debugOnly?: boolean,
28
+ * debug?: { keystore: string, storePassword: string, alias: string, password: string },
29
+ * release?: { keystore: string, storePassword: string, alias: string, password: string },
30
+ * }} options
31
+ */
32
+ export function buildAndroidBuildJson(options = {}) {
33
+ /** @type {Record<string, unknown>} */
34
+ const android = {
35
+ debug: {
36
+ keystore: options.debug?.keystore ?? './android/debug.keystore',
37
+ packageType: 'apk',
38
+ storePassword: options.debug?.storePassword ?? DEBUG_PASSWORD,
39
+ alias: options.debug?.alias ?? DEBUG_ALIAS,
40
+ password: options.debug?.password ?? DEBUG_PASSWORD,
41
+ keystoreType: '',
42
+ },
43
+ };
44
+
45
+ if (!options.debugOnly && options.release) {
46
+ android.release = {
47
+ keystore: options.release.keystore,
48
+ packageType: 'bundle',
49
+ storePassword: options.release.storePassword,
50
+ alias: options.release.alias,
51
+ password: options.release.password,
52
+ keystoreType: '',
53
+ };
54
+ }
55
+
56
+ return { android };
57
+ }
58
+
59
+ /**
60
+ * @param {string[]} args
61
+ * @param {{ command?: string }} [options]
62
+ * @returns {Promise<void>}
63
+ */
64
+ export function runKeytool(args, options = {}) {
65
+ const command = options.command ?? 'keytool';
66
+
67
+ return new Promise((resolve, reject) => {
68
+ const child = spawn(command, args, {
69
+ stdio: ['ignore', 'pipe', 'pipe'],
70
+ shell: process.platform === 'win32',
71
+ });
72
+
73
+ let stderr = '';
74
+ child.stderr?.on('data', (chunk) => {
75
+ stderr += String(chunk);
76
+ });
77
+ child.on('error', (err) => {
78
+ reject(new Error(
79
+ `Unable to run "${command}". Install a JDK and ensure keytool is on PATH. (${err.message})`,
80
+ ));
81
+ });
82
+ child.on('close', (code) => {
83
+ if (code === 0) {
84
+ resolve();
85
+ return;
86
+ }
87
+ reject(new Error(`keytool failed (exit ${code}): ${stderr.trim() || 'no output'}`));
88
+ });
89
+ });
90
+ }
91
+
92
+ /**
93
+ * @param {{
94
+ * keystorePath: string,
95
+ * alias: string,
96
+ * storePassword: string,
97
+ * keyPassword: string,
98
+ * dname: string,
99
+ * validityDays?: number,
100
+ * runKeytoolFn?: typeof runKeytool,
101
+ * }} options
102
+ */
103
+ export async function generateKeystore(options) {
104
+ const run = options.runKeytoolFn ?? runKeytool;
105
+ await fsp.mkdir(path.dirname(options.keystorePath), { recursive: true });
106
+ await run([
107
+ '-genkeypair',
108
+ '-v',
109
+ '-keystore', options.keystorePath,
110
+ '-alias', options.alias,
111
+ '-keyalg', 'RSA',
112
+ '-keysize', '2048',
113
+ '-validity', String(options.validityDays ?? 10000),
114
+ '-storepass', options.storePassword,
115
+ '-keypass', options.keyPassword,
116
+ '-dname', options.dname,
117
+ ]);
118
+ }
119
+
120
+ /**
121
+ * @param {{
122
+ * deployment?: string,
123
+ * projectRoot?: string,
124
+ * debugOnly?: boolean,
125
+ * yes?: boolean,
126
+ * alias?: string,
127
+ * storePassword?: string,
128
+ * keyPassword?: string,
129
+ * cn?: string,
130
+ * log?: (message: string) => void,
131
+ * runKeytoolFn?: typeof runKeytool,
132
+ * }} [options]
133
+ */
134
+ export async function runAndroidKeystore(options = {}) {
135
+ const log = options.log ?? console.log;
136
+ const projectRoot = options.projectRoot ?? '.';
137
+ const deploymentKey = options.deployment ?? 'android';
138
+ const deploymentDir = defaultAndroidDeploymentDir(projectRoot, deploymentKey);
139
+ const keystoreDir = path.join(deploymentDir, 'android');
140
+ const buildJsonPath = path.join(deploymentDir, 'build.json');
141
+ const debugOnly = options.debugOnly === true;
142
+
143
+ let buildJsonExists = false;
144
+ try {
145
+ await fsp.access(buildJsonPath);
146
+ buildJsonExists = true;
147
+ } catch {
148
+ buildJsonExists = false;
149
+ }
150
+
151
+ if (buildJsonExists) {
152
+ const overwrite = options.yes === true
153
+ || await promptConfirm(`Overwrite existing ${buildJsonPath}?`, false);
154
+ if (!overwrite) {
155
+ throw new Error(`Refusing to overwrite ${buildJsonPath}. Pass --yes to overwrite.`);
156
+ }
157
+ }
158
+
159
+ const debugKeystorePath = path.join(keystoreDir, 'debug.keystore');
160
+ log(`adaptfully: generating debug keystore → ${debugKeystorePath}`);
161
+ await generateKeystore({
162
+ keystorePath: debugKeystorePath,
163
+ alias: DEBUG_ALIAS,
164
+ storePassword: DEBUG_PASSWORD,
165
+ keyPassword: DEBUG_PASSWORD,
166
+ dname: DEBUG_DNAME,
167
+ runKeytoolFn: options.runKeytoolFn,
168
+ });
169
+
170
+ /** @type {{ keystore: string, storePassword: string, alias: string, password: string } | undefined} */
171
+ let release;
172
+
173
+ if (!debugOnly) {
174
+ const alias = options.alias
175
+ ?? await promptRequired('Release keystore alias: ');
176
+ const storePassword = options.storePassword
177
+ ?? await promptRequired('Release store password: ');
178
+ const keyPassword = options.keyPassword
179
+ ?? options.storePassword
180
+ ?? await promptRequired('Release key password (often same as store): ');
181
+ const cn = options.cn
182
+ ?? await promptRequired('Certificate CN (e.g. Your Studio): ');
183
+
184
+ const releaseKeystorePath = path.join(keystoreDir, 'release.keystore');
185
+ log(`adaptfully: generating release keystore → ${releaseKeystorePath}`);
186
+ await generateKeystore({
187
+ keystorePath: releaseKeystorePath,
188
+ alias,
189
+ storePassword,
190
+ keyPassword,
191
+ dname: `CN=${cn},O=${cn},C=US`,
192
+ runKeytoolFn: options.runKeytoolFn,
193
+ });
194
+
195
+ release = {
196
+ keystore: './android/release.keystore',
197
+ storePassword,
198
+ alias,
199
+ password: keyPassword,
200
+ };
201
+ }
202
+
203
+ const buildJson = buildAndroidBuildJson({
204
+ debugOnly,
205
+ debug: {
206
+ keystore: './android/debug.keystore',
207
+ storePassword: DEBUG_PASSWORD,
208
+ alias: DEBUG_ALIAS,
209
+ password: DEBUG_PASSWORD,
210
+ },
211
+ release,
212
+ });
213
+
214
+ await fsp.mkdir(deploymentDir, { recursive: true });
215
+ await fsp.writeFile(buildJsonPath, `${JSON.stringify(buildJson, null, 4)}\n`);
216
+ await ensureDeploymentManifest(deploymentDir, 'google', log);
217
+ await ensurePublishCredentialsGitignore(projectRoot, {
218
+ extraPaths: [buildJsonPath, keystoreDir],
219
+ log,
220
+ });
221
+
222
+ log(`adaptfully: wrote ${buildJsonPath}`);
223
+ if (debugOnly) {
224
+ log('adaptfully: debug-only keystore ready. For Play uploads, re-run without --debug-only, then use google-publish.');
225
+ } else {
226
+ log('adaptfully: next — create a Play Console service account JSON, then: adaptfully google-publish --from <sa.json>');
227
+ }
228
+
229
+ return {
230
+ deploymentKey,
231
+ deploymentDir,
232
+ buildJsonPath,
233
+ buildJson,
234
+ debugOnly,
235
+ };
236
+ }
237
+
238
+ /**
239
+ * @param {string[]} [argv]
240
+ */
241
+ export async function androidKeystoreFromCli(argv = process.argv) {
242
+ return runAndroidKeystore(parsePublishCredentialArgv(argv));
243
+ }
@@ -0,0 +1,392 @@
1
+ import { spawn } from 'node:child_process';
2
+ import fsp from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import {
5
+ defaultDeploymentCredentialPath,
6
+ ensureDeploymentManifest,
7
+ ensurePublishCredentialsGitignore,
8
+ parsePublishCredentialArgv,
9
+ promptConfirm,
10
+ promptRequired,
11
+ resolveUserPath,
12
+ } from './publish-credentials.js';
13
+
14
+ /** @typedef {'development' | 'distribution'} AppleSigningKind */
15
+
16
+ /**
17
+ * @param {string} [projectRoot]
18
+ * @param {string} [deploymentKey='ios']
19
+ */
20
+ export function defaultAppleSigningDir(projectRoot = '.', deploymentKey = 'ios') {
21
+ return path.join(
22
+ path.dirname(defaultDeploymentCredentialPath(projectRoot, deploymentKey, 'apple.json')),
23
+ 'apple',
24
+ );
25
+ }
26
+
27
+ /**
28
+ * @param {string} kind
29
+ * @returns {AppleSigningKind}
30
+ */
31
+ export function normalizeAppleSigningKind(kind) {
32
+ const value = String(kind ?? '').trim().toLowerCase();
33
+ if (value === 'development' || value === 'dev' || value === 'debug') {
34
+ return 'development';
35
+ }
36
+ if (value === 'distribution' || value === 'dist' || value === 'release' || value === 'app-store') {
37
+ return 'distribution';
38
+ }
39
+ throw new Error(
40
+ `Unknown Apple signing kind "${kind}". Use "development" or "distribution".`,
41
+ );
42
+ }
43
+
44
+ /**
45
+ * @param {AppleSigningKind} kind
46
+ */
47
+ export function appleSigningFilenames(kind) {
48
+ if (kind === 'development') {
49
+ return {
50
+ p12: 'development.p12',
51
+ provision: 'development.mobileprovision',
52
+ certLabel: 'Apple Development',
53
+ };
54
+ }
55
+ return {
56
+ p12: 'distribution.p12',
57
+ provision: 'app-store.mobileprovision',
58
+ certLabel: 'Apple Distribution',
59
+ };
60
+ }
61
+
62
+ /**
63
+ * Merge or create build.json with apple.p12Password.
64
+ * @param {object | null | undefined} existing
65
+ * @param {string} p12Password
66
+ */
67
+ export function mergeAppleP12PasswordBuildJson(existing, p12Password) {
68
+ /** @type {Record<string, unknown>} */
69
+ const next = existing && typeof existing === 'object' && !Array.isArray(existing)
70
+ ? { ...existing }
71
+ : {};
72
+ const apple = next.apple && typeof next.apple === 'object' && !Array.isArray(next.apple)
73
+ ? { .../** @type {Record<string, unknown>} */ (next.apple) }
74
+ : {};
75
+ apple.p12Password = p12Password;
76
+ next.apple = apple;
77
+ return next;
78
+ }
79
+
80
+ /**
81
+ * @param {string[]} args
82
+ * @param {{ command?: string }} [options]
83
+ * @returns {Promise<void>}
84
+ */
85
+ export function runOpenssl(args, options = {}) {
86
+ const command = options.command ?? 'openssl';
87
+
88
+ return new Promise((resolve, reject) => {
89
+ const child = spawn(command, args, {
90
+ stdio: ['ignore', 'pipe', 'pipe'],
91
+ shell: process.platform === 'win32',
92
+ });
93
+
94
+ let stderr = '';
95
+ child.stderr?.on('data', (chunk) => {
96
+ stderr += String(chunk);
97
+ });
98
+ child.on('error', (err) => {
99
+ reject(new Error(
100
+ `Unable to run "${command}". Install OpenSSL and ensure it is on PATH. (${err.message})`,
101
+ ));
102
+ });
103
+ child.on('close', (code) => {
104
+ if (code === 0) {
105
+ resolve();
106
+ return;
107
+ }
108
+ reject(new Error(`openssl failed (exit ${code}): ${stderr.trim() || 'no output'}`));
109
+ });
110
+ });
111
+ }
112
+
113
+ /**
114
+ * @param {{
115
+ * workdir: string,
116
+ * cn: string,
117
+ * email?: string,
118
+ * runOpensslFn?: typeof runOpenssl,
119
+ * }} options
120
+ */
121
+ export async function generateAppleCsr(options) {
122
+ const run = options.runOpensslFn ?? runOpenssl;
123
+ await fsp.mkdir(options.workdir, { recursive: true });
124
+
125
+ const keyPath = path.join(options.workdir, 'private.key');
126
+ const csrPath = path.join(options.workdir, 'CertificateSigningRequest.certSigningRequest');
127
+ const subject = options.email
128
+ ? `/emailAddress=${options.email}/CN=${options.cn}/C=US`
129
+ : `/CN=${options.cn}/C=US`;
130
+
131
+ await run(['genrsa', '-out', keyPath, '2048']);
132
+ await run([
133
+ 'req',
134
+ '-new',
135
+ '-key', keyPath,
136
+ '-out', csrPath,
137
+ '-subj', subject,
138
+ ]);
139
+
140
+ return { keyPath, csrPath };
141
+ }
142
+
143
+ /**
144
+ * @param {{
145
+ * cerPath: string,
146
+ * keyPath: string,
147
+ * p12Path: string,
148
+ * p12Password: string,
149
+ * runOpensslFn?: typeof runOpenssl,
150
+ * }} options
151
+ */
152
+ export async function exportAppleP12(options) {
153
+ const run = options.runOpensslFn ?? runOpenssl;
154
+ await fsp.mkdir(path.dirname(options.p12Path), { recursive: true });
155
+
156
+ const pemPath = `${options.cerPath}.pem`;
157
+ await run(['x509', '-in', options.cerPath, '-inform', 'DER', '-out', pemPath, '-outform', 'PEM']);
158
+
159
+ try {
160
+ await run([
161
+ 'pkcs12',
162
+ '-export',
163
+ '-inkey', options.keyPath,
164
+ '-in', pemPath,
165
+ '-out', options.p12Path,
166
+ '-passout', `pass:${options.p12Password}`,
167
+ ]);
168
+ } catch (derErr) {
169
+ // Some downloads are already PEM
170
+ try {
171
+ await run([
172
+ 'pkcs12',
173
+ '-export',
174
+ '-inkey', options.keyPath,
175
+ '-in', options.cerPath,
176
+ '-out', options.p12Path,
177
+ '-passout', `pass:${options.p12Password}`,
178
+ ]);
179
+ } catch {
180
+ throw derErr;
181
+ }
182
+ } finally {
183
+ try {
184
+ await fsp.unlink(pemPath);
185
+ } catch {
186
+ // ignore
187
+ }
188
+ }
189
+ }
190
+
191
+ /**
192
+ * @param {(message: string) => void} log
193
+ * @param {AppleSigningKind} kind
194
+ * @param {string} csrPath
195
+ */
196
+ function printPortalChecklist(log, kind, csrPath) {
197
+ const names = appleSigningFilenames(kind);
198
+ log('');
199
+ log('adaptfully: Apple Developer portal steps (browser):');
200
+ log(` 1. Open https://developer.apple.com/account/resources/certificates/list`);
201
+ log(` 2. Create a new "${names.certLabel}" certificate`);
202
+ log(` 3. Upload CSR: ${csrPath}`);
203
+ log(' 4. Download the .cer file');
204
+ log(' 5. Ensure your App ID exists; enable Sign in with Apple if you use Capgo Apple auth');
205
+ if (kind === 'development') {
206
+ log(' 6. Register device UDIDs, then create a Development provisioning profile');
207
+ } else {
208
+ log(' 6. Create an App Store Connect provisioning profile for the App ID');
209
+ }
210
+ log(' 7. Download the .mobileprovision file');
211
+ log('');
212
+ }
213
+
214
+ /**
215
+ * @param {{
216
+ * deployment?: string,
217
+ * projectRoot?: string,
218
+ * workdir?: string,
219
+ * csrOnly?: boolean,
220
+ * fromCer?: string,
221
+ * kind?: string,
222
+ * provision?: string,
223
+ * p12Password?: string,
224
+ * cn?: string,
225
+ * email?: string,
226
+ * yes?: boolean,
227
+ * log?: (message: string) => void,
228
+ * runOpensslFn?: typeof runOpenssl,
229
+ * }} [options]
230
+ */
231
+ export async function runAppleSigning(options = {}) {
232
+ const log = options.log ?? console.log;
233
+ const projectRoot = options.projectRoot ?? '.';
234
+ const deploymentKey = options.deployment ?? 'ios';
235
+ const appleDir = defaultAppleSigningDir(projectRoot, deploymentKey);
236
+ const deploymentDir = path.dirname(appleDir);
237
+ const workdir = path.resolve(
238
+ options.workdir
239
+ ?? path.join(appleDir, '.work'),
240
+ );
241
+
242
+ let kind = options.kind
243
+ ? normalizeAppleSigningKind(options.kind)
244
+ : null;
245
+
246
+ if (!kind && (options.fromCer || options.provision || !options.csrOnly)) {
247
+ kind = normalizeAppleSigningKind(
248
+ await promptRequired('Signing kind (development|distribution): ', options.kind),
249
+ );
250
+ }
251
+
252
+ if (!kind) {
253
+ kind = 'development';
254
+ }
255
+
256
+ const names = appleSigningFilenames(kind);
257
+ const keyPath = path.join(workdir, 'private.key');
258
+ const csrPath = path.join(workdir, 'CertificateSigningRequest.certSigningRequest');
259
+
260
+ let createdCsr = false;
261
+ try {
262
+ await fsp.access(keyPath);
263
+ await fsp.access(csrPath);
264
+ } catch {
265
+ const cn = options.cn ?? await promptRequired('Common name for CSR (e.g. Your Name): ');
266
+ const email = options.email;
267
+ log(`adaptfully: generating CSR in ${workdir}`);
268
+ await generateAppleCsr({
269
+ workdir,
270
+ cn,
271
+ email,
272
+ runOpensslFn: options.runOpensslFn,
273
+ });
274
+ createdCsr = true;
275
+ }
276
+
277
+ printPortalChecklist(log, kind, csrPath);
278
+
279
+ if (options.csrOnly) {
280
+ await ensurePublishCredentialsGitignore(projectRoot, {
281
+ extraPaths: [appleDir],
282
+ log,
283
+ });
284
+ log('adaptfully: --csr-only set; stop here, then re-run with --from-cer after downloading the .cer');
285
+ return {
286
+ deploymentKey,
287
+ appleDir,
288
+ workdir,
289
+ csrPath,
290
+ keyPath,
291
+ kind,
292
+ csrOnly: true,
293
+ createdCsr,
294
+ };
295
+ }
296
+
297
+ const cerPath = resolveUserPath(
298
+ await promptRequired('Path to downloaded Apple .cer: ', options.fromCer),
299
+ );
300
+
301
+ const p12Password = options.p12Password != null
302
+ ? String(options.p12Password)
303
+ : await promptRequired('Passphrase for the .p12 (remember this for build.json apple.p12Password): ');
304
+
305
+ const p12Path = path.join(appleDir, names.p12);
306
+ log(`adaptfully: exporting ${p12Path}`);
307
+ await exportAppleP12({
308
+ cerPath,
309
+ keyPath,
310
+ p12Path,
311
+ p12Password,
312
+ runOpensslFn: options.runOpensslFn,
313
+ });
314
+
315
+ const buildJsonPath = path.join(deploymentDir, 'build.json');
316
+ let existingBuild = null;
317
+ try {
318
+ existingBuild = JSON.parse(await fsp.readFile(buildJsonPath, 'utf8'));
319
+ } catch {
320
+ existingBuild = null;
321
+ }
322
+
323
+ const writePassword = options.yes === true
324
+ || p12Password === ''
325
+ || await promptConfirm(
326
+ `Write apple.p12Password into ${buildJsonPath}?`,
327
+ true,
328
+ );
329
+
330
+ if (writePassword) {
331
+ const merged = mergeAppleP12PasswordBuildJson(existingBuild, p12Password);
332
+ await fsp.mkdir(deploymentDir, { recursive: true });
333
+ await fsp.writeFile(buildJsonPath, `${JSON.stringify(merged, null, 4)}\n`);
334
+ log(`adaptfully: wrote ${buildJsonPath}`);
335
+ }
336
+
337
+ let provisionPath = options.provision;
338
+ if (!provisionPath) {
339
+ if (options.yes === true) {
340
+ log(`adaptfully: --yes set without --provision; skipping provisioning profile copy`);
341
+ } else {
342
+ const rlAnswer = await promptRequired(
343
+ `Path to downloaded ${names.provision} (type skip to finish later): `,
344
+ );
345
+ if (rlAnswer.toLowerCase() !== 'skip') {
346
+ provisionPath = rlAnswer;
347
+ }
348
+ }
349
+ }
350
+
351
+ if (provisionPath) {
352
+ const dest = path.join(appleDir, names.provision);
353
+ await fsp.mkdir(appleDir, { recursive: true });
354
+ await fsp.copyFile(resolveUserPath(provisionPath), dest);
355
+ log(`adaptfully: copied provisioning profile → ${dest}`);
356
+ } else {
357
+ log(`adaptfully: skipped provisioning profile — place ${names.provision} under ${appleDir} when ready`);
358
+ }
359
+
360
+ await ensureDeploymentManifest(deploymentDir, 'apple', log);
361
+ await ensurePublishCredentialsGitignore(projectRoot, {
362
+ extraPaths: [appleDir, buildJsonPath],
363
+ log,
364
+ });
365
+
366
+ log(`adaptfully: signing files under ${appleDir}`);
367
+ if (kind === 'distribution') {
368
+ log('adaptfully: next for App Store upload — adaptfully apple-publish');
369
+ } else {
370
+ log('adaptfully: development signing ready for ios-dev device builds');
371
+ }
372
+
373
+ return {
374
+ deploymentKey,
375
+ appleDir,
376
+ workdir,
377
+ csrPath,
378
+ keyPath,
379
+ p12Path,
380
+ kind,
381
+ csrOnly: false,
382
+ createdCsr,
383
+ provisionPath: provisionPath ? resolveUserPath(provisionPath) : null,
384
+ };
385
+ }
386
+
387
+ /**
388
+ * @param {string[]} [argv]
389
+ */
390
+ export async function appleSigningFromCli(argv = process.argv) {
391
+ return runAppleSigning(parsePublishCredentialArgv(argv));
392
+ }
package/lib/node/index.js CHANGED
@@ -23,7 +23,6 @@ export { prebuildPlatform, prebuildOutputDir, resolveHtmlInjections } from './pr
23
23
  export { getPackageRoot, getRuntimeDir, resolveRuntimeScript } from './paths.js';
24
24
  export {
25
25
  CapacitorPackager,
26
- CordovaPackager,
27
26
  ElectronPackager,
28
27
  Packager,
29
28
  VALID_PACKAGERS,
@@ -63,6 +62,7 @@ export {
63
62
  ensurePublishCredentialsGitignore,
64
63
  normalizeUserPath,
65
64
  parsePublishCredentialArgv,
65
+ promptConfirm,
66
66
  promptRequired,
67
67
  PUBLISH_CREDENTIAL_GITIGNORE_PATTERNS,
68
68
  resolveUserPath,
@@ -91,3 +91,22 @@ export {
91
91
  runApplePublish,
92
92
  validateApplePublishJson,
93
93
  } from './apple-publish.js';
94
+ export {
95
+ androidKeystoreFromCli,
96
+ buildAndroidBuildJson,
97
+ defaultAndroidDeploymentDir,
98
+ generateKeystore,
99
+ runAndroidKeystore,
100
+ runKeytool,
101
+ } from './android-keystore.js';
102
+ export {
103
+ appleSigningFilenames,
104
+ appleSigningFromCli,
105
+ defaultAppleSigningDir,
106
+ exportAppleP12,
107
+ generateAppleCsr,
108
+ mergeAppleP12PasswordBuildJson,
109
+ normalizeAppleSigningKind,
110
+ runAppleSigning,
111
+ runOpenssl,
112
+ } from './apple-signing.js';
@@ -4,10 +4,10 @@ import { STANDARD_PLUGINS } from '../registrations.js';
4
4
  import { resolvePlatformConfig } from '../platform-config.js';
5
5
 
6
6
  /** @typedef {import('../registrations.js').RegistrationMap} RegistrationMap */
7
- /** @typedef {'web' | 'electron' | 'cordova' | 'capacitor'} PackagerName */
7
+ /** @typedef {'web' | 'electron' | 'capacitor'} PackagerName */
8
8
 
9
9
  /** @type {PackagerName[]} */
10
- export const VALID_PACKAGERS = ['web', 'electron', 'cordova', 'capacitor'];
10
+ export const VALID_PACKAGERS = ['web', 'electron', 'capacitor'];
11
11
 
12
12
  const PACKAGER_MARKER = '<!-- adaptfully-packager -->';
13
13
  const PACKAGER_END_MARKER = '<!-- /adaptfully-packager -->';
@@ -16,7 +16,7 @@ const HEAD_PACKAGER_END_MARKER = '<!-- /adaptfully-packager-head -->';
16
16
 
17
17
  /**
18
18
  * @typedef {Object} PackagerOptions
19
- * @property {string[]} [platforms] Platform keys this packager targets (e.g. ios + android for Cordova)
19
+ * @property {string[]} [platforms] Platform keys this packager targets
20
20
  * @property {string} [platformKey] Active platform for a single prebuild run
21
21
  * @property {(message: string) => void} [log]
22
22
  */