react-native-bspatch 1.1.4 → 2.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.
Files changed (89) hide show
  1. package/README.md +22 -32
  2. package/android/src/main/java/vn/reactnativebspatch/BsPatchModule.kt +15 -102
  3. package/android/src/main/java/vn/reactnativebspatch/OtaBundleResolver.kt +21 -1
  4. package/cpp/bsdiff/bspatch.c +1 -0
  5. package/ios/OtaBundleResolver.swift +16 -1
  6. package/ios/RNBsPatch.mm +61 -154
  7. package/lib/commonjs/NativeBsPatch.js.map +1 -1
  8. package/lib/commonjs/index.js +4 -4
  9. package/lib/commonjs/index.js.map +1 -1
  10. package/lib/commonjs/ota/OtaProvider.js +26 -22
  11. package/lib/commonjs/ota/OtaProvider.js.map +1 -1
  12. package/lib/commonjs/ota/otaAssetResolver.js +8 -2
  13. package/lib/commonjs/ota/otaAssetResolver.js.map +1 -1
  14. package/lib/commonjs/ota/otaCore.js +89 -141
  15. package/lib/commonjs/ota/otaCore.js.map +1 -1
  16. package/lib/commonjs/ota/otaLogger.js +0 -2
  17. package/lib/commonjs/ota/otaLogger.js.map +1 -1
  18. package/lib/commonjs/ota/otaMetadata.js +18 -7
  19. package/lib/commonjs/ota/otaMetadata.js.map +1 -1
  20. package/lib/commonjs/ota/storage/GitHubRawStorage.js +3 -1
  21. package/lib/commonjs/ota/storage/GitHubRawStorage.js.map +1 -1
  22. package/lib/commonjs/ota/types.js +1 -10
  23. package/lib/commonjs/ota/types.js.map +1 -1
  24. package/lib/module/NativeBsPatch.js.map +1 -1
  25. package/lib/module/index.js +1 -1
  26. package/lib/module/index.js.map +1 -1
  27. package/lib/module/ota/OtaProvider.js +26 -22
  28. package/lib/module/ota/OtaProvider.js.map +1 -1
  29. package/lib/module/ota/otaAssetResolver.js +8 -2
  30. package/lib/module/ota/otaAssetResolver.js.map +1 -1
  31. package/lib/module/ota/otaCore.js +88 -139
  32. package/lib/module/ota/otaCore.js.map +1 -1
  33. package/lib/module/ota/otaLogger.js +0 -2
  34. package/lib/module/ota/otaLogger.js.map +1 -1
  35. package/lib/module/ota/otaMetadata.js +18 -7
  36. package/lib/module/ota/otaMetadata.js.map +1 -1
  37. package/lib/module/ota/storage/GitHubRawStorage.js +3 -1
  38. package/lib/module/ota/storage/GitHubRawStorage.js.map +1 -1
  39. package/lib/module/ota/types.js +0 -9
  40. package/lib/module/ota/types.js.map +1 -1
  41. package/lib/typescript/NativeBsPatch.d.ts +3 -15
  42. package/lib/typescript/NativeBsPatch.d.ts.map +1 -1
  43. package/lib/typescript/index.d.ts +1 -1
  44. package/lib/typescript/index.d.ts.map +1 -1
  45. package/lib/typescript/ota/OtaProvider.d.ts.map +1 -1
  46. package/lib/typescript/ota/otaAssetResolver.d.ts.map +1 -1
  47. package/lib/typescript/ota/otaCore.d.ts +5 -42
  48. package/lib/typescript/ota/otaCore.d.ts.map +1 -1
  49. package/lib/typescript/ota/otaLogger.d.ts +1 -3
  50. package/lib/typescript/ota/otaLogger.d.ts.map +1 -1
  51. package/lib/typescript/ota/otaMetadata.d.ts +2 -2
  52. package/lib/typescript/ota/otaMetadata.d.ts.map +1 -1
  53. package/lib/typescript/ota/types.d.ts +18 -54
  54. package/lib/typescript/ota/types.d.ts.map +1 -1
  55. package/package.json +3 -6
  56. package/react-native-bspatch.podspec +0 -1
  57. package/src/NativeBsPatch.ts +3 -16
  58. package/src/index.ts +1 -1
  59. package/src/ota/OtaProvider.tsx +24 -23
  60. package/src/ota/otaAssetResolver.ts +5 -2
  61. package/src/ota/otaCore.ts +118 -176
  62. package/src/ota/otaLogger.ts +0 -2
  63. package/src/ota/otaMetadata.ts +18 -8
  64. package/src/ota/storage/GitHubRawStorage.ts +1 -1
  65. package/src/ota/types.ts +18 -57
  66. package/tools/build_ota.sh +117 -183
  67. package/tools/setup_project.js +33 -14
  68. package/tools/update_registry.js +24 -28
  69. package/tools/{upload_ota_custom.sh → upload_ota.sh} +33 -114
  70. package/lib/commonjs/crypto-js.d.js +0 -2
  71. package/lib/commonjs/crypto-js.d.js.map +0 -1
  72. package/lib/commonjs/ota/storage/CustomStorage.js +0 -160
  73. package/lib/commonjs/ota/storage/CustomStorage.js.map +0 -1
  74. package/lib/commonjs/ota/storage/GitHubReleaseStorage.js +0 -99
  75. package/lib/commonjs/ota/storage/GitHubReleaseStorage.js.map +0 -1
  76. package/lib/module/crypto-js.d.js +0 -2
  77. package/lib/module/crypto-js.d.js.map +0 -1
  78. package/lib/module/ota/storage/CustomStorage.js +0 -154
  79. package/lib/module/ota/storage/CustomStorage.js.map +0 -1
  80. package/lib/module/ota/storage/GitHubReleaseStorage.js +0 -93
  81. package/lib/module/ota/storage/GitHubReleaseStorage.js.map +0 -1
  82. package/lib/typescript/ota/storage/CustomStorage.d.ts +0 -12
  83. package/lib/typescript/ota/storage/CustomStorage.d.ts.map +0 -1
  84. package/lib/typescript/ota/storage/GitHubReleaseStorage.d.ts +0 -20
  85. package/lib/typescript/ota/storage/GitHubReleaseStorage.d.ts.map +0 -1
  86. package/src/crypto-js.d.ts +0 -1
  87. package/src/ota/storage/CustomStorage.ts +0 -166
  88. package/src/ota/storage/GitHubReleaseStorage.ts +0 -103
  89. package/tools/bsdiff +0 -0
@@ -1,99 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.GitHubReleaseStorageProvider = void 0;
7
- var _reactNative = require("react-native");
8
- var _reactNativeBlobUtil = _interopRequireDefault(require("react-native-blob-util"));
9
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
- /**
11
- * GitHub Releases Storage Provider
12
- *
13
- * Reads the OTA registry from a GitHub Release asset and resolves download URLs
14
- * directly from the release. Supports both public and token-authenticated repos.
15
- *
16
- * Registry format:
17
- * - Expected at: `https://raw.githubusercontent.com/{owner}/{repo}/{tag}/{registryPath}`
18
- * - Asset download: `https://github.com/{owner}/{repo}/releases/download/{tag}/{filename}`
19
- */
20
-
21
- class GitHubReleaseStorageProvider {
22
- getRawRegistryUrl(config) {
23
- const {
24
- repo,
25
- tag,
26
- registryPath = 'ota_registry.json'
27
- } = config.githubRelease;
28
- return `https://raw.githubusercontent.com/${repo}/${tag}/${registryPath}`;
29
- }
30
- getAssetDownloadUrl(config, filename) {
31
- const {
32
- repo,
33
- tag
34
- } = config.githubRelease;
35
- return `https://github.com/${repo}/releases/download/${tag}/${filename}`;
36
- }
37
- authHeaders(token) {
38
- if (!token) return {};
39
- return {
40
- Authorization: `Bearer ${token}`
41
- };
42
- }
43
- async fetchManifest(config) {
44
- if (!config.githubRelease) return config.bundledPatches || [];
45
- const {
46
- token
47
- } = config.githubRelease;
48
- const url = this.getRawRegistryUrl(config);
49
- try {
50
- const res = await _reactNativeBlobUtil.default.fetch('GET', url, this.authHeaders(token));
51
- if (res.respInfo.status !== 200) {
52
- throw new Error(`Registry fetch failed with status ${res.respInfo.status}`);
53
- }
54
- const registry = typeof res.data === 'string' ? JSON.parse(res.data) : JSON.parse(JSON.stringify(res.data));
55
-
56
- // Support both flat array (legacy) and structured format
57
- if (Array.isArray(registry)) {
58
- return registry.filter(p => !p.platform || p.platform === _reactNative.Platform.OS);
59
- }
60
-
61
- // Structured: apps["1.0.0"].channels["production"].patches[]
62
- if (!config.appVersion) {
63
- throw new Error('[GitHubReleaseStorage] config.appVersion is required to query OTA registry');
64
- }
65
- const appGroup = registry?.apps?.[config.appVersion];
66
- const channelGroup = appGroup?.channels?.[config.githubRelease.repo] // use repo as channel fallback
67
- ?? appGroup?.channels?.production ?? appGroup?.flavors?.production;
68
- if (!channelGroup?.patches?.length) {
69
- return config.bundledPatches || [];
70
- }
71
- return channelGroup.patches.filter(p => !p.platform || p.platform === _reactNative.Platform.OS);
72
- } catch (error) {
73
- console.warn('[GitHubStorage] Manifest fetch error:', error.message);
74
- return config.bundledPatches || [];
75
- }
76
- }
77
- async getUpdateFileUrl(filename, config) {
78
- if (!config.githubRelease) throw new Error('githubRelease config missing');
79
- return this.getAssetDownloadUrl(config, filename);
80
- }
81
- async getAssetUrl(hash, ext, config) {
82
- if (!config.githubRelease) return '';
83
- const {
84
- assetBaseUrl,
85
- tag,
86
- repo
87
- } = config.githubRelease;
88
-
89
- // If a custom CDN/base is provided, use it
90
- if (assetBaseUrl) {
91
- return `${assetBaseUrl}/${hash}.${ext}`;
92
- }
93
-
94
- // Fallback: serve from GitHub raw with optional token
95
- return `https://raw.githubusercontent.com/${repo}/${tag}/assets/${hash}.${ext}`;
96
- }
97
- }
98
- exports.GitHubReleaseStorageProvider = GitHubReleaseStorageProvider;
99
- //# sourceMappingURL=GitHubReleaseStorage.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_reactNative","require","_reactNativeBlobUtil","_interopRequireDefault","e","__esModule","default","GitHubReleaseStorageProvider","getRawRegistryUrl","config","repo","tag","registryPath","githubRelease","getAssetDownloadUrl","filename","authHeaders","token","Authorization","fetchManifest","bundledPatches","url","res","ReactNativeBlobUtil","fetch","respInfo","status","Error","registry","data","JSON","parse","stringify","Array","isArray","filter","p","platform","Platform","OS","appVersion","appGroup","apps","channelGroup","channels","production","flavors","patches","length","error","console","warn","message","getUpdateFileUrl","getAssetUrl","hash","ext","assetBaseUrl","exports"],"sourceRoot":"../../../../src","sources":["ota/storage/GitHubReleaseStorage.ts"],"mappings":"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","ignoreList":[]}
@@ -1,2 +0,0 @@
1
- "use strict";
2
- //# sourceMappingURL=crypto-js.d.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":[],"sourceRoot":"../../src","sources":["crypto-js.d.ts"],"mappings":"","ignoreList":[]}
@@ -1,154 +0,0 @@
1
- "use strict";
2
-
3
- import { Platform } from 'react-native';
4
- import ReactNativeBlobUtil from 'react-native-blob-util';
5
- /** Cache tokens per server endpoint so switching configs invalidates stale tokens. */
6
- const tokenCache = new Map();
7
- /** Cache registry ETag and parsed patches to avoid redownloading unmodified manifests. */
8
- const registryCache = new Map();
9
-
10
- /**
11
- * Implementation for the custom MinIO-based storage server.
12
- */
13
- export class CustomStorageProvider {
14
- getEndpoint(config, key, fallback) {
15
- return config.customServer?.endpoints?.[key] ?? fallback;
16
- }
17
- async getAccessToken(config) {
18
- if (!config.customServer) {
19
- throw new Error('customServer configuration missing');
20
- }
21
- const {
22
- baseUrl,
23
- username,
24
- password
25
- } = config.customServer;
26
- const cacheKey = `${baseUrl}|${username}`;
27
- const now = Date.now();
28
- const cached = tokenCache.get(cacheKey);
29
- if (cached && now < cached.expiresAt - 30000) {
30
- return cached.token;
31
- }
32
- const loginPath = this.getEndpoint(config, 'login', 'public/authen/login');
33
- const loginUrl = baseUrl.endsWith('/') ? `${baseUrl}${loginPath}` : `${baseUrl}/${loginPath}`;
34
- try {
35
- const res = await ReactNativeBlobUtil.fetch('POST', loginUrl, {
36
- 'Content-Type': 'application/json; charset=utf-8'
37
- }, JSON.stringify({
38
- username,
39
- password
40
- }));
41
- const json = JSON.parse(res.data);
42
- const token = json.data?.accessTokenInfo?.accessToken;
43
- if (!token) throw new Error('Login failed: token not found');
44
- tokenCache.set(cacheKey, {
45
- token,
46
- expiresAt: now + 3600000
47
- }); // 1 hour
48
- return token;
49
- } catch (error) {
50
- throw new Error(`Authentication failed: ${error.message}`);
51
- }
52
- }
53
- async fetchManifest(config) {
54
- if (!config.customServer) return config.bundledPatches || [];
55
- const {
56
- baseUrl,
57
- channel,
58
- baseFolder = 'bspatch'
59
- } = config.customServer;
60
- const registryPath = `${baseFolder}/ota_registry.json`;
61
- const regCacheKey = `${baseUrl}|${registryPath}|${config.appVersion}|${channel}`;
62
- const cachedReg = registryCache.get(regCacheKey);
63
- try {
64
- const token = await this.getAccessToken(config);
65
- const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
66
- const genLinkPath = this.getEndpoint(config, 'genDownloadLink', 'api/minio/gen-download-link');
67
- const genLinkUrl = `${normalizedBaseUrl}/${genLinkPath}?pathFile=${encodeURIComponent(registryPath)}`;
68
- const linkRes = await ReactNativeBlobUtil.fetch('GET', genLinkUrl, {
69
- Authorization: `Bearer ${token}`
70
- });
71
- const linkJson = JSON.parse(linkRes.data);
72
- const registryUrl = linkJson.data;
73
- if (!registryUrl) throw new Error('Failed to generate registry download link');
74
- const reqHeaders = {};
75
- if (cachedReg?.etag) {
76
- reqHeaders['If-None-Match'] = cachedReg.etag;
77
- }
78
- const registryRes = await ReactNativeBlobUtil.fetch('GET', registryUrl, reqHeaders);
79
- if (registryRes.respInfo.status === 304 && cachedReg) {
80
- return cachedReg.patches;
81
- }
82
- if (registryRes.respInfo.status !== 200) {
83
- throw new Error(`Registry fetch failed with status ${registryRes.respInfo.status}`);
84
- }
85
- const etag = registryRes.respInfo.headers?.['etag'] || registryRes.respInfo.headers?.['ETag'];
86
- if (!config.appVersion) {
87
- throw new Error('[CustomStorage] config.appVersion is required to query OTA registry');
88
- }
89
- const registry = JSON.parse(registryRes.data);
90
- const appGroup = registry?.apps?.[config.appVersion];
91
- const flavorGroup = appGroup?.flavors?.[channel.toLowerCase()];
92
- if (!flavorGroup || !flavorGroup.patches?.length) {
93
- return config.bundledPatches || [];
94
- }
95
- const matchedPatches = (flavorGroup.patches || []).filter(p => p.platform === Platform.OS);
96
- registryCache.set(regCacheKey, {
97
- etag,
98
- patches: matchedPatches
99
- });
100
- return matchedPatches;
101
- } catch (error) {
102
- console.warn('[CustomStorage] Manifest fetch error:', error.message);
103
- return cachedReg?.patches || config.bundledPatches || [];
104
- }
105
- }
106
- async getUpdateFileUrl(filename, config) {
107
- if (!config.customServer) throw new Error('customServer config missing');
108
- const {
109
- baseUrl,
110
- baseFolder = 'bspatch',
111
- useMinio
112
- } = config.customServer;
113
- const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
114
- const channel = config.customServer.channel.toLowerCase();
115
- const remotePath = `${baseFolder}/${config.appVersion}/${channel}/${filename}`;
116
- if (useMinio) {
117
- const token = await this.getAccessToken(config);
118
- const genLinkPath = this.getEndpoint(config, 'genDownloadLink', 'api/minio/gen-download-link');
119
- const genLinkUrl = `${normalizedBaseUrl}/${genLinkPath}?pathFile=${encodeURIComponent(remotePath)}`;
120
- const res = await ReactNativeBlobUtil.fetch('GET', genLinkUrl, {
121
- Authorization: `Bearer ${token}`
122
- });
123
- const json = JSON.parse(res.data);
124
- if (!json.data) throw new Error(`Failed to generate link for: ${filename}`);
125
- return json.data;
126
- }
127
- const downloadPath = this.getEndpoint(config, 'downloadFile', 'files/downloadStreamFile');
128
- return `${normalizedBaseUrl}/${downloadPath}?filepath=${encodeURIComponent(remotePath)}`;
129
- }
130
- async getAssetUrl(hash, ext, config) {
131
- if (!config.customServer) return '';
132
- const {
133
- baseUrl,
134
- baseFolder = 'bspatch',
135
- useMinio
136
- } = config.customServer;
137
- const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
138
- const filename = `${hash}.${ext}`;
139
- const remotePath = `${baseFolder}/assets/${filename}`;
140
- if (useMinio) {
141
- const token = await this.getAccessToken(config);
142
- const genLinkPath = this.getEndpoint(config, 'genDownloadLink', 'api/minio/gen-download-link');
143
- const genLinkUrl = `${normalizedBaseUrl}/${genLinkPath}?pathFile=${encodeURIComponent(remotePath)}`;
144
- const res = await ReactNativeBlobUtil.fetch('GET', genLinkUrl, {
145
- Authorization: `Bearer ${token}`
146
- });
147
- const json = JSON.parse(res.data);
148
- return json.data || '';
149
- }
150
- const downloadPath = this.getEndpoint(config, 'downloadFile', 'files/downloadStreamFile');
151
- return `${normalizedBaseUrl}/${downloadPath}?filepath=${encodeURIComponent(remotePath)}`;
152
- }
153
- }
154
- //# sourceMappingURL=CustomStorage.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["Platform","ReactNativeBlobUtil","tokenCache","Map","registryCache","CustomStorageProvider","getEndpoint","config","key","fallback","customServer","endpoints","getAccessToken","Error","baseUrl","username","password","cacheKey","now","Date","cached","get","expiresAt","token","loginPath","loginUrl","endsWith","res","fetch","JSON","stringify","json","parse","data","accessTokenInfo","accessToken","set","error","message","fetchManifest","bundledPatches","channel","baseFolder","registryPath","regCacheKey","appVersion","cachedReg","normalizedBaseUrl","slice","genLinkPath","genLinkUrl","encodeURIComponent","linkRes","Authorization","linkJson","registryUrl","reqHeaders","etag","registryRes","respInfo","status","patches","headers","registry","appGroup","apps","flavorGroup","flavors","toLowerCase","length","matchedPatches","filter","p","platform","OS","console","warn","getUpdateFileUrl","filename","useMinio","remotePath","downloadPath","getAssetUrl","hash","ext"],"sourceRoot":"../../../../src","sources":["ota/storage/CustomStorage.ts"],"mappings":"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","ignoreList":[]}
@@ -1,93 +0,0 @@
1
- "use strict";
2
-
3
- /**
4
- * GitHub Releases Storage Provider
5
- *
6
- * Reads the OTA registry from a GitHub Release asset and resolves download URLs
7
- * directly from the release. Supports both public and token-authenticated repos.
8
- *
9
- * Registry format:
10
- * - Expected at: `https://raw.githubusercontent.com/{owner}/{repo}/{tag}/{registryPath}`
11
- * - Asset download: `https://github.com/{owner}/{repo}/releases/download/{tag}/{filename}`
12
- */
13
-
14
- import { Platform } from 'react-native';
15
- import ReactNativeBlobUtil from 'react-native-blob-util';
16
- export class GitHubReleaseStorageProvider {
17
- getRawRegistryUrl(config) {
18
- const {
19
- repo,
20
- tag,
21
- registryPath = 'ota_registry.json'
22
- } = config.githubRelease;
23
- return `https://raw.githubusercontent.com/${repo}/${tag}/${registryPath}`;
24
- }
25
- getAssetDownloadUrl(config, filename) {
26
- const {
27
- repo,
28
- tag
29
- } = config.githubRelease;
30
- return `https://github.com/${repo}/releases/download/${tag}/${filename}`;
31
- }
32
- authHeaders(token) {
33
- if (!token) return {};
34
- return {
35
- Authorization: `Bearer ${token}`
36
- };
37
- }
38
- async fetchManifest(config) {
39
- if (!config.githubRelease) return config.bundledPatches || [];
40
- const {
41
- token
42
- } = config.githubRelease;
43
- const url = this.getRawRegistryUrl(config);
44
- try {
45
- const res = await ReactNativeBlobUtil.fetch('GET', url, this.authHeaders(token));
46
- if (res.respInfo.status !== 200) {
47
- throw new Error(`Registry fetch failed with status ${res.respInfo.status}`);
48
- }
49
- const registry = typeof res.data === 'string' ? JSON.parse(res.data) : JSON.parse(JSON.stringify(res.data));
50
-
51
- // Support both flat array (legacy) and structured format
52
- if (Array.isArray(registry)) {
53
- return registry.filter(p => !p.platform || p.platform === Platform.OS);
54
- }
55
-
56
- // Structured: apps["1.0.0"].channels["production"].patches[]
57
- if (!config.appVersion) {
58
- throw new Error('[GitHubReleaseStorage] config.appVersion is required to query OTA registry');
59
- }
60
- const appGroup = registry?.apps?.[config.appVersion];
61
- const channelGroup = appGroup?.channels?.[config.githubRelease.repo] // use repo as channel fallback
62
- ?? appGroup?.channels?.production ?? appGroup?.flavors?.production;
63
- if (!channelGroup?.patches?.length) {
64
- return config.bundledPatches || [];
65
- }
66
- return channelGroup.patches.filter(p => !p.platform || p.platform === Platform.OS);
67
- } catch (error) {
68
- console.warn('[GitHubStorage] Manifest fetch error:', error.message);
69
- return config.bundledPatches || [];
70
- }
71
- }
72
- async getUpdateFileUrl(filename, config) {
73
- if (!config.githubRelease) throw new Error('githubRelease config missing');
74
- return this.getAssetDownloadUrl(config, filename);
75
- }
76
- async getAssetUrl(hash, ext, config) {
77
- if (!config.githubRelease) return '';
78
- const {
79
- assetBaseUrl,
80
- tag,
81
- repo
82
- } = config.githubRelease;
83
-
84
- // If a custom CDN/base is provided, use it
85
- if (assetBaseUrl) {
86
- return `${assetBaseUrl}/${hash}.${ext}`;
87
- }
88
-
89
- // Fallback: serve from GitHub raw with optional token
90
- return `https://raw.githubusercontent.com/${repo}/${tag}/assets/${hash}.${ext}`;
91
- }
92
- }
93
- //# sourceMappingURL=GitHubReleaseStorage.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["Platform","ReactNativeBlobUtil","GitHubReleaseStorageProvider","getRawRegistryUrl","config","repo","tag","registryPath","githubRelease","getAssetDownloadUrl","filename","authHeaders","token","Authorization","fetchManifest","bundledPatches","url","res","fetch","respInfo","status","Error","registry","data","JSON","parse","stringify","Array","isArray","filter","p","platform","OS","appVersion","appGroup","apps","channelGroup","channels","production","flavors","patches","length","error","console","warn","message","getUpdateFileUrl","getAssetUrl","hash","ext","assetBaseUrl"],"sourceRoot":"../../../../src","sources":["ota/storage/GitHubReleaseStorage.ts"],"mappings":"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","ignoreList":[]}
@@ -1,12 +0,0 @@
1
- import type { OtaPatch, OtaConfig, OtaStorageProvider } from '../types';
2
- /**
3
- * Implementation for the custom MinIO-based storage server.
4
- */
5
- export declare class CustomStorageProvider implements OtaStorageProvider {
6
- private getEndpoint;
7
- private getAccessToken;
8
- fetchManifest(config: OtaConfig): Promise<OtaPatch[]>;
9
- getUpdateFileUrl(filename: string, config: OtaConfig): Promise<string>;
10
- getAssetUrl(hash: string, ext: string, config: OtaConfig): Promise<string>;
11
- }
12
- //# sourceMappingURL=CustomStorage.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"CustomStorage.d.ts","sourceRoot":"","sources":["../../../../src/ota/storage/CustomStorage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAiBxE;;GAEG;AACH,qBAAa,qBAAsB,YAAW,kBAAkB;IAC9D,OAAO,CAAC,WAAW;YAIL,cAAc;IAqCtB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAuDrD,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAwBtE,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;CAsBjF"}
@@ -1,20 +0,0 @@
1
- /**
2
- * GitHub Releases Storage Provider
3
- *
4
- * Reads the OTA registry from a GitHub Release asset and resolves download URLs
5
- * directly from the release. Supports both public and token-authenticated repos.
6
- *
7
- * Registry format:
8
- * - Expected at: `https://raw.githubusercontent.com/{owner}/{repo}/{tag}/{registryPath}`
9
- * - Asset download: `https://github.com/{owner}/{repo}/releases/download/{tag}/{filename}`
10
- */
11
- import type { OtaPatch, OtaConfig, OtaStorageProvider } from '../types';
12
- export declare class GitHubReleaseStorageProvider implements OtaStorageProvider {
13
- private getRawRegistryUrl;
14
- private getAssetDownloadUrl;
15
- private authHeaders;
16
- fetchManifest(config: OtaConfig): Promise<OtaPatch[]>;
17
- getUpdateFileUrl(filename: string, config: OtaConfig): Promise<string>;
18
- getAssetUrl(hash: string, ext: string, config: OtaConfig): Promise<string>;
19
- }
20
- //# sourceMappingURL=GitHubReleaseStorage.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"GitHubReleaseStorage.d.ts","sourceRoot":"","sources":["../../../../src/ota/storage/GitHubReleaseStorage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAExE,qBAAa,4BAA6B,YAAW,kBAAkB;IACnE,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,WAAW;IAKb,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAqDrD,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAKtE,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;CAanF"}
@@ -1 +0,0 @@
1
- declare module 'crypto-js';
@@ -1,166 +0,0 @@
1
- import { Platform } from 'react-native';
2
- import ReactNativeBlobUtil from 'react-native-blob-util';
3
- import type { OtaPatch, OtaConfig, OtaStorageProvider } from '../types';
4
-
5
- interface TokenCache {
6
- token: string;
7
- expiresAt: number;
8
- }
9
-
10
- interface RegistryCache {
11
- etag?: string;
12
- patches: OtaPatch[];
13
- }
14
-
15
- /** Cache tokens per server endpoint so switching configs invalidates stale tokens. */
16
- const tokenCache = new Map<string, TokenCache>();
17
- /** Cache registry ETag and parsed patches to avoid redownloading unmodified manifests. */
18
- const registryCache = new Map<string, RegistryCache>();
19
-
20
- /**
21
- * Implementation for the custom MinIO-based storage server.
22
- */
23
- export class CustomStorageProvider implements OtaStorageProvider {
24
- private getEndpoint(config: OtaConfig, key: 'login' | 'genDownloadLink' | 'downloadFile', fallback: string): string {
25
- return config.customServer?.endpoints?.[key] ?? fallback;
26
- }
27
-
28
- private async getAccessToken(config: OtaConfig): Promise<string> {
29
- if (!config.customServer) {
30
- throw new Error('customServer configuration missing');
31
- }
32
-
33
- const { baseUrl, username, password } = config.customServer;
34
- const cacheKey = `${baseUrl}|${username}`;
35
- const now = Date.now();
36
-
37
- const cached = tokenCache.get(cacheKey);
38
- if (cached && now < cached.expiresAt - 30000) {
39
- return cached.token;
40
- }
41
-
42
- const loginPath = this.getEndpoint(config, 'login', 'public/authen/login');
43
- const loginUrl = baseUrl.endsWith('/') ? `${baseUrl}${loginPath}` : `${baseUrl}/${loginPath}`;
44
-
45
- try {
46
- const res = await ReactNativeBlobUtil.fetch(
47
- 'POST',
48
- loginUrl,
49
- { 'Content-Type': 'application/json; charset=utf-8' },
50
- JSON.stringify({ username, password })
51
- );
52
-
53
- const json = JSON.parse(res.data);
54
- const token = json.data?.accessTokenInfo?.accessToken;
55
-
56
- if (!token) throw new Error('Login failed: token not found');
57
-
58
- tokenCache.set(cacheKey, { token, expiresAt: now + 3600000 }); // 1 hour
59
- return token;
60
- } catch (error) {
61
- throw new Error(`Authentication failed: ${(error as Error).message}`);
62
- }
63
- }
64
-
65
- async fetchManifest(config: OtaConfig): Promise<OtaPatch[]> {
66
- if (!config.customServer) return config.bundledPatches || [];
67
-
68
- const { baseUrl, channel, baseFolder = 'bspatch' } = config.customServer;
69
- const registryPath = `${baseFolder}/ota_registry.json`;
70
- const regCacheKey = `${baseUrl}|${registryPath}|${config.appVersion}|${channel}`;
71
- const cachedReg = registryCache.get(regCacheKey);
72
-
73
- try {
74
- const token = await this.getAccessToken(config);
75
- const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
76
- const genLinkPath = this.getEndpoint(config, 'genDownloadLink', 'api/minio/gen-download-link');
77
- const genLinkUrl = `${normalizedBaseUrl}/${genLinkPath}?pathFile=${encodeURIComponent(registryPath)}`;
78
-
79
- const linkRes = await ReactNativeBlobUtil.fetch('GET', genLinkUrl, {
80
- Authorization: `Bearer ${token}`,
81
- });
82
- const linkJson = JSON.parse(linkRes.data);
83
- const registryUrl = linkJson.data;
84
- if (!registryUrl) throw new Error('Failed to generate registry download link');
85
-
86
- const reqHeaders: Record<string, string> = {};
87
- if (cachedReg?.etag) {
88
- reqHeaders['If-None-Match'] = cachedReg.etag;
89
- }
90
-
91
- const registryRes = await ReactNativeBlobUtil.fetch('GET', registryUrl, reqHeaders);
92
- if (registryRes.respInfo.status === 304 && cachedReg) {
93
- return cachedReg.patches;
94
- }
95
- if (registryRes.respInfo.status !== 200) {
96
- throw new Error(`Registry fetch failed with status ${registryRes.respInfo.status}`);
97
- }
98
-
99
- const etag = registryRes.respInfo.headers?.['etag'] || registryRes.respInfo.headers?.['ETag'];
100
- if (!config.appVersion) {
101
- throw new Error('[CustomStorage] config.appVersion is required to query OTA registry');
102
- }
103
- const registry = JSON.parse(registryRes.data);
104
- const appGroup = registry?.apps?.[config.appVersion];
105
- const flavorGroup = appGroup?.flavors?.[channel.toLowerCase()];
106
-
107
- if (!flavorGroup || !flavorGroup.patches?.length) {
108
- return config.bundledPatches || [];
109
- }
110
-
111
- const matchedPatches = (flavorGroup.patches || []).filter((p: OtaPatch) => p.platform === Platform.OS);
112
- registryCache.set(regCacheKey, { etag, patches: matchedPatches });
113
- return matchedPatches;
114
- } catch (error) {
115
- console.warn('[CustomStorage] Manifest fetch error:', (error as Error).message);
116
- return cachedReg?.patches || config.bundledPatches || [];
117
- }
118
- }
119
-
120
- async getUpdateFileUrl(filename: string, config: OtaConfig): Promise<string> {
121
- if (!config.customServer) throw new Error('customServer config missing');
122
-
123
- const { baseUrl, baseFolder = 'bspatch', useMinio } = config.customServer;
124
- const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
125
- const channel = config.customServer.channel.toLowerCase();
126
- const remotePath = `${baseFolder}/${config.appVersion}/${channel}/${filename}`;
127
-
128
- if (useMinio) {
129
- const token = await this.getAccessToken(config);
130
- const genLinkPath = this.getEndpoint(config, 'genDownloadLink', 'api/minio/gen-download-link');
131
- const genLinkUrl = `${normalizedBaseUrl}/${genLinkPath}?pathFile=${encodeURIComponent(remotePath)}`;
132
- const res = await ReactNativeBlobUtil.fetch('GET', genLinkUrl, {
133
- Authorization: `Bearer ${token}`,
134
- });
135
- const json = JSON.parse(res.data);
136
- if (!json.data) throw new Error(`Failed to generate link for: ${filename}`);
137
- return json.data;
138
- }
139
-
140
- const downloadPath = this.getEndpoint(config, 'downloadFile', 'files/downloadStreamFile');
141
- return `${normalizedBaseUrl}/${downloadPath}?filepath=${encodeURIComponent(remotePath)}`;
142
- }
143
-
144
- async getAssetUrl(hash: string, ext: string, config: OtaConfig): Promise<string> {
145
- if (!config.customServer) return '';
146
-
147
- const { baseUrl, baseFolder = 'bspatch', useMinio } = config.customServer;
148
- const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
149
- const filename = `${hash}.${ext}`;
150
- const remotePath = `${baseFolder}/assets/${filename}`;
151
-
152
- if (useMinio) {
153
- const token = await this.getAccessToken(config);
154
- const genLinkPath = this.getEndpoint(config, 'genDownloadLink', 'api/minio/gen-download-link');
155
- const genLinkUrl = `${normalizedBaseUrl}/${genLinkPath}?pathFile=${encodeURIComponent(remotePath)}`;
156
- const res = await ReactNativeBlobUtil.fetch('GET', genLinkUrl, {
157
- Authorization: `Bearer ${token}`,
158
- });
159
- const json = JSON.parse(res.data);
160
- return json.data || '';
161
- }
162
-
163
- const downloadPath = this.getEndpoint(config, 'downloadFile', 'files/downloadStreamFile');
164
- return `${normalizedBaseUrl}/${downloadPath}?filepath=${encodeURIComponent(remotePath)}`;
165
- }
166
- }