diff --git a/package.json b/package.json index 8cb86557..78a8cc2f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@adobe/aio-lib-runtime", - "version": "7.4.2", + "version": "7.5.0", "license": "Apache-2.0", "main": "src/index.js", "bugs": { @@ -14,7 +14,7 @@ "@adobe/aio-lib-core-logging": "^3", "@adobe/aio-lib-core-networking": "^5", "@adobe/aio-lib-env": "^3.0.0", - "archiver": "^7.0.1", + "archiver": "^8.0.0", "dependency-tree": "^11.0.1", "execa": "^4.0.3", "folder-hash": "^4.0.4", @@ -39,6 +39,7 @@ "@types/node-fetch": "^2.5.4", "babel-runtime": "^6.26.0", "codecov": "^3.5.0", + "cross-env": "^7.0.3", "dotenv": "^16.3.1", "eol": "^0.9.1", "eslint": "^8.57.1", @@ -70,7 +71,7 @@ "beautify": "eslint src test e2e --fix", "test": "npm run unit-tests && npm run lint", "typings": "jsdoc -t node_modules/tsd-jsdoc/dist -r src -d .", - "unit-tests": "jest --ci", + "unit-tests": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --ci", "version": "npm run generate-docs && git add README.md" } } diff --git a/src/utils.js b/src/utils.js index 04e947f2..6c0cdea0 100644 --- a/src/utils.js +++ b/src/utils.js @@ -18,7 +18,7 @@ const yaml = require('js-yaml') const { createFetch } = require('@adobe/aio-lib-core-networking') const globby = require('globby') const path = require('path') -const archiver = require('archiver') +// archiver 8 is ESM-only and exposes a class API; load it lazily via dynamic import from this CommonJS module // this is a static list that comes from here: https://developer.adobe.com/runtime/docs/guides/reference/runtimes/ const SupportedRuntimes = ['sequence', 'blackbox', 'nodejs:10', 'nodejs:12', 'nodejs:14', 'nodejs:16', 'nodejs:18', 'nodejs:20', 'nodejs:22', 'nodejs:24', 'nodejs:26'] const { HttpProxyAgent } = require('http-proxy-agent') @@ -451,8 +451,9 @@ function getActionEntryFile (pkgJsonPath) { * @param {boolean} pathInZip internal path in zip * @returns {Promise} returns with a blank promise when done */ -function zip (filePath, out, pathInZip = false) { +async function zip (filePath, out, pathInZip = false) { aioLogger.debug(`Creating zip of file/folder ${filePath}`) + const { ZipArchive } = await import('archiver') // eslint-disable-line node/no-unsupported-features/es-syntax return new Promise((resolve, reject) => { let stats @@ -463,7 +464,7 @@ function zip (filePath, out, pathInZip = false) { } const stream = fs.createWriteStream(out) - const archive = archiver('zip', { zlib: { level: 9 } }) + const archive = new ZipArchive({ zlib: { level: 9 } }) stream.on('close', () => resolve()) archive.pipe(stream) archive.on('error', err => reject(err)) diff --git a/test/__mocks__/archiver.js b/test/__mocks__/archiver.js index b916cdd6..e654521a 100644 --- a/test/__mocks__/archiver.js +++ b/test/__mocks__/archiver.js @@ -28,20 +28,25 @@ const mockArchive = () => { return ret } -const archiver = function (...args) { - mockConstructor(args) - return mockArchive() +// archiver 8 exposes a class API (`new ZipArchive(options)`); mock it as a class whose +// constructor returns the fake archive stream, preserving the previous mock behavior. +class ZipArchive { + constructor (...args) { + mockConstructor(args) + return mockArchive() + } } -archiver.mockFile = mockFile -archiver.mockDirectory = mockDirectory -archiver.mockConstructor = mockConstructor -archiver.setFakeError = function (e) { fakeError = e } -archiver.mockReset = () => { - mockConstructor.mockReset() - mockDirectory.mockReset() - mockFile.mockReset() - fakeError = false +module.exports = { + ZipArchive, + mockFile, + mockDirectory, + mockConstructor, + setFakeError: function (e) { fakeError = e }, + mockReset: () => { + mockConstructor.mockReset() + mockDirectory.mockReset() + mockFile.mockReset() + fakeError = false + } } - -module.exports = archiver diff --git a/test/utils.test.js b/test/utils.test.js index 6be08f33..8143407f 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -14,13 +14,13 @@ const fs = require('fs-extra') const cloneDeep = require('lodash.clonedeep') const os = require('os') const path = require('path') -const archiver = require('archiver') +const archiver = require('./__mocks__/archiver') // eslint-disable-line jest/no-mocks-import const networking = require('@adobe/aio-lib-core-networking') const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-lib-runtime:utils', { provider: 'debug', level: process.env.LOG_LEVEL }) networking.createFetch = jest.fn() const mockFetch = jest.fn() networking.createFetch.mockReturnValue(mockFetch) -jest.mock('archiver') +jest.unstable_mockModule('archiver', () => archiver) jest.mock('@adobe/aio-lib-core-networking') jest.mock('globby')