@capgo/cli 7.18.1 → 7.18.3
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/dist/index.js +238 -237
- package/dist/package.json +5 -5
- package/dist/src/api/app.d.ts +13 -0
- package/dist/src/api/app.d.ts.map +1 -0
- package/dist/src/api/app.js +45 -0
- package/dist/src/api/app.js.map +1 -0
- package/dist/src/api/channels.d.ts +4505 -0
- package/dist/src/api/channels.d.ts.map +1 -0
- package/dist/src/api/channels.js +167 -0
- package/dist/src/api/channels.js.map +1 -0
- package/dist/src/api/cryptoV2.d.ts +16 -0
- package/dist/src/api/cryptoV2.d.ts.map +1 -0
- package/dist/src/api/cryptoV2.js +102 -0
- package/dist/src/api/cryptoV2.js.map +1 -0
- package/dist/src/api/update.d.ts +2 -0
- package/dist/src/api/update.d.ts.map +1 -0
- package/dist/src/api/update.js +14 -0
- package/dist/src/api/update.js.map +1 -0
- package/dist/src/api/versions.d.ts +56 -0
- package/dist/src/api/versions.d.ts.map +1 -0
- package/dist/src/api/versions.js +92 -0
- package/dist/src/api/versions.js.map +1 -0
- package/dist/src/app/add.d.ts +18 -0
- package/dist/src/app/add.d.ts.map +1 -0
- package/dist/src/app/add.js +150 -0
- package/dist/src/app/add.js.map +1 -0
- package/dist/src/app/debug.d.ts +33 -0
- package/dist/src/app/debug.d.ts.map +1 -0
- package/dist/src/app/debug.js +222 -0
- package/dist/src/app/debug.js.map +1 -0
- package/dist/src/app/delete.d.ts +3 -0
- package/dist/src/app/delete.d.ts.map +1 -0
- package/dist/src/app/delete.js +89 -0
- package/dist/src/app/delete.js.map +1 -0
- package/dist/src/app/info.d.ts +13 -0
- package/dist/src/app/info.d.ts.map +1 -0
- package/dist/src/app/info.js +84 -0
- package/dist/src/app/info.js.map +1 -0
- package/dist/src/app/list.d.ts +16 -0
- package/dist/src/app/list.d.ts.map +1 -0
- package/dist/src/app/list.js +48 -0
- package/dist/src/app/list.js.map +1 -0
- package/dist/src/app/set.d.ts +3 -0
- package/dist/src/app/set.d.ts.map +1 -0
- package/dist/src/app/set.js +96 -0
- package/dist/src/app/set.js.map +1 -0
- package/dist/src/app/setting.d.ts +8 -0
- package/dist/src/app/setting.d.ts.map +1 -0
- package/dist/src/app/setting.js +50 -0
- package/dist/src/app/setting.js.map +1 -0
- package/dist/src/bundle/check.d.ts +3 -0
- package/dist/src/bundle/check.d.ts.map +1 -0
- package/dist/src/bundle/check.js +30 -0
- package/dist/src/bundle/check.js.map +1 -0
- package/dist/src/bundle/cleanup.d.ts +14 -0
- package/dist/src/bundle/cleanup.d.ts.map +1 -0
- package/dist/src/bundle/cleanup.js +105 -0
- package/dist/src/bundle/cleanup.js.map +1 -0
- package/dist/src/bundle/compatibility.d.ts +15 -0
- package/dist/src/bundle/compatibility.d.ts.map +1 -0
- package/dist/src/bundle/compatibility.js +62 -0
- package/dist/src/bundle/compatibility.js.map +1 -0
- package/dist/src/bundle/decryptV2.d.ts +13 -0
- package/dist/src/bundle/decryptV2.d.ts.map +1 -0
- package/dist/src/bundle/decryptV2.js +76 -0
- package/dist/src/bundle/decryptV2.js.map +1 -0
- package/dist/src/bundle/delete.d.ts +7 -0
- package/dist/src/bundle/delete.d.ts.map +1 -0
- package/dist/src/bundle/delete.js +40 -0
- package/dist/src/bundle/delete.js.map +1 -0
- package/dist/src/bundle/encryptV2.d.ts +14 -0
- package/dist/src/bundle/encryptV2.d.ts.map +1 -0
- package/dist/src/bundle/encryptV2.js +108 -0
- package/dist/src/bundle/encryptV2.js.map +1 -0
- package/dist/src/bundle/list.d.ts +22 -0
- package/dist/src/bundle/list.d.ts.map +1 -0
- package/dist/src/bundle/list.js +36 -0
- package/dist/src/bundle/list.js.map +1 -0
- package/dist/src/bundle/partial.d.ts +14 -0
- package/dist/src/bundle/partial.d.ts.map +1 -0
- package/dist/src/bundle/partial.js +332 -0
- package/dist/src/bundle/partial.js.map +1 -0
- package/dist/src/bundle/unlink.d.ts +9 -0
- package/dist/src/bundle/unlink.d.ts.map +1 -0
- package/dist/src/bundle/unlink.js +70 -0
- package/dist/src/bundle/unlink.js.map +1 -0
- package/dist/src/bundle/upload.d.ts +19 -0
- package/dist/src/bundle/upload.d.ts.map +1 -0
- package/dist/src/bundle/upload.js +700 -0
- package/dist/src/bundle/upload.js.map +1 -0
- package/dist/src/bundle/upload_interface.d.ts +49 -0
- package/dist/src/bundle/upload_interface.d.ts.map +1 -0
- package/dist/src/bundle/upload_interface.js +2 -0
- package/dist/src/bundle/upload_interface.js.map +1 -0
- package/dist/src/bundle/zip.d.ts +19 -0
- package/dist/src/bundle/zip.d.ts.map +1 -0
- package/dist/src/bundle/zip.js +148 -0
- package/dist/src/bundle/zip.js.map +1 -0
- package/dist/src/channel/add.d.ts +26 -0
- package/dist/src/channel/add.d.ts.map +1 -0
- package/dist/src/channel/add.js +68 -0
- package/dist/src/channel/add.js.map +1 -0
- package/dist/src/channel/currentBundle.d.ts +8 -0
- package/dist/src/channel/currentBundle.d.ts.map +1 -0
- package/dist/src/channel/currentBundle.js +54 -0
- package/dist/src/channel/currentBundle.js.map +1 -0
- package/dist/src/channel/delete.d.ts +8 -0
- package/dist/src/channel/delete.d.ts.map +1 -0
- package/dist/src/channel/delete.js +77 -0
- package/dist/src/channel/delete.js.map +1 -0
- package/dist/src/channel/list.d.ts +3 -0
- package/dist/src/channel/list.d.ts.map +1 -0
- package/dist/src/channel/list.js +45 -0
- package/dist/src/channel/list.js.map +1 -0
- package/dist/src/channel/set.d.ts +18 -0
- package/dist/src/channel/set.d.ts.map +1 -0
- package/dist/src/channel/set.js +220 -0
- package/dist/src/channel/set.js.map +1 -0
- package/dist/src/config/index.d.ts +16 -0
- package/dist/src/config/index.d.ts.map +1 -0
- package/dist/src/config/index.js +31 -0
- package/dist/src/config/index.js.map +1 -0
- package/dist/src/docs.d.ts +2 -0
- package/dist/src/docs.d.ts.map +1 -0
- package/dist/src/docs.js +280 -0
- package/dist/src/docs.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +504 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/init.d.ts +7 -0
- package/dist/src/init.d.ts.map +1 -0
- package/dist/src/init.js +797 -0
- package/dist/src/init.js.map +1 -0
- package/dist/src/keyV2.d.ts +20 -0
- package/dist/src/keyV2.d.ts.map +1 -0
- package/dist/src/keyV2.js +163 -0
- package/dist/src/keyV2.js.map +1 -0
- package/dist/src/login.d.ts +10 -0
- package/dist/src/login.d.ts.map +1 -0
- package/dist/src/login.js +51 -0
- package/dist/src/login.js.map +1 -0
- package/dist/src/organisation/add.d.ts +18 -0
- package/dist/src/organisation/add.d.ts.map +1 -0
- package/dist/src/organisation/add.js +82 -0
- package/dist/src/organisation/add.js.map +1 -0
- package/dist/src/organisation/delete.d.ts +8 -0
- package/dist/src/organisation/delete.d.ts.map +1 -0
- package/dist/src/organisation/delete.js +91 -0
- package/dist/src/organisation/delete.js.map +1 -0
- package/dist/src/organisation/index.d.ts +5 -0
- package/dist/src/organisation/index.d.ts.map +1 -0
- package/dist/src/organisation/index.js +5 -0
- package/dist/src/organisation/index.js.map +1 -0
- package/dist/src/organisation/list.d.ts +19 -0
- package/dist/src/organisation/list.d.ts.map +1 -0
- package/dist/src/organisation/list.js +60 -0
- package/dist/src/organisation/list.js.map +1 -0
- package/dist/src/organisation/set.d.ts +13 -0
- package/dist/src/organisation/set.d.ts.map +1 -0
- package/dist/src/organisation/set.js +95 -0
- package/dist/src/organisation/set.js.map +1 -0
- package/dist/src/sdk.d.ts +605 -0
- package/dist/src/sdk.d.ts.map +1 -0
- package/dist/src/sdk.js +441 -0
- package/dist/src/sdk.js.map +1 -0
- package/dist/src/types/supabase.types.d.ts +2305 -0
- package/dist/src/types/supabase.types.d.ts.map +1 -0
- package/dist/src/types/supabase.types.js +86 -0
- package/dist/src/types/supabase.types.js.map +1 -0
- package/dist/src/user/account.d.ts +4 -0
- package/dist/src/user/account.d.ts.map +1 -0
- package/dist/src/user/account.js +31 -0
- package/dist/src/user/account.js.map +1 -0
- package/dist/src/utils.d.ts +2426 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/dist/src/utils.js +1184 -0
- package/dist/src/utils.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decryptV2.js","sourceRoot":"","sources":["../../../src/bundle/decryptV2.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { OptionsBase } from '../utils';
|
|
2
|
+
interface Options extends OptionsBase {
|
|
3
|
+
bundle: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function deleteBundle(bundleId: string, appId: string, options: Options, silent?: boolean): Promise<boolean>;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=delete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/bundle/delete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAM3C,UAAU,OAAQ,SAAQ,WAAW;IACnC,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,UAAQ,oBA4CnG"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { intro, log, outro } from '@clack/prompts';
|
|
2
|
+
import { checkAppExistsAndHasPermissionOrgErr } from '../api/app';
|
|
3
|
+
import { deleteSpecificVersion } from '../api/versions';
|
|
4
|
+
import { createSupabaseClient, findSavedKey, getAppId, getConfig, OrganizationPerm, verifyUser } from '../utils';
|
|
5
|
+
export async function deleteBundle(bundleId, appId, options, silent = false) {
|
|
6
|
+
if (!silent)
|
|
7
|
+
intro('Delete bundle');
|
|
8
|
+
options.apikey = options.apikey || findSavedKey();
|
|
9
|
+
const extConfig = await getConfig();
|
|
10
|
+
appId = getAppId(appId, extConfig?.config);
|
|
11
|
+
if (!options.apikey) {
|
|
12
|
+
if (!silent)
|
|
13
|
+
log.error('Missing API key, you need to provide an API key to upload your bundle');
|
|
14
|
+
throw new Error('Missing API key');
|
|
15
|
+
}
|
|
16
|
+
if (!appId) {
|
|
17
|
+
if (!silent)
|
|
18
|
+
log.error('Missing argument, you need to provide a appId, or be in a capacitor project');
|
|
19
|
+
throw new Error('Missing appId');
|
|
20
|
+
}
|
|
21
|
+
if (!bundleId) {
|
|
22
|
+
if (!silent)
|
|
23
|
+
log.error('Missing argument, you need to provide a bundleId, or be in a capacitor project');
|
|
24
|
+
throw new Error('Missing bundleId');
|
|
25
|
+
}
|
|
26
|
+
const supabase = await createSupabaseClient(options.apikey, options.supaHost, options.supaAnon);
|
|
27
|
+
await verifyUser(supabase, options.apikey, ['write', 'all']);
|
|
28
|
+
await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.write, silent);
|
|
29
|
+
if (!silent) {
|
|
30
|
+
log.info(`Deleting bundle ${appId}@${bundleId} from Capgo`);
|
|
31
|
+
log.info(`Keep in mind that you will not be able to reuse this bundle version, it's gone forever`);
|
|
32
|
+
}
|
|
33
|
+
await deleteSpecificVersion(supabase, appId, bundleId);
|
|
34
|
+
if (!silent) {
|
|
35
|
+
log.success(`Bundle ${appId}@${bundleId} deleted in Capgo`);
|
|
36
|
+
outro('Done');
|
|
37
|
+
}
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../src/bundle/delete.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAAE,oCAAoC,EAAE,MAAM,YAAY,CAAA;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAMhH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB,EAAE,KAAa,EAAE,OAAgB,EAAE,MAAM,GAAG,KAAK;IAClG,IAAI,CAAC,MAAM;QACT,KAAK,CAAC,eAAe,CAAC,CAAA;IAExB,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,YAAY,EAAE,CAAA;IACjD,MAAM,SAAS,GAAG,MAAM,SAAS,EAAE,CAAA;IACnC,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,CAAA;IAE1C,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACpB,IAAI,CAAC,MAAM;YACT,GAAG,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAA;QACpF,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACpC,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,CAAC,MAAM;YACT,GAAG,CAAC,KAAK,CAAC,6EAA6E,CAAC,CAAA;QAC1F,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAA;IAClC,CAAC;IAED,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,IAAI,CAAC,MAAM;YACT,GAAG,CAAC,KAAK,CAAC,gFAAgF,CAAC,CAAA;QAC7F,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAA;IACrC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IAE/F,MAAM,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAA;IAC5D,MAAM,oCAAoC,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IAE3G,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,GAAG,CAAC,IAAI,CAAC,mBAAmB,KAAK,IAAI,QAAQ,aAAa,CAAC,CAAA;QAC3D,GAAG,CAAC,IAAI,CAAC,wFAAwF,CAAC,CAAA;IACpG,CAAC;IAED,MAAM,qBAAqB,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAA;IAEtD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,GAAG,CAAC,OAAO,CAAC,UAAU,KAAK,IAAI,QAAQ,mBAAmB,CAAC,CAAA;QAC3D,KAAK,CAAC,MAAM,CAAC,CAAA;IACf,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface Options {
|
|
2
|
+
key?: string;
|
|
3
|
+
keyData?: string;
|
|
4
|
+
json?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface EncryptResult {
|
|
7
|
+
checksum: string;
|
|
8
|
+
filename: string;
|
|
9
|
+
ivSessionKey: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function encryptZipV2Internal(zipPath: string, checksum: string, options: Options, silent?: boolean): Promise<EncryptResult>;
|
|
12
|
+
export declare function encryptZipV2(zipPath: string, checksum: string, options: Options): Promise<void>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=encryptV2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryptV2.d.ts","sourceRoot":"","sources":["../../../src/bundle/encryptV2.ts"],"names":[],"mappings":"AAMA,UAAU,OAAO;IACf,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;CACrB;AAMD,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,MAAM,UAAQ,GACb,OAAO,CAAC,aAAa,CAAC,CA4GxB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,iBAErF"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { intro, log, outro } from '@clack/prompts';
|
|
3
|
+
import { encryptChecksumV2, encryptSourceV2, generateSessionKey } from '../api/cryptoV2';
|
|
4
|
+
import { checkAlerts } from '../api/update';
|
|
5
|
+
import { baseKeyV2, formatError, getConfig } from '../utils';
|
|
6
|
+
function emitJsonError(error) {
|
|
7
|
+
console.error(formatError(error));
|
|
8
|
+
}
|
|
9
|
+
export async function encryptZipV2Internal(zipPath, checksum, options, silent = false) {
|
|
10
|
+
const { json } = options;
|
|
11
|
+
const shouldShowPrompts = !json && !silent;
|
|
12
|
+
if (shouldShowPrompts) {
|
|
13
|
+
intro('Encryption');
|
|
14
|
+
await checkAlerts();
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
const extConfig = await getConfig();
|
|
18
|
+
const hasPrivateKeyInConfig = !!extConfig.config.plugins?.CapacitorUpdater?.privateKey;
|
|
19
|
+
const hasPublicKeyInConfig = !!extConfig.config.plugins?.CapacitorUpdater?.publicKey;
|
|
20
|
+
if (hasPrivateKeyInConfig && shouldShowPrompts)
|
|
21
|
+
log.warning('There is still a privateKey in the config');
|
|
22
|
+
if (!existsSync(zipPath)) {
|
|
23
|
+
const message = `Zip not found at the path ${zipPath}`;
|
|
24
|
+
if (!silent) {
|
|
25
|
+
if (json)
|
|
26
|
+
emitJsonError({ error: 'zip_not_found' });
|
|
27
|
+
else
|
|
28
|
+
log.error(`Error: ${message}`);
|
|
29
|
+
}
|
|
30
|
+
throw new Error(message);
|
|
31
|
+
}
|
|
32
|
+
if (!hasPublicKeyInConfig) {
|
|
33
|
+
if (!silent) {
|
|
34
|
+
if (json)
|
|
35
|
+
emitJsonError({ error: 'missing_public_key' });
|
|
36
|
+
else
|
|
37
|
+
log.warning('Warning: Missing Public Key in config');
|
|
38
|
+
}
|
|
39
|
+
throw new Error('Missing public key in config');
|
|
40
|
+
}
|
|
41
|
+
const keyPath = options.key || baseKeyV2;
|
|
42
|
+
let privateKey = options.keyData || '';
|
|
43
|
+
if (!existsSync(keyPath) && !privateKey) {
|
|
44
|
+
if (!silent) {
|
|
45
|
+
if (json) {
|
|
46
|
+
emitJsonError({ error: 'missing_key' });
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
log.warning(`Cannot find a private key at ${keyPath} or as a keyData option`);
|
|
50
|
+
log.error('Error: Missing key');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
throw new Error('Missing private key');
|
|
54
|
+
}
|
|
55
|
+
else if (existsSync(keyPath)) {
|
|
56
|
+
privateKey = readFileSync(keyPath, 'utf8');
|
|
57
|
+
}
|
|
58
|
+
if (privateKey && !privateKey.startsWith('-----BEGIN RSA PRIVATE KEY-----')) {
|
|
59
|
+
if (!silent) {
|
|
60
|
+
if (json)
|
|
61
|
+
emitJsonError({ error: 'invalid_private_key' });
|
|
62
|
+
else
|
|
63
|
+
log.error('The private key provided is not a valid RSA Private key');
|
|
64
|
+
}
|
|
65
|
+
throw new Error('Invalid private key format');
|
|
66
|
+
}
|
|
67
|
+
const zipFile = readFileSync(zipPath);
|
|
68
|
+
const { sessionKey, ivSessionKey } = generateSessionKey(privateKey);
|
|
69
|
+
const encryptedData = encryptSourceV2(zipFile, sessionKey, ivSessionKey);
|
|
70
|
+
const encodedChecksum = encryptChecksumV2(checksum, privateKey);
|
|
71
|
+
const filenameEncrypted = `${zipPath}_encrypted.zip`;
|
|
72
|
+
writeFileSync(filenameEncrypted, encryptedData);
|
|
73
|
+
if (!silent) {
|
|
74
|
+
if (json) {
|
|
75
|
+
// eslint-disable-next-line no-console
|
|
76
|
+
console.log(JSON.stringify({
|
|
77
|
+
checksum: encodedChecksum,
|
|
78
|
+
filename: filenameEncrypted,
|
|
79
|
+
ivSessionKey,
|
|
80
|
+
}, null, 2));
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
log.success(`Encoded Checksum: ${encodedChecksum}`);
|
|
84
|
+
log.success(`ivSessionKey: ${ivSessionKey}`);
|
|
85
|
+
log.success(`Encrypted zip saved at ${filenameEncrypted}`);
|
|
86
|
+
outro('Done ✅');
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
checksum: encodedChecksum,
|
|
91
|
+
filename: filenameEncrypted,
|
|
92
|
+
ivSessionKey,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
if (!silent) {
|
|
97
|
+
if (options.json)
|
|
98
|
+
emitJsonError(error);
|
|
99
|
+
else
|
|
100
|
+
log.error(`Error encrypting zip file ${formatError(error)}`);
|
|
101
|
+
}
|
|
102
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export async function encryptZipV2(zipPath, checksum, options) {
|
|
106
|
+
await encryptZipV2Internal(zipPath, checksum, options, false);
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=encryptV2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryptV2.js","sourceRoot":"","sources":["../../../src/bundle/encryptV2.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { OptionsBase } from '../utils';
|
|
2
|
+
export declare function listBundle(appId: string, options: OptionsBase, silent?: boolean): Promise<{
|
|
3
|
+
app_id: string;
|
|
4
|
+
checksum: string | null;
|
|
5
|
+
comment: string | null;
|
|
6
|
+
created_at: string | null;
|
|
7
|
+
deleted: boolean;
|
|
8
|
+
external_url: string | null;
|
|
9
|
+
id: number;
|
|
10
|
+
link: string | null;
|
|
11
|
+
manifest: import("../sdk").Database["public"]["CompositeTypes"]["manifest_entry"][] | null;
|
|
12
|
+
min_update_version: string | null;
|
|
13
|
+
name: string;
|
|
14
|
+
native_packages: import("../types/supabase.types").Json[] | null;
|
|
15
|
+
owner_org: string;
|
|
16
|
+
r2_path: string | null;
|
|
17
|
+
session_key: string | null;
|
|
18
|
+
storage_provider: string;
|
|
19
|
+
updated_at: string | null;
|
|
20
|
+
user_id: string | null;
|
|
21
|
+
}[]>;
|
|
22
|
+
//# sourceMappingURL=list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/bundle/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAO3C,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,UAAQ;;;;;;;;;cAuCyQ,mCAAmB,kBAAkB;;;;;;;;;;KADjY"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { intro, log, outro } from '@clack/prompts';
|
|
2
|
+
import { checkAppExistsAndHasPermissionOrgErr } from '../api/app';
|
|
3
|
+
import { checkAlerts } from '../api/update';
|
|
4
|
+
import { displayBundles, getActiveAppVersions } from '../api/versions';
|
|
5
|
+
import { createSupabaseClient, findSavedKey, getAppId, getConfig, OrganizationPerm, verifyUser } from '../utils';
|
|
6
|
+
export async function listBundle(appId, options, silent = false) {
|
|
7
|
+
if (!silent)
|
|
8
|
+
intro('List bundles');
|
|
9
|
+
await checkAlerts();
|
|
10
|
+
options.apikey = options.apikey || findSavedKey();
|
|
11
|
+
const extConfig = await getConfig();
|
|
12
|
+
appId = getAppId(appId, extConfig?.config);
|
|
13
|
+
if (!options.apikey) {
|
|
14
|
+
if (!silent)
|
|
15
|
+
log.error('Missing API key, you need to provide an API key to upload your bundle');
|
|
16
|
+
throw new Error('Missing API key');
|
|
17
|
+
}
|
|
18
|
+
if (!appId) {
|
|
19
|
+
if (!silent)
|
|
20
|
+
log.error('Missing argument, you need to provide a appid, or be in a capacitor project');
|
|
21
|
+
throw new Error('Missing appId');
|
|
22
|
+
}
|
|
23
|
+
const supabase = await createSupabaseClient(options.apikey, options.supaHost, options.supaAnon);
|
|
24
|
+
await verifyUser(supabase, options.apikey, ['write', 'all', 'read', 'upload']);
|
|
25
|
+
await checkAppExistsAndHasPermissionOrgErr(supabase, options.apikey, appId, OrganizationPerm.read, silent);
|
|
26
|
+
if (!silent)
|
|
27
|
+
log.info(`Querying available versions of: ${appId} in Capgo`);
|
|
28
|
+
const allVersions = await getActiveAppVersions(supabase, appId);
|
|
29
|
+
if (!silent) {
|
|
30
|
+
log.info(`Active versions in Capgo: ${allVersions?.length ?? 0}`);
|
|
31
|
+
displayBundles(allVersions);
|
|
32
|
+
outro('Done ✅');
|
|
33
|
+
}
|
|
34
|
+
return allVersions;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/bundle/list.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAAE,oCAAoC,EAAE,MAAM,YAAY,CAAA;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AACtE,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAEhH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAa,EAAE,OAAoB,EAAE,MAAM,GAAG,KAAK;IAClF,IAAI,CAAC,MAAM;QACT,KAAK,CAAC,cAAc,CAAC,CAAA;IAEvB,MAAM,WAAW,EAAE,CAAA;IACnB,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,YAAY,EAAE,CAAA;IACjD,MAAM,SAAS,GAAG,MAAM,SAAS,EAAE,CAAA;IACnC,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,CAAA;IAE1C,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACpB,IAAI,CAAC,MAAM;YACT,GAAG,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAA;QACpF,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACpC,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,CAAC,MAAM;YACT,GAAG,CAAC,KAAK,CAAC,6EAA6E,CAAC,CAAA;QAC1F,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAA;IAClC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IAE/F,MAAM,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAA;IAC9E,MAAM,oCAAoC,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IAE1G,IAAI,CAAC,MAAM;QACT,GAAG,CAAC,IAAI,CAAC,mCAAmC,KAAK,WAAW,CAAC,CAAA;IAE/D,MAAM,WAAW,GAAG,MAAM,oBAAoB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;IAE/D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,GAAG,CAAC,IAAI,CAAC,6BAA6B,WAAW,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC,CAAA;QACjE,cAAc,CAAC,WAAW,CAAC,CAAA;QAC3B,KAAK,CAAC,QAAQ,CAAC,CAAA;IACjB,CAAC;IAED,OAAO,WAAW,CAAA;AACpB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { manifestType } from '../utils';
|
|
2
|
+
import type { OptionsUpload } from './upload_interface';
|
|
3
|
+
import { Buffer } from 'node:buffer';
|
|
4
|
+
export declare function prepareBundlePartialFiles(path: string, apikey: string, orgId: string, appid: string, encryptionMethod: 'none' | 'v2' | 'v1', finalKeyData: string): Promise<{
|
|
5
|
+
file: string;
|
|
6
|
+
hash: string;
|
|
7
|
+
}[]>;
|
|
8
|
+
interface PartialEncryptionOptions {
|
|
9
|
+
sessionKey: Buffer;
|
|
10
|
+
ivSessionKey: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function uploadPartial(apikey: string, manifest: manifestType, path: string, appId: string, bundleName: string, orgId: string, encryptionOptions: PartialEncryptionOptions | undefined, options: OptionsUpload): Promise<any[] | null>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=partial.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"partial.d.ts","sourceRoot":"","sources":["../../../src/bundle/partial.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAyKpC,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,EACtC,YAAY,EAAE,MAAM;;;KA0BrB;AAoBD,UAAU,wBAAwB;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,iBAAiB,EAAE,wBAAwB,GAAG,SAAS,EACvD,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CA4KvB"}
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
import { createReadStream, statSync } from 'node:fs';
|
|
3
|
+
import { platform as osPlatform } from 'node:os';
|
|
4
|
+
import { join, posix, win32 } from 'node:path';
|
|
5
|
+
import { cwd } from 'node:process';
|
|
6
|
+
import { buffer as readBuffer } from 'node:stream/consumers';
|
|
7
|
+
import { createBrotliCompress } from 'node:zlib';
|
|
8
|
+
import { log, spinner as spinnerC } from '@clack/prompts';
|
|
9
|
+
import * as brotli from 'brotli';
|
|
10
|
+
// @ts-expect-error - No type definitions available for micromatch
|
|
11
|
+
import * as micromatch from 'micromatch';
|
|
12
|
+
import coerceVersion from 'semver/functions/coerce';
|
|
13
|
+
import semverGte from 'semver/functions/gte';
|
|
14
|
+
import semverSatisfies from 'semver/functions/satisfies';
|
|
15
|
+
import * as tus from 'tus-js-client';
|
|
16
|
+
import { encryptChecksumV2, encryptSourceV2 } from '../api/cryptoV2';
|
|
17
|
+
import { findRoot, generateManifest, getAllPackagesDependencies, getLocalConfig, PACKNAME, sendEvent } from '../utils';
|
|
18
|
+
// Check if file already exists on server
|
|
19
|
+
async function fileExists(localConfig, filename) {
|
|
20
|
+
try {
|
|
21
|
+
const response = await fetch(`${localConfig.hostFilesApi}/files/read/attachments/${encodeURIComponent(filename)}`, {
|
|
22
|
+
method: 'HEAD',
|
|
23
|
+
});
|
|
24
|
+
return response.ok;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Threshold for small files where Node.js might skip compression (in bytes)
|
|
31
|
+
const SMALL_FILE_THRESHOLD = 4096;
|
|
32
|
+
// Minimum size for Brotli compression according to RFC
|
|
33
|
+
// Files smaller than this won't be compressed with Brotli
|
|
34
|
+
const BROTLI_MIN_SIZE = 8192;
|
|
35
|
+
// Version required for Brotli support with .br extension
|
|
36
|
+
const BROTLI_MIN_UPDATER_VERSION = '7.0.37';
|
|
37
|
+
// Precomputed minimal Brotli stream for an empty file, compatible with iOS and Android
|
|
38
|
+
const EMPTY_BROTLI_STREAM = Buffer.from([0x1B, 0x00, 0x06]); // Header + final empty block
|
|
39
|
+
// Check if the updater version supports .br extension
|
|
40
|
+
async function getUpdaterVersion(uploadOptions) {
|
|
41
|
+
const root = join(findRoot(cwd()), PACKNAME);
|
|
42
|
+
const dependencies = await getAllPackagesDependencies(undefined, uploadOptions.packageJson || root);
|
|
43
|
+
const updaterVersion = dependencies.get('@capgo/capacitor-updater');
|
|
44
|
+
const coerced = coerceVersion(updaterVersion);
|
|
45
|
+
if (!updaterVersion || !coerced)
|
|
46
|
+
return { version: null, supportsBrotliV2: false };
|
|
47
|
+
// Brotli is only supported in updater versions >= 7.0.37
|
|
48
|
+
const supportsBrotliV2 = semverGte(coerced.version, BROTLI_MIN_UPDATER_VERSION);
|
|
49
|
+
return { version: coerced.version, supportsBrotliV2 };
|
|
50
|
+
}
|
|
51
|
+
// Check if a file should be excluded from brotli compression
|
|
52
|
+
function shouldExcludeFromBrotli(filePath, noBrotliPatterns) {
|
|
53
|
+
if (!noBrotliPatterns) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
const patterns = noBrotliPatterns.split(',').map(p => p.trim()).filter(p => !!p);
|
|
57
|
+
if (patterns.length === 0) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
return micromatch.isMatch(filePath, patterns);
|
|
61
|
+
}
|
|
62
|
+
// Compress file, ensuring compatibility and no failures
|
|
63
|
+
// Legacy function for backward compatibility (updater < 7.0.37)
|
|
64
|
+
// DO NOT MODIFY THIS FUNCTION to maintain backward compatibility
|
|
65
|
+
async function compressFileLegacy(filePath, uploadOptions) {
|
|
66
|
+
const stats = statSync(filePath);
|
|
67
|
+
const fileSize = stats.size;
|
|
68
|
+
if (fileSize === 0) {
|
|
69
|
+
return EMPTY_BROTLI_STREAM;
|
|
70
|
+
}
|
|
71
|
+
const originalBuffer = await readBuffer(createReadStream(filePath));
|
|
72
|
+
const compressedBuffer = await readBuffer(createReadStream(filePath).pipe(createBrotliCompress({})));
|
|
73
|
+
// For small files or ineffective compression, use brotli library
|
|
74
|
+
if (fileSize < SMALL_FILE_THRESHOLD || compressedBuffer.length >= fileSize - 10) {
|
|
75
|
+
const uncompressedBrotli = brotli.compress(originalBuffer, {
|
|
76
|
+
mode: 0, // Generic mode
|
|
77
|
+
quality: 0, // No compression, just wrap
|
|
78
|
+
});
|
|
79
|
+
if (uncompressedBrotli) {
|
|
80
|
+
return Buffer.from(uncompressedBrotli);
|
|
81
|
+
}
|
|
82
|
+
// Fallback if brotli.compress fails
|
|
83
|
+
// will work only with > 6.14.12 or > 7.0.23
|
|
84
|
+
const root = join(findRoot(cwd()), PACKNAME);
|
|
85
|
+
const dependencies = await getAllPackagesDependencies(undefined, uploadOptions.packageJson || root);
|
|
86
|
+
const updaterVersion = dependencies.get('@capgo/capacitor-updater');
|
|
87
|
+
const coerced = coerceVersion(updaterVersion);
|
|
88
|
+
if (!updaterVersion || !coerced) {
|
|
89
|
+
log.warn(`Cannot find @capgo/capacitor-updater in package.json, please provide the package.json path to the command with --package-json`);
|
|
90
|
+
throw new Error('Updater version not found');
|
|
91
|
+
}
|
|
92
|
+
if (!semverSatisfies(coerced, '>=6.14.12 <7.0.0 || >=7.0.23')) {
|
|
93
|
+
log.warn(`Brotli library failed for ${filePath}, falling back to zlib output or minimal stream, this require updater 6.14.12 for Capacitor 6 or 7.0.23 for Capacitor 7`);
|
|
94
|
+
throw new Error(`To use partial update, you need to upgrade @capgo/capacitor-updater to version >=6.14.12 <7.0.0 or >=7.0.23`);
|
|
95
|
+
}
|
|
96
|
+
if (compressedBuffer.length > 0 && compressedBuffer.length < fileSize + 10) {
|
|
97
|
+
return compressedBuffer; // Use zlib if it produced something reasonable
|
|
98
|
+
}
|
|
99
|
+
// Last resort: minimal manual stream (shouldn't reach here often)
|
|
100
|
+
return Buffer.from([0x1B, 0x00, 0x06, ...originalBuffer, 0x03]);
|
|
101
|
+
}
|
|
102
|
+
return compressedBuffer;
|
|
103
|
+
}
|
|
104
|
+
// Function to determine if a file should use Brotli compression (for version >= 7.0.37)
|
|
105
|
+
async function shouldUseBrotli(filePath, filePathUnix, options) {
|
|
106
|
+
const stats = statSync(filePath);
|
|
107
|
+
const fileSize = stats.size;
|
|
108
|
+
const originalBuffer = await readBuffer(createReadStream(filePath));
|
|
109
|
+
if (fileSize === 0) {
|
|
110
|
+
// Empty files - just return the original content (which is empty)
|
|
111
|
+
return { buffer: originalBuffer, useBrotli: false };
|
|
112
|
+
}
|
|
113
|
+
// Skip brotli if file matches exclusion patterns
|
|
114
|
+
if (shouldExcludeFromBrotli(filePathUnix, options.noBrotliPatterns)) {
|
|
115
|
+
log.info(`Skipping brotli for excluded file: ${filePathUnix}`);
|
|
116
|
+
// Don't compress excluded files - just return the original content
|
|
117
|
+
return { buffer: originalBuffer, useBrotli: false };
|
|
118
|
+
}
|
|
119
|
+
// Skip brotli for files smaller than RFC minimum size
|
|
120
|
+
if (fileSize < BROTLI_MIN_SIZE) {
|
|
121
|
+
// Don't compress small files - just return the original content
|
|
122
|
+
return { buffer: originalBuffer, useBrotli: false };
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
// Try Brotli compression
|
|
126
|
+
const compressedBuffer = await readBuffer(createReadStream(filePath).pipe(createBrotliCompress({})));
|
|
127
|
+
// If compression isn't effective, don't use Brotli and don't compress
|
|
128
|
+
if (compressedBuffer.length >= fileSize - 10) {
|
|
129
|
+
log.info(`Brotli not effective for ${filePathUnix} (${fileSize} bytes), using original file`);
|
|
130
|
+
return { buffer: originalBuffer, useBrotli: false };
|
|
131
|
+
}
|
|
132
|
+
// Brotli compression worked well
|
|
133
|
+
return { buffer: compressedBuffer, useBrotli: true };
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
log.warn(`Brotli compression failed for ${filePath}: ${error}, using original file`);
|
|
137
|
+
return { buffer: originalBuffer, useBrotli: false };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
export async function prepareBundlePartialFiles(path, apikey, orgId, appid, encryptionMethod, finalKeyData) {
|
|
141
|
+
const spinner = spinnerC();
|
|
142
|
+
spinner.start(encryptionMethod !== 'v2' ? 'Generating the update manifest' : 'Generating the update manifest with v2 encryption');
|
|
143
|
+
const manifest = await generateManifest(path);
|
|
144
|
+
if (encryptionMethod === 'v2') {
|
|
145
|
+
for (const file of manifest) {
|
|
146
|
+
file.hash = encryptChecksumV2(file.hash, finalKeyData);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
spinner.stop('Manifest generated successfully');
|
|
150
|
+
await sendEvent(apikey, {
|
|
151
|
+
channel: 'partial-update',
|
|
152
|
+
event: 'Generate manifest',
|
|
153
|
+
icon: '📂',
|
|
154
|
+
user_id: orgId,
|
|
155
|
+
tags: {
|
|
156
|
+
'app-id': appid,
|
|
157
|
+
},
|
|
158
|
+
notify: false,
|
|
159
|
+
});
|
|
160
|
+
return manifest;
|
|
161
|
+
}
|
|
162
|
+
function convertToUnixPath(windowsPath) {
|
|
163
|
+
if (osPlatform() !== 'win32') {
|
|
164
|
+
return windowsPath;
|
|
165
|
+
}
|
|
166
|
+
const normalizedPath = win32.normalize(windowsPath);
|
|
167
|
+
return normalizedPath.split(win32.sep).join(posix.sep);
|
|
168
|
+
}
|
|
169
|
+
// Properly encode path segments while preserving slashes
|
|
170
|
+
function encodePathSegments(path) {
|
|
171
|
+
const result = path.split('/').map(segment => encodeURIComponent(segment)).join('/');
|
|
172
|
+
// if has space print it
|
|
173
|
+
if (path.includes(' ')) {
|
|
174
|
+
log.warn(`File "${path}" contains spaces in its name.`);
|
|
175
|
+
}
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
export async function uploadPartial(apikey, manifest, path, appId, bundleName, orgId, encryptionOptions, options) {
|
|
179
|
+
const spinner = spinnerC();
|
|
180
|
+
spinner.start('Preparing partial update with TUS protocol');
|
|
181
|
+
const startTime = performance.now();
|
|
182
|
+
const localConfig = await getLocalConfig();
|
|
183
|
+
// Check the updater version and Brotli support
|
|
184
|
+
const { version, supportsBrotliV2 } = await getUpdaterVersion(options);
|
|
185
|
+
// Check for incompatible options with older updater versions
|
|
186
|
+
if (!supportsBrotliV2) {
|
|
187
|
+
// Always warn about options that have no effect with older versions
|
|
188
|
+
if (options.disableBrotli) {
|
|
189
|
+
log.warn(`--disable-brotli option has no effect with updater version ${version || 'unknown'} (requires ${BROTLI_MIN_UPDATER_VERSION}+)`);
|
|
190
|
+
}
|
|
191
|
+
if (options.noBrotliPatterns) {
|
|
192
|
+
throw new Error(`--no-brotli-patterns option requires updater version ${BROTLI_MIN_UPDATER_VERSION} or higher, but you have ${version || 'unknown'}`);
|
|
193
|
+
}
|
|
194
|
+
log.info(`Using legacy compression (updater ${version || 'unknown'} < ${BROTLI_MIN_UPDATER_VERSION})`);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
// Only newer versions can use Brotli with .br extension
|
|
198
|
+
if (options.disableBrotli) {
|
|
199
|
+
log.info('Brotli compression disabled by user request');
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
spinner.message(`Using .br extension for compatible files (updater ${version} >= ${BROTLI_MIN_UPDATER_VERSION})`);
|
|
203
|
+
if (options.noBrotliPatterns) {
|
|
204
|
+
log.info(`Files matching patterns (${options.noBrotliPatterns}) will be excluded from brotli compression`);
|
|
205
|
+
}
|
|
206
|
+
log.info(`Files smaller than ${BROTLI_MIN_SIZE} bytes will be excluded from brotli compression (Brotli RFC minimum)`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// Check if any files have spaces in their names
|
|
210
|
+
const filesWithSpaces = manifest.filter(file => file.file.includes(' '));
|
|
211
|
+
if (filesWithSpaces.length > 0) {
|
|
212
|
+
throw new Error(`Files with spaces in their names (${filesWithSpaces.map(f => f.file).join(', ')}). Please rename the files.`);
|
|
213
|
+
}
|
|
214
|
+
let uploadedFiles = 0;
|
|
215
|
+
const totalFiles = manifest.length;
|
|
216
|
+
let brFilesCount = 0;
|
|
217
|
+
try {
|
|
218
|
+
const uploadFiles = manifest.map(async (file) => {
|
|
219
|
+
const finalFilePath = join(path, file.file);
|
|
220
|
+
const filePathUnix = convertToUnixPath(file.file);
|
|
221
|
+
let fileBuffer;
|
|
222
|
+
let isBrotli = false;
|
|
223
|
+
// Version check is the primary decision point - no option to override legacy for older versions
|
|
224
|
+
if (!supportsBrotliV2) {
|
|
225
|
+
// For versions < 7.0.37, ALWAYS use legacy compression
|
|
226
|
+
fileBuffer = await compressFileLegacy(finalFilePath, options);
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
// For versions >= 7.0.37, allow user options
|
|
230
|
+
if (options.disableBrotli) {
|
|
231
|
+
// User explicitly disabled Brotli, don't compress at all
|
|
232
|
+
fileBuffer = await readBuffer(createReadStream(finalFilePath));
|
|
233
|
+
isBrotli = false;
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
// Normal case: use Brotli when appropriate
|
|
237
|
+
const result = await shouldUseBrotli(finalFilePath, filePathUnix, options);
|
|
238
|
+
fileBuffer = result.buffer;
|
|
239
|
+
isBrotli = result.useBrotli;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
let finalBuffer = fileBuffer;
|
|
243
|
+
if (encryptionOptions) {
|
|
244
|
+
finalBuffer = encryptSourceV2(fileBuffer, encryptionOptions.sessionKey, encryptionOptions.ivSessionKey);
|
|
245
|
+
}
|
|
246
|
+
// Determine the upload path (with or without .br extension)
|
|
247
|
+
let uploadPathUnix = filePathUnix;
|
|
248
|
+
// Only add .br extension if file was actually compressed with brotli
|
|
249
|
+
if (isBrotli) {
|
|
250
|
+
uploadPathUnix = `${filePathUnix}.br`;
|
|
251
|
+
brFilesCount++;
|
|
252
|
+
}
|
|
253
|
+
const filePathUnixSafe = encodePathSegments(uploadPathUnix);
|
|
254
|
+
const filename = `orgs/${orgId}/apps/${appId}/delta/${file.hash}_${filePathUnixSafe}`;
|
|
255
|
+
// Check if file already exists
|
|
256
|
+
if (await fileExists(localConfig, filename)) {
|
|
257
|
+
uploadedFiles++;
|
|
258
|
+
return Promise.resolve({
|
|
259
|
+
file_name: filePathUnixSafe,
|
|
260
|
+
s3_path: filename,
|
|
261
|
+
file_hash: file.hash,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
return new Promise((resolve, reject) => {
|
|
265
|
+
const upload = new tus.Upload(finalBuffer, {
|
|
266
|
+
endpoint: `${localConfig.hostFilesApi}/files/upload/attachments/`,
|
|
267
|
+
chunkSize: options.tusChunkSize,
|
|
268
|
+
metadata: {
|
|
269
|
+
filename,
|
|
270
|
+
},
|
|
271
|
+
headers: {
|
|
272
|
+
Authorization: apikey,
|
|
273
|
+
},
|
|
274
|
+
onError(error) {
|
|
275
|
+
log.info(`Failed to upload ${filePathUnix}: ${error}`);
|
|
276
|
+
reject(error);
|
|
277
|
+
},
|
|
278
|
+
onProgress() {
|
|
279
|
+
const percentage = ((uploadedFiles / totalFiles) * 100).toFixed(2);
|
|
280
|
+
spinner.message(`Uploading partial update: ${percentage}%`);
|
|
281
|
+
},
|
|
282
|
+
onSuccess() {
|
|
283
|
+
uploadedFiles++;
|
|
284
|
+
resolve({
|
|
285
|
+
file_name: filePathUnixSafe,
|
|
286
|
+
s3_path: filename,
|
|
287
|
+
file_hash: file.hash,
|
|
288
|
+
});
|
|
289
|
+
},
|
|
290
|
+
});
|
|
291
|
+
upload.start();
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
const results = await Promise.all(uploadFiles);
|
|
295
|
+
const endTime = performance.now();
|
|
296
|
+
const uploadTime = ((endTime - startTime) / 1000).toFixed(2);
|
|
297
|
+
spinner.stop(`Partial update uploaded successfully 💪 in (${uploadTime} seconds)`);
|
|
298
|
+
if (brFilesCount > 0) {
|
|
299
|
+
log.info(`${brFilesCount} of ${totalFiles} files were compressed with brotli and use .br extension`);
|
|
300
|
+
}
|
|
301
|
+
await sendEvent(apikey, {
|
|
302
|
+
channel: 'app',
|
|
303
|
+
event: `App Partial TUS done${brFilesCount > 0 ? ' with .br extension' : ''}`,
|
|
304
|
+
icon: '⏫',
|
|
305
|
+
user_id: orgId,
|
|
306
|
+
tags: {
|
|
307
|
+
'app-id': appId,
|
|
308
|
+
},
|
|
309
|
+
notify: false,
|
|
310
|
+
});
|
|
311
|
+
await sendEvent(apikey, {
|
|
312
|
+
channel: 'performance',
|
|
313
|
+
event: 'Partial upload performance',
|
|
314
|
+
icon: '🚄',
|
|
315
|
+
user_id: orgId,
|
|
316
|
+
tags: {
|
|
317
|
+
'app-id': appId,
|
|
318
|
+
'time': uploadTime,
|
|
319
|
+
},
|
|
320
|
+
notify: false,
|
|
321
|
+
});
|
|
322
|
+
return results;
|
|
323
|
+
}
|
|
324
|
+
catch (error) {
|
|
325
|
+
const endTime = performance.now();
|
|
326
|
+
const uploadTime = ((endTime - startTime) / 1000).toFixed(2);
|
|
327
|
+
spinner.stop(`Failed to upload Partial bundle (after ${uploadTime} seconds)`);
|
|
328
|
+
log.info(`Error uploading partial update: ${error}, This is not a critical error, the bundle has been uploaded without the partial files`);
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
//# sourceMappingURL=partial.js.map
|