@capawesome/cli 4.5.0 → 4.6.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
4
4
 
5
+ ## [4.6.0](https://github.com/capawesome-team/cli/compare/v4.5.0...v4.6.0) (2026-03-18)
6
+
7
+
8
+ ### Features
9
+
10
+ * add `apps:devices:probe` command ([#129](https://github.com/capawesome-team/cli/issues/129)) ([33607cd](https://github.com/capawesome-team/cli/commit/33607cdb2e65e26c48d114d694b876db3762b8ec))
11
+
5
12
  ## [4.5.0](https://github.com/capawesome-team/cli/compare/v4.4.0...v4.5.0) (2026-03-15)
6
13
 
7
14
 
@@ -0,0 +1,70 @@
1
+ import appDevicesService from '../../../services/app-devices.js';
2
+ import { withAuth } from '../../../utils/auth.js';
3
+ import { isInteractive } from '../../../utils/environment.js';
4
+ import { prompt, promptAppSelection, promptOrganizationSelection } from '../../../utils/prompt.js';
5
+ import { defineCommand, defineOptions } from '@robingenz/zli';
6
+ import { AxiosError } from 'axios';
7
+ import consola from 'consola';
8
+ import { z } from 'zod';
9
+ export default defineCommand({
10
+ description: 'Check whether a device would receive a live update.',
11
+ options: defineOptions(z.object({
12
+ appId: z.string().optional().describe('ID of the app.'),
13
+ deviceId: z.string().optional().describe('ID of the device.'),
14
+ json: z.boolean().optional().describe('Output in JSON format.'),
15
+ })),
16
+ action: withAuth(async (options) => {
17
+ let { appId, deviceId, json } = options;
18
+ if (!appId) {
19
+ if (!isInteractive()) {
20
+ consola.error('You must provide an app ID when running in non-interactive environment.');
21
+ process.exit(1);
22
+ }
23
+ const organizationId = await promptOrganizationSelection();
24
+ appId = await promptAppSelection(organizationId);
25
+ }
26
+ if (!deviceId) {
27
+ if (!isInteractive()) {
28
+ consola.error('You must provide the device ID when running in non-interactive environment.');
29
+ process.exit(1);
30
+ }
31
+ deviceId = await prompt('Enter the device ID:', {
32
+ type: 'text',
33
+ });
34
+ }
35
+ const device = await appDevicesService.findOneById({ appId, deviceId });
36
+ try {
37
+ const result = await appDevicesService.probe({
38
+ appId,
39
+ appVersionCode: device.appVersionCode,
40
+ appVersionName: device.appVersionName,
41
+ channelName: device.appChannel?.name,
42
+ customId: device.customId ?? undefined,
43
+ deviceId: device.id,
44
+ osVersion: device.osVersion,
45
+ platform: device.platform,
46
+ pluginVersion: device.pluginVersion,
47
+ });
48
+ if (json) {
49
+ console.log(JSON.stringify(result, null, 2));
50
+ }
51
+ else {
52
+ console.table(result);
53
+ consola.success('Update available for this device.');
54
+ }
55
+ }
56
+ catch (error) {
57
+ if (error instanceof AxiosError && error.response?.status === 404) {
58
+ if (json) {
59
+ console.log(JSON.stringify({ bundleId: null }, null, 2));
60
+ }
61
+ else {
62
+ consola.info('No update available for this device.');
63
+ }
64
+ }
65
+ else {
66
+ throw error;
67
+ }
68
+ }
69
+ }),
70
+ });
package/dist/index.js CHANGED
@@ -52,6 +52,7 @@ const config = defineConfig({
52
52
  'apps:destinations:update': await import('./commands/apps/destinations/update.js').then((mod) => mod.default),
53
53
  'apps:devices:delete': await import('./commands/apps/devices/delete.js').then((mod) => mod.default),
54
54
  'apps:devices:forcechannel': await import('./commands/apps/devices/forcechannel.js').then((mod) => mod.default),
55
+ 'apps:devices:probe': await import('./commands/apps/devices/probe.js').then((mod) => mod.default),
55
56
  'apps:devices:unforcechannel': await import('./commands/apps/devices/unforcechannel.js').then((mod) => mod.default),
56
57
  'apps:environments:create': await import('./commands/apps/environments/create.js').then((mod) => mod.default),
57
58
  'apps:environments:delete': await import('./commands/apps/environments/delete.js').then((mod) => mod.default),
@@ -12,6 +12,42 @@ class AppDevicesServiceImpl {
12
12
  },
13
13
  });
14
14
  }
15
+ async findOneById(data) {
16
+ const response = await this.httpClient.get(`/v1/apps/${data.appId}/devices/${data.deviceId}`, {
17
+ headers: {
18
+ Authorization: `Bearer ${authorizationService.getCurrentAuthorizationToken()}`,
19
+ },
20
+ params: {
21
+ relations: 'appChannel',
22
+ },
23
+ });
24
+ return response.data;
25
+ }
26
+ async probe(data) {
27
+ const params = {
28
+ appVersionCode: data.appVersionCode,
29
+ appVersionName: data.appVersionName,
30
+ osVersion: data.osVersion,
31
+ platform: data.platform.toString(),
32
+ pluginVersion: data.pluginVersion,
33
+ };
34
+ if (data.channelName) {
35
+ params.channelName = data.channelName;
36
+ }
37
+ if (data.customId) {
38
+ params.customId = data.customId;
39
+ }
40
+ if (data.deviceId) {
41
+ params.deviceId = data.deviceId;
42
+ }
43
+ const response = await this.httpClient.get(`/v1/apps/${data.appId}/bundles/latest`, {
44
+ headers: {
45
+ Authorization: `Bearer ${authorizationService.getCurrentAuthorizationToken()}`,
46
+ },
47
+ params,
48
+ });
49
+ return response.data;
50
+ }
15
51
  async update(data) {
16
52
  await this.httpClient.patch(`/v1/apps/${data.appId}/devices/${data.deviceId}`, { forcedAppChannelId: data.forcedAppChannelId }, {
17
53
  headers: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capawesome/cli",
3
- "version": "4.5.0",
3
+ "version": "4.6.0",
4
4
  "description": "The Capawesome Cloud Command Line Interface (CLI) to manage Live Updates and more.",
5
5
  "type": "module",
6
6
  "scripts": {