diff --git a/index.js b/index.js index 57460bf..d11f7c1 100644 --- a/index.js +++ b/index.js @@ -13,7 +13,7 @@ function escapeRegExp(str) { } function isJsFile(str) { - return !!str.match(/\.c?js$/); + return !!str.match(/\.(?:c?js|ts)$/); } function defaultLogger(params) { @@ -107,6 +107,35 @@ function findMatchingPath(requestPath, requestMethodFiles) { return result; } +function normalizeMiddleware(mod) { + // 1. Already a function or array → OK + if (typeof mod === 'function' || Array.isArray(mod)) { + return mod; + } + + // 2. Babel / TS interop + if (mod && mod.__esModule && 'default' in mod) { + return mod.default; + } + + // 3. Native ESM via Symbol.toStringTag + if ( + mod && + typeof mod === 'object' && + mod[Symbol.toStringTag] === 'Module' && + 'default' in mod + ) { + return mod.default; + } + + // 4. Node ESM interop fallback (safe) + if (mod && typeof mod === 'object' && 'default' in mod) { + return mod.default; + } + + return mod; +} + /** * @param {string|object} urlRoot Base path for API url or full config object * @param {string|object} pathRoot Base path of API mock files. eg: ./mock/api or @@ -170,10 +199,10 @@ module.exports = function (urlRoot, pathRoot) { const returnForPath = function (filePath, requestParams) { if (isJsFile(filePath)) { logger({ - req, filePath, fileType: 'js', config + req, filePath, config }); delete require.cache[require.resolve(path.resolve(filePath))]; - let customMiddleware = require(path.resolve(filePath)); + let customMiddleware = normalizeMiddleware(require(path.resolve(filePath))); if (requestParams) { req.params = requestParams; } @@ -222,7 +251,7 @@ module.exports = function (urlRoot, pathRoot) { methodFileExtension = req.accepts(['json', 'xml']); } - const fileExtensions = [methodFileExtension, 'cjs', 'js']; + const fileExtensions = [methodFileExtension, 'ts', 'cjs', 'js']; const jsMockFiles = fileExtensions.map((ext) => `${req.method}.${ext}`); const wildcardJsMockFiles = fileExtensions.map((ext) => `ANY.${ext}`); const methodFiles = [...jsMockFiles, ...wildcardJsMockFiles]; diff --git a/test/api-mocker.spec.js b/test/api-mocker.spec.js index 0ad2bd4..13d5454 100644 --- a/test/api-mocker.spec.js +++ b/test/api-mocker.spec.js @@ -115,6 +115,19 @@ describe('cjs extensions for custom middlewares', () => { }); }); +describe('ts extensions for custom middlewares', () => { + it('responds by simple ts middleware', (done) => { + request(app) + + .get('/api/users/4') + .expect('Content-Type', /json/) + .expect(200) + .expect({ + result: 'ts works' + }, done); + }); +}); + describe('nextOnNotFound setting', () => { it('returns correct response when mock is exits', (done) => { request(app) diff --git a/test/mocks/users/4/GET.ts b/test/mocks/users/4/GET.ts new file mode 100644 index 0000000..6b59f72 --- /dev/null +++ b/test/mocks/users/4/GET.ts @@ -0,0 +1,5 @@ +export default function (req: any, res: any) { + res.json({ + result: 'ts works' + }); +};