From cc9df7fe3cf942377c93d67f25af2b0490ad19ad Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Wed, 26 Oct 2022 01:29:22 -0700 Subject: [PATCH] feat: add support for forge.config.ts et. al This brings in rechoir and interpret which allow arbitrary extensions / loaders for our forge config. Notably this allows us to make forge.config.ts a thing (and thus generate type safe configurations). --- .eslintrc.json | 2 +- package.json | 4 +++ packages/api/core/package.json | 4 +++ packages/api/core/src/api/make.ts | 6 ++-- packages/api/core/src/util/forge-config.ts | 35 ++++++++++++------- packages/api/core/src/util/hook.ts | 6 ++-- packages/api/core/src/util/out-dir.ts | 4 +-- .../api/core/src/util/plugin-interface.ts | 6 ++-- .../api/core/src/util/read-package-json.ts | 4 +-- .../api/core/test/fast/forge-config_spec.ts | 24 ++++++++----- packages/api/core/test/fast/hook_spec.ts | 4 +-- packages/api/core/test/fast/out-dir_spec.ts | 8 ++--- .../core/test/fast/read-package-json_spec.ts | 8 ++--- .../test/fast/upgrade-forge-config_spec.ts | 3 ++ .../dummy_default_ts_conf/forge.config.ts | 7 ++++ .../dummy_default_ts_conf/package.json | 17 +++++++++ packages/api/core/test/slow/api_spec_slow.ts | 5 +++ packages/maker/base/src/Maker.ts | 4 +-- .../src/AutoUnpackNativesPlugin.ts | 4 +-- packages/plugin/base/src/Plugin.ts | 4 +-- .../plugin/compile/src/lib/compile-hook.ts | 4 +-- .../src/ElectronegativityPlugin.ts | 4 +-- .../local-electron/src/LocalElectronPlugin.ts | 4 +-- .../test/LocalElectronPlugin_spec.ts | 10 +++--- packages/plugin/webpack/src/WebpackPlugin.ts | 10 +++--- .../plugin/webpack/test/WebpackPlugin_spec.ts | 22 ++++++------ packages/publisher/base/src/Publisher.ts | 4 +-- .../test/PublisherERS_spec.ts | 14 ++++---- packages/utils/types/src/index.ts | 7 ++-- yarn.lock | 26 ++++++++++++++ 30 files changed, 174 insertions(+), 90 deletions(-) create mode 100644 packages/api/core/test/fixture/dummy_default_ts_conf/forge.config.ts create mode 100644 packages/api/core/test/fixture/dummy_default_ts_conf/package.json diff --git a/.eslintrc.json b/.eslintrc.json index 28cf3a5721..1eac58badf 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -55,7 +55,7 @@ } }, { - "files": ["packages/*/*/test/**/*_spec*.ts"], + "files": ["packages/*/*/test/**/*_spec*.ts", "packages/*/*/test/fixture/**/*.ts"], "rules": { "global-require": "off", "import/no-dynamic-require": "off", diff --git a/package.json b/package.json index 8fb7e6ff3c..6c9d613795 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "got": "^11.8.5", "html-webpack-plugin": "^5.3.1", "inquirer": "^8.0.0", + "interpret": "^3.1.1", "lodash": "^4.17.20", "log-symbols": "^4.0.0", "mime-types": "^2.1.25", @@ -73,6 +74,7 @@ "parse-author": "^2.0.0", "pretty-ms": "^7.0.0", "progress": "^2.0.3", + "rechoir": "^0.8.0", "resolve-package": "^1.0.1", "semver": "^7.2.1", "source-map-support": "^0.5.13", @@ -102,6 +104,7 @@ "@types/fetch-mock": "^7.3.1", "@types/fs-extra": "^9.0.6", "@types/inquirer": "^8.1.1", + "@types/interpret": "^1.1.1", "@types/listr": "^0.14.2", "@types/lodash": "^4.14.166", "@types/mime-types": "^2.1.0", @@ -111,6 +114,7 @@ "@types/node-fetch": "^2.5.5", "@types/progress": "^2.0.5", "@types/proxyquire": "^1.3.28", + "@types/rechoir": "^0.6.1", "@types/semver": "^7.3.4", "@types/sinon": "^10.0.0", "@types/sinon-chai": "^3.2.5", diff --git a/packages/api/core/package.json b/packages/api/core/package.json index 9bd7f64f8c..d2d5ec05a9 100644 --- a/packages/api/core/package.json +++ b/packages/api/core/package.json @@ -25,7 +25,9 @@ "@electron-forge/maker-wix": "6.0.0-beta.68", "@electron-forge/maker-zip": "6.0.0-beta.68", "@electron-forge/test-utils": "6.0.0-beta.68", + "@types/interpret": "^1.1.1", "@types/progress": "^2.0.5", + "@types/rechoir": "^0.6.1", "chai": "^4.3.3", "chai-as-promised": "^7.0.0", "cross-env": "^7.0.2", @@ -56,10 +58,12 @@ "find-up": "^5.0.0", "fs-extra": "^10.0.0", "got": "^11.8.5", + "interpret": "^3.1.1", "lodash": "^4.17.20", "log-symbols": "^4.0.0", "node-fetch": "^2.6.7", "progress": "^2.0.3", + "rechoir": "^0.8.0", "resolve-package": "^1.0.1", "semver": "^7.2.1", "source-map-support": "^0.5.13", diff --git a/packages/api/core/src/api/make.ts b/packages/api/core/src/api/make.ts index 5e47110103..aa9a169f0f 100644 --- a/packages/api/core/src/api/make.ts +++ b/packages/api/core/src/api/make.ts @@ -2,7 +2,7 @@ import path from 'path'; import { asyncOra } from '@electron-forge/async-ora'; import { MakerBase } from '@electron-forge/maker-base'; -import { ForgeArch, ForgeConfig, ForgeConfigMaker, ForgeMakeResult, ForgePlatform, IForgeResolvableMaker } from '@electron-forge/shared-types'; +import { ForgeArch, ForgeConfigMaker, ForgeMakeResult, ForgePlatform, IForgeResolvableMaker, ResolvedForgeConfig } from '@electron-forge/shared-types'; import { getHostArch } from '@electron/get'; import chalk from 'chalk'; import filenamify from 'filenamify'; @@ -29,7 +29,7 @@ class MakerImpl extends MakerBase { type MakeTargets = ForgeConfigMaker[] | string[]; -function generateTargets(forgeConfig: ForgeConfig, overrideTargets?: MakeTargets) { +function generateTargets(forgeConfig: ResolvedForgeConfig, overrideTargets?: MakeTargets) { if (overrideTargets) { return overrideTargets.map((target) => { if (typeof target === 'string') { @@ -90,7 +90,7 @@ export default async ({ }: MakeOptions): Promise => { asyncOra.interactive = interactive; - let forgeConfig!: ForgeConfig; + let forgeConfig!: ResolvedForgeConfig; await asyncOra('Resolving Forge Config', async () => { const resolvedDir = await resolveDir(dir); if (!resolvedDir) { diff --git a/packages/api/core/src/util/forge-config.ts b/packages/api/core/src/util/forge-config.ts index d52493fffc..e1d951b3bd 100644 --- a/packages/api/core/src/util/forge-config.ts +++ b/packages/api/core/src/util/forge-config.ts @@ -1,8 +1,10 @@ import path from 'path'; -import { ForgeConfig, IForgeResolvableMaker } from '@electron-forge/shared-types'; +import { ForgeConfig, IForgeResolvableMaker, ResolvedForgeConfig } from '@electron-forge/shared-types'; import fs from 'fs-extra'; +import * as interpret from 'interpret'; import { template } from 'lodash'; +import * as rechoir from 'rechoir'; import { runMutatingHook } from './hook'; import PluginInterface from './plugin-interface'; @@ -119,22 +121,29 @@ export function renderConfigTemplate(dir: string, templateObj: any, obj: any): v } } -export default async (dir: string): Promise => { +type MaybeESM = T | { default: T }; + +export default async (dir: string): Promise => { const packageJSON = await readRawPackageJson(dir); let forgeConfig: ForgeConfig | string | null = packageJSON.config && packageJSON.config.forge ? packageJSON.config.forge : null; if (!forgeConfig) { - if (await fs.pathExists(path.resolve(dir, 'forge.config.js'))) { - forgeConfig = 'forge.config.js'; - } else { - forgeConfig = {} as ForgeConfig; + for (const extension of ['.js', ...Object.keys(interpret.extensions)]) { + const pathToConfig = path.resolve(dir, `forge.config${extension}`); + if (await fs.pathExists(pathToConfig)) { + rechoir.prepare(interpret.extensions, pathToConfig, dir); + forgeConfig = `forge.config${extension}`; + break; + } } } + forgeConfig = forgeConfig || ({} as ForgeConfig); if (await forgeConfigIsValidFilePath(dir, forgeConfig)) { try { // eslint-disable-next-line @typescript-eslint/no-var-requires - forgeConfig = require(path.resolve(dir, forgeConfig as string)) as ForgeConfig; + const loaded = require(path.resolve(dir, forgeConfig as string)) as MaybeESM; + forgeConfig = 'default' in loaded ? loaded.default : loaded; } catch (err) { console.error(`Failed to load: ${path.resolve(dir, forgeConfig as string)}`); throw err; @@ -149,17 +158,19 @@ export default async (dir: string): Promise => { publishers: [], plugins: [], }; - forgeConfig = { + let resolvedForgeConfig: ResolvedForgeConfig = { ...defaultForgeConfig, ...forgeConfig, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + pluginInterface: null as any, }; const templateObj = { ...packageJSON, year: new Date().getFullYear() }; - renderConfigTemplate(dir, templateObj, forgeConfig); + renderConfigTemplate(dir, templateObj, resolvedForgeConfig); - forgeConfig.pluginInterface = new PluginInterface(dir, forgeConfig); + resolvedForgeConfig.pluginInterface = new PluginInterface(dir, resolvedForgeConfig); - forgeConfig = await runMutatingHook(forgeConfig, 'resolveForgeConfig', forgeConfig); + resolvedForgeConfig = await runMutatingHook(resolvedForgeConfig, 'resolveForgeConfig', resolvedForgeConfig); - return proxify(forgeConfig.buildIdentifier || '', forgeConfig, 'ELECTRON_FORGE'); + return proxify(resolvedForgeConfig.buildIdentifier || '', resolvedForgeConfig, 'ELECTRON_FORGE'); }; diff --git a/packages/api/core/src/util/hook.ts b/packages/api/core/src/util/hook.ts index ca88234c53..490232db7d 100644 --- a/packages/api/core/src/util/hook.ts +++ b/packages/api/core/src/util/hook.ts @@ -1,10 +1,10 @@ -import { ForgeConfig } from '@electron-forge/shared-types'; +import { ResolvedForgeConfig } from '@electron-forge/shared-types'; import debug from 'debug'; const d = debug('electron-forge:hook'); // eslint-disable-next-line @typescript-eslint/no-explicit-any -export const runHook = async (forgeConfig: ForgeConfig, hookName: string, ...hookArgs: any[]): Promise => { +export const runHook = async (forgeConfig: ResolvedForgeConfig, hookName: string, ...hookArgs: any[]): Promise => { const { hooks } = forgeConfig; if (hooks) { d(`hook triggered: ${hookName}`); @@ -16,7 +16,7 @@ export const runHook = async (forgeConfig: ForgeConfig, hookName: string, ...hoo await forgeConfig.pluginInterface.triggerHook(hookName, hookArgs); }; -export async function runMutatingHook(forgeConfig: ForgeConfig, hookName: string, item: T): Promise { +export async function runMutatingHook(forgeConfig: ResolvedForgeConfig, hookName: string, item: T): Promise { const { hooks } = forgeConfig; if (hooks) { d(`hook triggered: ${hookName}`); diff --git a/packages/api/core/src/util/out-dir.ts b/packages/api/core/src/util/out-dir.ts index ebebeb9c52..9b5ae6013a 100644 --- a/packages/api/core/src/util/out-dir.ts +++ b/packages/api/core/src/util/out-dir.ts @@ -1,10 +1,10 @@ import path from 'path'; -import { ForgeConfig } from '@electron-forge/shared-types'; +import { ResolvedForgeConfig } from '@electron-forge/shared-types'; const BASE_OUT_DIR = 'out'; -export default (baseDir: string, forgeConfig: ForgeConfig): string => { +export default (baseDir: string, forgeConfig: ResolvedForgeConfig): string => { if (forgeConfig.buildIdentifier) { let identifier = forgeConfig.buildIdentifier; if (typeof identifier === 'function') { diff --git a/packages/api/core/src/util/plugin-interface.ts b/packages/api/core/src/util/plugin-interface.ts index 6d11f063c9..3398e159a6 100644 --- a/packages/api/core/src/util/plugin-interface.ts +++ b/packages/api/core/src/util/plugin-interface.ts @@ -1,5 +1,5 @@ import PluginBase from '@electron-forge/plugin-base'; -import { ForgeConfig, IForgePlugin, IForgePluginInterface, StartResult } from '@electron-forge/shared-types'; +import { IForgePlugin, IForgePluginInterface, ResolvedForgeConfig, StartResult } from '@electron-forge/shared-types'; import debug from 'debug'; import { StartOptions } from '../api'; @@ -15,9 +15,9 @@ function isForgePlugin(plugin: IForgePlugin | unknown): plugin is IForgePlugin { export default class PluginInterface implements IForgePluginInterface { private plugins: IForgePlugin[]; - private config: ForgeConfig; + private config: ResolvedForgeConfig; - constructor(dir: string, forgeConfig: ForgeConfig) { + constructor(dir: string, forgeConfig: ResolvedForgeConfig) { this.plugins = forgeConfig.plugins.map((plugin) => { if (isForgePlugin(plugin)) { return plugin; diff --git a/packages/api/core/src/util/read-package-json.ts b/packages/api/core/src/util/read-package-json.ts index b85705c517..edd180e6bc 100644 --- a/packages/api/core/src/util/read-package-json.ts +++ b/packages/api/core/src/util/read-package-json.ts @@ -1,6 +1,6 @@ import path from 'path'; -import { ForgeConfig } from '@electron-forge/shared-types'; +import { ResolvedForgeConfig } from '@electron-forge/shared-types'; import fs from 'fs-extra'; import { runMutatingHook } from './hook'; @@ -9,5 +9,5 @@ import { runMutatingHook } from './hook'; export const readRawPackageJson = async (dir: string): Promise => fs.readJson(path.resolve(dir, 'package.json')); // eslint-disable-next-line @typescript-eslint/no-explicit-any -export const readMutatedPackageJson = async (dir: string, forgeConfig: ForgeConfig): Promise => +export const readMutatedPackageJson = async (dir: string, forgeConfig: ResolvedForgeConfig): Promise => runMutatingHook(forgeConfig, 'readPackageJson', await readRawPackageJson(dir)); diff --git a/packages/api/core/test/fast/forge-config_spec.ts b/packages/api/core/test/fast/forge-config_spec.ts index 4bf396e72b..2210b788a8 100644 --- a/packages/api/core/test/fast/forge-config_spec.ts +++ b/packages/api/core/test/fast/forge-config_spec.ts @@ -1,6 +1,6 @@ import path from 'path'; -import { ForgeConfig } from '@electron-forge/shared-types'; +import { ResolvedForgeConfig } from '@electron-forge/shared-types'; import { expect } from 'chai'; import findConfig, { @@ -106,21 +106,27 @@ describe('forge-config', () => { }); it('should resolve the JS file exports in config.forge points to a JS file and maintain functions', async () => { - type MagicFunctionConfig = ForgeConfig & { magicFn: () => string }; + type MagicFunctionConfig = ResolvedForgeConfig & { magicFn: () => string }; const conf = (await findConfig(path.resolve(__dirname, '../fixture/dummy_js_conf'))) as MagicFunctionConfig; expect(conf.magicFn).to.be.a('function'); expect(conf.magicFn()).to.be.equal('magic result'); }); - it('should resolve the JS file exports of forge.config.js if config.forge does not exist points', async () => { - type DefaultResolvedConfig = ForgeConfig & { defaultResolved: boolean }; + it('should resolve the JS file exports of forge.config.js if config.forge does not exist ', async () => { + type DefaultResolvedConfig = ResolvedForgeConfig & { defaultResolved: boolean }; const conf = (await findConfig(path.resolve(__dirname, '../fixture/dummy_default_js_conf'))) as DefaultResolvedConfig; expect(conf.buildIdentifier).to.equal('default'); expect(conf.defaultResolved).to.equal(true); }); + it('should resolve the TS file exports of forge.config.ts if config.forge does not exist and the TS config exists', async () => { + type DefaultResolvedConfig = ResolvedForgeConfig; + const conf = (await findConfig(path.resolve(__dirname, '../fixture/dummy_default_ts_conf'))) as DefaultResolvedConfig; + expect(conf.buildIdentifier).to.equal('typescript'); + }); + it('should magically map properties to environment variables', async () => { - type MappedConfig = ForgeConfig & { + type MappedConfig = ResolvedForgeConfig & { s3: { secretAccessKey?: string; }; @@ -140,7 +146,7 @@ describe('forge-config', () => { }); it('should resolve values fromBuildIdentifier', async () => { - type ResolveBIConfig = ForgeConfig & { + type ResolveBIConfig = ResolvedForgeConfig & { topLevelProp: string; sub: { prop: { @@ -164,13 +170,13 @@ describe('forge-config', () => { }); it('should resolve undefined from fromBuildIdentifier if no value is provided', async () => { - type ResolveUndefConfig = ForgeConfig & { topLevelUndef?: string }; + type ResolveUndefConfig = ResolvedForgeConfig & { topLevelUndef?: string }; const conf = (await findConfig(path.resolve(__dirname, '../fixture/dummy_js_conf'))) as ResolveUndefConfig; expect(conf.topLevelUndef).to.equal(undefined); }); it('should leave arrays intact', async () => { - type NestedConfig = ForgeConfig & { + type NestedConfig = ResolvedForgeConfig & { sub: { prop: { inArray: string[]; @@ -182,7 +188,7 @@ describe('forge-config', () => { }); it('should leave regexps intact', async () => { - type RegExpConfig = ForgeConfig & { regexp: RegExp }; + type RegExpConfig = ResolvedForgeConfig & { regexp: RegExp }; const conf = (await findConfig(path.resolve(__dirname, '../fixture/dummy_js_conf'))) as RegExpConfig; expect(conf.regexp).to.be.instanceOf(RegExp); expect(conf.regexp.test('foo')).to.equal(true, 'regexp should match foo'); diff --git a/packages/api/core/test/fast/hook_spec.ts b/packages/api/core/test/fast/hook_spec.ts index 8929d60cf9..d41d7e13ac 100644 --- a/packages/api/core/test/fast/hook_spec.ts +++ b/packages/api/core/test/fast/hook_spec.ts @@ -1,4 +1,4 @@ -import { ForgeConfig, ForgeHookFn } from '@electron-forge/shared-types'; +import { ForgeHookFn, ResolvedForgeConfig } from '@electron-forge/shared-types'; import { expect } from 'chai'; import { SinonStub, stub } from 'sinon'; @@ -9,7 +9,7 @@ const fakeConfig = { triggerHook: async () => false, triggerMutatingHook: async (_hookName: string, item: unknown) => item, }, -} as unknown as ForgeConfig; +} as unknown as ResolvedForgeConfig; describe('hooks', () => { describe('runHook', () => { diff --git a/packages/api/core/test/fast/out-dir_spec.ts b/packages/api/core/test/fast/out-dir_spec.ts index b737a47eb7..cff0ba13ce 100644 --- a/packages/api/core/test/fast/out-dir_spec.ts +++ b/packages/api/core/test/fast/out-dir_spec.ts @@ -1,6 +1,6 @@ import path from 'path'; -import { ForgeConfig } from '@electron-forge/shared-types'; +import { ResolvedForgeConfig } from '@electron-forge/shared-types'; import { expect } from 'chai'; import getCurrentOutDir from '../../src/util/out-dir'; @@ -10,14 +10,14 @@ describe('out-dir', () => { describe('getCurrentOutDir', () => { it('resolves to the default out directory when nothing extra is declared', () => { - expect(getCurrentOutDir(DIR, {} as ForgeConfig)).to.equal(`${DIR}${path.sep}out`); + expect(getCurrentOutDir(DIR, {} as ResolvedForgeConfig)).to.equal(`${DIR}${path.sep}out`); }); it('resolves to the provided identifier', () => { expect( getCurrentOutDir(DIR, { buildIdentifier: 'bar', - } as ForgeConfig) + } as ResolvedForgeConfig) ).to.equal(`${DIR}${path.sep}out${path.sep}bar`); }); @@ -25,7 +25,7 @@ describe('out-dir', () => { expect( getCurrentOutDir(DIR, { buildIdentifier: () => 'thing', - } as ForgeConfig) + } as ResolvedForgeConfig) ).to.equal(`${DIR}${path.sep}out${path.sep}thing`); }); }); diff --git a/packages/api/core/test/fast/read-package-json_spec.ts b/packages/api/core/test/fast/read-package-json_spec.ts index 2c8f37dd38..d0a50d0a9e 100644 --- a/packages/api/core/test/fast/read-package-json_spec.ts +++ b/packages/api/core/test/fast/read-package-json_spec.ts @@ -1,11 +1,11 @@ import path from 'path'; -import { ForgeConfig } from '@electron-forge/shared-types'; +import { ResolvedForgeConfig } from '@electron-forge/shared-types'; import { expect } from 'chai'; import { readMutatedPackageJson, readRawPackageJson } from '../../src/util/read-package-json'; -const emptyForgeConfig: Partial = { +const emptyForgeConfig: Partial = { packagerConfig: {}, rebuildConfig: {}, makers: [], @@ -31,7 +31,7 @@ describe('read-package-json', () => { triggerHook: () => Promise.resolve(), overrideStartLogic: () => Promise.resolve(false), }, - } as ForgeConfig) + } as ResolvedForgeConfig) ).to.deep.equal(require('../../package.json')); }); @@ -44,7 +44,7 @@ describe('read-package-json', () => { triggerHook: () => Promise.resolve(), overrideStartLogic: () => Promise.resolve(false), }, - } as ForgeConfig) + } as ResolvedForgeConfig) ).to.deep.equal('test_mut'); }); }); diff --git a/packages/api/core/test/fast/upgrade-forge-config_spec.ts b/packages/api/core/test/fast/upgrade-forge-config_spec.ts index 8ffab4a841..e8012b6911 100644 --- a/packages/api/core/test/fast/upgrade-forge-config_spec.ts +++ b/packages/api/core/test/fast/upgrade-forge-config_spec.ts @@ -1,3 +1,5 @@ +import assert from 'assert'; + import { ForgeConfig, IForgeResolvableMaker, IForgeResolvablePublisher } from '@electron-forge/shared-types'; import { expect } from 'chai'; import { merge } from 'lodash'; @@ -104,6 +106,7 @@ describe('upgradeForgeConfig', () => { }; const newConfig = upgradeForgeConfig(oldConfig); expect(newConfig.publishers).to.have.lengthOf(1); + assert(newConfig.publishers); const publisherConfig = (newConfig.publishers[0] as IForgeResolvablePublisher).config; expect(publisherConfig.repository).to.deep.equal(repo); expect(publisherConfig.octokitOptions).to.deep.equal(octokitOptions); diff --git a/packages/api/core/test/fixture/dummy_default_ts_conf/forge.config.ts b/packages/api/core/test/fixture/dummy_default_ts_conf/forge.config.ts new file mode 100644 index 0000000000..7994240c3b --- /dev/null +++ b/packages/api/core/test/fixture/dummy_default_ts_conf/forge.config.ts @@ -0,0 +1,7 @@ +import type { ForgeConfig } from '@electron-forge/shared-types'; + +const config: ForgeConfig = { + buildIdentifier: 'typescript', +}; + +export default config; diff --git a/packages/api/core/test/fixture/dummy_default_ts_conf/package.json b/packages/api/core/test/fixture/dummy_default_ts_conf/package.json new file mode 100644 index 0000000000..6339a1a841 --- /dev/null +++ b/packages/api/core/test/fixture/dummy_default_ts_conf/package.json @@ -0,0 +1,17 @@ +{ + "name": "", + "productName": "", + "version": "1.0.0", + "description": "", + "main": "src/index.js", + "scripts": { + "start": "electron-forge start" + }, + "keywords": [], + "author": "", + "license": "MIT", + "devDependencies": { + "@electron-forge/shared-types": "*", + "electron-prebuilt": "9.9.9" + } +} diff --git a/packages/api/core/test/slow/api_spec_slow.ts b/packages/api/core/test/slow/api_spec_slow.ts index bf46ed1820..f7ead4ad15 100644 --- a/packages/api/core/test/slow/api_spec_slow.ts +++ b/packages/api/core/test/slow/api_spec_slow.ts @@ -1,3 +1,4 @@ +import assert from 'assert'; import { execSync } from 'child_process'; import path from 'path'; @@ -241,6 +242,7 @@ describe('Electron Forge API', () => { packageJSON.name = 'testapp'; packageJSON.version = '1.0.0-beta.1'; packageJSON.productName = 'Test-App'; + assert(packageJSON.config.forge.packagerConfig); packageJSON.config.forge.packagerConfig.asar = false; if (process.platform === 'win32') { await fs.copy(path.join(__dirname, '..', 'fixture', 'bogus-private-key.pvk'), path.join(dir, 'default.pvk')); @@ -255,10 +257,12 @@ describe('Electron Forge API', () => { it('throws an error when all is set', async () => { await updatePackageJSON(dir, async (packageJSON) => { + assert(packageJSON.config.forge.packagerConfig); packageJSON.config.forge.packagerConfig.all = true; }); await expect(forge.package({ dir })).to.eventually.be.rejectedWith(/packagerConfig\.all is not supported by Electron Forge/); await updatePackageJSON(dir, async (packageJSON) => { + assert(packageJSON.config.forge.packagerConfig); delete packageJSON.config.forge.packagerConfig.all; }); }); @@ -308,6 +312,7 @@ describe('Electron Forge API', () => { it('can package without errors', async () => { await updatePackageJSON(dir, async (packageJSON) => { + assert(packageJSON.config.forge.packagerConfig); packageJSON.config.forge.packagerConfig.asar = true; }); diff --git a/packages/maker/base/src/Maker.ts b/packages/maker/base/src/Maker.ts index 7376a5d63b..56118d0a50 100644 --- a/packages/maker/base/src/Maker.ts +++ b/packages/maker/base/src/Maker.ts @@ -1,6 +1,6 @@ import path from 'path'; -import { ForgeArch, ForgeConfig, ForgePlatform, IForgeMaker } from '@electron-forge/shared-types'; +import { ForgeArch, ForgePlatform, IForgeMaker, ResolvedForgeConfig } from '@electron-forge/shared-types'; import fs from 'fs-extra'; import which from 'which'; @@ -31,7 +31,7 @@ export interface MakerOptions { /** * Fully resolved forge configuration, you shouldn't really need this */ - forgeConfig: ForgeConfig; + forgeConfig: ResolvedForgeConfig; /** * The application's package.json file */ diff --git a/packages/plugin/auto-unpack-natives/src/AutoUnpackNativesPlugin.ts b/packages/plugin/auto-unpack-natives/src/AutoUnpackNativesPlugin.ts index ce894519f5..02fc20eee6 100644 --- a/packages/plugin/auto-unpack-natives/src/AutoUnpackNativesPlugin.ts +++ b/packages/plugin/auto-unpack-natives/src/AutoUnpackNativesPlugin.ts @@ -1,5 +1,5 @@ import { PluginBase } from '@electron-forge/plugin-base'; -import { ForgeConfig, ForgeHookFn } from '@electron-forge/shared-types'; +import { ForgeHookFn, ResolvedForgeConfig } from '@electron-forge/shared-types'; import { AutoUnpackNativesConfig } from './Config'; @@ -13,7 +13,7 @@ export default class AutoUnpackNativesPlugin extends PluginBase => { + resolveForgeConfig = async (forgeConfig: ResolvedForgeConfig): Promise => { if (!forgeConfig.packagerConfig) { forgeConfig.packagerConfig = {}; } diff --git a/packages/plugin/base/src/Plugin.ts b/packages/plugin/base/src/Plugin.ts index 5f5373ff99..6f96e2f65d 100644 --- a/packages/plugin/base/src/Plugin.ts +++ b/packages/plugin/base/src/Plugin.ts @@ -1,4 +1,4 @@ -import { ElectronProcess, ForgeConfig, ForgeHookFn, IForgePlugin, StartOptions } from '@electron-forge/shared-types'; +import { ElectronProcess, ForgeHookFn, IForgePlugin, ResolvedForgeConfig, StartOptions } from '@electron-forge/shared-types'; export { StartOptions }; @@ -16,7 +16,7 @@ export default abstract class Plugin implements IForgePlugin { }); } - init(_dir: string, _config: ForgeConfig): void { + init(_dir: string, _config: ResolvedForgeConfig): void { // By default, do nothing. This can be overridden. } diff --git a/packages/plugin/compile/src/lib/compile-hook.ts b/packages/plugin/compile/src/lib/compile-hook.ts index 76913efe08..8aa4c09831 100644 --- a/packages/plugin/compile/src/lib/compile-hook.ts +++ b/packages/plugin/compile/src/lib/compile-hook.ts @@ -1,12 +1,12 @@ import path from 'path'; import { asyncOra } from '@electron-forge/async-ora'; -import { ForgeConfig } from '@electron-forge/shared-types'; +import { ResolvedForgeConfig } from '@electron-forge/shared-types'; import fs from 'fs-extra'; export const createCompileHook = (originalDir: string) => - async (_config: ForgeConfig, buildPath: string): Promise => { + async (_config: ResolvedForgeConfig, buildPath: string): Promise => { await asyncOra('Compiling Application', async () => { // eslint-disable-next-line @typescript-eslint/no-var-requires const compileCLI = require(path.resolve(originalDir, 'node_modules/electron-compile/lib/cli.js')); diff --git a/packages/plugin/electronegativity/src/ElectronegativityPlugin.ts b/packages/plugin/electronegativity/src/ElectronegativityPlugin.ts index 33dba9e083..0562d804d9 100644 --- a/packages/plugin/electronegativity/src/ElectronegativityPlugin.ts +++ b/packages/plugin/electronegativity/src/ElectronegativityPlugin.ts @@ -1,6 +1,6 @@ import runElectronegativity from '@doyensec/electronegativity'; import { PluginBase } from '@electron-forge/plugin-base'; -import { ForgeConfig, ForgeHookFn } from '@electron-forge/shared-types'; +import { ForgeHookFn, ResolvedForgeConfig } from '@electron-forge/shared-types'; // To be more precise, postPackage options we care about. type PostPackageOptions = { @@ -67,7 +67,7 @@ export default class ElectronegativityPlugin extends PluginBase => { + postPackage = async (_forgeConfig: ResolvedForgeConfig, options: PostPackageOptions): Promise => { await runElectronegativity( { ...this.config, diff --git a/packages/plugin/local-electron/src/LocalElectronPlugin.ts b/packages/plugin/local-electron/src/LocalElectronPlugin.ts index 0523c4cae2..e4329391de 100644 --- a/packages/plugin/local-electron/src/LocalElectronPlugin.ts +++ b/packages/plugin/local-electron/src/LocalElectronPlugin.ts @@ -1,5 +1,5 @@ import { PluginBase } from '@electron-forge/plugin-base'; -import { ForgeConfig, ForgeHookFn } from '@electron-forge/shared-types'; +import { ForgeHookFn, ResolvedForgeConfig } from '@electron-forge/shared-types'; import fs from 'fs-extra'; import { LocalElectronPluginConfig } from './Config'; @@ -50,7 +50,7 @@ export default class LocalElectronPlugin extends PluginBase { + private afterExtract = async (_config: ResolvedForgeConfig, buildPath: string, _electronVersion: string, platform: string, arch: string) => { if (!this.enabled) return; this.checkPlatform(platform); diff --git a/packages/plugin/local-electron/test/LocalElectronPlugin_spec.ts b/packages/plugin/local-electron/test/LocalElectronPlugin_spec.ts index 7b53ab1bf4..5ecd087584 100644 --- a/packages/plugin/local-electron/test/LocalElectronPlugin_spec.ts +++ b/packages/plugin/local-electron/test/LocalElectronPlugin_spec.ts @@ -1,7 +1,7 @@ import os from 'os'; import path from 'path'; -import { ForgeConfig } from '@electron-forge/shared-types'; +import { ResolvedForgeConfig } from '@electron-forge/shared-types'; import { expect } from 'chai'; import fs from 'fs-extra'; @@ -78,7 +78,7 @@ describe('LocalElectronPlugin', () => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const fn = p.getHook('packageAfterExtract')!; - await fn({} as ForgeConfig, tmpDir, null, process.platform, process.arch); + await fn({} as ResolvedForgeConfig, tmpDir, null, process.platform, process.arch); expect(await fs.pathExists(tmpDir)).to.equal(true); expect(await fs.pathExists(path.resolve(tmpDir, 'touch'))).to.equal(true); @@ -88,7 +88,7 @@ describe('LocalElectronPlugin', () => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const fn = p.getHook('packageAfterExtract')!; - await expect(fn({} as ForgeConfig, tmpDir, null, 'bad', process.arch)).to.eventually.be.rejectedWith( + await expect(fn({} as ResolvedForgeConfig, tmpDir, null, 'bad', process.arch)).to.eventually.be.rejectedWith( `Can not use local Electron version, required platform "bad" but local platform is "${process.platform}"` ); }); @@ -97,7 +97,7 @@ describe('LocalElectronPlugin', () => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const fn = p.getHook('packageAfterExtract')!; - await expect(fn({} as ForgeConfig, tmpDir, null, process.platform, 'bad')).to.eventually.be.rejectedWith( + await expect(fn({} as ResolvedForgeConfig, tmpDir, null, process.platform, 'bad')).to.eventually.be.rejectedWith( `Can not use local Electron version, required arch "bad" but local arch is "${process.arch}"` ); }); @@ -109,7 +109,7 @@ describe('LocalElectronPlugin', () => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const fn = p.getHook('packageAfterExtract')!; - await fn({} as ForgeConfig, tmpDir, null, process.platform, process.arch); + await fn({} as ResolvedForgeConfig, tmpDir, null, process.platform, process.arch); expect(await fs.pathExists(path.resolve(tmpDir, 'touch'))).to.equal(false); expect(await fs.pathExists(path.resolve(tmpDir, 'electron'))).to.equal(true); diff --git a/packages/plugin/webpack/src/WebpackPlugin.ts b/packages/plugin/webpack/src/WebpackPlugin.ts index 306c61aff6..a8705fd449 100644 --- a/packages/plugin/webpack/src/WebpackPlugin.ts +++ b/packages/plugin/webpack/src/WebpackPlugin.ts @@ -4,7 +4,7 @@ import path from 'path'; import { asyncOra } from '@electron-forge/async-ora'; import { utils } from '@electron-forge/core'; import { PluginBase } from '@electron-forge/plugin-base'; -import { ElectronProcess, ForgeArch, ForgeConfig, ForgeHookFn, ForgePlatform } from '@electron-forge/shared-types'; +import { ElectronProcess, ForgeArch, ForgeHookFn, ForgePlatform, ResolvedForgeConfig } from '@electron-forge/shared-types'; import Logger, { Tab } from '@electron-forge/web-multi-logger'; import chalk from 'chalk'; import debug from 'debug'; @@ -155,7 +155,7 @@ export default class WebpackPlugin extends PluginBase { switch (name) { case 'prePackage': this.isProd = true; - return async (config: ForgeConfig, platform: ForgePlatform, arch: ForgeArch) => { + return async (config: ResolvedForgeConfig, platform: ForgePlatform, arch: ForgeArch) => { await fs.remove(this.baseDir); await utils.rebuildHook( this.projectDir, @@ -168,7 +168,7 @@ export default class WebpackPlugin extends PluginBase { await this.compileRenderers(); }; case 'postStart': - return async (_config: ForgeConfig, child: ElectronProcess) => { + return async (_config: ResolvedForgeConfig, child: ElectronProcess) => { if (!this.loggedOutputUrl) { console.info(`\n\nWebpack Output Available: ${chalk.cyan(`http://localhost:${this.loggerPort}`)}\n`); this.loggedOutputUrl = true; @@ -188,7 +188,7 @@ export default class WebpackPlugin extends PluginBase { } } - resolveForgeConfig = async (forgeConfig: ForgeConfig): Promise => { + resolveForgeConfig = async (forgeConfig: ResolvedForgeConfig): Promise => { if (!forgeConfig.packagerConfig) { forgeConfig.packagerConfig = {}; } @@ -222,7 +222,7 @@ Your packaged app may be larger than expected if you dont ignore everything othe return forgeConfig; }; - packageAfterCopy = async (_forgeConfig: ForgeConfig, buildPath: string): Promise => { + packageAfterCopy = async (_forgeConfig: ResolvedForgeConfig, buildPath: string): Promise => { const pj = await fs.readJson(path.resolve(this.projectDir, 'package.json')); if (!pj.main?.endsWith('.webpack/main')) { diff --git a/packages/plugin/webpack/test/WebpackPlugin_spec.ts b/packages/plugin/webpack/test/WebpackPlugin_spec.ts index 128d6abf47..4d6080190d 100644 --- a/packages/plugin/webpack/test/WebpackPlugin_spec.ts +++ b/packages/plugin/webpack/test/WebpackPlugin_spec.ts @@ -1,7 +1,7 @@ import * as os from 'os'; import * as path from 'path'; -import { ForgeConfig } from '@electron-forge/shared-types'; +import { ResolvedForgeConfig } from '@electron-forge/shared-types'; import { expect } from 'chai'; import { IgnoreFunction } from 'electron-packager'; import * as fs from 'fs-extra'; @@ -45,7 +45,7 @@ describe('WebpackPlugin', () => { it('should remove config.forge from package.json', async () => { const packageJSON = { main: './.webpack/main', config: { forge: 'config.js' } }; await fs.writeJson(packageJSONPath, packageJSON); - await plugin.packageAfterCopy({} as ForgeConfig, packagedPath); + await plugin.packageAfterCopy({} as ResolvedForgeConfig, packagedPath); expect(await fs.pathExists(packagedPackageJSONPath)).to.equal(true); expect((await fs.readJson(packagedPackageJSONPath)).config).to.not.have.property('forge'); }); @@ -53,7 +53,7 @@ describe('WebpackPlugin', () => { it('should succeed if there is no config.forge', async () => { const packageJSON = { main: '.webpack/main' }; await fs.writeJson(packageJSONPath, packageJSON); - await plugin.packageAfterCopy({} as ForgeConfig, packagedPath); + await plugin.packageAfterCopy({} as ResolvedForgeConfig, packagedPath); expect(await fs.pathExists(packagedPackageJSONPath)).to.equal(true); expect(await fs.readJson(packagedPackageJSONPath)).to.not.have.property('config'); }); @@ -61,13 +61,13 @@ describe('WebpackPlugin', () => { it('should fail if there is no main key in package.json', async () => { const packageJSON = {}; await fs.writeJson(packageJSONPath, packageJSON); - await expect(plugin.packageAfterCopy({} as ForgeConfig, packagedPath)).to.eventually.be.rejectedWith(/entry point/); + await expect(plugin.packageAfterCopy({} as ResolvedForgeConfig, packagedPath)).to.eventually.be.rejectedWith(/entry point/); }); it('should fail if main in package.json does not end with .webpack/main', async () => { const packageJSON = { main: 'src/main.js' }; await fs.writeJson(packageJSONPath, packageJSON); - await expect(plugin.packageAfterCopy({} as ForgeConfig, packagedPath)).to.eventually.be.rejectedWith(/entry point/); + await expect(plugin.packageAfterCopy({} as ResolvedForgeConfig, packagedPath)).to.eventually.be.rejectedWith(/entry point/); }); after(async () => { @@ -83,7 +83,7 @@ describe('WebpackPlugin', () => { }); it('sets packagerConfig and packagerConfig.ignore if it does not exist', async () => { - const config = await plugin.resolveForgeConfig({} as ForgeConfig); + const config = await plugin.resolveForgeConfig({} as ResolvedForgeConfig); expect(config.packagerConfig).to.not.equal(undefined); expect(config.packagerConfig.ignore).to.be.a('function'); }); @@ -94,13 +94,13 @@ describe('WebpackPlugin', () => { packagerConfig: { ignore: /test/, }, - } as ForgeConfig); + } as ResolvedForgeConfig); expect(config.packagerConfig.ignore).to.deep.equal(/test/); }); it('ignores everything but files in .webpack', async () => { - const config = await plugin.resolveForgeConfig({} as ForgeConfig); + const config = await plugin.resolveForgeConfig({} as ResolvedForgeConfig); const ignore = config.packagerConfig.ignore as IgnoreFunction; expect(ignore('')).to.equal(false); @@ -113,7 +113,7 @@ describe('WebpackPlugin', () => { const webpackConfig = { ...baseConfig, jsonStats: true }; webpackConfig.renderer.jsonStats = true; plugin = new WebpackPlugin(webpackConfig); - const config = await plugin.resolveForgeConfig({} as ForgeConfig); + const config = await plugin.resolveForgeConfig({} as ResolvedForgeConfig); const ignore = config.packagerConfig.ignore as IgnoreFunction; expect(ignore(path.join('foo', 'bar', '.webpack', 'main', 'stats.json'))).to.equal(true); @@ -123,7 +123,7 @@ describe('WebpackPlugin', () => { it('ignores source map files by default', async () => { const webpackConfig = { ...baseConfig }; plugin = new WebpackPlugin(webpackConfig); - const config = await plugin.resolveForgeConfig({} as ForgeConfig); + const config = await plugin.resolveForgeConfig({} as ResolvedForgeConfig); const ignore = config.packagerConfig.ignore as IgnoreFunction; expect(ignore(path.join('/.webpack', 'main', 'index.js'))).to.equal(false); @@ -135,7 +135,7 @@ describe('WebpackPlugin', () => { it('includes source map files when specified by config', async () => { const webpackConfig = { ...baseConfig, packageSourceMaps: true }; plugin = new WebpackPlugin(webpackConfig); - const config = await plugin.resolveForgeConfig({} as ForgeConfig); + const config = await plugin.resolveForgeConfig({} as ResolvedForgeConfig); const ignore = config.packagerConfig.ignore as IgnoreFunction; expect(ignore(path.join('/.webpack', 'main', 'index.js'))).to.equal(false); diff --git a/packages/publisher/base/src/Publisher.ts b/packages/publisher/base/src/Publisher.ts index 7546f9c8bc..29f0f949ec 100644 --- a/packages/publisher/base/src/Publisher.ts +++ b/packages/publisher/base/src/Publisher.ts @@ -1,4 +1,4 @@ -import { ForgeConfig, ForgeMakeResult, ForgePlatform, IForgePublisher } from '@electron-forge/shared-types'; +import { ForgeMakeResult, ForgePlatform, IForgePublisher, ResolvedForgeConfig } from '@electron-forge/shared-types'; export interface PublisherOptions { /** @@ -14,7 +14,7 @@ export interface PublisherOptions { * * You probably shouldn't use this */ - forgeConfig: ForgeConfig; + forgeConfig: ResolvedForgeConfig; } export default abstract class Publisher implements IForgePublisher { diff --git a/packages/publisher/electron-release-server/test/PublisherERS_spec.ts b/packages/publisher/electron-release-server/test/PublisherERS_spec.ts index e9dddafd33..53e2f21e4d 100644 --- a/packages/publisher/electron-release-server/test/PublisherERS_spec.ts +++ b/packages/publisher/electron-release-server/test/PublisherERS_spec.ts @@ -1,4 +1,4 @@ -import { ForgeConfig, ForgeMakeResult } from '@electron-forge/shared-types'; +import { ForgeMakeResult, ResolvedForgeConfig } from '@electron-forge/shared-types'; import { expect } from 'chai'; import fetchMock from 'fetch-mock'; import proxyquire from 'proxyquire'; @@ -55,7 +55,7 @@ describe('PublisherERS', () => { }, ]; - await publisher.publish({ makeResults, dir: '', forgeConfig: {} as ForgeConfig }); + await publisher.publish({ makeResults, dir: '', forgeConfig: {} as ResolvedForgeConfig }); const calls = fetch.calls(); @@ -102,7 +102,7 @@ describe('PublisherERS', () => { }, ]; - await publisher.publish({ makeResults, dir: '', forgeConfig: {} as ForgeConfig }); + await publisher.publish({ makeResults, dir: '', forgeConfig: {} as ResolvedForgeConfig }); const calls = fetch.calls(); @@ -139,7 +139,7 @@ describe('PublisherERS', () => { }, ]; - await publisher.publish({ makeResults, dir: '', forgeConfig: {} as ForgeConfig }); + await publisher.publish({ makeResults, dir: '', forgeConfig: {} as ResolvedForgeConfig }); const calls = fetch.calls(); expect(calls).to.have.length(2); @@ -178,7 +178,7 @@ describe('PublisherERS', () => { }, ]; - await publisher.publish({ makeResults, dir: '', forgeConfig: {} as ForgeConfig }); + await publisher.publish({ makeResults, dir: '', forgeConfig: {} as ResolvedForgeConfig }); const calls = fetch.calls(); @@ -198,7 +198,7 @@ describe('PublisherERS', () => { it('fails if username and password are not provided', () => { const publisher = new PublisherERS({}); - expect(publisher.publish({ makeResults: [], dir: '', forgeConfig: {} as ForgeConfig })).to.eventually.be.rejectedWith( + expect(publisher.publish({ makeResults: [], dir: '', forgeConfig: {} as ResolvedForgeConfig })).to.eventually.be.rejectedWith( 'In order to publish to ERS you must set the "electronReleaseServer.baseUrl", "electronReleaseServer.username" and "electronReleaseServer.password" properties in your Forge config. See the docs for more info' ); }); @@ -211,7 +211,7 @@ describe('PublisherERS', () => { username: 'test', password: 'test', }); - return expect(publisher.publish({ makeResults: [], dir: '', forgeConfig: {} as ForgeConfig })).to.eventually.be.rejectedWith( + return expect(publisher.publish({ makeResults: [], dir: '', forgeConfig: {} as ResolvedForgeConfig })).to.eventually.be.rejectedWith( 'ERS publish failed with status code: 400 (http://example.com/api/auth/login)' ); }); diff --git a/packages/utils/types/src/index.ts b/packages/utils/types/src/index.ts index f16640645f..477e01fb81 100644 --- a/packages/utils/types/src/index.ts +++ b/packages/utils/types/src/index.ts @@ -9,7 +9,7 @@ export type ForgePlatform = TargetPlatform; export type ForgeArch = ArchOption; // Why: hooks have any number/kind of args/return values /* eslint-disable @typescript-eslint/no-explicit-any */ -export type ForgeHookFn = (forgeConfig: ForgeConfig, ...args: any[]) => Promise; +export type ForgeHookFn = (forgeConfig: ResolvedForgeConfig, ...args: any[]) => Promise; export type ForgeConfigPublisher = IForgeResolvablePublisher | IForgePublisher; export type ForgeConfigMaker = IForgeResolvableMaker | IForgeMaker; export type ForgeConfigPlugin = IForgeResolvablePlugin | IForgePlugin; @@ -22,7 +22,7 @@ export interface IForgePluginInterface { export type ForgeRebuildOptions = Omit; export type ForgePackagerOptions = Omit; -export interface ForgeConfig { +export interface ResolvedForgeConfig { /** * A string to uniquely identify artifacts of this build, will be appended * to the out dir to generate a nested directory. E.g. out/current-timestamp @@ -46,6 +46,7 @@ export interface ForgeConfig { makers: ForgeConfigMaker[]; publishers: ForgeConfigPublisher[]; } +export type ForgeConfig = Partial>; export interface ForgeMakeResult { /** * An array of paths to artifacts generated for this make run @@ -75,7 +76,7 @@ export interface IForgePlugin { __isElectronForgePlugin: boolean; name: string; - init(dir: string, forgeConfig: ForgeConfig): void; + init(dir: string, forgeConfig: ResolvedForgeConfig): void; getHook?(hookName: string): ForgeHookFn | null; startLogic?(opts: StartOptions): Promise; } diff --git a/yarn.lock b/yarn.lock index db16ac366b..f743195215 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1826,6 +1826,13 @@ "@types/through" "*" rxjs "^7.2.0" +"@types/interpret@*", "@types/interpret@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/interpret/-/interpret-1.1.1.tgz#b1bf85b0420e2414b989ce237658ad20dc03719b" + integrity sha512-HZ4d0m2Ebl8DmrOdYZHgYyipj/8Ftq1/ssB/oQR7fqfUrwtTP7IW3BDi2V445nhPBLzZjEkApaPVp83moSCXlA== + dependencies: + "@types/node" "*" + "@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.9" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" @@ -1921,6 +1928,13 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== +"@types/rechoir@^0.6.1": + version "0.6.1" + resolved "https://registry.yarnpkg.com/@types/rechoir/-/rechoir-0.6.1.tgz#e7589df255d2638db48b0dfc3294c87dc9db19ba" + integrity sha512-HbMQqyZC8W9NxE3R89rW+hFwFXeIdmCT7x91NQjzB4+0CI42K/CJfRak5/jAQ7L5qi1cGcQQdo+GI9pqqUhbKQ== + dependencies: + "@types/interpret" "*" + "@types/responselike@*", "@types/responselike@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" @@ -5686,6 +5700,11 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" +interpret@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4" + integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ== + ip@^1.1.0, ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" @@ -7925,6 +7944,13 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +rechoir@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" + integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== + dependencies: + resolve "^1.20.0" + redent@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde"