diff --git a/rollup.config.js b/rollup.config.js index ca145fc9..f61c53cc 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -23,13 +23,20 @@ const wasmOptions = { browser: { targetEnv: 'browser', maxFileSize: undefined } // always inlline (our wasm files are small) }; -const getChunkFileName = (chunkInfo, extension) => { - // index files result in chunks named simply 'index', so we rename them to include the package name - if (chunkInfo.name === 'index') { - const packageName = chunkInfo.facadeModuleId.split('/').at(-2); // assume index file is under the root folder - return `${packageName}.${extension}`; +const getChunkFileName = (chunkInfo, extension) => `[name].${extension}`; + +/** + * Dynamically imported modules which expose an index file as entrypoint end up with a chunk named `index` + * by default. We want to preserve the module name instead. + */ +const setManualChunkName = chunkId => { + if (chunkId.includes('seek-bzip')) { + return 'seek-bzip'; + } else if (chunkId.includes('argon2id')) { + return 'argon2id'; + } else { + return undefined; } - return `[name].${extension}`; }; const banner = @@ -50,112 +57,120 @@ const terserOptions = { } }; +const nodeBuild = { + input: 'src/index.js', + external: nodeBuiltinModules.concat(nodeDependencies), + output: [ + { file: 'dist/node/openpgp.cjs', format: 'cjs', name: pkg.name, banner, intro }, + { file: 'dist/node/openpgp.min.cjs', format: 'cjs', name: pkg.name, banner, intro, plugins: [terser(terserOptions)], sourcemap: true }, + { file: 'dist/node/openpgp.mjs', format: 'es', banner, intro }, + { file: 'dist/node/openpgp.min.mjs', format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } + ].map(options => ({ ...options, inlineDynamicImports: true })), + plugins: [ + resolve({ + exportConditions: ['node'] // needed for resolution of noble-curves import of '@noble/crypto' in Node 18 + }), + typescript({ + compilerOptions: { outDir: './dist/tmp-ts' } + }), + commonjs(), + replace({ + 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}` + }), + wasm(wasmOptions.node) + ] +}; + +const fullBrowserBuild = { + input: 'src/index.js', + external: nodeBuiltinModules.concat(nodeDependencies), + output: [ + { file: 'dist/openpgp.js', format: 'iife', name: pkg.name, banner, intro }, + { file: 'dist/openpgp.min.js', format: 'iife', name: pkg.name, banner, intro, plugins: [terser(terserOptions)], sourcemap: true }, + { file: 'dist/openpgp.mjs', format: 'es', banner, intro }, + { file: 'dist/openpgp.min.mjs', format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } + ].map(options => ({ ...options, inlineDynamicImports: true })), + plugins: [ + resolve({ + browser: true + }), + typescript({ + compilerOptions: { outDir: './dist/tmp-ts' } // to avoid js files being overwritten + }), + commonjs({ + ignore: nodeBuiltinModules.concat(nodeDependencies) + }), + replace({ + 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}`, + "import { createRequire } from 'module';": 'const createRequire = () => () => {}', + delimiters: ['', ''] + }), + wasm(wasmOptions.browser) + ] +}; + +const lightweightBrowserBuild = { + input: 'src/index.js', + external: nodeBuiltinModules.concat(nodeDependencies), + output: [ + { entryFileNames: 'openpgp.mjs', chunkFileNames: chunkInfo => getChunkFileName(chunkInfo, 'mjs') }, + { entryFileNames: 'openpgp.min.mjs', chunkFileNames: chunkInfo => getChunkFileName(chunkInfo, 'min.mjs'), plugins: [terser(terserOptions)], sourcemap: true } + ].map(options => ({ ...options, dir: 'dist/lightweight', manualChunks: setManualChunkName, format: 'es', banner, intro })), + preserveEntrySignatures: 'exports-only', + plugins: [ + resolve({ + browser: true + }), + typescript({ + compilerOptions: { outDir: './dist/lightweight/tmp-ts' } + }), + commonjs({ + ignore: nodeBuiltinModules.concat(nodeDependencies) + }), + replace({ + 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}`, + "import { createRequire } from 'module';": 'const createRequire = () => () => {}', + delimiters: ['', ''] + }), + wasm(wasmOptions.browser) + ] +}; + +const testBuild = { + input: 'test/unittests.js', + output: [ + { file: 'test/lib/unittests-bundle.js', format: 'es', intro, sourcemap: true, inlineDynamicImports: true } + ], + external: nodeBuiltinModules.concat(nodeDependencies), + plugins: [ + alias({ + entries: { + openpgp: `./dist/${process.env.npm_config_lightweight ? 'lightweight/' : ''}openpgp.mjs` + } + }), + resolve({ + browser: true + }), + typescript({ + compilerOptions: { outDir: './test/lib/tmp-ts' } + }), + commonjs({ + ignore: nodeBuiltinModules.concat(nodeDependencies), + requireReturnsDefault: 'preferred' + }), + replace({ + "import { createRequire } from 'module';": 'const createRequire = () => () => {}', + delimiters: ['', ''] + }), + wasm(wasmOptions.browser) + ] +}; + export default Object.assign([ - { - input: 'src/index.js', - external: nodeBuiltinModules.concat(nodeDependencies), - output: [ - { file: 'dist/openpgp.js', format: 'iife', name: pkg.name, banner, intro }, - { file: 'dist/openpgp.min.js', format: 'iife', name: pkg.name, banner, intro, plugins: [terser(terserOptions)], sourcemap: true }, - { file: 'dist/openpgp.mjs', format: 'es', banner, intro }, - { file: 'dist/openpgp.min.mjs', format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } - ].map(options => ({ ...options, inlineDynamicImports: true })), - plugins: [ - resolve({ - browser: true - }), - typescript({ - compilerOptions: { outDir: './dist/tmp-ts' } // to avoid js files being overwritten - }), - commonjs({ - ignore: nodeBuiltinModules.concat(nodeDependencies) - }), - replace({ - 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}`, - "import { createRequire } from 'module';": 'const createRequire = () => () => {}', - delimiters: ['', ''] - }), - wasm(wasmOptions.browser) - ] - }, - { - input: 'src/index.js', - external: nodeBuiltinModules.concat(nodeDependencies), - output: [ - { file: 'dist/node/openpgp.cjs', format: 'cjs', name: pkg.name, banner, intro }, - { file: 'dist/node/openpgp.min.cjs', format: 'cjs', name: pkg.name, banner, intro, plugins: [terser(terserOptions)], sourcemap: true }, - { file: 'dist/node/openpgp.mjs', format: 'es', banner, intro }, - { file: 'dist/node/openpgp.min.mjs', format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } - ].map(options => ({ ...options, inlineDynamicImports: true })), - plugins: [ - resolve({ - exportConditions: ['node'] // needed for resolution of noble-curves import of '@noble/crypto' in Node 18 - }), - typescript({ - compilerOptions: { outDir: './dist/tmp-ts' } - }), - commonjs(), - replace({ - 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}` - }), - wasm(wasmOptions.node) - ] - }, - { - input: 'src/index.js', - external: nodeBuiltinModules.concat(nodeDependencies), - output: [ - { dir: 'dist/lightweight', entryFileNames: 'openpgp.mjs', chunkFileNames: chunkInfo => getChunkFileName(chunkInfo, 'mjs'), format: 'es', banner, intro }, - { dir: 'dist/lightweight', entryFileNames: 'openpgp.min.mjs', chunkFileNames: chunkInfo => getChunkFileName(chunkInfo, 'min.mjs'), format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } - ], - preserveEntrySignatures: 'exports-only', - plugins: [ - resolve({ - browser: true - }), - typescript({ - compilerOptions: { outDir: './dist/lightweight/tmp-ts' } - }), - commonjs({ - ignore: nodeBuiltinModules.concat(nodeDependencies) - }), - replace({ - 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}`, - "import { createRequire } from 'module';": 'const createRequire = () => () => {}', - delimiters: ['', ''] - }), - wasm(wasmOptions.browser) - ] - }, - { - input: 'test/unittests.js', - output: [ - { file: 'test/lib/unittests-bundle.js', format: 'es', intro, sourcemap: true, inlineDynamicImports: true } - ], - external: nodeBuiltinModules.concat(nodeDependencies), - plugins: [ - alias({ - entries: { - openpgp: `./dist/${process.env.npm_config_lightweight ? 'lightweight/' : ''}openpgp.mjs` - } - }), - resolve({ - browser: true - }), - typescript({ - compilerOptions: { outDir: './test/lib/tmp-ts' } - }), - commonjs({ - ignore: nodeBuiltinModules.concat(nodeDependencies), - requireReturnsDefault: 'preferred' - }), - replace({ - "import { createRequire } from 'module';": 'const createRequire = () => () => {}', - delimiters: ['', ''] - }), - wasm(wasmOptions.browser) - ] - } + nodeBuild, + fullBrowserBuild, + lightweightBrowserBuild, + testBuild ].filter(config => { config.output = config.output.filter(output => { return (output.file || output.dir + '/' + output.entryFileNames).includes( diff --git a/src/packet/compressed_data.js b/src/packet/compressed_data.js index 9a46cd87..03de3529 100644 --- a/src/packet/compressed_data.js +++ b/src/packet/compressed_data.js @@ -16,7 +16,6 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import { Inflate, Deflate, Zlib, Unzlib } from 'fflate'; -import { decode as BunzipDecode } from '@openpgp/seek-bzip'; import * as stream from '@openpgp/web-stream-tools'; import enums from '../enums'; import util from '../util'; @@ -108,12 +107,12 @@ class CompressedDataPacket { */ async decompress(config = defaultConfig) { const compressionName = enums.read(enums.compression, this.algorithm); - const decompressionFn = decompress_fns[compressionName]; + const decompressionFn = decompress_fns[compressionName]; // bzip decompression is async if (!decompressionFn) { throw new Error(`${compressionName} decompression not supported`); } - this.packets = await PacketList.fromBinary(decompressionFn(this.compressed), allowedPackets, config); + this.packets = await PacketList.fromBinary(await decompressionFn(this.compressed), allowedPackets, config); } /** @@ -202,9 +201,10 @@ function zlib(compressionStreamInstantiator, ZlibStreamedConstructor) { }; } -function bzip2(func) { - return function(data) { - return stream.fromAsync(async () => func(await stream.readToEnd(data))); +function bzip2Decompress() { + return async function(data) { + const { decode: bunzipDecode } = await import('@openpgp/seek-bzip'); + return stream.fromAsync(async () => bunzipDecode(await stream.readToEnd(data))); }; } @@ -229,6 +229,6 @@ const decompress_fns = { uncompressed: data => data, zip: /*#__PURE__*/ zlib(getCompressionStreamInstantiators('deflate-raw').decompressor, Inflate), zlib: /*#__PURE__*/ zlib(getCompressionStreamInstantiators('deflate').decompressor, Unzlib), - bzip2: /*#__PURE__*/ bzip2(BunzipDecode) + bzip2: /*#__PURE__*/ bzip2Decompress() // NB: async due to dynamic lib import };