diff --git a/.gitignore b/.gitignore index 0fe487f..66b2180 100644 --- a/.gitignore +++ b/.gitignore @@ -107,4 +107,10 @@ lib/ .DS_Store # react-native-update .update -.pushy \ No newline at end of file +.pushytest-output/ +test-output2/ +bench.ts +bench2.ts +test-output3/ +test-output4/ +bench-node.js diff --git a/bun.lock b/bun.lock index 16f8208..ceb56ae 100644 --- a/bun.lock +++ b/bun.lock @@ -12,7 +12,7 @@ "compare-versions": "^6.1.1", "filesize-parser": "^1.5.1", "form-data": "^4.0.5", - "fs-extra": "8", + "fs-extra": "^11.3.5", "global-dirs": "^4.0.0", "gradle-to-js": "^2.0.1", "i18next": "^26.0.4", @@ -397,7 +397,7 @@ "form-data-encoder": ["form-data-encoder@4.1.0", "", {}, "sha512-G6NsmEW15s0Uw9XnCg+33H3ViYRyiM0hMrMhhqQOR8NFc5GhYrI+6I3u7OTw7b91J2g8rtvMBZJDbcGb2YUniw=="], - "fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], + "fs-extra": ["fs-extra@11.3.5", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg=="], "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], @@ -517,7 +517,7 @@ "isexe": ["isexe@4.0.0", "", {}, "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw=="], - "jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="], + "jsonfile": ["jsonfile@6.2.1", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q=="], "keyv": ["keyv@5.6.0", "", { "dependencies": { "@keyv/serialize": "^1.1.1" } }, "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw=="], @@ -743,7 +743,7 @@ "unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="], - "universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], + "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], "wcwidth": ["wcwidth@1.0.1", "", { "dependencies": { "defaults": "^1.0.3" } }, "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg=="], diff --git a/package.json b/package.json index 73c773d..f10e3c9 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "compare-versions": "^6.1.1", "filesize-parser": "^1.5.1", "form-data": "^4.0.5", - "fs-extra": "8", + "fs-extra": "^11.3.5", "global-dirs": "^4.0.0", "gradle-to-js": "^2.0.1", "i18next": "^26.0.4", diff --git a/src/bundle-runner.ts b/src/bundle-runner.ts index 7096c7f..c1a7902 100644 --- a/src/bundle-runner.ts +++ b/src/bundle-runner.ts @@ -596,11 +596,11 @@ export async function copyDebugidForSentry( fs.removeSync(path.join(outputFolder, `${bundleName}.txt.map`)); } -export function prepareSentryUploadArtifacts( +export async function prepareSentryUploadArtifacts( bundleName: string, outputFolder: string, platform: string, -): SentryUploadArtifacts { +): Promise { const bundlePath = path.join(outputFolder, bundleName); const sourcemapPath = path.join(outputFolder, `${bundleName}.map`); @@ -616,13 +616,13 @@ export function prepareSentryUploadArtifacts( outputFolder, `${ANDROID_SENTRY_BUNDLE_NAME}.map`, ); - fs.copyFileSync(bundlePath, androidBundlePath); + await fs.promises.copyFile(bundlePath, androidBundlePath); const sourcemap = JSON.parse( - fs.readFileSync(sourcemapPath, 'utf8'), + await fs.promises.readFile(sourcemapPath, 'utf8'), ) as Record; sourcemap.file = ANDROID_SENTRY_BUNDLE_NAME; - fs.writeFileSync(androidSourcemapPath, JSON.stringify(sourcemap)); + await fs.promises.writeFile(androidSourcemapPath, JSON.stringify(sourcemap)); return { bundlePath: androidBundlePath, @@ -630,12 +630,12 @@ export function prepareSentryUploadArtifacts( }; } -export function readSourcemapDebugId( +export async function readSourcemapDebugId( sourcemapPath: string, -): string | undefined { +): Promise { try { const sourcemap = JSON.parse( - fs.readFileSync(sourcemapPath, 'utf8'), + await fs.promises.readFile(sourcemapPath, 'utf8'), ) as Record; const debugId = sourcemap.debugId ?? sourcemap.debug_id; return typeof debugId === 'string' ? normalizeString(debugId) : undefined; @@ -658,10 +658,10 @@ function resolveSentryReleaseFromValues( }; } -export function resolveSentryUploadMode( +export async function resolveSentryUploadMode( sourcemapPath: string, options: SentryUploadOptions = {}, -): SentryUploadMode { +): Promise { const optionRelease = resolveSentryReleaseFromValues( options.sentryRelease, options.sentryDist, @@ -673,7 +673,7 @@ export function resolveSentryUploadMode( }; } - const debugId = readSourcemapDebugId(sourcemapPath); + const debugId = await readSourcemapDebugId(sourcemapPath); if (debugId) { return { type: 'debug-id', @@ -848,12 +848,15 @@ export async function uploadSourcemapForSentry( return; } - const { bundlePath, sourcemapPath } = prepareSentryUploadArtifacts( + const { bundlePath, sourcemapPath } = await prepareSentryUploadArtifacts( bundleName, outputFolder, platform, ); - const uploadMode = resolveSentryUploadMode(sourcemapPath, sentryOptions); + const uploadMode = await resolveSentryUploadMode( + sourcemapPath, + sentryOptions, + ); const useStandaloneSourcemapsCommand = supportsStandaloneSentrySourcemapsUpload(sentryCliPath); diff --git a/tests/bundle-runner.test.ts b/tests/bundle-runner.test.ts index 480209e..a648960 100644 --- a/tests/bundle-runner.test.ts +++ b/tests/bundle-runner.test.ts @@ -299,32 +299,32 @@ describe('Sentry Debug ID upload mode', () => { } }); - test('reads debugId from source maps', () => { + test('reads debugId from source maps', async () => { const sourcemapPath = path.join(tempRoot, 'index.bundlejs.map'); writeJson(sourcemapPath, { version: 3, debugId: '85314830-023f-4cf1-a267-535f4e37bb17', }); - expect(readSourcemapDebugId(sourcemapPath)).toBe( + expect(await readSourcemapDebugId(sourcemapPath)).toBe( '85314830-023f-4cf1-a267-535f4e37bb17', ); }); - test('prefers Debug ID upload when the source map has a Debug ID', () => { + test('prefers Debug ID upload when the source map has a Debug ID', async () => { const sourcemapPath = path.join(tempRoot, 'index.bundlejs.map'); writeJson(sourcemapPath, { version: 3, debug_id: '85314830-023f-4cf1-a267-535f4e37bb17', }); - expect(resolveSentryUploadMode(sourcemapPath)).toEqual({ + expect(await resolveSentryUploadMode(sourcemapPath)).toEqual({ type: 'debug-id', debugId: '85314830-023f-4cf1-a267-535f4e37bb17', }); }); - test('uses explicit release and dist before Debug ID for legacy self-hosted fallback', () => { + test('uses explicit release and dist before Debug ID for legacy self-hosted fallback', async () => { const sourcemapPath = path.join(tempRoot, 'index.bundlejs.map'); writeJson(sourcemapPath, { version: 3, @@ -332,7 +332,7 @@ describe('Sentry Debug ID upload mode', () => { }); expect( - resolveSentryUploadMode(sourcemapPath, { + await resolveSentryUploadMode(sourcemapPath, { sentryRelease: 'com.example@1.0.0+10+pushy:4.1', sentryDist: 'pushy:4.1', }), @@ -343,14 +343,14 @@ describe('Sentry Debug ID upload mode', () => { }); }); - test('falls back to explicit release and dist when no Debug ID exists', () => { + test('falls back to explicit release and dist when no Debug ID exists', async () => { const sourcemapPath = path.join(tempRoot, 'index.bundlejs.map'); writeJson(sourcemapPath, { version: 3, }); expect( - resolveSentryUploadMode(sourcemapPath, { + await resolveSentryUploadMode(sourcemapPath, { sentryRelease: 'com.example@1.0.0+10+pushy:hash', sentryDist: 'pushy:hash', }), @@ -361,7 +361,7 @@ describe('Sentry Debug ID upload mode', () => { }); }); - test('uses SENTRY_RELEASE and SENTRY_DIST for legacy fallback', () => { + test('uses SENTRY_RELEASE and SENTRY_DIST for legacy fallback', async () => { process.env.SENTRY_RELEASE = 'com.example@1.0.0+10+pushy:hash'; process.env.SENTRY_DIST = 'pushy:hash'; const sourcemapPath = path.join(tempRoot, 'index.bundlejs.map'); @@ -369,20 +369,20 @@ describe('Sentry Debug ID upload mode', () => { version: 3, }); - expect(resolveSentryUploadMode(sourcemapPath)).toEqual({ + expect(await resolveSentryUploadMode(sourcemapPath)).toEqual({ type: 'release', release: 'com.example@1.0.0+10+pushy:hash', dist: 'pushy:hash', }); }); - test('fails loudly when neither Debug ID nor explicit release is available', () => { + test('fails loudly when neither Debug ID nor explicit release is available', async () => { const sourcemapPath = path.join(tempRoot, 'index.bundlejs.map'); writeJson(sourcemapPath, { version: 3, }); - expect(() => resolveSentryUploadMode(sourcemapPath)).toThrow( + await expect(resolveSentryUploadMode(sourcemapPath)).rejects.toThrow( 'Generated source map does not contain a Debug ID', ); }); @@ -401,7 +401,7 @@ describe('prepareSentryUploadArtifacts', () => { } }); - test('aliases Android OTA bundles to the default Android bundle name', () => { + test('aliases Android OTA bundles to the default Android bundle name', async () => { _writeFile(path.join(tempRoot, 'index.bundlejs'), 'bundle'); writeJson(path.join(tempRoot, 'index.bundlejs.map'), { version: 3, @@ -409,7 +409,7 @@ describe('prepareSentryUploadArtifacts', () => { sources: ['src/App.tsx'], }); - const artifacts = prepareSentryUploadArtifacts( + const artifacts = await prepareSentryUploadArtifacts( 'index.bundlejs', tempRoot, 'android', @@ -429,8 +429,8 @@ describe('prepareSentryUploadArtifacts', () => { }); }); - test('keeps non-Android artifacts unchanged', () => { - const artifacts = prepareSentryUploadArtifacts( + test('keeps non-Android artifacts unchanged', async () => { + const artifacts = await prepareSentryUploadArtifacts( 'index.bundlejs', tempRoot, 'ios',