@capawesome/cli 3.11.0 → 4.0.1
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 +34 -0
- package/dist/commands/apps/builds/cancel.js +1 -1
- package/dist/commands/apps/builds/create.js +58 -50
- package/dist/commands/apps/builds/download.js +27 -3
- package/dist/commands/apps/bundles/create.js +5 -449
- package/dist/commands/apps/bundles/delete.js +3 -68
- package/dist/commands/apps/bundles/update.js +3 -66
- package/dist/commands/apps/channels/create.js +5 -8
- package/dist/commands/apps/channels/create.test.js +6 -9
- package/dist/commands/apps/channels/delete.js +3 -2
- package/dist/commands/apps/channels/get.js +2 -12
- package/dist/commands/apps/channels/get.test.js +1 -2
- package/dist/commands/apps/channels/list.js +2 -10
- package/dist/commands/apps/channels/list.test.js +2 -3
- package/dist/commands/apps/channels/pause.js +85 -0
- package/dist/commands/apps/channels/resume.js +85 -0
- package/dist/commands/apps/channels/update.js +4 -7
- package/dist/commands/apps/channels/update.test.js +2 -4
- package/dist/commands/apps/create.js +1 -1
- package/dist/commands/apps/delete.js +3 -2
- package/dist/commands/apps/deployments/cancel.js +1 -1
- package/dist/commands/apps/deployments/create.js +82 -31
- package/dist/commands/apps/devices/delete.js +3 -2
- package/dist/commands/apps/environments/create.js +1 -1
- package/dist/commands/apps/environments/delete.js +3 -2
- package/dist/commands/apps/liveupdates/bundle.js +117 -0
- package/dist/commands/apps/liveupdates/generate-manifest.js +39 -0
- package/dist/commands/{manifests/generate.test.js → apps/liveupdates/generate-manifest.test.js} +6 -6
- package/dist/commands/apps/liveupdates/register.js +291 -0
- package/dist/commands/apps/{bundles/create.test.js → liveupdates/register.test.js} +123 -111
- package/dist/commands/apps/liveupdates/rollback.js +171 -0
- package/dist/commands/apps/liveupdates/rollout.js +147 -0
- package/dist/commands/apps/liveupdates/upload.js +420 -0
- package/dist/commands/apps/liveupdates/upload.test.js +325 -0
- package/dist/commands/manifests/generate.js +2 -27
- package/dist/commands/organizations/create.js +1 -1
- package/dist/index.js +8 -0
- package/dist/services/app-builds.js +9 -2
- package/dist/services/app-channels.js +19 -0
- package/dist/services/app-deployments.js +24 -14
- package/dist/services/config.js +2 -0
- package/dist/utils/app-environments.js +2 -1
- package/dist/utils/time-format.js +26 -0
- package/package.json +3 -3
- package/dist/commands/apps/bundles/delete.test.js +0 -142
- package/dist/commands/apps/bundles/update.test.js +0 -144
- package/dist/utils/capacitor-config.js +0 -96
- package/dist/utils/package-json.js +0 -58
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_API_BASE_URL } from '../../../config/consts.js';
|
|
2
|
-
import authorizationService from '../../../services/authorization-service.js';
|
|
3
|
-
import { prompt } from '../../../utils/prompt.js';
|
|
4
|
-
import userConfig from '../../../utils/user-config.js';
|
|
5
|
-
import consola from 'consola';
|
|
6
|
-
import nock from 'nock';
|
|
7
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
8
|
-
import deleteBundleCommand from './delete.js';
|
|
9
|
-
// Mock dependencies
|
|
10
|
-
vi.mock('@/utils/user-config.js');
|
|
11
|
-
vi.mock('@/utils/prompt.js');
|
|
12
|
-
vi.mock('@/services/authorization-service.js');
|
|
13
|
-
vi.mock('consola');
|
|
14
|
-
vi.mock('@/utils/environment.js', () => ({
|
|
15
|
-
isInteractive: () => true,
|
|
16
|
-
}));
|
|
17
|
-
describe('apps-bundles-delete', () => {
|
|
18
|
-
const mockUserConfig = vi.mocked(userConfig);
|
|
19
|
-
const mockPrompt = vi.mocked(prompt);
|
|
20
|
-
const mockConsola = vi.mocked(consola);
|
|
21
|
-
const mockAuthorizationService = vi.mocked(authorizationService);
|
|
22
|
-
beforeEach(() => {
|
|
23
|
-
vi.clearAllMocks();
|
|
24
|
-
mockUserConfig.read.mockReturnValue({ token: 'test-token' });
|
|
25
|
-
mockAuthorizationService.getCurrentAuthorizationToken.mockReturnValue('test-token');
|
|
26
|
-
mockAuthorizationService.hasAuthorizationToken.mockReturnValue(true);
|
|
27
|
-
vi.spyOn(process, 'exit').mockImplementation(() => undefined);
|
|
28
|
-
});
|
|
29
|
-
afterEach(() => {
|
|
30
|
-
nock.cleanAll();
|
|
31
|
-
vi.restoreAllMocks();
|
|
32
|
-
});
|
|
33
|
-
it('should delete bundle with provided appId and bundleId after confirmation', async () => {
|
|
34
|
-
const appId = 'app-123';
|
|
35
|
-
const bundleId = 'bundle-456';
|
|
36
|
-
const testToken = 'test-token';
|
|
37
|
-
const options = { appId, bundleId };
|
|
38
|
-
mockPrompt.mockResolvedValueOnce(true); // confirmation
|
|
39
|
-
const scope = nock(DEFAULT_API_BASE_URL)
|
|
40
|
-
.delete(`/v1/apps/${appId}/bundles/${bundleId}`)
|
|
41
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
42
|
-
.reply(200);
|
|
43
|
-
await deleteBundleCommand.action(options, undefined);
|
|
44
|
-
expect(scope.isDone()).toBe(true);
|
|
45
|
-
expect(mockPrompt).toHaveBeenCalledWith('Are you sure you want to delete this bundle?', {
|
|
46
|
-
type: 'confirm',
|
|
47
|
-
});
|
|
48
|
-
expect(mockConsola.success).toHaveBeenCalledWith('Bundle deleted successfully.');
|
|
49
|
-
});
|
|
50
|
-
it('should not delete bundle when confirmation is declined', async () => {
|
|
51
|
-
const appId = 'app-123';
|
|
52
|
-
const bundleId = 'bundle-456';
|
|
53
|
-
const options = { appId, bundleId };
|
|
54
|
-
mockPrompt.mockResolvedValueOnce(false); // declined confirmation
|
|
55
|
-
await deleteBundleCommand.action(options, undefined);
|
|
56
|
-
expect(mockPrompt).toHaveBeenCalledWith('Are you sure you want to delete this bundle?', {
|
|
57
|
-
type: 'confirm',
|
|
58
|
-
});
|
|
59
|
-
expect(mockConsola.success).not.toHaveBeenCalled();
|
|
60
|
-
});
|
|
61
|
-
it('should prompt for app selection when appId not provided', async () => {
|
|
62
|
-
const orgId = 'org-1';
|
|
63
|
-
const appId = 'app-1';
|
|
64
|
-
const bundleId = 'bundle-456';
|
|
65
|
-
const testToken = 'test-token';
|
|
66
|
-
const organization = { id: orgId, name: 'Org 1' };
|
|
67
|
-
const app = { id: appId, name: 'App 1' };
|
|
68
|
-
const options = { bundleId };
|
|
69
|
-
const orgsScope = nock(DEFAULT_API_BASE_URL)
|
|
70
|
-
.get('/v1/organizations')
|
|
71
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
72
|
-
.reply(200, [organization]);
|
|
73
|
-
const appsScope = nock(DEFAULT_API_BASE_URL)
|
|
74
|
-
.get('/v1/apps')
|
|
75
|
-
.query({ organizationId: orgId })
|
|
76
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
77
|
-
.reply(200, [app]);
|
|
78
|
-
const deleteScope = nock(DEFAULT_API_BASE_URL)
|
|
79
|
-
.delete(`/v1/apps/${appId}/bundles/${bundleId}`)
|
|
80
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
81
|
-
.reply(200);
|
|
82
|
-
mockPrompt
|
|
83
|
-
.mockResolvedValueOnce(orgId) // organization selection
|
|
84
|
-
.mockResolvedValueOnce(appId) // app selection
|
|
85
|
-
.mockResolvedValueOnce(true); // confirmation
|
|
86
|
-
await deleteBundleCommand.action(options, undefined);
|
|
87
|
-
expect(orgsScope.isDone()).toBe(true);
|
|
88
|
-
expect(appsScope.isDone()).toBe(true);
|
|
89
|
-
expect(deleteScope.isDone()).toBe(true);
|
|
90
|
-
expect(mockConsola.success).toHaveBeenCalledWith('Bundle deleted successfully.');
|
|
91
|
-
});
|
|
92
|
-
it('should prompt for bundleId when not provided', async () => {
|
|
93
|
-
const appId = 'app-123';
|
|
94
|
-
const bundleId = 'bundle-456';
|
|
95
|
-
const testToken = 'test-token';
|
|
96
|
-
const options = { appId };
|
|
97
|
-
const scope = nock(DEFAULT_API_BASE_URL)
|
|
98
|
-
.delete(`/v1/apps/${appId}/bundles/${bundleId}`)
|
|
99
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
100
|
-
.reply(200);
|
|
101
|
-
mockPrompt
|
|
102
|
-
.mockResolvedValueOnce(bundleId) // bundle ID input
|
|
103
|
-
.mockResolvedValueOnce(true); // confirmation
|
|
104
|
-
await deleteBundleCommand.action(options, undefined);
|
|
105
|
-
expect(scope.isDone()).toBe(true);
|
|
106
|
-
expect(mockPrompt).toHaveBeenCalledWith('Enter the bundle ID:', { type: 'text' });
|
|
107
|
-
expect(mockConsola.success).toHaveBeenCalledWith('Bundle deleted successfully.');
|
|
108
|
-
});
|
|
109
|
-
it('should handle error when no organizations exist', async () => {
|
|
110
|
-
const testToken = 'test-token';
|
|
111
|
-
const options = {};
|
|
112
|
-
const scope = nock(DEFAULT_API_BASE_URL)
|
|
113
|
-
.get('/v1/organizations')
|
|
114
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
115
|
-
.reply(200, []);
|
|
116
|
-
const exitSpy = vi.spyOn(process, 'exit').mockImplementation((code) => {
|
|
117
|
-
throw new Error(`process.exit called with code ${code}`);
|
|
118
|
-
});
|
|
119
|
-
try {
|
|
120
|
-
await deleteBundleCommand.action(options, undefined);
|
|
121
|
-
}
|
|
122
|
-
catch (error) {
|
|
123
|
-
expect(error.message).toBe('process.exit called with code 1');
|
|
124
|
-
}
|
|
125
|
-
expect(scope.isDone()).toBe(true);
|
|
126
|
-
expect(mockConsola.error).toHaveBeenCalledWith('You must create an organization before deleting a bundle.');
|
|
127
|
-
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
128
|
-
});
|
|
129
|
-
it('should handle API error during deletion', async () => {
|
|
130
|
-
const appId = 'app-123';
|
|
131
|
-
const bundleId = 'bundle-456';
|
|
132
|
-
const testToken = 'test-token';
|
|
133
|
-
const options = { appId, bundleId };
|
|
134
|
-
mockPrompt.mockResolvedValueOnce(true);
|
|
135
|
-
const scope = nock(DEFAULT_API_BASE_URL)
|
|
136
|
-
.delete(`/v1/apps/${appId}/bundles/${bundleId}`)
|
|
137
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
138
|
-
.reply(404, { message: 'Bundle not found' });
|
|
139
|
-
await expect(deleteBundleCommand.action(options, undefined)).rejects.toThrow();
|
|
140
|
-
expect(scope.isDone()).toBe(true);
|
|
141
|
-
});
|
|
142
|
-
});
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_API_BASE_URL } from '../../../config/consts.js';
|
|
2
|
-
import authorizationService from '../../../services/authorization-service.js';
|
|
3
|
-
import { prompt } from '../../../utils/prompt.js';
|
|
4
|
-
import userConfig from '../../../utils/user-config.js';
|
|
5
|
-
import consola from 'consola';
|
|
6
|
-
import nock from 'nock';
|
|
7
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
8
|
-
import updateBundleCommand from './update.js';
|
|
9
|
-
// Mock dependencies
|
|
10
|
-
vi.mock('@/utils/user-config.js');
|
|
11
|
-
vi.mock('@/utils/prompt.js');
|
|
12
|
-
vi.mock('@/services/authorization-service.js');
|
|
13
|
-
vi.mock('consola');
|
|
14
|
-
vi.mock('@/utils/environment.js', () => ({
|
|
15
|
-
isInteractive: () => true,
|
|
16
|
-
}));
|
|
17
|
-
describe('apps-bundles-update', () => {
|
|
18
|
-
const mockUserConfig = vi.mocked(userConfig);
|
|
19
|
-
const mockPrompt = vi.mocked(prompt);
|
|
20
|
-
const mockConsola = vi.mocked(consola);
|
|
21
|
-
const mockAuthorizationService = vi.mocked(authorizationService);
|
|
22
|
-
beforeEach(() => {
|
|
23
|
-
vi.clearAllMocks();
|
|
24
|
-
mockUserConfig.read.mockReturnValue({ token: 'test-token' });
|
|
25
|
-
mockAuthorizationService.hasAuthorizationToken.mockReturnValue(true);
|
|
26
|
-
mockAuthorizationService.getCurrentAuthorizationToken.mockReturnValue('test-token');
|
|
27
|
-
vi.spyOn(process, 'exit').mockImplementation((code) => {
|
|
28
|
-
throw new Error(`Process exited with code ${code}`);
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
afterEach(() => {
|
|
32
|
-
nock.cleanAll();
|
|
33
|
-
vi.restoreAllMocks();
|
|
34
|
-
});
|
|
35
|
-
it('should require authentication', async () => {
|
|
36
|
-
const appId = 'app-123';
|
|
37
|
-
const bundleId = 'bundle-456';
|
|
38
|
-
const options = { appId, bundleId };
|
|
39
|
-
mockAuthorizationService.hasAuthorizationToken.mockReturnValue(false);
|
|
40
|
-
await expect(updateBundleCommand.action(options, undefined)).rejects.toThrow('Process exited with code 1');
|
|
41
|
-
expect(mockConsola.error).toHaveBeenCalledWith('You must be logged in to run this command. Please run the `login` command first.');
|
|
42
|
-
});
|
|
43
|
-
it('should update bundle with provided options', async () => {
|
|
44
|
-
const appId = 'app-123';
|
|
45
|
-
const bundleId = 'bundle-456';
|
|
46
|
-
const rollout = 0.5;
|
|
47
|
-
const androidMax = '1000';
|
|
48
|
-
const iosMin = '2.0.0';
|
|
49
|
-
const testToken = 'test-token';
|
|
50
|
-
const options = { appId, bundleId, rollout, androidMax, iosMin };
|
|
51
|
-
const scope = nock(DEFAULT_API_BASE_URL)
|
|
52
|
-
.patch(`/v1/apps/${appId}/bundles/${bundleId}`, {
|
|
53
|
-
appId,
|
|
54
|
-
appBundleId: bundleId,
|
|
55
|
-
maxAndroidAppVersionCode: androidMax,
|
|
56
|
-
maxIosAppVersionCode: undefined,
|
|
57
|
-
minAndroidAppVersionCode: undefined,
|
|
58
|
-
minIosAppVersionCode: iosMin,
|
|
59
|
-
rolloutPercentage: rollout,
|
|
60
|
-
})
|
|
61
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
62
|
-
.reply(200, { id: bundleId });
|
|
63
|
-
await updateBundleCommand.action(options, undefined);
|
|
64
|
-
expect(scope.isDone()).toBe(true);
|
|
65
|
-
expect(mockConsola.success).toHaveBeenCalledWith('Bundle updated successfully.');
|
|
66
|
-
});
|
|
67
|
-
it('should prompt for app selection when appId not provided', async () => {
|
|
68
|
-
const orgId = 'org-1';
|
|
69
|
-
const appId = 'app-1';
|
|
70
|
-
const bundleId = 'bundle-456';
|
|
71
|
-
const testToken = 'test-token';
|
|
72
|
-
const organization = { id: orgId, name: 'Org 1' };
|
|
73
|
-
const app = { id: appId, name: 'App 1' };
|
|
74
|
-
const options = { bundleId, rollout: 1 };
|
|
75
|
-
const orgsScope = nock(DEFAULT_API_BASE_URL)
|
|
76
|
-
.get('/v1/organizations')
|
|
77
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
78
|
-
.reply(200, [organization]);
|
|
79
|
-
const appsScope = nock(DEFAULT_API_BASE_URL)
|
|
80
|
-
.get('/v1/apps')
|
|
81
|
-
.query({ organizationId: orgId })
|
|
82
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
83
|
-
.reply(200, [app]);
|
|
84
|
-
const updateScope = nock(DEFAULT_API_BASE_URL)
|
|
85
|
-
.patch(`/v1/apps/${appId}/bundles/${bundleId}`)
|
|
86
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
87
|
-
.reply(200, { id: bundleId });
|
|
88
|
-
mockPrompt
|
|
89
|
-
.mockResolvedValueOnce(orgId) // organization selection
|
|
90
|
-
.mockResolvedValueOnce(appId); // app selection
|
|
91
|
-
await updateBundleCommand.action(options, undefined);
|
|
92
|
-
expect(orgsScope.isDone()).toBe(true);
|
|
93
|
-
expect(appsScope.isDone()).toBe(true);
|
|
94
|
-
expect(updateScope.isDone()).toBe(true);
|
|
95
|
-
expect(mockConsola.success).toHaveBeenCalledWith('Bundle updated successfully.');
|
|
96
|
-
});
|
|
97
|
-
it('should prompt for bundleId when not provided', async () => {
|
|
98
|
-
const appId = 'app-123';
|
|
99
|
-
const bundleId = 'bundle-456';
|
|
100
|
-
const testToken = 'test-token';
|
|
101
|
-
const options = { appId };
|
|
102
|
-
const scope = nock(DEFAULT_API_BASE_URL)
|
|
103
|
-
.patch(`/v1/apps/${appId}/bundles/${bundleId}`)
|
|
104
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
105
|
-
.reply(200, { id: bundleId });
|
|
106
|
-
mockPrompt.mockResolvedValueOnce(bundleId); // bundle ID input
|
|
107
|
-
await updateBundleCommand.action(options, undefined);
|
|
108
|
-
expect(scope.isDone()).toBe(true);
|
|
109
|
-
expect(mockPrompt).toHaveBeenCalledWith('Enter the bundle ID:', { type: 'text' });
|
|
110
|
-
expect(mockConsola.success).toHaveBeenCalledWith('Bundle updated successfully.');
|
|
111
|
-
});
|
|
112
|
-
it('should handle API error during update', async () => {
|
|
113
|
-
const appId = 'app-123';
|
|
114
|
-
const bundleId = 'bundle-456';
|
|
115
|
-
const testToken = 'test-token';
|
|
116
|
-
const options = { appId, bundleId };
|
|
117
|
-
const scope = nock(DEFAULT_API_BASE_URL)
|
|
118
|
-
.patch(`/v1/apps/${appId}/bundles/${bundleId}`)
|
|
119
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
120
|
-
.reply(404, { message: 'Bundle not found' });
|
|
121
|
-
await expect(updateBundleCommand.action(options, undefined)).rejects.toThrow();
|
|
122
|
-
expect(scope.isDone()).toBe(true);
|
|
123
|
-
});
|
|
124
|
-
it('should handle error when no organizations exist', async () => {
|
|
125
|
-
const testToken = 'test-token';
|
|
126
|
-
const options = {};
|
|
127
|
-
const scope = nock(DEFAULT_API_BASE_URL)
|
|
128
|
-
.get('/v1/organizations')
|
|
129
|
-
.matchHeader('Authorization', `Bearer ${testToken}`)
|
|
130
|
-
.reply(200, []);
|
|
131
|
-
const exitSpy = vi.spyOn(process, 'exit').mockImplementation((code) => {
|
|
132
|
-
throw new Error(`process.exit called with code ${code}`);
|
|
133
|
-
});
|
|
134
|
-
try {
|
|
135
|
-
await updateBundleCommand.action(options, undefined);
|
|
136
|
-
}
|
|
137
|
-
catch (error) {
|
|
138
|
-
expect(error.message).toBe('process.exit called with code 1');
|
|
139
|
-
}
|
|
140
|
-
expect(scope.isDone()).toBe(true);
|
|
141
|
-
expect(mockConsola.error).toHaveBeenCalledWith('You must create an organization before updating a bundle.');
|
|
142
|
-
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
143
|
-
});
|
|
144
|
-
});
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import pathModule from 'path';
|
|
3
|
-
import { fileExistsAtPath } from './file.js';
|
|
4
|
-
/**
|
|
5
|
-
* Find the Capacitor config file in the current working directory.
|
|
6
|
-
* Looks for capacitor.config.json or capacitor.config.ts.
|
|
7
|
-
*
|
|
8
|
-
* @returns The path to the config file, or undefined if not found.
|
|
9
|
-
*/
|
|
10
|
-
export const findCapacitorConfigPath = async () => {
|
|
11
|
-
const cwd = process.cwd();
|
|
12
|
-
const jsonPath = pathModule.join(cwd, 'capacitor.config.json');
|
|
13
|
-
const tsPath = pathModule.join(cwd, 'capacitor.config.ts');
|
|
14
|
-
if (await fileExistsAtPath(jsonPath)) {
|
|
15
|
-
return jsonPath;
|
|
16
|
-
}
|
|
17
|
-
if (await fileExistsAtPath(tsPath)) {
|
|
18
|
-
return tsPath;
|
|
19
|
-
}
|
|
20
|
-
return undefined;
|
|
21
|
-
};
|
|
22
|
-
/**
|
|
23
|
-
* Read and parse the Capacitor config file.
|
|
24
|
-
*
|
|
25
|
-
* @param configPath The path to the config file.
|
|
26
|
-
* @returns The parsed config object, or undefined if parsing fails.
|
|
27
|
-
*/
|
|
28
|
-
export const readCapacitorConfig = async (configPath) => {
|
|
29
|
-
try {
|
|
30
|
-
if (configPath.endsWith('.json')) {
|
|
31
|
-
const content = await fs.promises.readFile(configPath, 'utf-8');
|
|
32
|
-
return JSON.parse(content);
|
|
33
|
-
}
|
|
34
|
-
else if (configPath.endsWith('.ts')) {
|
|
35
|
-
// For TypeScript config, parse as text and extract values
|
|
36
|
-
const content = await fs.promises.readFile(configPath, 'utf-8');
|
|
37
|
-
// Extract webDir using regex
|
|
38
|
-
const webDirMatch = content.match(/webDir:\s*['"]([^'"]+)['"]/);
|
|
39
|
-
const appIdMatch = content.match(/LiveUpdate:\s*{[^}]*appId:\s*['"]([^'"]+)['"]/s);
|
|
40
|
-
const publicKeyMatch = content.match(/LiveUpdate:\s*{[^}]*publicKey:\s*['"]([^'"]+)['"]/s);
|
|
41
|
-
const config = {};
|
|
42
|
-
if (webDirMatch) {
|
|
43
|
-
config.webDir = webDirMatch[1];
|
|
44
|
-
}
|
|
45
|
-
if (appIdMatch || publicKeyMatch) {
|
|
46
|
-
config.plugins = {
|
|
47
|
-
LiveUpdate: {
|
|
48
|
-
...(appIdMatch && { appId: appIdMatch[1] }),
|
|
49
|
-
...(publicKeyMatch && { publicKey: publicKeyMatch[1] }),
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
return Object.keys(config).length > 0 ? config : undefined;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
catch (error) {
|
|
57
|
-
// Return undefined if parsing fails
|
|
58
|
-
}
|
|
59
|
-
return undefined;
|
|
60
|
-
};
|
|
61
|
-
/**
|
|
62
|
-
* Get the webDir from the Capacitor config.
|
|
63
|
-
* Returns the absolute path to the webDir.
|
|
64
|
-
*
|
|
65
|
-
* @param configPath The path to the config file.
|
|
66
|
-
* @returns The absolute path to the webDir, or undefined if not found.
|
|
67
|
-
*/
|
|
68
|
-
export const getWebDirFromConfig = async (configPath) => {
|
|
69
|
-
const config = await readCapacitorConfig(configPath);
|
|
70
|
-
if (config?.webDir) {
|
|
71
|
-
// Resolve the webDir relative to the config file location
|
|
72
|
-
const configDir = pathModule.dirname(configPath);
|
|
73
|
-
return pathModule.resolve(configDir, config.webDir);
|
|
74
|
-
}
|
|
75
|
-
return undefined;
|
|
76
|
-
};
|
|
77
|
-
/**
|
|
78
|
-
* Get the LiveUpdate appId from the Capacitor config.
|
|
79
|
-
*
|
|
80
|
-
* @param configPath The path to the config file.
|
|
81
|
-
* @returns The appId, or undefined if not found.
|
|
82
|
-
*/
|
|
83
|
-
export const getLiveUpdatePluginAppIdFromConfig = async (configPath) => {
|
|
84
|
-
const config = await readCapacitorConfig(configPath);
|
|
85
|
-
return config?.plugins?.LiveUpdate?.appId;
|
|
86
|
-
};
|
|
87
|
-
/**
|
|
88
|
-
* Get the LiveUpdate publicKey from the Capacitor config.
|
|
89
|
-
*
|
|
90
|
-
* @param configPath The path to the config file.
|
|
91
|
-
* @returns The publicKey, or undefined if not found.
|
|
92
|
-
*/
|
|
93
|
-
export const getLiveUpdatePluginPublicKeyFromConfig = async (configPath) => {
|
|
94
|
-
const config = await readCapacitorConfig(configPath);
|
|
95
|
-
return config?.plugins?.LiveUpdate?.publicKey;
|
|
96
|
-
};
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { fileExistsAtPath } from './file.js';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import pathModule from 'path';
|
|
4
|
-
/**
|
|
5
|
-
* Find the package.json file in the current working directory.
|
|
6
|
-
*
|
|
7
|
-
* @returns The path to the package.json file, or undefined if not found.
|
|
8
|
-
*/
|
|
9
|
-
export const findPackageJsonPath = async () => {
|
|
10
|
-
const cwd = process.cwd();
|
|
11
|
-
const packageJsonPath = pathModule.join(cwd, 'package.json');
|
|
12
|
-
if (await fileExistsAtPath(packageJsonPath)) {
|
|
13
|
-
return packageJsonPath;
|
|
14
|
-
}
|
|
15
|
-
return undefined;
|
|
16
|
-
};
|
|
17
|
-
/**
|
|
18
|
-
* Read and parse the package.json file.
|
|
19
|
-
*
|
|
20
|
-
* @param packageJsonPath The path to the package.json file.
|
|
21
|
-
* @returns The parsed package.json object, or undefined if parsing fails.
|
|
22
|
-
*/
|
|
23
|
-
export const readPackageJson = async (packageJsonPath) => {
|
|
24
|
-
try {
|
|
25
|
-
const content = await fs.promises.readFile(packageJsonPath, 'utf-8');
|
|
26
|
-
return JSON.parse(content);
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
return undefined;
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
/**
|
|
33
|
-
* Get the build script from package.json.
|
|
34
|
-
* Prefers 'capawesome:build' over 'build' if both exist.
|
|
35
|
-
*
|
|
36
|
-
* @param packageJsonPath The path to the package.json file.
|
|
37
|
-
* @returns An object with the script name and command, or undefined if not found.
|
|
38
|
-
*/
|
|
39
|
-
export const getBuildScript = async (packageJsonPath) => {
|
|
40
|
-
const packageJson = await readPackageJson(packageJsonPath);
|
|
41
|
-
if (!packageJson?.scripts) {
|
|
42
|
-
return undefined;
|
|
43
|
-
}
|
|
44
|
-
// Prefer 'capawesome:build' over 'build'
|
|
45
|
-
if (packageJson.scripts['capawesome:build']) {
|
|
46
|
-
return {
|
|
47
|
-
name: 'capawesome:build',
|
|
48
|
-
command: packageJson.scripts['capawesome:build'],
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
if (packageJson.scripts['build']) {
|
|
52
|
-
return {
|
|
53
|
-
name: 'build',
|
|
54
|
-
command: packageJson.scripts['build'],
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
return undefined;
|
|
58
|
-
};
|