From 515368052eafbc23cbf9a6abdfd293dd11baa83c Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 29 Oct 2025 17:28:39 -0400 Subject: [PATCH 1/3] feat: load config with jiti --- packages/orval/package.json | 1 + packages/orval/src/generate.ts | 33 ++++++++++++++++++++---------- tests/configs/multi-file.config.ts | 3 +++ tests/configs/my-module.ts | 1 + yarn.lock | 10 +++++++++ 5 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 tests/configs/my-module.ts diff --git a/packages/orval/package.json b/packages/orval/package.json index 0580daf71..739d267ca 100644 --- a/packages/orval/package.json +++ b/packages/orval/package.json @@ -90,6 +90,7 @@ "execa": "^5.1.1", "find-up": "5.0.0", "fs-extra": "^11.3.2", + "jiti": "^2.6.1", "js-yaml": "4.1.0", "lodash.uniq": "^4.5.0", "openapi3-ts": "4.5.0", diff --git a/packages/orval/src/generate.ts b/packages/orval/src/generate.ts index 998787a6d..ee9ea7d46 100644 --- a/packages/orval/src/generate.ts +++ b/packages/orval/src/generate.ts @@ -1,7 +1,6 @@ import fs from 'node:fs'; import path from 'node:path'; import process from 'node:process'; -import url from 'node:url'; import { asyncReduce, @@ -17,6 +16,7 @@ import { type NormalizedOptions, removeFilesAndEmptyFolders, } from '@orval/core'; +import { createJiti } from 'jiti'; import { importSpecs } from './import-specs'; import { normalizeOptions } from './utils/options'; @@ -95,10 +95,14 @@ export const generateSpecs = async ( function findConfigFile(configFilePath?: string) { if (configFilePath) { - if (!fs.existsSync(configFilePath)) + const absolutePath = path.isAbsolute(configFilePath) + ? configFilePath + : path.resolve(process.cwd(), configFilePath); + + if (!fs.existsSync(absolutePath)) throw new Error(`Config file ${configFilePath} does not exist`); - return configFilePath; + return absolutePath; } const root = process.cwd(); @@ -113,6 +117,20 @@ function findConfigFile(configFilePath?: string) { throw new Error(`No config file found in ${root}`); } +async function loadConfigFile(configFilePath: string): Promise { + const jiti = createJiti(import.meta.url, { + interopDefault: true, + }); + + const module = await jiti.import(configFilePath, { default: true }); + + if (module === undefined) { + throw new Error(`${configFilePath} doesn't have a default export`); + } + + return await Promise.resolve(module as ConfigExternal); +} + export const generateConfig = async ( configFile?: string, options?: GlobalOptions, @@ -120,14 +138,7 @@ export const generateConfig = async ( const configFilePath = findConfigFile(configFile); let configExternal: ConfigExternal; try { - const importPath = url.pathToFileURL(configFilePath).href; - const importedModule = (await import(importPath)) as { - default?: ConfigExternal; - }; - if (importedModule.default === undefined) { - throw new Error(`${configFilePath} doesn't have a default export`); - } - configExternal = importedModule.default; + configExternal = await loadConfigFile(configFilePath); } catch (error) { const errorMsg = error instanceof Error ? error.message : 'unknown error'; throw new Error(`failed to load from ${configFilePath} => ${errorMsg}`); diff --git a/tests/configs/multi-file.config.ts b/tests/configs/multi-file.config.ts index 24835513f..b18b154c5 100644 --- a/tests/configs/multi-file.config.ts +++ b/tests/configs/multi-file.config.ts @@ -1,5 +1,8 @@ import { defineConfig } from 'orval'; +// test esm module import +export { MY_CONST } from './my-module'; + export default defineConfig({ api: { input: '../specifications/multi-files/api.yaml', diff --git a/tests/configs/my-module.ts b/tests/configs/my-module.ts new file mode 100644 index 000000000..4868bcea4 --- /dev/null +++ b/tests/configs/my-module.ts @@ -0,0 +1 @@ +export const MY_CONST = 42; diff --git a/yarn.lock b/yarn.lock index 4f3aaabe7..fbe3d697b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16603,6 +16603,15 @@ __metadata: languageName: node linkType: hard +"jiti@npm:^2.6.1": + version: 2.6.1 + resolution: "jiti@npm:2.6.1" + bin: + jiti: lib/jiti-cli.mjs + checksum: 10c0/79b2e96a8e623f66c1b703b98ec1b8be4500e1d217e09b09e343471bbb9c105381b83edbb979d01cef18318cc45ce6e153571b6c83122170eefa531c64b6789b + languageName: node + linkType: hard + "js-beautify@npm:^1.14.9": version: 1.15.4 resolution: "js-beautify@npm:1.15.4" @@ -19191,6 +19200,7 @@ __metadata: execa: "npm:^5.1.1" find-up: "npm:5.0.0" fs-extra: "npm:^11.3.2" + jiti: "npm:^2.6.1" js-yaml: "npm:4.1.0" lodash.uniq: "npm:^4.5.0" openapi-types: "npm:^12.1.3" From 884881c8e7464de5446c62ce0c07e3eb316d072a Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 29 Oct 2025 20:12:32 -0400 Subject: [PATCH 2/3] fix: _faker as faker --- packages/mock/src/msw/mocks.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/mock/src/msw/mocks.ts b/packages/mock/src/msw/mocks.ts index d45435d06..c65d3e07b 100644 --- a/packages/mock/src/msw/mocks.ts +++ b/packages/mock/src/msw/mocks.ts @@ -23,7 +23,7 @@ const getMockPropertiesWithoutFunc = (properties: any, spec: OpenAPIObject) => : stringify(value as string)!; acc[key] = implementation?.replaceAll( - /import_faker.defaults|import_faker.faker/g, + /import_faker\.defaults|import_faker\.faker|_faker\.faker/g, 'faker', ); return acc; @@ -284,7 +284,7 @@ export const getMockOptionsDataOverride = ( : stringify(responseOverride); return implementation?.replaceAll( - /import_faker.defaults|import_faker.faker/g, + /import_faker\.defaults|import_faker\.faker|_faker\.faker/g, 'faker', ); }; From aba75f4105ce6c408b35bd5c5d6ec6aa0495c002 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 30 Oct 2025 12:33:27 -0400 Subject: [PATCH 3/3] test: improve test of module import in config file --- tests/configs/multi-file.config.ts | 9 +++++++-- tests/configs/my-module.ts | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/configs/multi-file.config.ts b/tests/configs/multi-file.config.ts index b18b154c5..f4d3b11e7 100644 --- a/tests/configs/multi-file.config.ts +++ b/tests/configs/multi-file.config.ts @@ -1,7 +1,12 @@ +/* eslint-disable simple-import-sort/exports */ +/* eslint-disable simple-import-sort/imports */ +/* eslint-disable unicorn/prefer-export-from */ import { defineConfig } from 'orval'; -// test esm module import -export { MY_CONST } from './my-module'; +// test esm module import/export +import { MY_CONST, ANOTHER_CONST } from './my-module'; +console.log('TESTING ES MODULE IMPORT/EXPORT', MY_CONST, ANOTHER_CONST); +export { MY_CONST, ANOTHER_CONST }; export default defineConfig({ api: { diff --git a/tests/configs/my-module.ts b/tests/configs/my-module.ts index 4868bcea4..71047230b 100644 --- a/tests/configs/my-module.ts +++ b/tests/configs/my-module.ts @@ -1 +1,2 @@ export const MY_CONST = 42; +export const ANOTHER_CONST = 'Hello, World!';