diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 4c34e85..82e90eb 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -19,7 +19,7 @@ jobs: strategy: matrix: - node-version: [10.x, 12.x] + node-version: [12.x, 14.x] steps: - uses: actions/checkout@v2 @@ -39,7 +39,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [10.x, 12.x] + node-version: [12.x, 14.x] steps: - uses: actions/checkout@v2 @@ -59,7 +59,7 @@ jobs: - name: Node setup uses: actions/setup-node@v1 with: - node-version: 12 + node-version: 14 - name: Prepare run: yarn && yarn build - name: Release diff --git a/.nvmrc b/.nvmrc index 48082f7..8351c19 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -12 +14 diff --git a/package.json b/package.json index d4866e3..776128f 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ "eslint-plugin-jest": "^24.1.5", "eslint-plugin-prettier": "^3.1.2", "jest": "^26.0.1", - "mock-fs": "^4.11.0", "prettier": "^2.0.5", "rimraf": "^3.0.2", "semantic-release": "^17.0.4", diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts index b40c800..880a897 100644 --- a/src/__tests__/index.test.ts +++ b/src/__tests__/index.test.ts @@ -1,261 +1,228 @@ -import * as childProcess from 'child_process' -import { readFileSync } from 'fs' - -import mockFS from 'mock-fs' +import { promises as fs } from 'fs' +import { tmpdir } from 'os' +import { join, resolve } from 'path' +import type { Report } from '../index.d' import runPackwatch from '..' -jest.mock('child_process') - -function getPackOutput({ packageSize, unpackedSize }) { - return ` -npm notice -npm notice 📦 footprint@0.0.0 -npm notice === Tarball Contents === -npm notice 732B package.json -npm notice 1.8kB dist/helpers.js -npm notice 1.9kB dist/index.js -npm notice === Tarball Details === -npm notice name: footprint -npm notice version: 0.0.0 -npm notice filename: footprint-0.0.0.tgz -npm notice package size: ${packageSize} -npm notice unpacked size: ${unpackedSize} -npm notice shasum: bdf33d471543cd8126338a82a27b16a9010b8dbd -npm notice integrity: sha512-ZZvTg9GVcJw8J[...]bkE0xlqQhlt4Q== -npm notice total files: 3 -npm notice - ` +async function prepareWorkspace(): Promise { + const workspacePath = await fs.mkdtemp(`${tmpdir()}/`, { recursive: true }) + return workspacePath } -function getManifest() { - try { - return JSON.parse(readFileSync('.packwatch.json', { encoding: 'utf8' })) - } catch { - /* No manifest */ - } +async function cleanUpWorkspace(paths: string[]): Promise { + return Promise.all( + paths.map(async path => fs.rmdir(path, { recursive: true })), + ) } -function setupMockFS({ - hasPackageJSON, - hasManifest, - manifestLimit, - manifestSize, -}) { - const fs = {} +async function createFile(path: string, content: string): Promise { + await fs.writeFile(path, content) +} - if (hasPackageJSON) fs['package.json'] = '{}' +async function createPackageJson(cwd: string): Promise { + const path = resolve(join(cwd, 'package.json')) + await createFile( + path, + '{ "name": "wow", "version": "0.0.0", "files": ["!.packwatch.json"] }', + ) +} - if (hasManifest) - fs['.packwatch.json'] = JSON.stringify({ - unpackedSize: '0.5 B', - limitBytes: manifestLimit, - limit: `${manifestLimit} B`, - packageSize: `${manifestSize} B`, - packageSizeBytes: manifestSize, - }) - mockFS(fs) +async function createManifest( + cwd: string, + configuration: Report, +): Promise { + const path = resolve(join(cwd, '.packwatch.json')) + await createFile(path, JSON.stringify(configuration)) } describe('Packwatch', () => { let mockLogger + let workspacePath beforeEach(() => { - mockFS({}) mockLogger = jest.spyOn(global.console, 'log').mockImplementation() }) - afterEach(jest.restoreAllMocks) + afterEach(async () => { + jest.restoreAllMocks() - afterAll(mockFS.restore) + if (workspacePath) { + await cleanUpWorkspace([workspacePath]) + workspacePath = null + } + }) - it('warns the user and errors if run away from package.json', () => { - mockFS({}) - runPackwatch() + it('warns the user and errors if run away from package.json', async () => { + workspacePath = await prepareWorkspace() + runPackwatch({ cwd: workspacePath }) expect(mockLogger.mock.calls).toHaveLength(1) - expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot( - '"🤔 There is no package.json file here. Are you in the root directory of your project?"', + expect(mockLogger.mock.calls[0][0]).toEqual( + expect.stringMatching( + 'There is no package.json file here. Are you in the root directory of your project?', + ), ) }) describe('without manifest', () => { - beforeEach(() => { - setupMockFS({ hasPackageJSON: true }) - }) + it('generates the initial manifest properly', async () => { + workspacePath = await prepareWorkspace() + await createPackageJson(workspacePath) - it.each(['1 B', '1.1 B', '1 kB', '1.1 kB', '1 mB', '1.1 mB'])( - 'generates the initial manifest properly (size = %s)', - mockSize => { - jest.spyOn(childProcess, 'spawnSync').mockReturnValue({ - stderr: getPackOutput({ - packageSize: mockSize, - unpackedSize: mockSize, - }), - }) - const returnCode = runPackwatch() - const manifest = getManifest() - expect(returnCode).toEqual(1) - expect(manifest).toEqual({ - limit: mockSize, - packageSize: mockSize, - unpackedSize: mockSize, - }) - }, - ) + runPackwatch({ cwd: workspacePath }) - it('outputs expected messaging', () => { - jest.spyOn(childProcess, 'spawnSync').mockReturnValue({ - stderr: getPackOutput({ - packageSize: '1 B', - unpackedSize: '2 B', - }), - }) + const generatedManifest = await fs.readFile( + resolve(join(workspacePath, '.packwatch.json')), + { encoding: 'utf8' }, + ) - runPackwatch() - - expect(mockLogger.mock.calls).toHaveLength(2) - expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot(` - "📝 No Manifest to compare against! Current package stats written to .packwatch.json! - Package size (1 B) adopted as new limit." - `) - expect(mockLogger.mock.calls[1][0]).toMatchInlineSnapshot( - '"❗ It looks like you ran PackWatch without a manifest. To prevent accidental passes in CI or hooks, packwatch will terminate with an error. If you are running packwatch for the first time in your project, this is expected!"', + expect(generatedManifest).toEqual( + '{"limit":"160 B","packageSize":"160 B","unpackedSize":"68 B"}', ) }) - it('outputs expected messaging when not updating the manifest', () => { - jest.spyOn(childProcess, 'spawnSync').mockReturnValue({ - stderr: getPackOutput({ - packageSize: '1 B', - unpackedSize: '2 B', - }), - }) + it('outputs expected messaging', async () => { + workspacePath = await prepareWorkspace() + await createPackageJson(workspacePath) - runPackwatch({ isUpdatingManifest: true }) + runPackwatch({ cwd: workspacePath }) + + expect(mockLogger.mock.calls).toHaveLength(2) + expect(mockLogger.mock.calls[0][0]).toEqual( + expect.stringMatching( + /No Manifest to compare against! Current package stats written to \.packwatch\.json!\nPackage size \(\d+ B\) adopted as new limit\./, + ), + ) + expect(mockLogger.mock.calls[1][0]).toEqual( + expect.stringMatching( + 'It looks like you ran PackWatch without a manifest. To prevent accidental passes in CI or hooks, packwatch will terminate with an error. If you are running packwatch for the first time in your project, this is expected!', + ), + ) + }) + + it('outputs expected messaging when not updating the manifest', async () => { + workspacePath = await prepareWorkspace() + + await createPackageJson(workspacePath) + + runPackwatch({ cwd: workspacePath, isUpdatingManifest: true }) expect(mockLogger.mock.calls).toHaveLength(1) - expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot(` - "📝 No Manifest to compare against! Current package stats written to .packwatch.json! - Package size (1 B) adopted as new limit." - `) + expect(mockLogger.mock.calls[0][0]).toEqual( + expect.stringMatching( + /No Manifest to compare against! Current package stats written to \.packwatch\.json!\nPackage size \(\d+ B\) adopted as new limit\./, + ), + ) }) }) describe('with manifest', () => { - it('messages when the size is equal to the limit', () => { - setupMockFS({ - hasPackageJSON: true, - hasManifest: true, - manifestLimit: 1, - manifestSize: 1, + it('messages when the size is equal to the limit', async () => { + workspacePath = await prepareWorkspace() + + await createPackageJson(workspacePath) + await createManifest(workspacePath, { + limit: '160B', + packageSize: '160B', + unpackedSize: '150B', }) - jest.spyOn(childProcess, 'spawnSync').mockReturnValue({ - stderr: getPackOutput({ - packageSize: '1 B', - unpackedSize: '2 B', - }), - }) - runPackwatch() + runPackwatch({ cwd: workspacePath }) expect(mockLogger.mock.calls).toHaveLength(1) - expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot( - '"📦 Nothing to report! Your package is the same size as the latest manifest reports! (Limit: 1 B)"', + expect(mockLogger.mock.calls[0][0]).toEqual( + expect.stringMatching( + /Nothing to report! Your package is the same size as the latest manifest reports! \(Limit: 160B\)/, + ), ) }) - it('messages when the size is lower than the limit (no growth)', () => { - setupMockFS({ - hasPackageJSON: true, - hasManifest: true, - manifestLimit: 5, - manifestSize: 1, + it('messages when the size is lower than the limit (no growth)', async () => { + workspacePath = await prepareWorkspace() + + await createPackageJson(workspacePath) + await createManifest(workspacePath, { + limit: '170B', + packageSize: '160B', + unpackedSize: '150B', }) - jest.spyOn(childProcess, 'spawnSync').mockReturnValue({ - stderr: getPackOutput({ - packageSize: '1 B', - unpackedSize: '2 B', - }), - }) - runPackwatch() + + runPackwatch({ cwd: workspacePath }) expect(mockLogger.mock.calls).toHaveLength(1) - expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot( - '"📦 Nothing to report! Your package is the same size as the latest manifest reports! (Limit: 5 B)"', + expect(mockLogger.mock.calls[0][0]).toEqual( + expect.stringMatching( + /Nothing to report! Your package is the same size as the latest manifest reports! \(Limit: 170B\)/, + ), ) }) - it('messages when the size is lower than the limit (growth)', () => { - setupMockFS({ - hasPackageJSON: true, - hasManifest: true, - manifestLimit: 5, - manifestSize: 2, + it('messages when the size is lower than the limit (growth)', async () => { + workspacePath = await prepareWorkspace() + + await createPackageJson(workspacePath) + await createManifest(workspacePath, { + limit: '180B', + packageSize: '150B', + unpackedSize: '140B', }) - jest.spyOn(childProcess, 'spawnSync').mockReturnValue({ - stderr: getPackOutput({ - packageSize: '3 B', - unpackedSize: '2 B', - }), - }) - runPackwatch() + + runPackwatch({ cwd: workspacePath }) expect(mockLogger.mock.calls).toHaveLength(1) - expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot( - '"📦 👀 Your package grew! 3 B > 2 B (Limit: 5 B)"', + expect(mockLogger.mock.calls[0][0]).toEqual( + expect.stringMatching( + /Your package grew! \d+ B > 150B \(Limit: 180B\)/, + ), ) }) - it('messages when the size is lower than the limit (shrinkage)', () => { - setupMockFS({ - hasPackageJSON: true, - hasManifest: true, - manifestLimit: 5, - manifestSize: 2, + it('messages when the size is lower than the limit (shrinkage)', async () => { + workspacePath = await prepareWorkspace() + + await createPackageJson(workspacePath) + await createManifest(workspacePath, { + limit: '180B', + packageSize: '170B', + unpackedSize: '140B', }) - jest.spyOn(childProcess, 'spawnSync').mockReturnValue({ - stderr: getPackOutput({ - packageSize: '1 B', - unpackedSize: '2 B', - }), - }) - runPackwatch() + + runPackwatch({ cwd: workspacePath }) expect(mockLogger.mock.calls).toHaveLength(1) - expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot( - '"📦 💯 Your package shrank! 1 B < 2 B (Limit: 5 B)"', + expect(mockLogger.mock.calls[0][0]).toEqual( + expect.stringMatching( + /Your package shrank! \d+ B < 170B \(Limit: 180B\)/, + ), ) }) - it('messages when the size exceeds the limit', () => { - setupMockFS({ - hasPackageJSON: true, - hasManifest: true, - manifestLimit: 0.5, - manifestSize: 0.5, + it('messages when the size exceeds the limit', async () => { + workspacePath = await prepareWorkspace() + + await createPackageJson(workspacePath) + await createManifest(workspacePath, { + limit: '10B', + packageSize: '170B', + unpackedSize: '140B', }) - jest.spyOn(childProcess, 'spawnSync').mockReturnValue({ - stderr: getPackOutput({ - packageSize: '1 B', - unpackedSize: '2 B', - }), - }) - runPackwatch() + + runPackwatch({ cwd: workspacePath }) expect(mockLogger.mock.calls).toHaveLength(1) - expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot(` - "🔥🔥📦🔥🔥 Your package exceeds the limit set in .packwatch.json! 1 B > 0.5 B - Either update the limit by using the --update-manifest flag or trim down your packed files!" - `) + expect(mockLogger.mock.calls[0][0]).toEqual( + expect.stringMatching( + /Your package exceeds the limit set in \.packwatch\.json! \d+ B > 10B\nEither update the limit by using the --update-manifest flag or trim down your packed files!/, + ), + ) }) - it('messages when updating the manifest', () => { - setupMockFS({ - hasPackageJSON: true, - hasManifest: true, - manifestLimit: 0.5, - manifestSize: 0.5, + it('messages when updating the manifest', async () => { + workspacePath = await prepareWorkspace() + + await createPackageJson(workspacePath) + await createManifest(workspacePath, { + limit: '10B', + packageSize: '170B', + unpackedSize: '140B', }) - jest.spyOn(childProcess, 'spawnSync').mockReturnValue({ - stderr: getPackOutput({ - packageSize: '1 B', - unpackedSize: '2 B', - }), - }) - runPackwatch({ isUpdatingManifest: true }) + + runPackwatch({ cwd: workspacePath, isUpdatingManifest: true }) expect(mockLogger.mock.calls).toHaveLength(1) - expect(mockLogger.mock.calls[0][0]).toMatchInlineSnapshot( - '"📝 Updated the manifest! Package size: 1 B, Limit: 1 B"', + expect(mockLogger.mock.calls[0][0]).toEqual( + expect.stringMatching( + /Updated the manifest! Package size: \d+ B, Limit: \d+ B/, + ), ) }) }) diff --git a/src/cli.ts b/src/cli.ts index 6742f26..a13de2f 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -3,5 +3,6 @@ import runPackwatch from '.' const isUpdatingManifest = process.argv.includes('--update-manifest') -const processExit = runPackwatch({ isUpdatingManifest }) +const cwd = process.cwd() +const processExit = runPackwatch({ cwd, isUpdatingManifest }) process.exit(processExit) diff --git a/src/index.ts b/src/index.ts index fb7d0ed..faced80 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,107 +1,40 @@ -import { spawnSync } from 'child_process' -import { existsSync, readFileSync, writeFileSync } from 'fs' +import { existsSync } from 'fs' +import { join, resolve } from 'path' -import { Report } from './index.d' - -const PACKAGE_SIZE_PATT = /package size:\s*([0-9]+\.?[0-9]*\s+[A-Za-z]{1,2})/ -const UNPACKED_SIZE_PATT = /unpacked size:\s*([0-9]+\.?[0-9]*\s+[A-Za-z]{1,2})/ -const SIZE_SUFFIX_PATT = /([A-Za-z]+)/ -const SIZE_MAGNITUDE_PATT = /([0-9]+\.?[0-9]*)/ +import { + createOrUpdateManifest, + getCurrentPackageStats, + getPreviousPackageStats, +} from './utils' const MANIFEST_FILENAME = '.packwatch.json' -function convertSizeToBytes(sizeString: string): number { - const sizeSuffix = SIZE_SUFFIX_PATT.exec(sizeString)[1] - const sizeMagnitude = SIZE_MAGNITUDE_PATT.exec(sizeString)[1] - - let multiplier = 1 - - if (sizeSuffix === 'kB') multiplier = 1000 - else if (sizeSuffix === 'mB') { - multiplier = 1000000 - } - - return multiplier * parseFloat(sizeMagnitude) -} - -function getCurrentPackageStats(): Report { - const { stderr } = spawnSync('npm', ['pack', '--dry-run'], { - encoding: 'utf-8', - }) - const stderrString = String(stderr) - const packageSize = PACKAGE_SIZE_PATT.exec(stderrString)[1] - const unpackedSize = UNPACKED_SIZE_PATT.exec(stderrString)[1] - - return { - packageSize, - unpackedSize, - packageSizeBytes: convertSizeToBytes(packageSize), - unpackedSizeBytes: convertSizeToBytes(unpackedSize), - } -} - -function getPreviousPackageStats(): Report | null { - try { - const currentManifest = readFileSync(MANIFEST_FILENAME, { - encoding: 'utf-8', - }) - const parsedManifest = JSON.parse(currentManifest) - return { - ...parsedManifest, - packageSizeBytes: convertSizeToBytes(parsedManifest.packageSize), - unpackedSizeBytes: convertSizeToBytes(parsedManifest.unpackedSize), - limitBytes: convertSizeToBytes(parsedManifest.limit), - } - } catch { - /* No manifest */ - } -} - -function createOrUpdateManifest({ - previous, - current, - updateLimit = false, +export default function run({ + cwd, + isUpdatingManifest, }: { - previous?: Report - current: Report - updateLimit?: boolean -}): void { - const { limit } = previous || {} - const { packageSize, unpackedSize } = current + cwd?: string + isUpdatingManifest?: boolean +}): number { + const packageJsonPath = resolve(join(cwd, 'package.json')) + const manifestPath = resolve(join(cwd, MANIFEST_FILENAME)) - const newManifest = { - limit: updateLimit ? packageSize : limit || packageSize, - packageSize: packageSize, - unpackedSize: unpackedSize, - } - - writeFileSync(MANIFEST_FILENAME, JSON.stringify(newManifest)) -} -export default function run( - { - manifestFn = MANIFEST_FILENAME, - isUpdatingManifest, - }: { manifestFn?: string; isUpdatingManifest?: boolean } = { - manifestFn: MANIFEST_FILENAME, - isUpdatingManifest: false, - }, -): number { - if (!existsSync('package.json')) { + if (!existsSync(packageJsonPath)) { console.log( '🤔 There is no package.json file here. Are you in the root directory of your project?', ) return 1 } - const currentStats = getCurrentPackageStats() + const currentStats = getCurrentPackageStats(cwd) /* * If there is no manifest file yet, we can use the current package stats as * a base to build one. The current package size becomes the limit. */ - if (!existsSync(manifestFn)) { - createOrUpdateManifest({ current: currentStats }) + if (!existsSync(manifestPath)) { + createOrUpdateManifest({ manifestPath, current: currentStats }) console.log( `📝 No Manifest to compare against! Current package stats written to ${MANIFEST_FILENAME}!\nPackage size (${currentStats.packageSize}) adopted as new limit.`, ) @@ -116,7 +49,7 @@ export default function run( return isUpdatingManifest ? 0 : 1 } - const previousStats = getPreviousPackageStats() + const previousStats = getPreviousPackageStats(cwd) const { packageSizeBytes, packageSize } = currentStats const { packageSize: previousSize, @@ -135,6 +68,7 @@ export default function run( previous: previousStats, current: currentStats, updateLimit: true, + manifestPath, }) console.log( `📝 Updated the manifest! Package size: ${packageSize}, Limit: ${packageSize}`, diff --git a/src/utils.test.ts b/src/utils.test.ts new file mode 100644 index 0000000..5a4ea33 --- /dev/null +++ b/src/utils.test.ts @@ -0,0 +1,15 @@ +import { convertSizeToBytes } from './utils' + +describe('utils', () => { + it.each` + initialSize | expectedSize + ${'1 B'} | ${1} + ${'1 kB'} | ${1000} + ${'1 mB'} | ${1000000} + `( + 'converts sizes properly ($initialSize -> $expectedSize)', + ({ initialSize, expectedSize }) => { + expect(convertSizeToBytes(initialSize)).toEqual(expectedSize) + }, + ) +}) diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..9e254fd --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,83 @@ +import { spawnSync } from 'child_process' +import { readFileSync, writeFileSync } from 'fs' +import { join, resolve } from 'path' + +import { Report } from './index.d' + +const PACKAGE_SIZE_PATT = /package size:\s*([0-9]+\.?[0-9]*\s+[A-Za-z]{1,2})/ +const UNPACKED_SIZE_PATT = /unpacked size:\s*([0-9]+\.?[0-9]*\s+[A-Za-z]{1,2})/ +const SIZE_SUFFIX_PATT = /([A-Za-z]+)/ +const SIZE_MAGNITUDE_PATT = /([0-9]+\.?[0-9]*)/ + +const MANIFEST_FILENAME = '.packwatch.json' + +export function convertSizeToBytes(sizeString: string): number { + const sizeSuffix = SIZE_SUFFIX_PATT.exec(sizeString)[1] + const sizeMagnitude = SIZE_MAGNITUDE_PATT.exec(sizeString)[1] + + let multiplier = 1 + + if (sizeSuffix === 'kB') multiplier = 1000 + else if (sizeSuffix === 'mB') { + multiplier = 1000000 + } + + return multiplier * parseFloat(sizeMagnitude) +} + +export function getCurrentPackageStats(cwd: string): Report { + const { stderr } = spawnSync('npm', ['pack', '--dry-run'], { + encoding: 'utf-8', + cwd, + }) + const stderrString = String(stderr) + const packageSize = PACKAGE_SIZE_PATT.exec(stderrString)[1] + const unpackedSize = UNPACKED_SIZE_PATT.exec(stderrString)[1] + + return { + packageSize, + unpackedSize, + packageSizeBytes: convertSizeToBytes(packageSize), + unpackedSizeBytes: convertSizeToBytes(unpackedSize), + } +} + +export function getPreviousPackageStats(cwd: string): Report | null { + const manifestPath = resolve(join(cwd, MANIFEST_FILENAME)) + try { + const currentManifest = readFileSync(manifestPath, { + encoding: 'utf-8', + }) + const parsedManifest = JSON.parse(currentManifest) + return { + ...parsedManifest, + packageSizeBytes: convertSizeToBytes(parsedManifest.packageSize), + unpackedSizeBytes: convertSizeToBytes(parsedManifest.unpackedSize), + limitBytes: convertSizeToBytes(parsedManifest.limit), + } + } catch { + /* No manifest */ + } +} + +export function createOrUpdateManifest({ + previous, + current, + manifestPath, + updateLimit = false, +}: { + previous?: Report + current: Report + updateLimit?: boolean +}): void { + const { limit } = previous || {} + const { packageSize, unpackedSize } = current + + const newManifest = { + limit: updateLimit ? packageSize : limit || packageSize, + packageSize: packageSize, + unpackedSize: unpackedSize, + } + + writeFileSync(manifestPath, JSON.stringify(newManifest)) +} diff --git a/yarn.lock b/yarn.lock index dbb0d9b..8bac12f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7501,13 +7501,6 @@ __metadata: languageName: node linkType: hard -"mock-fs@npm:^4.11.0": - version: 4.13.0 - resolution: "mock-fs@npm:4.13.0" - checksum: cfb2134de7dfa53ebbbbacdd1b4fc834cce99ee9c231e8e129d9d32b669d15936217a7cdef8325946dd4e398ecfc401aa14c79030b8421cdf6ebd904786d8578 - languageName: node - linkType: hard - "modify-values@npm:^1.0.0": version: 1.0.1 resolution: "modify-values@npm:1.0.1" @@ -8423,7 +8416,6 @@ __metadata: eslint-plugin-jest: ^24.1.5 eslint-plugin-prettier: ^3.1.2 jest: ^26.0.1 - mock-fs: ^4.11.0 prettier: ^2.0.5 rimraf: ^3.0.2 semantic-release: ^17.0.4