Socket
Socket
Sign inDemoInstall

@americanexpress/one-app-dev-bundler

Package Overview
Dependencies
Maintainers
9
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@americanexpress/one-app-dev-bundler - npm Package Compare versions

Comparing version 1.5.4 to 1.5.5

__tests__/utils/write-to-module-config.spec.js

3

__tests__/esbuild/generateESBuildOptions.spec.js

@@ -34,4 +34,3 @@ /*

jest.mock('@fal-works/esbuild-plugin-global-externals', () => ({ globalExternals: (...params) => `esbuild_plugin_for(esbuild-plugin-global-externals)(${JSON.stringify(params)})` }));
jest.mock('@esbuild-plugins/node-globals-polyfill', () => ({ NodeGlobalsPolyfillPlugin: (...params) => `esbuild_plugin_for(node-globals-polyfill)(${JSON.stringify(params)})` }));
jest.mock('@esbuild-plugins/node-modules-polyfill', () => ({ NodeModulesPolyfillPlugin: (...params) => `esbuild_plugin_for(node-modules-polyfill)(${JSON.stringify(params)})` }));
jest.mock('esbuild-plugin-polyfill-node', () => ({ polyfillNode: (...params) => `esbuild_plugin_for(polyfill-node)(${JSON.stringify(params)})` }));
jest.mock('esbuild-plugin-svgr', () => (...params) => `esbuild_plugin_for(esbuild-plugin-svgr)(${JSON.stringify(params)})`);

@@ -38,0 +37,0 @@ jest.mock('../../esbuild/plugins/restrict-runtime-symbols.js', () => (...params) => `esbuild_plugin_for(restrict-runtime-symbols)(${JSON.stringify(params)})`);

@@ -24,4 +24,5 @@ /*

readFile: jest.fn(() => 'mockFileContent'),
writeFile: jest.fn(() => 'mockWriteFileResponse'),
},
readFileSync: jest.fn(() => 'mockFileContent'),
writeFileSync: jest.fn(() => 'mockWriteFileResponse'),
}));

@@ -51,3 +52,3 @@

it('should generate a manifest based upon the content of the first file, and write a new file if the loaded manifest cant be parsed', async () => {
expect.assertions(8);
expect.assertions(9);
const plugin = generateIntegrityManifest({ bundleName: 'mockBundleName' });

@@ -59,3 +60,3 @@ const hooks = runSetupAndGetLifeHooks(plugin);

// second read is loading the existing manifest
fs.promises.readFile.mockImplementationOnce(() => '} Mock Bad JSON File');
fs.readFileSync.mockImplementationOnce(() => '} Mock Bad JSON File');

@@ -65,9 +66,10 @@ const mockResult = { metafile: { outputs: { '/path/to/bundle.js': {} } } };

expect(fs.promises.readFile).toHaveBeenCalledTimes(2);
expect(fs.promises.readFile).toHaveBeenCalledTimes(1);
expect(fs.readFileSync).toHaveBeenCalledTimes(1);
expect(fs.promises.readFile).toHaveBeenCalledWith('/path/to/bundle.js', 'utf8');
expect(fs.promises.readFile).toHaveBeenCalledWith('./bundle.integrity.manifest.json', 'utf8');
expect(fs.readFileSync).toHaveBeenCalledWith('./bundle.integrity.manifest.json', 'utf8');
expect(fs.promises.writeFile).toHaveBeenCalledTimes(1);
expect(fs.writeFileSync).toHaveBeenCalledTimes(1);
// first parameter of first call
expect(fs.promises.writeFile.mock.calls[0][0]).toBe('./bundle.integrity.manifest.json');
expect(fs.writeFileSync.mock.calls[0][0]).toBe('./bundle.integrity.manifest.json');
// Snapshot here for the hash. Its hashing the response from the first readFile mock,

@@ -77,3 +79,3 @@ // 'mockModuleFileContent', therefore if the hash below ever changes, its likely to be

// is also changed
expect(fs.promises.writeFile.mock.calls[0][1]).toMatchInlineSnapshot(`
expect(fs.writeFileSync.mock.calls[0][1]).toMatchInlineSnapshot(`
"{

@@ -89,3 +91,3 @@ \\"mockBundleName\\": \\"sha256-dVDfvIfLZ/EauFs99M0kCfTCNSTcAaeR8tIfSmPWMBU= sha384-bkhDhTm0NmB0SvMS9As2gTFJ86GfZIOyXBPzQPCTmtoDXvQTaTrNqe6skXgbJNT7\\"

it('should generate a manifest based upon the content of the first file, and preserve existing keys in the loaded manifest', async () => {
expect.assertions(8);
expect.assertions(9);
const plugin = generateIntegrityManifest({ bundleName: 'mockBundleName' });

@@ -95,6 +97,6 @@ const hooks = runSetupAndGetLifeHooks(plugin);

// first read is the bundle generated by the build
// read bundle generated by the build
fs.promises.readFile.mockImplementationOnce(() => 'mockModuleFileContent 2'); // A different content here that the other test, just to get a different set of hashes
// second read is loading the existing manifest
fs.promises.readFile.mockImplementationOnce(() => '{"existingKey": "existing value"}');
// this read is loading the existing manifest
fs.readFileSync.mockImplementationOnce(() => '{"existingKey": "existing value"}');

@@ -104,9 +106,10 @@ const mockResult = { metafile: { outputs: { '/path/to/bundle.js': {} } } };

expect(fs.promises.readFile).toHaveBeenCalledTimes(2);
expect(fs.promises.readFile).toHaveBeenCalledTimes(1);
expect(fs.readFileSync).toHaveBeenCalledTimes(1);
expect(fs.promises.readFile).toHaveBeenCalledWith('/path/to/bundle.js', 'utf8');
expect(fs.promises.readFile).toHaveBeenCalledWith('./bundle.integrity.manifest.json', 'utf8');
expect(fs.readFileSync).toHaveBeenCalledWith('./bundle.integrity.manifest.json', 'utf8');
expect(fs.promises.writeFile).toHaveBeenCalledTimes(1);
expect(fs.writeFileSync).toHaveBeenCalledTimes(1);
// first parameter of first call
expect(fs.promises.writeFile.mock.calls[0][0]).toBe('./bundle.integrity.manifest.json');
expect(fs.writeFileSync.mock.calls[0][0]).toBe('./bundle.integrity.manifest.json');
// Snapshot here for the hash. Its hashing the response from the first readFile mock,

@@ -116,3 +119,3 @@ // 'mockModuleFileContent 2', therefore if the hash below ever changes, its likely to be

// is also changed
expect(fs.promises.writeFile.mock.calls[0][1]).toMatchInlineSnapshot(`
expect(fs.writeFileSync.mock.calls[0][1]).toMatchInlineSnapshot(`
"{

@@ -136,3 +139,3 @@ \\"existingKey\\": \\"existing value\\",

expect(fs.promises.readFile).not.toHaveBeenCalled();
expect(fs.promises.writeFile).not.toHaveBeenCalled();
expect(fs.writeFileSync).not.toHaveBeenCalled();
});

@@ -139,0 +142,0 @@ });

@@ -17,6 +17,5 @@ /*

import fs from 'node:fs';
import esbuild from 'esbuild';
import { readPackageUpSync } from 'read-pkg-up';
import writeToModuleConfig from '../../utils/write-to-module-config';
import { bundleExternalFallbacks } from '../../utils/bundle-external-fallbacks.js';

@@ -50,4 +49,14 @@

jest.mock('node:fs');
// mock reading integrity manifest
jest.mock('node:fs', () => ({
readFileSync: jest.fn(() => JSON.stringify({
'awesome.browser': 'sha-awesome-browser',
'awesome.node': 'sha-awesome-node',
node: 'shaNode',
browser: 'shaBrowser',
})),
}));
jest.mock('../../utils/write-to-module-config');
jest.spyOn(process, 'cwd').mockImplementation(() => '/path/');

@@ -120,2 +129,5 @@

},
dependencies: {
awesome: '^1.2.3',
},
},

@@ -126,3 +138,3 @@ }));

packageJson: {
version: '1.0.0',
version: '1.2.3',
},

@@ -133,4 +145,2 @@ }));

fs.readFileSync.mockImplementationOnce(() => 'const testing = true;');
await bundleExternalFallbacks();

@@ -144,5 +154,5 @@

],
globalName: '__holocron_external__awesome__1_0_0',
globalName: '__holocron_external__awesome__1_2_3',
footer: {
js: 'Holocron.registerExternal({ name: "awesome", version: "1.0.0", module: __holocron_external__awesome__1_0_0});',
js: 'Holocron.registerExternal({ name: "awesome", version: "1.2.3", module: __holocron_external__awesome__1_2_3});',
},

@@ -171,2 +181,5 @@ mocked: 'browser',

},
dependencies: {
awesome: '^2.0.0',
},
},

@@ -177,3 +190,3 @@ }));

packageJson: {
version: '1.0.0',
version: '2.1.0',
},

@@ -184,4 +197,2 @@ }));

fs.readFileSync.mockImplementationOnce(() => 'const testing = true;');
const error = new Error('Testing');

@@ -198,5 +209,5 @@

],
globalName: '__holocron_external__awesome__1_0_0',
globalName: '__holocron_external__awesome__2_1_0',
mocked: 'browser',
footer: { js: 'Holocron.registerExternal({ name: "awesome", version: "1.0.0", module: __holocron_external__awesome__1_0_0});' },
footer: { js: 'Holocron.registerExternal({ name: "awesome", version: "2.1.0", module: __holocron_external__awesome__2_1_0});' },
outfile: '/path/build/1.0.0/awesome.browser.js',

@@ -213,3 +224,2 @@ });

expect(fs.writeFileSync).not.toHaveBeenCalled();
expect(console.error).toHaveBeenCalledTimes(2);

@@ -228,2 +238,38 @@ expect(console.error).toHaveBeenCalledWith('Failed to build fallback for external awesome for browser', error);

});
it('writes to module config', async () => {
readPackageUpSync.mockImplementationOnce(() => ({
packageJson: {
version: '1.0.0',
'one-amex': {
bundler: {
requiredExternals: ['awesome'],
},
},
dependencies: {
awesome: '^1.2.3',
},
},
}));
readPackageUpSync.mockImplementation(() => ({
packageJson: {
version: '1.2.3',
},
}));
await bundleExternalFallbacks();
expect(writeToModuleConfig).toHaveBeenCalledWith({
requiredExternals: {
awesome: {
name: 'awesome',
version: '1.2.3',
semanticRange: '^1.2.3',
browserIntegrity: 'sha-awesome-browser',
nodeIntegrity: 'sha-awesome-node',
},
},
});
});
});

@@ -6,2 +6,15 @@ # Change Log

## [1.5.5](https://github.com/americanexpress/one-app-cli/compare/@americanexpress/one-app-dev-bundler@1.5.3...@americanexpress/one-app-dev-bundler@1.5.5) (2023-11-13)
### Bug Fixes
* **fallback-integrity:** ensure node & browser integrity in module config ([#584](https://github.com/americanexpress/one-app-cli/issues/584)) ([e14fc4f](https://github.com/americanexpress/one-app-cli/commit/e14fc4f7d4110cd038379ac759fc54fcb6797ce2))
* **one-app-dev-bundler:** replace depreacted node polyfill plugin ([#582](https://github.com/americanexpress/one-app-cli/issues/582)) ([2f7fa3c](https://github.com/americanexpress/one-app-cli/commit/2f7fa3c0f337f05c9fea75e49600e5c9e6f3eb80))
* **one-app-dev-bundler:** sass style loader ([#577](https://github.com/americanexpress/one-app-cli/issues/577)) ([6559915](https://github.com/americanexpress/one-app-cli/commit/655991594a5161afce533e5966c5ad77fc7774f1))
## [1.5.4](https://github.com/americanexpress/one-app-cli/compare/@americanexpress/one-app-dev-bundler@1.5.3...@americanexpress/one-app-dev-bundler@1.5.4) (2023-10-04)

@@ -8,0 +21,0 @@

@@ -18,4 +18,4 @@ /*

import { globalExternals } from '@fal-works/esbuild-plugin-global-externals';
import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill';
import { NodeModulesPolyfillPlugin } from '@esbuild-plugins/node-modules-polyfill';
// eslint-disable-next-line import/no-unresolved -- false positive due to package not have main field in package.json
import { polyfillNode } from 'esbuild-plugin-polyfill-node';
import { readPackageUpSync } from 'read-pkg-up';

@@ -99,6 +99,3 @@ import path from 'node:path';

// TODO make these opt in, this would be a breaking change as webpack always includes them
NodeGlobalsPolyfillPlugin({
buffer: true,
}),
NodeModulesPolyfillPlugin(),
polyfillNode(),
bundleAssetSizeLimiter(commonConfigPluginOptions),

@@ -156,7 +153,5 @@ externalsLoader(browserConfigPluginOptions),

removeWebpackLoaderSyntax,
bundleAssetSizeLimiter(commonConfigPluginOptions),
env === 'browser' && legacyBundler(externalName),
generateIntegrityManifest({ bundleName: externalName }),
generateIntegrityManifest({ bundleName: `${externalName}.${env}` }),
restrictRuntimeSymbols(browserConfigPluginOptions),
timeBuild({ bundleName: externalName, watch }),
timeBuild({ bundleName: `${externalName}.${env}`, watch }),
].filter(Boolean),

@@ -163,0 +158,0 @@ });

@@ -21,6 +21,8 @@ /*

async function writeIntegrityFragment(bundleName, integrityString, fileName) {
// NOTE:: This needs to be synchronous to avoid race condition resulting in
// missing integrity manifest entries
function writeIntegrityFragment(bundleName, integrityString, fileName) {
let integrityObject = {};
try {
integrityObject = JSON.parse(await fs.promises.readFile(fileName, 'utf8'));
integrityObject = JSON.parse(fs.readFileSync(fileName, 'utf8'));
} catch (e) {

@@ -31,4 +33,3 @@ // empty catch in case file does not exist

integrityObject[bundleName] = integrityString;
return fs.promises.writeFile(fileName, JSON.stringify(integrityObject, null, 2));
return fs.writeFileSync(fileName, JSON.stringify(integrityObject, null, 2));
}

@@ -53,3 +54,3 @@

await writeIntegrityFragment(bundleName, integrityString, './bundle.integrity.manifest.json');
writeIntegrityFragment(bundleName, integrityString, './bundle.integrity.manifest.json');

@@ -56,0 +57,0 @@ return result;

{
"name": "@americanexpress/one-app-dev-bundler",
"version": "1.5.4",
"version": "1.5.5",
"description": "A development bundler focussed on speed and modern features.",

@@ -29,4 +29,2 @@ "main": "index.js",

"@americanexpress/one-app-locale-bundler": "^6.6.0",
"@esbuild-plugins/node-globals-polyfill": "^0.1.1",
"@esbuild-plugins/node-modules-polyfill": "^0.2.2",
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",

@@ -40,2 +38,3 @@ "@fullhuman/postcss-purgecss": "^3.0.0",

"esbuild": "^0.15.9",
"esbuild-plugin-polyfill-node": "^0.3.0",
"esbuild-plugin-svgr": "^1.0.1",

@@ -86,3 +85,3 @@ "filesize": "^9.0.1",

},
"gitHead": "b902ec72fac135c37870c4c860796955ae3eb23b"
"gitHead": "7995a388f1ee7d9c7ad20b60fa835dcb9dd1d751"
}

@@ -19,3 +19,5 @@ /*

import snakeCase from 'lodash.snakecase';
import fs from 'node:fs';
import generateESBuildOptions from '../esbuild/generateESBuildOptions.js';
import writeToModuleConfig from './write-to-module-config.js';

@@ -73,2 +75,22 @@ const EXTERNAL_PREFIX = '__holocron_external';

}))));
const integrityManifest = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'bundle.integrity.manifest.json'), 'utf-8'));
const requiredExternalsData = requiredExternals.reduce((obj, externalName) => {
const version = readPackageUpSync({
cwd: path.resolve(process.cwd(), 'node_modules', externalName),
})?.packageJson.version;
const semanticRange = packageJson.dependencies[externalName];
return {
...obj,
[externalName]: {
name: externalName,
version,
semanticRange,
browserIntegrity: integrityManifest[`${externalName}.browser`],
nodeIntegrity: integrityManifest[`${externalName}.node`],
},
};
}, {});
writeToModuleConfig({ requiredExternals: requiredExternalsData });
}

@@ -75,0 +97,0 @@ };

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc