graphql-mesh
graphql-mesh copied to clipboard
Bug in mesh build when composer does not export `defaults`
The mesh build command produces invalid index.js
file when no default exports are defined. This is a very common scenario when using typescript, but does also applies to js composers without default exports.
To Reproduce
# Mesh config excerpt
transforms:
- resolversComposition:
mode: bare
compositions:
- resolver: Query.*
composer: ./composers#isAuth
require:
- ts-node/register/transpile-only
// composers.ts
export function isAuth(next) => {
return (root, args, context, info) => {
// Check if Authorization header is present
if(!context.headers.authorization) {
throw new Error('Unauthorized');
}
return next(root, args, context, info);
}
}
This does generate the following code in the index file:
import ExternalModule_1 from './composers'; //<- since there is no default export this does not work
Expected behavior Mesh build should generate a valid import for composers without default export.
Additional context There three ways I can think of to check if a composer has defaults exports:
- Identify if a composer has default export
- by looking into the source file and search for
export defaults
- by importing the composer during build via
import * as DUMMY from '.mycomposer'
and then check ifDUMMY['defaults']
isundefined
- by intermediary importing the composer in generated index file via a
* as
import, but use the default import as actual import + fallback to* as
if no default export exists
- by looking into the source file and search for
import * as ExternalModule_1_all from './composers';
const ExternalModule_13 = ExternalModule_13_all['defaults'] || ExternalModule_13_all;
// if possible this would only be done for custom composers and not for handlers + transform packages itself.
Summary The last solution seems to be the most straight forward. It does not extend build time, while only having a absolutely tiny effect on startup time.
Let me know if you agree with the approach (or suggest a different one) and I will make a PR.
It needs some work on runtime
package because * as
is not valid for the actual ESM spec.
I did a test run via patch-package and it does seem to work without issues. Since you are generating a typescript document first and then compile to js the typescript compiler seems to resolve the * as
import somehow successfully and my mesh then starts without issues.
In js:
const ExternalModule_0 = (0, tslib_1.__importStar)(require("ts-node/register/transpile-only"));
In mjs:
import * as ExternalModule_0 from 'ts-node/register/transpile-only';
Since I couldn't keep my hands still in #2970 you can see a the first swing at a solution meant for discussion. Also fixed a minor typing error.
@ardatan Might have missed something completely, what do you mean by needs some work on runtime package?