Skip to content

Commit 35cabfe

Browse files
authored
feat(core)!: remove rechoir + lodash templates from config loader (#4066)
1 parent 5c3ffa7 commit 35cabfe

File tree

4 files changed

+35
-114
lines changed

4 files changed

+35
-114
lines changed

packages/api/core/spec/fast/util/forge-config.spec.ts

Lines changed: 23 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { describe, expect, it, vi } from 'vitest';
66
import findConfig, {
77
forgeConfigIsValidFilePath,
88
registerForgeConfigForDirectory,
9-
renderConfigTemplate,
109
unregisterForgeConfigForDirectory,
1110
} from '../../../src/util/forge-config';
1211

@@ -78,7 +77,7 @@ describe('findConfig', () => {
7877
'../../fixture/bad_forge_config',
7978
);
8079
const err =
81-
'Expected packageJSON.config.forge to be an object or point to a requirable JS file';
80+
'Expected `config.forge` in package.json to be an object or point to a Forge config file';
8281
await expect(findConfig(fixturePath)).rejects.toThrow(err);
8382
});
8483

@@ -90,7 +89,7 @@ describe('findConfig', () => {
9089
__dirname,
9190
'../../fixture/bad_external_forge_config',
9291
);
93-
const err = /Unexpected token/;
92+
const err = /Failed to parse/;
9493
await expect(findConfig(fixturePath)).rejects.toThrow(err);
9594
spy.mockRestore();
9695
});
@@ -294,43 +293,32 @@ describe('findConfig', () => {
294293
});
295294
});
296295

297-
describe('alternate config formats', () => {
298-
it('should resolve the yml config from forge.config.yml specified in config.forge', async () => {
296+
describe('TypeScript', () => {
297+
it('should resolve forge.config.ts', async () => {
299298
const fixturePath = path.resolve(
300299
__dirname,
301-
'../../fixture/dummy_ts_conf',
300+
'../../fixture/dummy_default_ts_conf',
302301
);
303302
const conf = await findConfig(fixturePath);
304-
expect(conf.buildIdentifier).toEqual('yml');
303+
expect(conf.buildIdentifier).toEqual('typescript');
305304
});
306305

307-
describe('TypeScript', () => {
308-
it('should resolve forge.config.ts', async () => {
309-
const fixturePath = path.resolve(
310-
__dirname,
311-
'../../fixture/dummy_default_ts_conf',
312-
);
313-
const conf = await findConfig(fixturePath);
314-
expect(conf.buildIdentifier).toEqual('typescript');
315-
});
316-
317-
it('should resolve forge.config.cts', async () => {
318-
const fixturePath = path.resolve(
319-
__dirname,
320-
'../../fixture/dummy_default_cts_conf',
321-
);
322-
const conf = await findConfig(fixturePath);
323-
expect(conf.buildIdentifier).toEqual('typescript-commonjs');
324-
});
306+
it('should resolve forge.config.cts', async () => {
307+
const fixturePath = path.resolve(
308+
__dirname,
309+
'../../fixture/dummy_default_cts_conf',
310+
);
311+
const conf = await findConfig(fixturePath);
312+
expect(conf.buildIdentifier).toEqual('typescript-commonjs');
313+
});
325314

326-
it('should resolve forge.config.mts', async () => {
327-
const fixturePath = path.resolve(
328-
__dirname,
329-
'../../fixture/dummy_default_mts_conf',
330-
);
331-
const conf = await findConfig(fixturePath);
332-
expect(conf.buildIdentifier).toEqual('typescript-esm');
333-
});
315+
it('should resolve forge.config.mts', async () => {
316+
const fixturePath = path.resolve(
317+
__dirname,
318+
'../../fixture/dummy_default_mts_conf',
319+
);
320+
const conf = await findConfig(fixturePath);
321+
expect(conf.buildIdentifier).toEqual('typescript-esm');
334322
});
335323
});
336324
});
@@ -366,28 +354,13 @@ describe('forgeConfigIsValidFilePath', () => {
366354
const fixturePath = path.resolve(__dirname, '../../fixture/dummy_js_conf/');
367355
await expect(
368356
forgeConfigIsValidFilePath(fixturePath, 'forge.different.config'),
369-
).resolves.toEqual(true);
357+
).toEqual(true);
370358
});
371359

372360
it('fails when a file is nonexistent', async () => {
373361
const fixturePath = path.resolve(__dirname, '../../fixture/dummy_js_conf/');
374362
await expect(
375363
forgeConfigIsValidFilePath(fixturePath, 'forge.nonexistent.config'),
376-
).resolves.toEqual(false);
377-
});
378-
});
379-
380-
describe('renderConfigTemplate', () => {
381-
it('should import a JS file when a string starts with "require:"', () => {
382-
const dir = path.resolve(__dirname, '../../fixture/dummy_js_conf');
383-
const config = {
384-
foo: 'require:foo',
385-
};
386-
renderConfigTemplate(dir, {}, config);
387-
expect(config.foo).toEqual({
388-
bar: {
389-
baz: 'quux',
390-
},
391-
});
364+
).toEqual(false);
392365
});
393366
});

packages/api/core/spec/fixture/dummy_ts_conf/forge.config.yml

Lines changed: 0 additions & 1 deletion
This file was deleted.

packages/api/core/spec/fixture/dummy_ts_conf/package.json

Lines changed: 0 additions & 20 deletions
This file was deleted.

packages/api/core/src/util/forge-config.ts

Lines changed: 12 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ import path from 'node:path';
22

33
import { ForgeConfig, ResolvedForgeConfig } from '@electron-forge/shared-types';
44
import fs from 'fs-extra';
5-
import * as interpret from 'interpret';
65
import { createJiti } from 'jiti';
7-
import { template } from 'lodash';
8-
import * as rechoir from 'rechoir';
96

107
// eslint-disable-next-line n/no-missing-import
118
import { dynamicImportMaybe } from '../../helper/dynamic-import.js';
@@ -126,36 +123,17 @@ export function fromBuildIdentifier<T>(
126123
};
127124
}
128125

129-
export async function forgeConfigIsValidFilePath(
126+
export function forgeConfigIsValidFilePath(
130127
dir: string,
131128
forgeConfig: string | ForgeConfig,
132-
): Promise<boolean> {
129+
): boolean {
133130
return (
134131
typeof forgeConfig === 'string' &&
135-
((await fs.pathExists(path.resolve(dir, forgeConfig))) ||
136-
fs.pathExists(path.resolve(dir, `${forgeConfig}.js`)))
132+
(fs.existsSync(path.resolve(dir, forgeConfig)) ||
133+
fs.existsSync(path.resolve(dir, `${forgeConfig}.js`)))
137134
);
138135
}
139136

140-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
141-
export function renderConfigTemplate(
142-
dir: string,
143-
templateObj: any,
144-
obj: any,
145-
): void {
146-
for (const [key, value] of Object.entries(obj)) {
147-
if (typeof value === 'object' && value !== null) {
148-
renderConfigTemplate(dir, templateObj, value);
149-
} else if (typeof value === 'string') {
150-
obj[key] = template(value)(templateObj);
151-
if (obj[key].startsWith('require:')) {
152-
// eslint-disable-next-line @typescript-eslint/no-require-imports
153-
obj[key] = require(path.resolve(dir, obj[key].substr(8)));
154-
}
155-
}
156-
}
157-
}
158-
159137
type MaybeESM<T> = T | { default: T };
160138
type AsyncForgeConfigGenerator = () => Promise<ForgeConfig>;
161139

@@ -172,27 +150,21 @@ export default async (dir: string): Promise<ResolvedForgeConfig> => {
172150
}
173151

174152
if (!forgeConfig || typeof forgeConfig === 'string') {
175-
// interpret.extensions doesn't support `.mts` files
176-
for (const extension of [
177-
'.js',
178-
'.mts',
179-
...Object.keys(interpret.extensions),
180-
]) {
153+
for (const extension of ['.js', '.mjs', '.cjs', '.ts', '.mts', '.cts']) {
181154
const pathToConfig = path.resolve(dir, `forge.config${extension}`);
182-
if (await fs.pathExists(pathToConfig)) {
183-
// Use rechoir to parse alternative syntaxes (except for TypeScript where we use jiti)
184-
if (!['.cts', '.mts', '.ts'].includes(extension)) {
185-
rechoir.prepare(interpret.extensions, pathToConfig, dir);
186-
}
155+
if (fs.existsSync(pathToConfig)) {
187156
forgeConfig = `forge.config${extension}`;
188157
break;
189158
}
190159
}
191160
}
192161
forgeConfig = forgeConfig || ({} as ForgeConfig);
193162

194-
if (await forgeConfigIsValidFilePath(dir, forgeConfig)) {
195-
const forgeConfigPath = path.resolve(dir, forgeConfig as string);
163+
if (
164+
typeof forgeConfig === 'string' &&
165+
forgeConfigIsValidFilePath(dir, forgeConfig)
166+
) {
167+
const forgeConfigPath = path.resolve(dir, forgeConfig);
196168
try {
197169
let loadFn;
198170
if (['.cts', '.mts', '.ts'].includes(path.extname(forgeConfigPath))) {
@@ -216,7 +188,7 @@ export default async (dir: string): Promise<ResolvedForgeConfig> => {
216188
}
217189
} else if (typeof forgeConfig !== 'object') {
218190
throw new Error(
219-
'Expected packageJSON.config.forge to be an object or point to a requirable JS file',
191+
'Expected `config.forge` in package.json to be an object or point to a Forge config file',
220192
);
221193
}
222194
const defaultForgeConfig = {
@@ -233,9 +205,6 @@ export default async (dir: string): Promise<ResolvedForgeConfig> => {
233205
pluginInterface: null as any,
234206
};
235207

236-
const templateObj = { ...packageJSON, year: new Date().getFullYear() };
237-
renderConfigTemplate(dir, templateObj, resolvedForgeConfig);
238-
239208
resolvedForgeConfig.pluginInterface = await PluginInterface.create(
240209
dir,
241210
resolvedForgeConfig,

0 commit comments

Comments
 (0)