react-native-update 10.53.0 → 10.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/README-CN.md +31 -31
  2. package/README.md +31 -31
  3. package/android/jni/HDiffPatch/.travis.yml +33 -0
  4. package/android/jni/HDiffPatch/builds/xcode/bestParams.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  5. package/android/jni/HDiffPatch/builds/xcode/hdiffz.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  6. package/android/jni/HDiffPatch/builds/xcode/hdiffz.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  7. package/android/jni/HDiffPatch/builds/xcode/hpatchz.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  8. package/android/jni/HDiffPatch/builds/xcode/lz4.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  9. package/android/jni/HDiffPatch/builds/xcode/lzma.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  10. package/android/jni/HDiffPatch/builds/xcode/testHashClash.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  11. package/android/jni/HDiffPatch/builds/xcode/testHashClash.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  12. package/android/jni/HDiffPatch/builds/xcode/unitTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  13. package/android/jni/HDiffPatch/builds/xcode/zstd.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  14. package/android/jni/lzma/DOC/7zC.txt +187 -0
  15. package/android/jni/lzma/DOC/7zFormat.txt +469 -0
  16. package/android/jni/lzma/DOC/Methods.txt +173 -0
  17. package/android/jni/lzma/DOC/installer.txt +166 -0
  18. package/android/jni/lzma/DOC/lzma-history.txt +446 -0
  19. package/android/jni/lzma/DOC/lzma-sdk.txt +357 -0
  20. package/android/jni/lzma/DOC/lzma-specification.txt +1176 -0
  21. package/android/jni/lzma/DOC/lzma.txt +328 -0
  22. package/android/jni/lzma/bin/7zS2.sfx +0 -0
  23. package/android/jni/lzma/bin/7zS2con.sfx +0 -0
  24. package/android/jni/lzma/bin/7zSD.sfx +0 -0
  25. package/android/jni/lzma/bin/7zdec.exe +0 -0
  26. package/android/jni/lzma/bin/7zr.exe +0 -0
  27. package/android/jni/lzma/bin/installer/config.txt +5 -0
  28. package/android/jni/lzma/bin/installer/cr.bat +5 -0
  29. package/android/jni/lzma/bin/lzma.exe +0 -0
  30. package/android/jni/lzma/bin/x64/7zr.exe +0 -0
  31. package/android/lib/arm64-v8a/librnupdate.so +0 -0
  32. package/android/lib/armeabi-v7a/librnupdate.so +0 -0
  33. package/android/lib/x86/librnupdate.so +0 -0
  34. package/android/lib/x86_64/librnupdate.so +0 -0
  35. package/android/src/main/java/cn/reactnative/modules/update/ApkInstaller.java +62 -30
  36. package/android/src/main/java/cn/reactnative/modules/update/ArchiveLimits.java +44 -0
  37. package/android/src/main/java/cn/reactnative/modules/update/DownloadTask.java +124 -40
  38. package/android/src/main/java/cn/reactnative/modules/update/InstallRecord.java +125 -0
  39. package/android/src/main/java/cn/reactnative/modules/update/NativeCheckOrchestrator.java +43 -11
  40. package/android/src/main/java/cn/reactnative/modules/update/NativeUpdateFlow.java +2 -0
  41. package/android/src/main/java/cn/reactnative/modules/update/SafeZipFile.java +90 -0
  42. package/android/src/main/java/cn/reactnative/modules/update/UpdateContext.java +79 -19
  43. package/android/src/main/java/cn/reactnative/modules/update/UpdateFileUtils.java +21 -0
  44. package/android/src/main/java/cn/reactnative/modules/update/UpdateModuleImpl.java +56 -17
  45. package/android/src/main/java/cn/reactnative/modules/update/UpdateModuleSupport.java +1 -0
  46. package/android/src/newarch/cn/reactnative/modules/update/UpdateModule.java +5 -0
  47. package/android/src/oldarch/cn/reactnative/modules/update/UpdateModule.java +5 -0
  48. package/cpp/patch_core/archive_limits.h +38 -0
  49. package/cpp/patch_core/install_record.h +36 -0
  50. package/cpp/update_flow_core/flow_json.h +1 -0
  51. package/cpp/update_flow_core/update_flow_core.cpp +41 -7
  52. package/cpp/update_flow_core/update_flow_core.h +9 -0
  53. package/cpp/update_flow_core/update_flow_jni.cpp +12 -0
  54. package/harmony/pushy/src/main/cpp/PushyTurboModule.cpp +2 -0
  55. package/harmony/pushy/src/main/cpp/pushy.cpp +37 -0
  56. package/harmony/pushy/src/main/ets/ArchiveLimits.ts +83 -0
  57. package/harmony/pushy/src/main/ets/DownloadTask.ts +126 -30
  58. package/harmony/pushy/src/main/ets/InstallRecord.ts +129 -0
  59. package/harmony/pushy/src/main/ets/NativeCheckOrchestrator.ts +24 -2
  60. package/harmony/pushy/src/main/ets/NativePatchCore.ts +5 -0
  61. package/harmony/pushy/src/main/ets/PushyTurboModule.ts +12 -0
  62. package/harmony/pushy/src/main/ets/UpdateContext.ts +78 -15
  63. package/harmony/pushy.har +0 -0
  64. package/ios/RCTPushy/RCTPushy.mm +384 -25
  65. package/ios/RCTPushy/RCTPushyDownloader.mm +32 -0
  66. package/package.json +25 -2
  67. package/src/NativePushy.ts +13 -0
  68. package/src/client.ts +160 -43
  69. package/src/core.ts +17 -3
  70. package/src/error.ts +3 -0
  71. package/src/index.ts +8 -0
  72. package/src/locales/en.ts +3 -0
  73. package/src/locales/zh.ts +2 -0
  74. package/src/metadata.ts +166 -0
  75. package/src/provider.tsx +52 -17
  76. package/src/type.ts +22 -0
  77. package/src/updateFlowCore.ts +95 -4
  78. package/src/utils.ts +31 -19
  79. package/.gitmodules +0 -6
  80. package/BUNDLEHASH_MIGRATION.md +0 -355
  81. package/NATIVE_CHECKUPDATE_DESIGN.md +0 -539
  82. package/NATIVE_CHECK_FOLLOWUPS.md +0 -514
  83. package/android/jni/HDiffPatch/test/_private_searchBestParams.cpp +0 -301
  84. package/android/jni/HDiffPatch/test/hpatchz_test.cpp +0 -292
  85. package/android/jni/HDiffPatch/test/testHashClash.cpp +0 -436
  86. package/android/jni/HDiffPatch/test/unit_test.cpp +0 -417
  87. package/biome.json +0 -59
  88. package/cpp/patch_core/tests/fixtures/rawstored.lzma2label.patch.bin +0 -0
  89. package/cpp/patch_core/tests/fixtures/rawstored.new.bin +0 -0
  90. package/cpp/patch_core/tests/fixtures/rawstored.old.bin +0 -0
  91. package/cpp/patch_core/tests/fixtures/v96.hbc +0 -0
  92. package/cpp/patch_core/tests/fixtures/v96.meta.json +0 -1
  93. package/cpp/patch_core/tests/fixtures/v96.streampatch.bin +0 -0
  94. package/cpp/patch_core/tests/fixtures/v96.t.hbc +0 -0
  95. package/cpp/patch_core/tests/fixtures/v96.tpatch.bin +0 -0
  96. package/cpp/patch_core/tests/fixtures/v96.tstreampatch.bin +0 -0
  97. package/cpp/patch_core/tests/fixtures/v96b.hbc +0 -0
  98. package/cpp/patch_core/tests/fixtures/v98.hbc +0 -0
  99. package/cpp/patch_core/tests/fixtures/v98.t.hbc +0 -0
  100. package/cpp/patch_core/tests/fixtures/v98b.hbc +0 -0
  101. package/cpp/patch_core/tests/fixtures/v98b.t.hbc +0 -0
  102. package/cpp/patch_core/tests/hbc_transform_test.cpp +0 -384
  103. package/cpp/patch_core/tests/patch_core_test.cpp +0 -970
  104. package/cpp/update_flow_core/tests/flow_vectors.json +0 -1401
  105. package/cpp/update_flow_core/tests/update_flow_core_test.cpp +0 -317
  106. package/scripts/check-expo-version.js +0 -92
@@ -1,317 +0,0 @@
1
- // Replays the golden vectors generated by scripts/generate-flow-vectors.ts
2
- // against the C++ port and compares canonical serializations. A mismatch
3
- // means the two implementations of the decision layer disagree — fix the C++
4
- // side (the TS side is the reference) or regenerate stale vectors.
5
- #include <cstdio>
6
- #include <fstream>
7
- #include <sstream>
8
- #include <string>
9
-
10
- #include "../flow_json.h"
11
- #include "../update_flow_core.h"
12
-
13
- using flowjson::Parse;
14
- using flowjson::Stringify;
15
- using flowjson::Value;
16
-
17
- namespace {
18
-
19
- Value Dispatch(const std::string& fn, const Value& args, bool* known) {
20
- *known = true;
21
- if (fn == "murmurhash3_32_gc") {
22
- return Value::Number(updateflow::Murmur3_32(args.At(0).AsString()));
23
- }
24
- if (fn == "isInRollout") {
25
- return Value::Bool(
26
- updateflow::IsInRollout(args.At(0).AsNumber(), args.At(1).AsString()));
27
- }
28
- if (fn == "joinUrls") {
29
- return updateflow::JoinUrls(args.At(0), args.At(1));
30
- }
31
- if (fn == "orderEndpointCandidates") {
32
- return updateflow::OrderEndpointCandidates(args.At(0),
33
- args.At(1).AsNumber());
34
- }
35
- if (fn == "buildCheckRequestBody") {
36
- return updateflow::BuildCheckRequestBody(args.At(0));
37
- }
38
- if (fn == "resolveCheckResult") {
39
- return updateflow::ResolveCheckResult(args.At(0), args.At(1));
40
- }
41
- if (fn == "decideDownload") {
42
- return updateflow::DecideDownload(args.At(0), args.At(1),
43
- args.At(2).Truthy());
44
- }
45
- if (fn == "shouldActivateAfterDownload") {
46
- return Value::Bool(updateflow::ShouldActivateAfterDownload(
47
- args.At(0), args.At(1).AsString()));
48
- }
49
- *known = false;
50
- return Value::Undefined();
51
- }
52
-
53
- // The parser consumes network data (checkUpdate responses); malformed and
54
- // hostile inputs must set ok=false without crashing — this suite runs under
55
- // ASan+UBSan in CI. Valid-but-tricky inputs pin the JS JSON.parse semantics
56
- // the port relies on.
57
- int RunParserRobustness() {
58
- int failures = 0;
59
-
60
- const char* malformed[] = {
61
- "",
62
- "{",
63
- "[1,2",
64
- "\"abc",
65
- "{\"a\":}",
66
- "{\"a\" 1}",
67
- "{\"a\":1,}",
68
- "[1,]",
69
- "tru",
70
- "nul",
71
- "falsy",
72
- "1x",
73
- "1 2",
74
- "- 1",
75
- "01",
76
- "-01",
77
- "1.",
78
- "1e",
79
- "1e+",
80
- "\"\\q\"",
81
- "\"\\u12\"",
82
- "\"\\ud800\\u0041\"", // high surrogate followed by a non-low escape
83
- "{\"a\":1}garbage",
84
- "[}",
85
- "{]",
86
- };
87
- for (const char* input : malformed) {
88
- bool ok = true;
89
- Parse(input, &ok);
90
- if (ok) {
91
- std::fprintf(stderr, "robustness: accepted malformed input: %s\n", input);
92
- failures++;
93
- }
94
- }
95
-
96
- // Nesting: 64 levels parse, 65 are rejected (stack-depth cap).
97
- for (int depth : {64, 65}) {
98
- std::string nested;
99
- for (int i = 0; i < depth; i++) {
100
- nested.push_back('[');
101
- }
102
- for (int i = 0; i < depth; i++) {
103
- nested.push_back(']');
104
- }
105
- bool ok = false;
106
- Parse(nested, &ok);
107
- bool expected = depth <= 64;
108
- if (ok != expected) {
109
- std::fprintf(stderr, "robustness: depth %d parsed=%d, expected %d\n",
110
- depth, ok, expected);
111
- failures++;
112
- }
113
- }
114
- // A deeply nested bomb must fail cleanly, not overflow the stack.
115
- {
116
- std::string bomb(100000, '[');
117
- bool ok = true;
118
- Parse(bomb, &ok);
119
- if (ok) {
120
- std::fprintf(stderr, "robustness: accepted nesting bomb\n");
121
- failures++;
122
- }
123
- }
124
-
125
- // Valid-but-tricky inputs: assert the parsed value via canonical stringify.
126
- const struct {
127
- const char* input;
128
- const char* expected;
129
- } tricky[] = {
130
- // Duplicate keys: first position, last value (JSON.parse semantics).
131
- {"{\"a\":1,\"b\":2,\"a\":3}", "{\"a\":3,\"b\":2}"},
132
- {"\"\\u00e9\"", "\"\xc3\xa9\""}, // BMP escape -> UTF-8
133
- {"\"\\ud83d\\ude00\"", "\"\xf0\x9f\x98\x80\""}, // surrogate pair
134
- {" { \"a\" : [ 1 , true , null ] } ", "{\"a\":[1,true,null]}"},
135
- {"-0.5", "-0.5"},
136
- {"1e2", "100"},
137
- };
138
- for (const auto& t : tricky) {
139
- bool ok = false;
140
- Value v = Parse(t.input, &ok);
141
- std::string actual = Stringify(v);
142
- if (!ok || actual != t.expected) {
143
- std::fprintf(stderr,
144
- "robustness: %s -> ok=%d %s (expected %s)\n", t.input, ok,
145
- actual.c_str(), t.expected);
146
- failures++;
147
- }
148
- }
149
-
150
- return failures;
151
- }
152
-
153
- // HandleCheckResponse is pure composition (no decision logic of its own), so
154
- // it is tested directly here instead of via TS-generated vectors: response
155
- // text in, canonical decision out.
156
- int RunHandleCheckResponse() {
157
- int failures = 0;
158
- Value identity = Value::Object();
159
- identity.Set("packageVersion", Value::String("2.3.4"));
160
- identity.Set("currentVersion", Value::String("cur"));
161
- identity.Set("uuid", Value::String("test1")); // bucket 62
162
- identity.Set("rolledBackVersion", Value::String("bad"));
163
-
164
- const struct {
165
- const char* name;
166
- const char* response;
167
- const char* afterDownload;
168
- const char* expected;
169
- } cases[] = {
170
- {"malformed", "not json{", "none",
171
- "{\"action\":\"none\",\"reason\":\"invalidResponse\"}"},
172
- {"non-object", "[1,2]", "none",
173
- "{\"action\":\"none\",\"reason\":\"invalidResponse\"}"},
174
- {"upToDate", "{\"upToDate\":true}", "none",
175
- "{\"action\":\"none\",\"reason\":\"noUpdate\",\"info\":{\"upToDate\":"
176
- "true}}"},
177
- {"expired",
178
- "{\"expired\":true,\"downloadUrl\":\"https://x/app.apk\"}", "none",
179
- "{\"action\":\"none\",\"reason\":\"noUpdate\",\"info\":{\"expired\":"
180
- "true,\"downloadUrl\":\"https://x/app.apk\"}}"},
181
- {"alreadyCurrent",
182
- "{\"update\":true,\"hash\":\"cur\",\"full\":\"cur.ppk\","
183
- "\"paths\":[\"cdn.x.com\"]}",
184
- "none",
185
- "{\"action\":\"none\",\"reason\":\"noUpdate\",\"info\":{\"upToDate\":"
186
- "true}}"},
187
- {"download",
188
- "{\"update\":true,\"hash\":\"h2\",\"full\":\"h2.ppk\","
189
- "\"paths\":[\"cdn.x.com\"],\"name\":\"v2\"}",
190
- "none",
191
- "{\"action\":\"download\",\"hash\":\"h2\",\"attempts\":[{\"type\":"
192
- "\"full\",\"urls\":[\"https://cdn.x.com/h2.ppk\"]}],\"devNoop\":false,"
193
- "\"activate\":false,"
194
- "\"info\":{\"update\":true,\"hash\":\"h2\",\"full\":\"h2.ppk\","
195
- "\"paths\":[\"cdn.x.com\"],\"name\":\"v2\"}}"},
196
- {"download-silent-strategy",
197
- "{\"update\":true,\"hash\":\"h2\",\"full\":\"h2.ppk\","
198
- "\"paths\":[\"cdn.x.com\"]}",
199
- "setNeedUpdate",
200
- "{\"action\":\"download\",\"hash\":\"h2\",\"attempts\":[{\"type\":"
201
- "\"full\",\"urls\":[\"https://cdn.x.com/h2.ppk\"]}],\"devNoop\":false,"
202
- "\"activate\":true,"
203
- "\"info\":{\"update\":true,\"hash\":\"h2\",\"full\":\"h2.ppk\","
204
- "\"paths\":[\"cdn.x.com\"]}}"},
205
- {"download-forceBoot",
206
- "{\"update\":true,\"hash\":\"h2\",\"full\":\"h2.ppk\","
207
- "\"paths\":[\"cdn.x.com\"],\"config\":{\"forceBoot\":true}}",
208
- "none",
209
- "{\"action\":\"download\",\"hash\":\"h2\",\"attempts\":[{\"type\":"
210
- "\"full\",\"urls\":[\"https://cdn.x.com/h2.ppk\"]}],\"devNoop\":false,"
211
- "\"activate\":true,"
212
- "\"info\":{\"update\":true,\"hash\":\"h2\",\"full\":\"h2.ppk\","
213
- "\"paths\":[\"cdn.x.com\"],\"config\":{\"forceBoot\":true}}}"},
214
- {"rollout-in-forceBoot",
215
- "{\"update\":true,\"hash\":\"root\",\"full\":\"root.ppk\","
216
- "\"paths\":[\"cdn.x.com\"],\"expVersion\":{\"name\":\"g\",\"hash\":"
217
- "\"gray\",\"full\":\"gray.ppk\",\"config\":{\"rollout\":{\"2.3.4\":"
218
- "63},\"forceBoot\":true}}}",
219
- "none",
220
- "{\"action\":\"download\",\"hash\":\"gray\",\"attempts\":[{\"type\":"
221
- "\"full\",\"urls\":[\"https://cdn.x.com/gray.ppk\"]}],\"devNoop\":"
222
- "false,\"activate\":true,"
223
- "\"info\":{\"update\":true,\"name\":\"g\",\"hash\":\"gray\","
224
- "\"full\":\"gray.ppk\",\"config\":{\"rollout\":{\"2.3.4\":63},"
225
- "\"forceBoot\":true},\"paths\":[\"cdn.x.com\"]}}"},
226
- {"rollout-out",
227
- "{\"update\":true,\"hash\":\"root\",\"full\":\"root.ppk\","
228
- "\"paths\":[\"cdn.x.com\"],\"expVersion\":{\"name\":\"g\",\"hash\":"
229
- "\"gray\",\"full\":\"gray.ppk\",\"config\":{\"rollout\":{\"2.3.4\":"
230
- "62}}}}",
231
- "none",
232
- "{\"action\":\"download\",\"hash\":\"root\",\"attempts\":[{\"type\":"
233
- "\"full\",\"urls\":[\"https://cdn.x.com/root.ppk\"]}],\"devNoop\":"
234
- "false,\"activate\":false,\"info\":{\"update\":true,\"hash\":\"root\","
235
- "\"full\":\"root.ppk\",\"paths\":[\"cdn.x.com\"]}}"},
236
- {"rolledBack-wins-over-forceBoot",
237
- "{\"update\":true,\"hash\":\"bad\",\"full\":\"bad.ppk\","
238
- "\"paths\":[\"cdn.x.com\"],\"config\":{\"forceBoot\":true}}",
239
- "none",
240
- "{\"action\":\"none\",\"reason\":\"rolledBack\",\"info\":{\"update\":"
241
- "true,\"hash\":\"bad\",\"full\":\"bad.ppk\",\"paths\":[\"cdn.x.com\"],"
242
- "\"config\":{\"forceBoot\":true}}}"},
243
- };
244
- for (const auto& c : cases) {
245
- Value decision = updateflow::HandleCheckResponse(c.response, identity,
246
- false, c.afterDownload);
247
- std::string actual = Stringify(decision);
248
- if (actual != c.expected) {
249
- std::fprintf(stderr,
250
- "handleCheckResponse %s MISMATCH\n expected: %s\n"
251
- " actual: %s\n",
252
- c.name, c.expected, actual.c_str());
253
- failures++;
254
- }
255
- }
256
- return failures;
257
- }
258
-
259
- } // namespace
260
-
261
- int main(int argc, char* argv[]) {
262
- if (argc < 2) {
263
- std::fprintf(stderr, "usage: %s <flow_vectors.json>\n", argv[0]);
264
- return 2;
265
- }
266
- std::ifstream file(argv[1]);
267
- if (!file) {
268
- std::fprintf(stderr, "cannot open %s\n", argv[1]);
269
- return 2;
270
- }
271
- std::stringstream buffer;
272
- buffer << file.rdbuf();
273
-
274
- bool ok = false;
275
- Value doc = Parse(buffer.str(), &ok);
276
- if (!ok) {
277
- std::fprintf(stderr, "failed to parse %s\n", argv[1]);
278
- return 2;
279
- }
280
-
281
- const Value& cases = doc.Get("cases");
282
- if (!cases.IsArray() || cases.Size() == 0) {
283
- std::fprintf(stderr, "%s must contain a non-empty cases array\n", argv[1]);
284
- return 2;
285
- }
286
- int failures = RunParserRobustness() + RunHandleCheckResponse();
287
- for (size_t i = 0; i < cases.Size(); i++) {
288
- const Value& testCase = cases.At(i);
289
- const std::string& fn = testCase.Get("fn").AsString();
290
- bool known = false;
291
- Value actual = Dispatch(fn, testCase.Get("args"), &known);
292
- if (!known) {
293
- std::fprintf(stderr, "case %zu: unknown fn %s\n", i, fn.c_str());
294
- failures++;
295
- continue;
296
- }
297
- std::string actualStr = Stringify(actual);
298
- std::string expectedStr = Stringify(testCase.Get("expected"));
299
- if (actualStr != expectedStr) {
300
- std::fprintf(stderr,
301
- "case %zu (%s) MISMATCH\n args: %s\n expected: %s\n"
302
- " actual: %s\n",
303
- i, fn.c_str(), Stringify(testCase.Get("args")).c_str(),
304
- expectedStr.c_str(), actualStr.c_str());
305
- failures++;
306
- }
307
- }
308
-
309
- if (failures) {
310
- std::fprintf(stderr, "%d failures (%zu vectors + parser robustness)\n",
311
- failures, cases.Size());
312
- return 1;
313
- }
314
- std::printf("all %zu flow vectors + parser robustness passed\n",
315
- cases.Size());
316
- return 0;
317
- }
@@ -1,92 +0,0 @@
1
- const ownPackageJson = require('../package.json');
2
-
3
- if (process.env.npm_package_name === ownPackageJson.name) {
4
- console.log('Skipping postinstall during local development.');
5
- process.exit(0);
6
- }
7
-
8
- const fs = require('fs');
9
- const path = require('path');
10
-
11
- const projectRoot = path.resolve(__dirname, '..'); // react-native-update module root
12
- const expoConfigPath = path.resolve(projectRoot, 'expo-module.config.json');
13
-
14
- function getExpoMajorVersion() {
15
- let resolvedExpoPackagePath;
16
- try {
17
- // Use require.resolve to find expo's package.json from the host project's perspective
18
- resolvedExpoPackagePath = require.resolve('expo/package.json', {
19
- paths: [path.resolve(projectRoot, '..', '..')],
20
- });
21
- } catch (e) {
22
- console.log(
23
- 'Expo not found in project node_modules (via require.resolve).',
24
- );
25
- return null; // Expo not found or resolvable
26
- }
27
-
28
- // Check if the resolved path actually exists (belt-and-suspenders)
29
- if (!fs.existsSync(resolvedExpoPackagePath)) {
30
- console.log(
31
- `Expo package.json path resolved to ${resolvedExpoPackagePath}, but file does not exist.`,
32
- );
33
- return null;
34
- }
35
-
36
- try {
37
- const packageJson = JSON.parse(
38
- fs.readFileSync(resolvedExpoPackagePath, 'utf8'),
39
- );
40
- const version = packageJson.version;
41
- if (!version) {
42
- console.log('Expo package.json does not contain a version.');
43
- return null; // Version not found
44
- }
45
-
46
- // Extract the first number sequence as the major version
47
- const match = version.match(/\d+/);
48
- if (!match) {
49
- console.log(
50
- `Could not parse major version from Expo version string: ${version}`,
51
- );
52
- return null; // Cannot parse version
53
- }
54
-
55
- return parseInt(match[0], 10);
56
- } catch (error) {
57
- console.error('Error reading or parsing Expo package.json:', error);
58
- return null; // Error during processing
59
- }
60
- }
61
-
62
- function checkAndCleanExpoConfig() {
63
- const majorVersion = getExpoMajorVersion();
64
-
65
- // Condition: Expo not found OR major version is less than 50
66
- if (majorVersion === null || majorVersion < 50) {
67
- if (fs.existsSync(expoConfigPath)) {
68
- try {
69
- fs.unlinkSync(expoConfigPath);
70
- console.log(
71
- `Expo version (${
72
- majorVersion !== null ? majorVersion : 'not found'
73
- }) is < 50 or Expo not found. Deleted ${expoConfigPath}`,
74
- );
75
- } catch (error) {
76
- console.error(`Failed to delete ${expoConfigPath}:`, error);
77
- }
78
- } else {
79
- console.log(
80
- `Expo version (${
81
- majorVersion !== null ? majorVersion : 'not found'
82
- }) is < 50 or Expo not found. ${expoConfigPath} does not exist, no action needed.`,
83
- );
84
- }
85
- } else {
86
- console.log(
87
- `Expo version (${majorVersion}) is >= 50. Kept ${expoConfigPath}`,
88
- );
89
- }
90
- }
91
-
92
- checkAndCleanExpoConfig();