@otakit/cli 1.0.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 (100) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +145 -0
  3. package/bin/otakit.js +3 -0
  4. package/dist/commands/config.d.ts +3 -0
  5. package/dist/commands/config.d.ts.map +1 -0
  6. package/dist/commands/config.js +115 -0
  7. package/dist/commands/config.js.map +1 -0
  8. package/dist/commands/delete.d.ts +3 -0
  9. package/dist/commands/delete.d.ts.map +1 -0
  10. package/dist/commands/delete.js +30 -0
  11. package/dist/commands/delete.js.map +1 -0
  12. package/dist/commands/generate-signing-key.d.ts +3 -0
  13. package/dist/commands/generate-signing-key.d.ts.map +1 -0
  14. package/dist/commands/generate-signing-key.js +41 -0
  15. package/dist/commands/generate-signing-key.js.map +1 -0
  16. package/dist/commands/list.d.ts +3 -0
  17. package/dist/commands/list.d.ts.map +1 -0
  18. package/dist/commands/list.js +30 -0
  19. package/dist/commands/list.js.map +1 -0
  20. package/dist/commands/login.d.ts +3 -0
  21. package/dist/commands/login.d.ts.map +1 -0
  22. package/dist/commands/login.js +79 -0
  23. package/dist/commands/login.js.map +1 -0
  24. package/dist/commands/logout.d.ts +3 -0
  25. package/dist/commands/logout.d.ts.map +1 -0
  26. package/dist/commands/logout.js +25 -0
  27. package/dist/commands/logout.js.map +1 -0
  28. package/dist/commands/register.d.ts +3 -0
  29. package/dist/commands/register.d.ts.map +1 -0
  30. package/dist/commands/register.js +77 -0
  31. package/dist/commands/register.js.map +1 -0
  32. package/dist/commands/release.d.ts +3 -0
  33. package/dist/commands/release.d.ts.map +1 -0
  34. package/dist/commands/release.js +40 -0
  35. package/dist/commands/release.js.map +1 -0
  36. package/dist/commands/releases.d.ts +3 -0
  37. package/dist/commands/releases.d.ts.map +1 -0
  38. package/dist/commands/releases.js +49 -0
  39. package/dist/commands/releases.js.map +1 -0
  40. package/dist/commands/upload.d.ts +3 -0
  41. package/dist/commands/upload.d.ts.map +1 -0
  42. package/dist/commands/upload.js +76 -0
  43. package/dist/commands/upload.js.map +1 -0
  44. package/dist/commands/whoami.d.ts +3 -0
  45. package/dist/commands/whoami.d.ts.map +1 -0
  46. package/dist/commands/whoami.js +43 -0
  47. package/dist/commands/whoami.js.map +1 -0
  48. package/dist/index.d.ts +3 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +32 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/lib/api.d.ts +61 -0
  53. package/dist/lib/api.d.ts.map +1 -0
  54. package/dist/lib/api.js +102 -0
  55. package/dist/lib/api.js.map +1 -0
  56. package/dist/lib/capacitor-config.d.ts +11 -0
  57. package/dist/lib/capacitor-config.d.ts.map +1 -0
  58. package/dist/lib/capacitor-config.js +105 -0
  59. package/dist/lib/capacitor-config.js.map +1 -0
  60. package/dist/lib/config.d.ts +60 -0
  61. package/dist/lib/config.d.ts.map +1 -0
  62. package/dist/lib/config.js +253 -0
  63. package/dist/lib/config.js.map +1 -0
  64. package/dist/lib/errors.d.ts +6 -0
  65. package/dist/lib/errors.d.ts.map +1 -0
  66. package/dist/lib/errors.js +19 -0
  67. package/dist/lib/errors.js.map +1 -0
  68. package/dist/lib/hash.d.ts +9 -0
  69. package/dist/lib/hash.d.ts.map +1 -0
  70. package/dist/lib/hash.js +21 -0
  71. package/dist/lib/hash.js.map +1 -0
  72. package/dist/lib/http.d.ts +9 -0
  73. package/dist/lib/http.d.ts.map +1 -0
  74. package/dist/lib/http.js +43 -0
  75. package/dist/lib/http.js.map +1 -0
  76. package/dist/lib/prompt.d.ts +3 -0
  77. package/dist/lib/prompt.d.ts.map +1 -0
  78. package/dist/lib/prompt.js +23 -0
  79. package/dist/lib/prompt.js.map +1 -0
  80. package/dist/lib/token-store.d.ts +12 -0
  81. package/dist/lib/token-store.d.ts.map +1 -0
  82. package/dist/lib/token-store.js +151 -0
  83. package/dist/lib/token-store.js.map +1 -0
  84. package/dist/lib/upload-workflow.d.ts +27 -0
  85. package/dist/lib/upload-workflow.d.ts.map +1 -0
  86. package/dist/lib/upload-workflow.js +252 -0
  87. package/dist/lib/upload-workflow.js.map +1 -0
  88. package/dist/lib/validate.d.ts +3 -0
  89. package/dist/lib/validate.d.ts.map +1 -0
  90. package/dist/lib/validate.js +16 -0
  91. package/dist/lib/validate.js.map +1 -0
  92. package/dist/lib/version.d.ts +4 -0
  93. package/dist/lib/version.d.ts.map +1 -0
  94. package/dist/lib/version.js +24 -0
  95. package/dist/lib/version.js.map +1 -0
  96. package/dist/lib/zip.d.ts +8 -0
  97. package/dist/lib/zip.d.ts.map +1 -0
  98. package/dist/lib/zip.js +78 -0
  99. package/dist/lib/zip.js.map +1 -0
  100. package/package.json +63 -0
@@ -0,0 +1,77 @@
1
+ import { Command } from 'commander';
2
+ import ora from 'ora';
3
+ import { resolveAuthToken, resolveServerUrl } from '../lib/config.js';
4
+ import { CliError, runCommand } from '../lib/errors.js';
5
+ import { fetchCli } from '../lib/http.js';
6
+ const APP_SLUG_REGEX = /^[A-Za-z0-9._-]{3,120}$/;
7
+ export const registerCommand = new Command('register')
8
+ .description('Create a new app')
9
+ .requiredOption('--slug <slug>', 'App slug (for example: com.example.app)')
10
+ .option('--server <url>', 'Server URL')
11
+ .option('--token <token>', 'Access token or organization secret key')
12
+ .option('--secret-key <key>', 'Organization secret API key')
13
+ .action(async (options) => {
14
+ await runCommand(async () => {
15
+ const slug = options.slug.trim();
16
+ if (!APP_SLUG_REGEX.test(slug)) {
17
+ throw new CliError('Invalid slug. Use 3-120 chars: letters, numbers, dot, underscore, hyphen.');
18
+ }
19
+ const serverUrl = resolveServerUrl(process.cwd(), options.server);
20
+ const explicitToken = options.token?.trim() || options.secretKey?.trim();
21
+ const resolvedAuth = explicitToken
22
+ ? { token: explicitToken }
23
+ : await resolveAuthToken(serverUrl);
24
+ if (!resolvedAuth?.token) {
25
+ throw new CliError([
26
+ 'Authentication required. Use one of:',
27
+ ' 1. otakit login',
28
+ ' 2. --token <token> (or --secret-key <key>)',
29
+ ' 3. OTAKIT_TOKEN env var',
30
+ ' 4. OTAKIT_ACCESS_TOKEN / OTAKIT_SECRET_KEY env vars',
31
+ ].join('\n'));
32
+ }
33
+ const spinner = ora(`Creating app "${slug}"...`).start();
34
+ const response = await fetchCli(`${serverUrl}/api/v1/apps`, {
35
+ method: 'POST',
36
+ headers: {
37
+ Authorization: `Bearer ${resolvedAuth.token}`,
38
+ 'Content-Type': 'application/json',
39
+ },
40
+ body: JSON.stringify({ slug }),
41
+ });
42
+ const contentType = response.headers.get('content-type') ?? '';
43
+ const isJson = contentType.includes('application/json');
44
+ const payload = isJson
45
+ ? (await response.json())
46
+ : null;
47
+ if (!response.ok) {
48
+ spinner.fail('Failed to create app');
49
+ const errorMessage = typeof payload?.error === 'string' ? payload.error : `API error (${response.status})`;
50
+ throw new CliError(errorMessage);
51
+ }
52
+ if (!payload?.id || !payload.slug) {
53
+ spinner.fail('Failed to create app');
54
+ throw new CliError('Server returned an invalid response.');
55
+ }
56
+ spinner.succeed('App created');
57
+ console.log(`App ID: ${payload.id}`);
58
+ console.log(`App Slug: ${payload.slug}`);
59
+ console.log('');
60
+ console.log('Add this to capacitor.config.ts:');
61
+ console.log('');
62
+ console.log('plugins: {');
63
+ console.log(' OtaKit: {');
64
+ console.log(` appId: "${payload.id}",`);
65
+ console.log(' appReadyTimeout: 10000,');
66
+ console.log(' // Optional:');
67
+ console.log(' // updateMode: "manual",');
68
+ console.log(' // updateMode: "immediate",');
69
+ console.log(' },');
70
+ console.log('}');
71
+ console.log('');
72
+ console.log('Next steps:');
73
+ console.log('1. Build your web app');
74
+ console.log('2. Run `otakit upload --release`');
75
+ });
76
+ });
77
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/commands/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,cAAc,GAAG,yBAAyB,CAAC;AAejD,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;KACnD,WAAW,CAAC,kBAAkB,CAAC;KAC/B,cAAc,CAAC,eAAe,EAAE,yCAAyC,CAAC;KAC1E,MAAM,CAAC,gBAAgB,EAAE,YAAY,CAAC;KACtC,MAAM,CAAC,iBAAiB,EAAE,yCAAyC,CAAC;KACpE,MAAM,CAAC,oBAAoB,EAAE,6BAA6B,CAAC;KAC3D,MAAM,CAAC,KAAK,EAAE,OAAwB,EAAE,EAAE;IACzC,MAAM,UAAU,CAAC,KAAK,IAAI,EAAE;QAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,QAAQ,CAChB,2EAA2E,CAC5E,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAClE,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC;QACzE,MAAM,YAAY,GAAG,aAAa;YAChC,CAAC,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE;YAC1B,CAAC,CAAC,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAEtC,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,QAAQ,CAChB;gBACE,sCAAsC;gBACtC,mBAAmB;gBACnB,8CAA8C;gBAC9C,2BAA2B;gBAC3B,uDAAuD;aACxD,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,GAAG,CAAC,iBAAiB,IAAI,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;QAEzD,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,GAAG,SAAS,cAAc,EAAE;YAC1D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,YAAY,CAAC,KAAK,EAAE;gBAC7C,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;SAC/B,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QAC/D,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;QACxD,MAAM,OAAO,GAAG,MAAM;YACpB,CAAC,CAAE,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA2C;YACpE,CAAC,CAAC,IAAI,CAAC;QAET,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;YACrC,MAAM,YAAY,GAChB,OAAO,OAAO,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,QAAQ,CAAC,MAAM,GAAG,CAAC;YACxF,MAAM,IAAI,QAAQ,CAAC,YAAY,CAAC,CAAC;QACnC,CAAC;QAED,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;YACrC,MAAM,IAAI,QAAQ,CAAC,sCAAsC,CAAC,CAAC;QAC7D,CAAC;QAED,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAE/B,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,eAAe,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const releaseCommand: Command;
3
+ //# sourceMappingURL=release.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../../src/commands/release.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,eAAO,MAAM,cAAc,SAmCvB,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { Command } from 'commander';
2
+ import ora from 'ora';
3
+ import { ApiClient } from '../lib/api.js';
4
+ import { requireConfig } from '../lib/config.js';
5
+ import { CliError, runCommand } from '../lib/errors.js';
6
+ import { normalizeChannel } from '../lib/validate.js';
7
+ export const releaseCommand = new Command('release')
8
+ .description('Release a bundle to the base channel or a named channel')
9
+ .argument('[bundleId]', 'Bundle ID to release')
10
+ .option('--app-id <id>', 'App ID override')
11
+ .option('--server <url>', 'Server URL override')
12
+ .option('--channel <channel>', 'Channel name (omit for the base channel)')
13
+ .action(async (bundleId, options) => {
14
+ await runCommand(async () => {
15
+ const config = await requireConfig({
16
+ appId: options.appId,
17
+ serverUrl: options.server,
18
+ });
19
+ const api = new ApiClient(config);
20
+ const channel = options.channel ? normalizeChannel(options.channel) : null;
21
+ const targetLabel = channel ?? 'base channel';
22
+ if (bundleId) {
23
+ const spinner = ora(`Releasing ${bundleId} to ${targetLabel}...`).start();
24
+ await api.release(channel, bundleId);
25
+ spinner.succeed(`Released ${bundleId} to ${targetLabel}.`);
26
+ return;
27
+ }
28
+ // No bundleId — release latest bundle
29
+ const spinner = ora('Finding latest bundle...').start();
30
+ const { bundles } = await api.listBundles({ limit: 1 });
31
+ if (bundles.length === 0) {
32
+ throw new CliError('No bundles found to release.');
33
+ }
34
+ const latest = bundles[0];
35
+ spinner.text = `Releasing ${latest.version} to ${targetLabel}...`;
36
+ await api.release(channel, latest.id);
37
+ spinner.succeed(`Released ${latest.version} to ${targetLabel}.`);
38
+ });
39
+ });
40
+ //# sourceMappingURL=release.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release.js","sourceRoot":"","sources":["../../src/commands/release.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAQtD,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC;KACjD,WAAW,CAAC,yDAAyD,CAAC;KACtE,QAAQ,CAAC,YAAY,EAAE,sBAAsB,CAAC;KAC9C,MAAM,CAAC,eAAe,EAAE,iBAAiB,CAAC;KAC1C,MAAM,CAAC,gBAAgB,EAAE,qBAAqB,CAAC;KAC/C,MAAM,CAAC,qBAAqB,EAAE,0CAA0C,CAAC;KACzE,MAAM,CAAC,KAAK,EAAE,QAA4B,EAAE,OAAuB,EAAE,EAAE;IACtE,MAAM,UAAU,CAAC,KAAK,IAAI,EAAE;QAC1B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC;YACjC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,SAAS,EAAE,OAAO,CAAC,MAAM;SAC1B,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3E,MAAM,WAAW,GAAG,OAAO,IAAI,cAAc,CAAC;QAE9C,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,CAAC,aAAa,QAAQ,OAAO,WAAW,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;YAC1E,MAAM,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACrC,OAAO,CAAC,OAAO,CAAC,YAAY,QAAQ,OAAO,WAAW,GAAG,CAAC,CAAC;YAC3D,OAAO;QACT,CAAC;QAED,sCAAsC;QACtC,MAAM,OAAO,GAAG,GAAG,CAAC,0BAA0B,CAAC,CAAC,KAAK,EAAE,CAAC;QACxD,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QACxD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,QAAQ,CAAC,8BAA8B,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAC1B,OAAO,CAAC,IAAI,GAAG,aAAa,MAAM,CAAC,OAAO,OAAO,WAAW,KAAK,CAAC;QAClE,MAAM,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QACtC,OAAO,CAAC,OAAO,CAAC,YAAY,MAAM,CAAC,OAAO,OAAO,WAAW,GAAG,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const releasesCommand: Command;
3
+ //# sourceMappingURL=releases.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"releases.d.ts","sourceRoot":"","sources":["../../src/commands/releases.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBpC,eAAO,MAAM,eAAe,SA6CxB,CAAC"}
@@ -0,0 +1,49 @@
1
+ import { Command } from 'commander';
2
+ import { ApiClient } from '../lib/api.js';
3
+ import { requireConfig } from '../lib/config.js';
4
+ import { CliError, runCommand } from '../lib/errors.js';
5
+ import { normalizeChannel, parsePositiveInteger } from '../lib/validate.js';
6
+ function formatReleaseTarget(channel) {
7
+ return channel ?? 'base channel';
8
+ }
9
+ export const releasesCommand = new Command('releases')
10
+ .description('Show release history across all streams or a specific target')
11
+ .option('--app-id <id>', 'App ID override')
12
+ .option('--server <url>', 'Server URL override')
13
+ .option('--channel <channel>', 'Channel name')
14
+ .option('--base', 'Show only the base channel')
15
+ .option('--limit <n>', 'Limit results', '10')
16
+ .action(async (options) => {
17
+ await runCommand(async () => {
18
+ if (options.base && options.channel) {
19
+ throw new CliError('Use either --base or --channel, not both.');
20
+ }
21
+ const config = await requireConfig({
22
+ appId: options.appId,
23
+ serverUrl: options.server,
24
+ });
25
+ const api = new ApiClient(config);
26
+ const channel = options.base
27
+ ? null
28
+ : options.channel
29
+ ? normalizeChannel(options.channel)
30
+ : undefined;
31
+ const limit = Math.min(parsePositiveInteger(options.limit, 'limit'), 200);
32
+ const response = await api.listReleases(channel, { limit });
33
+ if (response.releases.length === 0) {
34
+ if (channel === undefined) {
35
+ console.log('No releases found.');
36
+ }
37
+ else {
38
+ console.log(`No releases found for ${formatReleaseTarget(channel)}.`);
39
+ }
40
+ return;
41
+ }
42
+ for (const release of response.releases) {
43
+ const bundleVersion = release.bundleVersion ? ` (${release.bundleVersion})` : '';
44
+ console.log(`${formatReleaseTarget(release.channel)}: ${release.bundleId}${bundleVersion} at ${release.promotedAt}`);
45
+ }
46
+ console.log(`Total: ${response.total}`);
47
+ });
48
+ });
49
+ //# sourceMappingURL=releases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"releases.js","sourceRoot":"","sources":["../../src/commands/releases.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAU5E,SAAS,mBAAmB,CAAC,OAAsB;IACjD,OAAO,OAAO,IAAI,cAAc,CAAC;AACnC,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;KACnD,WAAW,CAAC,8DAA8D,CAAC;KAC3E,MAAM,CAAC,eAAe,EAAE,iBAAiB,CAAC;KAC1C,MAAM,CAAC,gBAAgB,EAAE,qBAAqB,CAAC;KAC/C,MAAM,CAAC,qBAAqB,EAAE,cAAc,CAAC;KAC7C,MAAM,CAAC,QAAQ,EAAE,4BAA4B,CAAC;KAC9C,MAAM,CAAC,aAAa,EAAE,eAAe,EAAE,IAAI,CAAC;KAC5C,MAAM,CAAC,KAAK,EAAE,OAAwB,EAAE,EAAE;IACzC,MAAM,UAAU,CAAC,KAAK,IAAI,EAAE;QAC1B,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpC,MAAM,IAAI,QAAQ,CAAC,2CAA2C,CAAC,CAAC;QAClE,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC;YACjC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,SAAS,EAAE,OAAO,CAAC,MAAM;SAC1B,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;QAElC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI;YAC1B,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,OAAO,CAAC,OAAO;gBACf,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC;gBACnC,CAAC,CAAC,SAAS,CAAC;QAChB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;QAE1E,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAE5D,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,yBAAyB,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACxE,CAAC;YACD,OAAO;QACT,CAAC;QAED,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACxC,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACjF,OAAO,CAAC,GAAG,CACT,GAAG,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,QAAQ,GAAG,aAAa,OAAO,OAAO,CAAC,UAAU,EAAE,CACxG,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,UAAU,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const uploadCommand: Command;
3
+ //# sourceMappingURL=upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiCpC,eAAO,MAAM,aAAa,SAiEtB,CAAC"}
@@ -0,0 +1,76 @@
1
+ import { Command } from 'commander';
2
+ import ora from 'ora';
3
+ import { ApiClient } from '../lib/api.js';
4
+ import { requireConfig } from '../lib/config.js';
5
+ import { runCommand } from '../lib/errors.js';
6
+ import { resolveBundlePath, resolveVersion, runUploadWorkflow } from '../lib/upload-workflow.js';
7
+ import { normalizeChannel, parsePositiveInteger } from '../lib/validate.js';
8
+ function resolveReleaseChannel(releaseOption) {
9
+ if (releaseOption === undefined || releaseOption === false) {
10
+ return undefined;
11
+ }
12
+ if (releaseOption === true) {
13
+ return null;
14
+ }
15
+ return normalizeChannel(releaseOption);
16
+ }
17
+ export const uploadCommand = new Command('upload')
18
+ .description('Upload a new bundle')
19
+ .argument('[path]', 'Path to the bundle directory')
20
+ .option('--app-id <id>', 'App ID override')
21
+ .option('--server <url>', 'Server URL override')
22
+ .option('--version <version>', 'Version string (default: OTAKIT_VERSION, then auto-generated)')
23
+ .option('--strict-version', 'Require explicit version (--version or OTAKIT_VERSION)')
24
+ .option('--min-native-build <build>', 'Minimum native build number')
25
+ .option('--release [channel]', 'Release after upload (base channel if omitted)')
26
+ .action(async (path, options) => {
27
+ await runCommand(async () => {
28
+ const config = await requireConfig({
29
+ appId: options.appId,
30
+ serverUrl: options.server,
31
+ });
32
+ const api = new ApiClient(config);
33
+ const sourcePath = resolveBundlePath(path, config);
34
+ const resolvedVersion = await resolveVersion(options.version, {
35
+ strict: options.strictVersion,
36
+ bundlePath: sourcePath,
37
+ });
38
+ const version = resolvedVersion.value;
39
+ if (resolvedVersion.source === 'auto') {
40
+ console.log(`Using auto-generated version: ${version}`);
41
+ }
42
+ const minNativeBuild = options.minNativeBuild
43
+ ? parsePositiveInteger(options.minNativeBuild, 'min-native-build')
44
+ : undefined;
45
+ const releaseChannel = resolveReleaseChannel(options.release);
46
+ const spinner = ora('Creating zip archive...').start();
47
+ const bundle = await (async () => {
48
+ try {
49
+ const result = await runUploadWorkflow({
50
+ api,
51
+ sourcePath,
52
+ version,
53
+ minNativeBuild,
54
+ releaseChannel,
55
+ onStatus: (message) => {
56
+ spinner.text = message;
57
+ },
58
+ });
59
+ return result.bundle;
60
+ }
61
+ catch (error) {
62
+ if (spinner.isSpinning) {
63
+ spinner.fail('Upload failed.');
64
+ }
65
+ throw error;
66
+ }
67
+ })();
68
+ if (releaseChannel !== undefined) {
69
+ spinner.succeed(`Uploaded ${bundle.version} (${bundle.id}) and released to ${releaseChannel ?? 'base channel'}.`);
70
+ }
71
+ else {
72
+ spinner.succeed(`Uploaded ${bundle.version} (${bundle.id}).`);
73
+ }
74
+ });
75
+ });
76
+ //# sourceMappingURL=upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const whoamiCommand: Command;
3
+ //# sourceMappingURL=whoami.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyBpC,eAAO,MAAM,aAAa,SA+CtB,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { Command } from 'commander';
2
+ import { resolveAuthToken, resolveServerUrl } from '../lib/config.js';
3
+ import { CliError, runCommand } from '../lib/errors.js';
4
+ import { fetchCli, parseApiError } from '../lib/http.js';
5
+ export const whoamiCommand = new Command('whoami')
6
+ .description('Show current authenticated user and organization context')
7
+ .option('--server <url>', 'Server URL')
8
+ .action(async (options) => {
9
+ await runCommand(async () => {
10
+ const serverUrl = resolveServerUrl(process.cwd(), options.server);
11
+ const auth = await resolveAuthToken(serverUrl);
12
+ if (!auth) {
13
+ throw new CliError([
14
+ 'Not authenticated.',
15
+ 'Run `otakit login`, or set OTAKIT_TOKEN.',
16
+ 'OTAKIT_ACCESS_TOKEN / OTAKIT_SECRET_KEY are also supported.',
17
+ ].join('\n'));
18
+ }
19
+ const response = await fetchCli(`${serverUrl}/api/v1/me`, {
20
+ headers: {
21
+ Authorization: `Bearer ${auth.token}`,
22
+ },
23
+ });
24
+ if (!response.ok) {
25
+ throw new CliError(await parseApiError(response));
26
+ }
27
+ const payload = (await response.json());
28
+ console.log(`User: ${payload.user.email}`);
29
+ console.log(`User ID: ${payload.user.id}`);
30
+ console.log(`Active organization: ${payload.user.activeOrganizationId ?? '(none)'}`);
31
+ console.log(`Auth source: ${auth.source}`);
32
+ console.log('');
33
+ if (payload.memberships.length === 0) {
34
+ console.log('Memberships: none');
35
+ return;
36
+ }
37
+ console.log('Memberships:');
38
+ for (const membership of payload.memberships) {
39
+ console.log(`- ${membership.organizationName} (${membership.organizationId}) [${membership.role}]`);
40
+ }
41
+ });
42
+ });
43
+ //# sourceMappingURL=whoami.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAqBzD,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,0DAA0D,CAAC;KACvE,MAAM,CAAC,gBAAgB,EAAE,YAAY,CAAC;KACtC,MAAM,CAAC,KAAK,EAAE,OAAsB,EAAE,EAAE;IACvC,MAAM,UAAU,CAAC,KAAK,IAAI,EAAE;QAC1B,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAClE,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAE/C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,QAAQ,CAChB;gBACE,oBAAoB;gBACpB,0CAA0C;gBAC1C,6DAA6D;aAC9D,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,GAAG,SAAS,YAAY,EAAE;YACxD,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;aACtC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,QAAQ,CAAC,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,OAAO,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAmB,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,SAAS,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,wBAAwB,OAAO,CAAC,IAAI,CAAC,oBAAoB,IAAI,QAAQ,EAAE,CAAC,CAAC;QACrF,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;YACjC,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC5B,KAAK,MAAM,UAAU,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YAC7C,OAAO,CAAC,GAAG,CACT,KAAK,UAAU,CAAC,gBAAgB,KAAK,UAAU,CAAC,cAAc,MAAM,UAAU,CAAC,IAAI,GAAG,CACvF,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { configCommand } from './commands/config.js';
4
+ import { registerCommand } from './commands/register.js';
5
+ import { uploadCommand } from './commands/upload.js';
6
+ import { releaseCommand } from './commands/release.js';
7
+ import { listCommand } from './commands/list.js';
8
+ import { deleteCommand } from './commands/delete.js';
9
+ import { releasesCommand } from './commands/releases.js';
10
+ import { generateSigningKeyCommand } from './commands/generate-signing-key.js';
11
+ import { loginCommand } from './commands/login.js';
12
+ import { whoamiCommand } from './commands/whoami.js';
13
+ import { logoutCommand } from './commands/logout.js';
14
+ import { CLI_VERSION } from './lib/version.js';
15
+ const program = new Command();
16
+ program
17
+ .name('otakit')
18
+ .description('CLI for managing OTA updates')
19
+ .version(CLI_VERSION, '--cli-version', 'Show CLI version');
20
+ program.addCommand(configCommand);
21
+ program.addCommand(registerCommand);
22
+ program.addCommand(uploadCommand);
23
+ program.addCommand(releaseCommand);
24
+ program.addCommand(listCommand);
25
+ program.addCommand(deleteCommand);
26
+ program.addCommand(releasesCommand);
27
+ program.addCommand(generateSigningKeyCommand);
28
+ program.addCommand(loginCommand);
29
+ program.addCommand(whoamiCommand);
30
+ program.addCommand(logoutCommand);
31
+ program.parse();
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,8BAA8B,CAAC;KAC3C,OAAO,CAAC,WAAW,EAAE,eAAe,EAAE,kBAAkB,CAAC,CAAC;AAE7D,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;AACpC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;AACpC,OAAO,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC;AAC9C,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAElC,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,61 @@
1
+ import type { CliConfig } from './config.js';
2
+ export interface Bundle {
3
+ id: string;
4
+ version: string;
5
+ sha256: string;
6
+ size: number;
7
+ minNativeBuild?: number;
8
+ createdAt: string;
9
+ }
10
+ export interface UploadInitResponse {
11
+ uploadId: string;
12
+ presignedUrl: string;
13
+ storageKey: string;
14
+ expiresAt: string;
15
+ }
16
+ export interface Release {
17
+ id: string;
18
+ channel: string | null;
19
+ bundleId: string;
20
+ bundleVersion?: string;
21
+ promotedAt: string;
22
+ promotedBy?: string;
23
+ }
24
+ export declare class ApiClient {
25
+ private readonly baseUrl;
26
+ private readonly authToken;
27
+ private readonly appId;
28
+ private readonly version;
29
+ constructor(config: CliConfig, version?: string);
30
+ private fetch;
31
+ private appPath;
32
+ initiateUpload(options: {
33
+ version: string;
34
+ minNativeBuild?: number;
35
+ size: number;
36
+ sha256: string;
37
+ }): Promise<UploadInitResponse>;
38
+ finalizeUpload(options: {
39
+ uploadId: string;
40
+ }): Promise<Bundle>;
41
+ listBundles(options?: {
42
+ limit?: number;
43
+ offset?: number;
44
+ }): Promise<{
45
+ bundles: Bundle[];
46
+ total: number;
47
+ }>;
48
+ deleteBundle(bundleId: string): Promise<void>;
49
+ release(channel: string | null, bundleId: string): Promise<{
50
+ release: Release;
51
+ previousRelease: Release | null;
52
+ }>;
53
+ listReleases(channel: string | null | undefined, options?: {
54
+ limit?: number;
55
+ offset?: number;
56
+ }): Promise<{
57
+ releases: Release[];
58
+ total: number;
59
+ }>;
60
+ }
61
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,EAAE,SAAS,EAAE,OAAO,GAAE,MAAoB;YAO9C,KAAK;IA+CnB,OAAO,CAAC,OAAO;IAIT,cAAc,CAAC,OAAO,EAAE;QAC5B,OAAO,EAAE,MAAM,CAAC;QAChB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAOzB,cAAc,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAO9D,WAAW,CAAC,OAAO,CAAC,EAAE;QAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAS3C,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7C,OAAO,CACX,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,eAAe,EAAE,OAAO,GAAG,IAAI,CAAA;KAAE,CAAC;IAO3D,YAAY,CAChB,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAClC,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GACA,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAUnD"}
@@ -0,0 +1,102 @@
1
+ import { fetchCli } from './http.js';
2
+ import { CLI_VERSION, getCliUserAgent } from './version.js';
3
+ export class ApiClient {
4
+ baseUrl;
5
+ authToken;
6
+ appId;
7
+ version;
8
+ constructor(config, version = CLI_VERSION) {
9
+ this.baseUrl = config.serverUrl.replace(/\/$/, '');
10
+ this.authToken = config.authToken;
11
+ this.appId = config.appId;
12
+ this.version = version;
13
+ }
14
+ async fetch(path, options = {}) {
15
+ const url = `${this.baseUrl}${path}`;
16
+ const hasBody = options.body !== undefined;
17
+ const headers = new Headers(options.headers);
18
+ headers.set('Authorization', `Bearer ${this.authToken}`);
19
+ headers.set('User-Agent', getCliUserAgent(this.version));
20
+ if (hasBody && !headers.has('Content-Type')) {
21
+ headers.set('Content-Type', 'application/json');
22
+ }
23
+ const response = await fetchCli(url, {
24
+ ...options,
25
+ headers,
26
+ });
27
+ const contentType = response.headers.get('content-type') ?? '';
28
+ const isJson = contentType.includes('application/json');
29
+ if (!response.ok) {
30
+ let errorMessage = `API error (${response.status})`;
31
+ if (isJson) {
32
+ const parsed = (await response.json());
33
+ if (typeof parsed.error === 'string') {
34
+ errorMessage = parsed.error;
35
+ }
36
+ }
37
+ else {
38
+ const text = await response.text();
39
+ if (text.trim().length > 0) {
40
+ errorMessage = text;
41
+ }
42
+ }
43
+ throw new Error(errorMessage);
44
+ }
45
+ if (response.status === 204) {
46
+ return undefined;
47
+ }
48
+ if (!isJson) {
49
+ return undefined;
50
+ }
51
+ return response.json();
52
+ }
53
+ appPath(suffix) {
54
+ return `/api/v1/apps/${encodeURIComponent(this.appId)}${suffix}`;
55
+ }
56
+ async initiateUpload(options) {
57
+ return this.fetch(this.appPath('/bundles/initiate'), {
58
+ method: 'POST',
59
+ body: JSON.stringify(options),
60
+ });
61
+ }
62
+ async finalizeUpload(options) {
63
+ return this.fetch(this.appPath('/bundles/finalize'), {
64
+ method: 'POST',
65
+ body: JSON.stringify(options),
66
+ });
67
+ }
68
+ async listBundles(options) {
69
+ const params = new URLSearchParams();
70
+ if (options?.limit)
71
+ params.set('limit', String(options.limit));
72
+ if (options?.offset)
73
+ params.set('offset', String(options.offset));
74
+ const query = params.toString();
75
+ return this.fetch(this.appPath(`/bundles${query ? `?${query}` : ''}`));
76
+ }
77
+ async deleteBundle(bundleId) {
78
+ await this.fetch(this.appPath(`/bundles/${encodeURIComponent(bundleId)}`), {
79
+ method: 'DELETE',
80
+ });
81
+ }
82
+ async release(channel, bundleId) {
83
+ return this.fetch(this.appPath('/releases'), {
84
+ method: 'POST',
85
+ body: JSON.stringify({ bundleId, channel }),
86
+ });
87
+ }
88
+ async listReleases(channel, options) {
89
+ const params = new URLSearchParams();
90
+ if (channel === null)
91
+ params.set('channel', '');
92
+ if (typeof channel === 'string')
93
+ params.set('channel', channel);
94
+ if (options?.limit)
95
+ params.set('limit', String(options.limit));
96
+ if (options?.offset)
97
+ params.set('offset', String(options.offset));
98
+ const query = params.toString();
99
+ return this.fetch(this.appPath(`/releases${query ? `?${query}` : ''}`));
100
+ }
101
+ }
102
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AA2B5D,MAAM,OAAO,SAAS;IACH,OAAO,CAAS;IAChB,SAAS,CAAS;IAClB,KAAK,CAAS;IACd,OAAO,CAAS;IAEjC,YAAY,MAAiB,EAAE,UAAkB,WAAW;QAC1D,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAEO,KAAK,CAAC,KAAK,CAAI,IAAY,EAAE,UAAuB,EAAE;QAC5D,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACzD,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE;YACnC,GAAG,OAAO;YACV,OAAO;SACR,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QAC/D,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;QAExD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,IAAI,YAAY,GAAG,cAAc,QAAQ,CAAC,MAAM,GAAG,CAAC;YAEpD,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAwB,CAAC;gBAC9D,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;oBACrC,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC;gBAC9B,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACnC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC3B,YAAY,GAAG,IAAI,CAAC;gBACtB,CAAC;YACH,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;QAChC,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,OAAO,SAAc,CAAC;QACxB,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,SAAc,CAAC;QACxB,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAC;IACvC,CAAC;IAEO,OAAO,CAAC,MAAc;QAC5B,OAAO,gBAAgB,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,OAKpB;QACC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE;YACnD,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,OAA6B;QAChD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE;YACnD,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAGjB;QACC,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QACrC,IAAI,OAAO,EAAE,KAAK;YAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/D,IAAI,OAAO,EAAE,MAAM;YAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAElE,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,QAAgB;QACjC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;YACzE,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO,CACX,OAAsB,EACtB,QAAgB;QAEhB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;YAC3C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;SAC5C,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,OAAkC,EAClC,OAGC;QAED,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QACrC,IAAI,OAAO,KAAK,IAAI;YAAE,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAChD,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAChE,IAAI,OAAO,EAAE,KAAK;YAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/D,IAAI,OAAO,EAAE,MAAM;YAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAElE,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1E,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ export declare const CAPACITOR_CONFIG_FILE_NAMES: readonly ["capacitor.config.ts", "capacitor.config.js", "capacitor.config.mjs", "capacitor.config.cjs", "capacitor.config.json"];
2
+ export interface CapacitorProjectConfig {
3
+ configPath: string;
4
+ appId?: string;
5
+ channel?: string;
6
+ configuredServerUrl?: string;
7
+ outputDir?: string;
8
+ }
9
+ export declare function readCapacitorProjectConfig(cwd?: string): CapacitorProjectConfig | null;
10
+ export declare function findCapacitorConfigPath(cwd?: string): string | null;
11
+ //# sourceMappingURL=capacitor-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capacitor-config.d.ts","sourceRoot":"","sources":["../../src/lib/capacitor-config.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,2BAA2B,kIAM9B,CAAC;AAIX,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,0BAA0B,CACxC,GAAG,GAAE,MAAsB,GAC1B,sBAAsB,GAAG,IAAI,CAQ/B;AAED,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAiBlF"}