react-native-update 10.37.13 → 10.37.16

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 (71) hide show
  1. package/README-CN.md +72 -0
  2. package/README.md +61 -49
  3. package/android/build.gradle +47 -17
  4. package/bunfig.toml +2 -0
  5. package/error.js +1609 -0
  6. package/harmony/har-wrapper/AppScope/app.json5 +8 -0
  7. package/harmony/har-wrapper/build-profile.json5 +35 -0
  8. package/harmony/har-wrapper/hvigor/hvigor-config.json5 +5 -0
  9. package/harmony/har-wrapper/hvigorfile.ts +6 -0
  10. package/harmony/har-wrapper/oh-package.json5 +4 -0
  11. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/.cmake/api/v1/reply/cache-v2-77b153ce45aba0ed28ef.json +1415 -0
  12. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/.cmake/api/v1/reply/cmakeFiles-v1-b65a07793384e0ce3e08.json +809 -0
  13. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/.cmake/api/v1/reply/codemodel-v2-ce0e89410afd8bf3a057.json +60 -0
  14. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/.cmake/api/v1/reply/directory-.-Release-f5ebdc15457944623624.json +14 -0
  15. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/.cmake/api/v1/reply/index-2026-03-16T14-00-08-0134.json +89 -0
  16. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/.cmake/api/v1/reply/target-rnupdate-Release-267153624504c9c3ffdd.json +222 -0
  17. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/.ninja_deps +0 -0
  18. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/.ninja_log +8 -0
  19. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeCache.txt +415 -0
  20. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/3.28.2/CMakeCCompiler.cmake +74 -0
  21. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/3.28.2/CMakeCXXCompiler.cmake +85 -0
  22. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/3.28.2/CMakeDetermineCompilerABI_C.bin +0 -0
  23. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/3.28.2/CMakeDetermineCompilerABI_CXX.bin +0 -0
  24. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/3.28.2/CMakeSystem.cmake +15 -0
  25. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/3.28.2/CompilerIdC/CMakeCCompilerId.c +880 -0
  26. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/3.28.2/CompilerIdC/CMakeCCompilerId.o +0 -0
  27. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/3.28.2/CompilerIdCXX/CMakeCXXCompilerId.cpp +869 -0
  28. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/3.28.2/CompilerIdCXX/CMakeCXXCompilerId.o +0 -0
  29. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/CMakeConfigureLog.yaml +388 -0
  30. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/TargetDirectories.txt +3 -0
  31. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/cmake.check_cache +1 -0
  32. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/rnupdate.dir/__w/react-native-update/react-native-update/android/jni/HDiffPatch/file_for_patch.c.o +0 -0
  33. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/rnupdate.dir/__w/react-native-update/react-native-update/android/jni/HDiffPatch/libHDiffPatch/HPatch/patch.c.o +0 -0
  34. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/rnupdate.dir/__w/react-native-update/react-native-update/android/jni/hpatch.c.o +0 -0
  35. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/rnupdate.dir/__w/react-native-update/react-native-update/android/jni/lzma/C/Lzma2Dec.c.o +0 -0
  36. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/rnupdate.dir/__w/react-native-update/react-native-update/android/jni/lzma/C/LzmaDec.c.o +0 -0
  37. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/rnupdate.dir/pushy.c.o +0 -0
  38. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/CMakeFiles/rules.ninja +64 -0
  39. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/additional_project_files.txt +0 -0
  40. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/build.ninja +206 -0
  41. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/build_file_index.txt +1 -0
  42. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/cmake_install.cmake +54 -0
  43. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/compile_commands.json +38 -0
  44. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/configure_fingerprint.json +1 -0
  45. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/hvigor_native_config.json +1 -0
  46. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/metadata_generation_command.txt +17 -0
  47. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/native_work_dir.txt +1 -0
  48. package/harmony/pushy/.cxx/default/default/release/arm64-v8a/output.log +14 -0
  49. package/harmony/pushy/.cxx/default/default/release/hvigor/arm64-v8a/summary.cmake +0 -0
  50. package/harmony/pushy/BuildProfile.ets +3 -5
  51. package/harmony/pushy/build-profile.json5 +8 -1
  52. package/harmony/pushy/oh-package-lock.json5 +1 -1
  53. package/harmony/pushy/src/main/cpp/CMakeLists.txt +42 -30
  54. package/harmony/pushy/src/main/ets/DownloadTask.ts +145 -106
  55. package/harmony/pushy/src/main/ets/Logger.ts +24 -7
  56. package/harmony/pushy/src/main/ets/PushyFileJSBundleProvider.ets +1 -1
  57. package/harmony/pushy/src/main/ets/PushyTurboModule.ts +9 -73
  58. package/harmony/pushy/src/main/ets/UpdateContext.ts +206 -70
  59. package/harmony/pushy.har +0 -0
  60. package/package.json +9 -6
  61. package/scripts/build-harmony-har.js +427 -0
  62. package/scripts/prepublish.ts +113 -0
  63. package/scripts/read.js +188 -0
  64. package/src/__tests__/core.test.ts +103 -0
  65. package/src/__tests__/setup.ts +37 -0
  66. package/src/__tests__/utils.test.ts +36 -0
  67. package/src/client.ts +17 -10
  68. package/src/core.ts +5 -5
  69. package/src/locales/en.ts +1 -0
  70. package/src/locales/zh.ts +1 -0
  71. package/src/utils.ts +13 -1
@@ -0,0 +1,427 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { spawnSync } = require('child_process');
6
+
7
+ const projectRoot = path.resolve(__dirname, '..');
8
+ const androidJniDir = path.join(projectRoot, 'android', 'jni');
9
+ const harmonyModuleDir = path.join(projectRoot, 'harmony', 'pushy');
10
+ const harmonyBuildDir = path.join(harmonyModuleDir, 'build');
11
+ const harmonyNativeStageDir = path.join(
12
+ harmonyModuleDir,
13
+ 'src',
14
+ 'main',
15
+ 'cpp',
16
+ 'android-generated',
17
+ );
18
+ const harmonyNativeStageJniDir = path.join(harmonyNativeStageDir, 'jni');
19
+ const wrapperProjectDir = path.join(projectRoot, 'harmony', 'har-wrapper');
20
+ const defaultOutputPath = path.join(projectRoot, 'harmony', 'pushy.har');
21
+ const wrapperProjectFiles = [
22
+ 'hvigorfile.ts',
23
+ path.join('hvigor', 'hvigor-config.json5'),
24
+ 'oh-package.json5',
25
+ path.join('AppScope', 'app.json5'),
26
+ 'build-profile.json5',
27
+ ];
28
+
29
+ const args = parseArgs(process.argv.slice(2));
30
+ const buildMode = normalizeBuildMode(
31
+ args['build-mode'] || process.env.HARMONY_BUILD_MODE || 'debug',
32
+ );
33
+ const skipInstall =
34
+ args['skip-install'] || process.env.HARMONY_SKIP_INSTALL === '1';
35
+ const outputDir = args['out-dir']
36
+ ? path.resolve(projectRoot, args['out-dir'])
37
+ : process.env.HARMONY_HAR_OUTPUT_DIR
38
+ ? path.resolve(projectRoot, process.env.HARMONY_HAR_OUTPUT_DIR)
39
+ : null;
40
+ const outputPath = args['out-file']
41
+ ? path.resolve(projectRoot, args['out-file'])
42
+ : process.env.HARMONY_HAR_OUTPUT_PATH
43
+ ? path.resolve(projectRoot, process.env.HARMONY_HAR_OUTPUT_PATH)
44
+ : outputDir
45
+ ? null
46
+ : defaultOutputPath;
47
+
48
+ try {
49
+ main();
50
+ } catch (error) {
51
+ console.error(error instanceof Error ? error.message : String(error));
52
+ process.exit(1);
53
+ }
54
+
55
+ function main() {
56
+ syncHarmonyNativeSources();
57
+ let buildError = null;
58
+
59
+ try {
60
+ buildHar();
61
+ } catch (error) {
62
+ buildError = error;
63
+ }
64
+
65
+ try {
66
+ cleanupHarmonyNativeSources();
67
+ } catch (error) {
68
+ if (!buildError) {
69
+ buildError = error;
70
+ } else {
71
+ console.warn(
72
+ `Warning: failed to clean staged Harmony native sources: ${
73
+ error instanceof Error ? error.message : String(error)
74
+ }`,
75
+ );
76
+ }
77
+ }
78
+
79
+ if (buildError) {
80
+ throw buildError;
81
+ }
82
+ }
83
+
84
+ function buildHar() {
85
+ ensureWrapperProject();
86
+
87
+ const devecoRoots = getDevEcoRoots();
88
+ const hvigorwPath = resolveBinary('hvigorw', [
89
+ process.env.HVIGORW_PATH,
90
+ ...devecoRoots.map((root) =>
91
+ path.join(root, 'tools', 'hvigor', 'bin', 'hvigorw'),
92
+ ),
93
+ ]);
94
+ const ohpmPath = resolveBinary('ohpm', [
95
+ process.env.OHPM_PATH,
96
+ ...devecoRoots.map((root) =>
97
+ path.join(root, 'tools', 'ohpm', 'bin', 'ohpm'),
98
+ ),
99
+ ]);
100
+
101
+ if (!hvigorwPath) {
102
+ fail(
103
+ 'Cannot find hvigorw. Set HVIGORW_PATH or install DevEco Studio.',
104
+ );
105
+ }
106
+
107
+ if (!ohpmPath) {
108
+ fail('Cannot find ohpm. Set OHPM_PATH or install DevEco Studio.');
109
+ }
110
+
111
+ const env = {
112
+ ...process.env,
113
+ };
114
+
115
+ if (!env.DEVECO_SDK_HOME) {
116
+ const devecoSdkHome = findExistingPath(
117
+ devecoRoots.map((root) => path.join(root, 'sdk')),
118
+ );
119
+ if (devecoSdkHome) {
120
+ env.DEVECO_SDK_HOME = devecoSdkHome;
121
+ }
122
+ }
123
+
124
+ if (!env.DEVECO_STUDIO_HOME) {
125
+ const devecoStudioHome = findExistingPath(devecoRoots);
126
+ if (devecoStudioHome) {
127
+ env.DEVECO_STUDIO_HOME = devecoStudioHome;
128
+ }
129
+ }
130
+
131
+ if (!skipInstall) {
132
+ runCommand(ohpmPath, ['install'], {
133
+ cwd: harmonyModuleDir,
134
+ env,
135
+ label: 'Install Harmony dependencies',
136
+ });
137
+
138
+ runCommand(ohpmPath, ['install'], {
139
+ cwd: wrapperProjectDir,
140
+ env,
141
+ label: 'Install wrapper project dependencies',
142
+ });
143
+ }
144
+
145
+ const hvigorArgs = ['assembleHar'];
146
+ if (buildMode !== 'debug') {
147
+ hvigorArgs.push('-p', `buildMode=${buildMode}`);
148
+ }
149
+
150
+ runCommand(hvigorwPath, hvigorArgs, {
151
+ cwd: wrapperProjectDir,
152
+ env,
153
+ label: `Build Harmony HAR (${buildMode})`,
154
+ });
155
+
156
+ const harPath = findNewestHar(harmonyBuildDir);
157
+ if (!harPath) {
158
+ fail(
159
+ `Build finished but no .har artifact was found under ${relativeToProject(
160
+ harmonyBuildDir,
161
+ )}`,
162
+ );
163
+ }
164
+
165
+ let finalPath = harPath;
166
+ if (outputDir || outputPath) {
167
+ finalPath = outputPath || path.join(outputDir, path.basename(harPath));
168
+ fs.mkdirSync(path.dirname(finalPath), { recursive: true });
169
+ fs.copyFileSync(harPath, finalPath);
170
+ }
171
+
172
+ console.log(`HAR package ready: ${finalPath}`);
173
+ }
174
+
175
+ function syncHarmonyNativeSources() {
176
+ ensureFileExists(
177
+ path.join(androidJniDir, 'hpatch.c'),
178
+ `Missing Android native source: ${relativeToProject(
179
+ path.join(androidJniDir, 'hpatch.c'),
180
+ )}`,
181
+ );
182
+ ensureFileExists(
183
+ path.join(androidJniDir, 'hpatch.h'),
184
+ `Missing Android native source: ${relativeToProject(
185
+ path.join(androidJniDir, 'hpatch.h'),
186
+ )}`,
187
+ );
188
+ ensureFileExists(
189
+ path.join(androidJniDir, 'HDiffPatch'),
190
+ `Missing Android native source directory: ${relativeToProject(
191
+ path.join(androidJniDir, 'HDiffPatch'),
192
+ )}`,
193
+ );
194
+ ensureFileExists(
195
+ path.join(androidJniDir, 'lzma', 'C'),
196
+ `Missing Android native source directory: ${relativeToProject(
197
+ path.join(androidJniDir, 'lzma', 'C'),
198
+ )}`,
199
+ );
200
+
201
+ fs.rmSync(harmonyNativeStageDir, { recursive: true, force: true });
202
+ fs.mkdirSync(path.join(harmonyNativeStageJniDir, 'lzma'), {
203
+ recursive: true,
204
+ });
205
+
206
+ copyPath(
207
+ path.join(androidJniDir, 'hpatch.c'),
208
+ path.join(harmonyNativeStageJniDir, 'hpatch.c'),
209
+ );
210
+ copyPath(
211
+ path.join(androidJniDir, 'hpatch.h'),
212
+ path.join(harmonyNativeStageJniDir, 'hpatch.h'),
213
+ );
214
+ copyPath(
215
+ path.join(androidJniDir, 'HDiffPatch'),
216
+ path.join(harmonyNativeStageJniDir, 'HDiffPatch'),
217
+ );
218
+ copyPath(
219
+ path.join(androidJniDir, 'lzma', 'C'),
220
+ path.join(harmonyNativeStageJniDir, 'lzma', 'C'),
221
+ );
222
+ }
223
+
224
+ function cleanupHarmonyNativeSources() {
225
+ fs.rmSync(harmonyNativeStageDir, { recursive: true, force: true });
226
+ }
227
+
228
+ function copyPath(sourcePath, targetPath) {
229
+ const stats = fs.statSync(sourcePath);
230
+ if (stats.isDirectory()) {
231
+ fs.cpSync(sourcePath, targetPath, {
232
+ recursive: true,
233
+ force: true,
234
+ filter: (entry) => path.basename(entry) !== '.git',
235
+ });
236
+ return;
237
+ }
238
+
239
+ fs.mkdirSync(path.dirname(targetPath), { recursive: true });
240
+ fs.copyFileSync(sourcePath, targetPath);
241
+ }
242
+
243
+ function ensureWrapperProject() {
244
+ wrapperProjectFiles.forEach((relativePath) => {
245
+ const fullPath = path.join(wrapperProjectDir, relativePath);
246
+ ensureFileExists(
247
+ fullPath,
248
+ `Missing Harmony wrapper file: ${relativeToProject(fullPath)}`,
249
+ );
250
+ });
251
+ }
252
+
253
+ function parseArgs(argv) {
254
+ const parsed = {};
255
+
256
+ for (let index = 0; index < argv.length; index += 1) {
257
+ const token = argv[index];
258
+ if (!token.startsWith('--')) {
259
+ fail(`Unsupported argument: ${token}`);
260
+ }
261
+
262
+ const keyValue = token.slice(2).split('=');
263
+ const key = keyValue[0];
264
+ const inlineValue = keyValue.length > 1 ? keyValue.slice(1).join('=') : '';
265
+
266
+ if (key === 'skip-install') {
267
+ parsed[key] = true;
268
+ continue;
269
+ }
270
+
271
+ const value = inlineValue || argv[index + 1];
272
+ if (!value || value.startsWith('--')) {
273
+ fail(`Missing value for --${key}`);
274
+ }
275
+
276
+ parsed[key] = value;
277
+ if (!inlineValue) {
278
+ index += 1;
279
+ }
280
+ }
281
+
282
+ return parsed;
283
+ }
284
+
285
+ function normalizeBuildMode(value) {
286
+ const mode = String(value).toLowerCase();
287
+ if (mode === 'debug' || mode === 'release') {
288
+ return mode;
289
+ }
290
+
291
+ fail(`Unsupported build mode: ${value}. Use debug or release.`);
292
+ }
293
+
294
+ function getDevEcoRoots() {
295
+ const roots = new Set();
296
+ const envCandidates = [
297
+ process.env.DEVECO_STUDIO_HOME,
298
+ process.env.DEVECO_SDK_HOME,
299
+ ].filter(Boolean);
300
+
301
+ envCandidates.forEach((candidate) => {
302
+ const normalized = normalizeDevEcoRoot(candidate);
303
+ if (normalized) {
304
+ roots.add(normalized);
305
+ }
306
+ });
307
+
308
+ roots.add('/Applications/DevEco-Studio.app/Contents');
309
+ return Array.from(roots);
310
+ }
311
+
312
+ function normalizeDevEcoRoot(value) {
313
+ const resolved = path.resolve(value);
314
+ const basename = path.basename(resolved);
315
+
316
+ if (basename === 'sdk') {
317
+ return path.dirname(resolved);
318
+ }
319
+
320
+ if (basename === 'Contents') {
321
+ return resolved;
322
+ }
323
+
324
+ if (resolved.endsWith('.app')) {
325
+ return path.join(resolved, 'Contents');
326
+ }
327
+
328
+ if (fs.existsSync(path.join(resolved, 'Contents', 'tools'))) {
329
+ return path.join(resolved, 'Contents');
330
+ }
331
+
332
+ return resolved;
333
+ }
334
+
335
+ function resolveBinary(name, candidates) {
336
+ const explicitPath = findExistingPath(candidates);
337
+ if (explicitPath) {
338
+ return explicitPath;
339
+ }
340
+
341
+ const whichResult = spawnSync('bash', ['-lc', `command -v ${name}`], {
342
+ encoding: 'utf8',
343
+ });
344
+ if (whichResult.status === 0) {
345
+ const resolved = whichResult.stdout.trim();
346
+ if (resolved) {
347
+ return resolved;
348
+ }
349
+ }
350
+
351
+ return null;
352
+ }
353
+
354
+ function findExistingPath(candidates) {
355
+ for (const candidate of candidates) {
356
+ if (candidate && fs.existsSync(candidate)) {
357
+ return candidate;
358
+ }
359
+ }
360
+
361
+ return null;
362
+ }
363
+
364
+ function runCommand(command, commandArgs, options) {
365
+ const { cwd, env, label } = options;
366
+ console.log(`> ${label}`);
367
+ console.log(` ${[command, ...commandArgs].join(' ')}`);
368
+
369
+ const result = spawnSync(command, commandArgs, {
370
+ cwd,
371
+ env,
372
+ stdio: 'inherit',
373
+ });
374
+
375
+ if (result.status !== 0) {
376
+ fail(`${label} failed with exit code ${result.status || 1}.`);
377
+ }
378
+ }
379
+
380
+ function findNewestHar(rootDir) {
381
+ if (!fs.existsSync(rootDir)) {
382
+ return null;
383
+ }
384
+
385
+ let latestFile = null;
386
+ let latestMtime = 0;
387
+ const queue = [rootDir];
388
+
389
+ while (queue.length > 0) {
390
+ const currentDir = queue.pop();
391
+ const entries = fs.readdirSync(currentDir, { withFileTypes: true });
392
+
393
+ for (const entry of entries) {
394
+ const fullPath = path.join(currentDir, entry.name);
395
+ if (entry.isDirectory()) {
396
+ queue.push(fullPath);
397
+ continue;
398
+ }
399
+
400
+ if (!entry.isFile() || !entry.name.endsWith('.har')) {
401
+ continue;
402
+ }
403
+
404
+ const stat = fs.statSync(fullPath);
405
+ if (!latestFile || stat.mtimeMs > latestMtime) {
406
+ latestFile = fullPath;
407
+ latestMtime = stat.mtimeMs;
408
+ }
409
+ }
410
+ }
411
+
412
+ return latestFile;
413
+ }
414
+
415
+ function ensureFileExists(filePath, message) {
416
+ if (!fs.existsSync(filePath)) {
417
+ fail(message);
418
+ }
419
+ }
420
+
421
+ function relativeToProject(filePath) {
422
+ return path.relative(projectRoot, filePath) || '.';
423
+ }
424
+
425
+ function fail(message) {
426
+ throw new Error(message);
427
+ }
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { access, readFile, writeFile } from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import { $ } from 'bun';
6
+
7
+ function normalizeVersion(version: string): string {
8
+ return version.trim().replace(/^refs\/tags\//, '').replace(/^v/, '');
9
+ }
10
+
11
+ function getVersionFromEnvironment(): string | null {
12
+ const candidates = [
13
+ process.env.RELEASE_VERSION,
14
+ process.env.CI_COMMIT_TAG,
15
+ process.env.GITHUB_REF_TYPE === 'tag' ? process.env.GITHUB_REF_NAME : null,
16
+ process.env.GITHUB_REF?.startsWith('refs/tags/')
17
+ ? process.env.GITHUB_REF
18
+ : null,
19
+ ];
20
+
21
+ for (const candidate of candidates) {
22
+ if (candidate?.trim()) {
23
+ return normalizeVersion(candidate);
24
+ }
25
+ }
26
+
27
+ return null;
28
+ }
29
+
30
+ function getShellErrorMessage(error: unknown): string {
31
+ if (
32
+ typeof error === 'object' &&
33
+ error !== null &&
34
+ 'stderr' in error &&
35
+ typeof error.stderr === 'string' &&
36
+ error.stderr.trim()
37
+ ) {
38
+ return error.stderr.trim();
39
+ }
40
+
41
+ if (error instanceof Error && error.message.trim()) {
42
+ return error.message.trim();
43
+ }
44
+
45
+ return 'Unknown git error';
46
+ }
47
+
48
+ async function getVersionFromGit(): Promise<string> {
49
+ try {
50
+ return normalizeVersion(await $`git describe --tags --always`.text());
51
+ } catch (error) {
52
+ const message = getShellErrorMessage(error);
53
+
54
+ if (message.includes('detected dubious ownership')) {
55
+ throw new Error(
56
+ 'Git refused to read repository metadata because this checkout is not marked as safe. Configure safe.directory in CI or provide RELEASE_VERSION/GITHUB_REF_NAME.',
57
+ { cause: error },
58
+ );
59
+ }
60
+
61
+ throw new Error(`Unable to resolve publish version from git: ${message}`, {
62
+ cause: error,
63
+ });
64
+ }
65
+ }
66
+
67
+ async function resolveVersion(): Promise<string> {
68
+ return getVersionFromEnvironment() ?? (await getVersionFromGit());
69
+ }
70
+
71
+ async function modifyPackageJson({
72
+ version,
73
+ }: {
74
+ version: string;
75
+ }): Promise<void> {
76
+ const packageJsonPath = path.join(__dirname, '..', 'package.json');
77
+
78
+ try {
79
+ await access(packageJsonPath);
80
+ } catch {
81
+ throw new Error(`package.json not found at ${packageJsonPath}`);
82
+ }
83
+
84
+ console.log('Reading package.json...');
85
+ const packageJsonContent = await readFile(packageJsonPath, 'utf-8');
86
+ const packageJson = JSON.parse(packageJsonContent);
87
+
88
+ packageJson.version = version;
89
+
90
+ console.log('Writing modified package.json...');
91
+
92
+ await writeFile(
93
+ packageJsonPath,
94
+ JSON.stringify(packageJson, null, 2),
95
+ 'utf-8',
96
+ );
97
+
98
+ console.log('package.json has been modified for publishing');
99
+ }
100
+
101
+ async function main(): Promise<void> {
102
+ try {
103
+ const version = await resolveVersion();
104
+ console.log(`Using publish version ${version}`);
105
+ await modifyPackageJson({ version });
106
+ console.log('✅ Prepublish script completed successfully');
107
+ } catch (error) {
108
+ console.error('❌ Prepublish script failed:', error);
109
+ process.exit(1);
110
+ }
111
+ }
112
+
113
+ main();