diff --git a/README.md b/README.md index e1407082..fe65bc49 100644 --- a/README.md +++ b/README.md @@ -13,17 +13,17 @@ integrating graphql-let. [A blog post](https://the-guild.dev/blog/graphql-let) ## Table of Contents -- [Why this exists](#why-this-exists) -- [Entrypoints and features](#entrypoints-and-features) -- [Getting started with webpack loader](#getting-started-with-webpack-loader) -- [Getting started with babel-plugin-macros](#getting-started-with-babel-plugin-macros) -- [Getting started with Babel Plugin](#getting-started-with-babel-plugin) -- [Difference between .graphql-let.yml and codegen.yml](#difference-between-graphql-letyml-and-codegenyml) -- [Jest Transformer](#jest-transformer) -- [Experimental feature: Resolver Types](#experimental-feature-resolver-types) -- [FAQ](#faq) -- [Contribution](#contribution) -- [License](#license) +- [Why this exists](#why-this-exists) +- [Entrypoints and features](#entrypoints-and-features) +- [Getting started with webpack loader](#getting-started-with-webpack-loader) +- [Getting started with babel-plugin-macros](#getting-started-with-babel-plugin-macros) +- [Getting started with Babel Plugin](#getting-started-with-babel-plugin) +- [Difference between .graphql-let.yml and codegen.yml](#difference-between-graphql-letyml-and-codegenyml) +- [Jest Transformer](#jest-transformer) +- [Experimental feature: Resolver Types](#experimental-feature-resolver-types) +- [FAQ](#faq) +- [Contribution](#contribution) +- [License](#license) ## Why this exists @@ -55,10 +55,10 @@ const News: React.FC = () => { Summary of characteristics of each entrypoint. -- **CLI** for efficient code generation before your type checking -- **webpack loader** to get HMR even on modifying GraphQL documents -- **babel-plugin-macros** for the minimum configuration -- **Babel plugin** if you don't want babel-plugin-macros +- **CLI** for efficient code generation before your type checking +- **webpack loader** to get HMR even on modifying GraphQL documents +- **babel-plugin-macros** for the minimum configuration +- **Babel plugin** if you don't want babel-plugin-macros All of them mostly do the same behind the scene. @@ -125,14 +125,14 @@ Note there are a few differences between the entrypoints. There are things to make graphql-let light and stable. -- Sharing the processes. Generating files is expensive, so it runs less time - to run GraphQL code generator and TypeScript API. -- Caching. Embedding hashes, as your source states, reduces the number of - unnecessary processing. -- Sharing the promises. The webpack compilation in typical SSR applications as - Next.js runs [targets](https://webpack.js.org/concepts/targets/) of `"node"` - and `"web"` simultaneously. If sources are the same, the compilation should - be once. +- Sharing the processes. Generating files is expensive, so it runs less time + to run GraphQL code generator and TypeScript API. +- Caching. Embedding hashes, as your source states, reduces the number of + unnecessary processing. +- Sharing the promises. The webpack compilation in typical SSR applications as + Next.js runs [targets](https://webpack.js.org/concepts/targets/) of `"node"` + and `"web"` simultaneously. If sources are the same, the compilation should + be once. @@ -214,6 +214,7 @@ Please note that files in `cacheDir` are only intermediate cache, possibly havin + "excludes": [".cache"] } ``` + Also, remember you have to `.gitignore` the `.cache` directory in the next section. ### 3. Add lines to .gitignore @@ -460,6 +461,15 @@ respectGitIgnore: true cacheDir: node_modules/.cache/graphql-let cacheDir: .cache +# "cwd", optional. Directory of the config file itself by default. +# When evaluating `documents`, `cacheDir`, `schema`, what should be the "root" dir. +# Because the cache is stored as a literal subdirectory matching the documents, +# the search paths must share a common ancestor defined here. +# Practically, this allows the config file and other folders +# to be stored outside the process directory +# Example: +cwd: ../../ + # "TSConfigFile", optional. `tsconfig.json` by default. # You can specify a custom config for generating `.d.ts`s. # Examples: @@ -480,33 +490,33 @@ silent: false Simple example: ```yaml -schema: "schema/**/*.graphqls" +schema: 'schema/**/*.graphqls' documents: - - "**/*.graphql" - - "!shouldBeIgnored1" + - '**/*.graphql' + - '!shouldBeIgnored1' plugins: - - typescript-operations - - typescript-react-apollo + - typescript-operations + - typescript-react-apollo ``` Example with a bit more complicated options: ```yaml schema: - - https://api.github.com/graphql: - headers: - Authorization: YOUR-TOKEN-HERE + - https://api.github.com/graphql: + headers: + Authorization: YOUR-TOKEN-HERE documents: - - "**/*.graphql" - - "!shouldBeIgnored1" + - '**/*.graphql' + - '!shouldBeIgnored1' plugins: - - typescript-operations - - typescript-react-apollo + - typescript-operations + - typescript-react-apollo respectGitIgnore: true config: - reactApolloVersion: 3 - apolloReactComponentsImportFrom: "@apollo/client/react/components" - useIndexSignature: true + reactApolloVersion: 3 + apolloReactComponentsImportFrom: '@apollo/client/react/components' + useIndexSignature: true cacheDir: .cache TSConfigFile: tsconfig.compile.json typeInjectEntrypoint: typings/graphql-let.d.ts @@ -514,11 +524,11 @@ typeInjectEntrypoint: typings/graphql-let.d.ts ### Limitations of `graphql-let/babel` -- **Sadly**, type injection can't be done with TaggedTemplateExpression such - as `` gql`query {}` ``. This is the limitation of TypeScript. - [Please answer me if you have any ideas.](https://stackoverflow.com/questions/61917066/can-taggedtempalte-have-overload-signatures-with-a-certain-string-literal-argume) -- Fragments are still not available. Please watch - [the issue.](https://github.com/piglovesyou/graphql-let/issues/65) +- **Sadly**, type injection can't be done with TaggedTemplateExpression such + as `` gql`query {}` ``. This is the limitation of TypeScript. + [Please answer me if you have any ideas.](https://stackoverflow.com/questions/61917066/can-taggedtempalte-have-overload-signatures-with-a-certain-string-literal-argume) +- Fragments are still not available. Please watch + [the issue.](https://github.com/piglovesyou/graphql-let/issues/65) ## Jest Transformer @@ -582,10 +592,10 @@ schema. Just use what you need; it's most likely to be `jest-transform-graphql`. If you meet the following conditions, graphql-let generates Resolver Types. -- You have file paths including glob patterns in `schema` -- You have - [`@graphql-codegen/typescript-resolvers`](https://graphql-code-generator.com/docs/plugins/typescript-resolvers) - installed +- You have file paths including glob patterns in `schema` +- You have + [`@graphql-codegen/typescript-resolvers`](https://graphql-code-generator.com/docs/plugins/typescript-resolvers) + installed Run: @@ -686,8 +696,8 @@ Define your fragment named as `partial.graphql` ```graphql fragment Partial on User { - id - name + id + name } ``` @@ -696,9 +706,9 @@ and import it. ```graphql # import Partial from './partial.graphql' query Viewer { - viewer { - ...Partial - } + viewer { + ...Partial + } } ``` @@ -714,14 +724,14 @@ You're seeing the `*2`. It's used to skip `*1` and `*3`, and recodnized as gener ## Contribution -- **[Create an issue](https://github.com/piglovesyou/graphql-let/issues/new)** - if you have ideas, find a bug, or anything. -- **Creating a PR** is always welcome! - - Running `npm run prepublishOnly` locally will get your local development - ready. - - Adding tests is preferable, but not necessary. Maybe someone else will - fill it. -- [We have a chronic accumulation of dependabot PRs](https://github.com/piglovesyou/graphql-let/pulls/app%2Fdependabot). Please help us fix these version conflicts by cloning the dependabot branches. +- **[Create an issue](https://github.com/piglovesyou/graphql-let/issues/new)** + if you have ideas, find a bug, or anything. +- **Creating a PR** is always welcome! + - Running `yarn run prepack` locally will get your local development + ready. + - Adding tests is preferable, but not necessary. Maybe someone else will + fill it. +- [We have a chronic accumulation of dependabot PRs](https://github.com/piglovesyou/graphql-let/pulls/app%2Fdependabot). Please help us fix these version conflicts by cloning the dependabot branches. ## License diff --git a/src/__fixtures/jestTransformerCustomPaths/subdir/.graphql-let.yml b/src/__fixtures/jestTransformerCustomPaths/subdir/.graphql-let.yml new file mode 100644 index 00000000..6d76f329 --- /dev/null +++ b/src/__fixtures/jestTransformerCustomPaths/subdir/.graphql-let.yml @@ -0,0 +1,7 @@ +schema: ./schema/type-defs.graphqls +documents: "**/*.graphql" +plugins: + - typescript-operations + - typescript-react-apollo +respectGitIgnore: true +cacheDir: ../.cache diff --git a/src/__fixtures/jestTransformerCustomPaths/subdir/babel.config.json b/src/__fixtures/jestTransformerCustomPaths/subdir/babel.config.json new file mode 100644 index 00000000..dd380960 --- /dev/null +++ b/src/__fixtures/jestTransformerCustomPaths/subdir/babel.config.json @@ -0,0 +1,7 @@ +{ + presets: [ + '@babel/preset-env', + '@babel/preset-typescript', + '@babel/preset-react', + ], +} diff --git a/src/__fixtures/jestTransformerCustomPaths/subdir/pages/viewer.graphql b/src/__fixtures/jestTransformerCustomPaths/subdir/pages/viewer.graphql new file mode 100644 index 00000000..7f2a5b4f --- /dev/null +++ b/src/__fixtures/jestTransformerCustomPaths/subdir/pages/viewer.graphql @@ -0,0 +1,7 @@ +query Viewer { + viewer { + id + name + status + } +} diff --git a/src/__fixtures/jestTransformerCustomPaths/subdir/schema/type-defs.graphqls b/src/__fixtures/jestTransformerCustomPaths/subdir/schema/type-defs.graphqls new file mode 100644 index 00000000..aed22561 --- /dev/null +++ b/src/__fixtures/jestTransformerCustomPaths/subdir/schema/type-defs.graphqls @@ -0,0 +1,9 @@ +type User { + id: ID! + name: String! + status: String! +} + +type Query { + viewer: User +} diff --git a/src/__fixtures/loader/monorepo/config/.graphql-let.yml b/src/__fixtures/loader/monorepo/config/.graphql-let.yml index 567f7a6d..f5cd1982 100644 --- a/src/__fixtures/loader/monorepo/config/.graphql-let.yml +++ b/src/__fixtures/loader/monorepo/config/.graphql-let.yml @@ -1,7 +1,8 @@ -schema: ../../packages/schema/type-defs.graphqls -documents: "**/*.graphql" +schema: ../schema/type-defs.graphqls +documents: '**/*.graphql' plugins: - - typescript-operations - - typescript-react-apollo + - typescript-operations + - typescript-react-apollo respectGitIgnore: true +cwd: ../packages/app cacheDir: .cache diff --git a/src/__snapshots__/jestTransformer.test.ts.snap b/src/__snapshots__/jestTransformer.test.ts.snap index e23c143a..541ff145 100644 --- a/src/__snapshots__/jestTransformer.test.ts.snap +++ b/src/__snapshots__/jestTransformer.test.ts.snap @@ -60,3 +60,64 @@ function useViewerLazyQuery(baseOptions) { return Apollo.useLazyQuery(ViewerDocument, options); }" `; + +exports[`graphql-let/jestTransformer transforms .graphql when custom configFile and cache dirs set 1`] = ` +"\\"use strict\\"; + +function _typeof(obj) { \\"@babel/helpers - typeof\\"; if (typeof Symbol === \\"function\\" && typeof Symbol.iterator === \\"symbol\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\"function\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }; } return _typeof(obj); } + +Object.defineProperty(exports, \\"__esModule\\", { + value: true +}); +exports.useViewerQuery = useViewerQuery; +exports.useViewerLazyQuery = useViewerLazyQuery; +exports.ViewerDocument = void 0; + +var Apollo = _interopRequireWildcard(require(\\"@apollo/client\\")); + +var _templateObject; + +function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } + +function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } + +var defaultOptions = {}; +var ViewerDocument = (0, Apollo.gql)(_templateObject || (_templateObject = _taggedTemplateLiteral([\\"\\\\n query Viewer {\\\\n viewer {\\\\n id\\\\n name\\\\n status\\\\n }\\\\n}\\\\n \\"]))); +/** + * __useViewerQuery__ + * + * To run a query within a React component, call \`useViewerQuery\` and pass it any options that fit your needs. + * When your component renders, \`useViewerQuery\` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useViewerQuery({ + * variables: { + * }, + * }); + */ + +exports.ViewerDocument = ViewerDocument; + +function useViewerQuery(baseOptions) { + var options = _objectSpread(_objectSpread({}, defaultOptions), baseOptions); + + return Apollo.useQuery(ViewerDocument, options); +} + +function useViewerLazyQuery(baseOptions) { + var options = _objectSpread(_objectSpread({}, defaultOptions), baseOptions); + + return Apollo.useLazyQuery(ViewerDocument, options); +}" +`; diff --git a/src/jestTransformer.test.ts b/src/jestTransformer.test.ts index 8f99fea9..dbc6f23b 100644 --- a/src/jestTransformer.test.ts +++ b/src/jestTransformer.test.ts @@ -9,12 +9,9 @@ let cwd: string; let config: Config.ProjectConfig; describe('graphql-let/jestTransformer', () => { - beforeAll(async () => { + test('transforms .graphql', async () => { [cwd] = await prepareFixtures(__dirname, '__fixtures/jestTransformer'); config = { rootDir: cwd } as Config.ProjectConfig; - }); - - test('transforms .graphql', async () => { const fileName = 'pages/viewer.graphql'; const stats = await compiler(cwd, [fileName], 'node'); const { 0: fileData } = stats @@ -30,6 +27,44 @@ describe('graphql-let/jestTransformer', () => { ) as { code: string }; expect(removeSourcemapReference(transformedContent)).toMatchSnapshot(); }); + + test('transforms .graphql when custom configFile and cache dirs set', async () => { + [cwd] = await prepareFixtures( + __dirname, + '__fixtures/jestTransformerCustomPaths', + ); + + // Compile the file + const fileName = 'pages/viewer.graphql'; + const stats = await compiler(cwd + '/subdir', [fileName], 'node', { + configFile: './.graphql-let.yml', + }); + const { 0: fileData } = stats + .toJson() + .modules!.map((m) => m.source) + .filter(Boolean); + + // Run the config + config = { + rootDir: cwd, + transform: [ + [ + 'filePattern', + 'graphql-let/jestTransformer.js', + { + configFile: './subdir/.graphql-let.yml', + }, + ], + ], + } as any; + const fullPath = join(cwd + '/subdir', fileName); + const { code: transformedContent } = jestTransformer.process( + fileData!, + fullPath, + { config } as TransformOptions, + ) as { code: string }; + expect(removeSourcemapReference(transformedContent)).toMatchSnapshot(); + }); }); function removeSourcemapReference(code: string) { diff --git a/src/jestTransformer.ts b/src/jestTransformer.ts index 04e486f9..3548da16 100644 --- a/src/jestTransformer.ts +++ b/src/jestTransformer.ts @@ -38,9 +38,12 @@ const jestTransformer: SyncTransformer = { const [__compatJestConfig] = rest; const jestConfig = __compatJestConfig?.config ?? __compatJestConfig; // jest v26 vs v27 changes to support both formats: end - const { rootDir: cwd } = jestConfig; + const { rootDir } = jestConfig; const { configFile, subsequentTransformer } = getOption(jestConfig); - const [config, configHash] = loadConfigSync(cwd, configFile); + // If the congFile is in another directory from jest's rootDir, reset the working path since + // since the cache and transforms will operate relative to that config's location + const [config, configHash] = loadConfigSync(rootDir, configFile); + const cwd = config.cwd; const { execContext } = createExecContextSync(cwd, config, configHash); const { tsxFullPath } = createPaths(execContext, relative(cwd, sourcePath)); diff --git a/src/lib/config.test.ts b/src/lib/config.test.ts index 58198e97..9d708698 100644 --- a/src/lib/config.test.ts +++ b/src/lib/config.test.ts @@ -1,8 +1,12 @@ -import loadConfig, { loadConfigSync } from './config'; +import loadConfig, { ConfigTypes, loadConfigSync } from './config'; import { prepareFixtures } from './__tools/file'; let cwd: string; +// Some returned config values are absolute file paths that can change +// depending on the environment. This function makes them consistent by removing them. +const cleanConfig = ({ cwd, ...other }: ConfigTypes) => other; + describe('config.ts', () => { beforeAll(async () => { [cwd] = await prepareFixtures(__dirname, '__fixtures/config'); @@ -16,8 +20,8 @@ describe('config.ts', () => { }); test('loads config with default values', async () => { - const actual = await loadConfig(cwd, '.graphql-let-simple.yml'); - expect(actual).toMatchSnapshot(); + const [actual, hash] = await loadConfig(cwd, '.graphql-let-simple.yml'); + expect([cleanConfig(actual), hash]).toMatchSnapshot(); }); test('interpolates environment variables', () => { @@ -32,6 +36,6 @@ describe('config.ts', () => { test('overwrite default values', async () => { const [actual] = await loadConfig(cwd, '.graphql-let-overwrite.yml'); - expect(actual).toMatchSnapshot(); + expect(cleanConfig(actual)).toMatchSnapshot(); }); }); diff --git a/src/lib/config.ts b/src/lib/config.ts index 3eee7a87..2de6213a 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -1,5 +1,5 @@ import { Types } from '@graphql-codegen/plugin-helpers'; -import { resolve } from 'path'; +import { dirname, resolve } from 'path'; import { env } from 'string-env-interpolation'; import { parse as parseYaml } from 'yaml'; import { DEFAULT_CONFIG_FILENAME } from './consts'; @@ -8,12 +8,13 @@ import { createHash } from './hash'; import { SCHEMA_TYPES_BASENAME } from './paths'; import { printError, printWarning } from './print'; -export type PartialGraphqlCodegenOptions = Omit; +type PartialGraphqlCodegenOptions = Omit; -export type GraphQLLetAdditionalOptions = { +type GraphQLLetAdditionalOptions = { plugins: Array>; respectGitIgnore?: boolean; cacheDir?: string; + cwd?: string; TSConfigFile?: string; // gqlDtsEntrypoint?: string; typeInjectEntrypoint?: string; @@ -27,7 +28,7 @@ export type ConfigTypes = PartialGraphqlCodegenOptions & { documents: Types.OperationDocumentGlobPath[]; } & Required; -export function buildConfig(raw: UserConfigTypes): ConfigTypes { +function buildConfig(raw: UserConfigTypes, configDir: string): ConfigTypes { if (typeof raw !== 'object') printError(new Error('A config file must shape an object')); @@ -70,10 +71,19 @@ You can still have it, but it's redundant and can be problem if the types are ma new Error(`config.documents should be an array or a string`), ) as never); + if (documents.some((doc) => doc.indexOf('../') === 0)) + printError( + new Error( + `"documents" should not escape the config directory and must have a common ancestor. + Consider using cwd to set the common parent folder and define documents relative from that.`, + ), + ); + return { ...raw, // Normalized codegen options documents, + cwd: raw.cwd ? resolve(configDir, raw.cwd) : configDir, // Set graphql-let default values respectGitIgnore: raw.respectGitIgnore !== undefined ? raw.respectGitIgnore : true, @@ -86,12 +96,15 @@ You can still have it, but it's redundant and can be problem if the types are ma }; } -export const getConfigPath = (cwd: string, configFilePath?: string) => +const getConfigPath = (cwd: string, configFilePath?: string) => resolve(cwd, configFilePath || DEFAULT_CONFIG_FILENAME); -const getConfigFromContent = (content: string): [ConfigTypes, string] => { +const getConfigFromContent = ( + content: string, + configDir: string, +): [ConfigTypes, string] => { content = env(content); - return [buildConfig(parseYaml(content)), createHash(content)]; + return [buildConfig(parseYaml(content), configDir), createHash(content)]; }; // Refactor with gensync @@ -101,7 +114,7 @@ export default async function loadConfig( ): Promise<[ConfigTypes, string]> { const configPath = getConfigPath(cwd, configFilePath); const content = await readFile(configPath, 'utf-8'); - return getConfigFromContent(content); + return getConfigFromContent(content, dirname(configPath)); } export function loadConfigSync( @@ -110,5 +123,5 @@ export function loadConfigSync( ): [ConfigTypes, string] { const configPath = getConfigPath(cwd, configFilePath); const content = readFileSync(configPath, 'utf-8'); - return getConfigFromContent(content); + return getConfigFromContent(content, dirname(configPath)); } diff --git a/src/lib/exec-context.ts b/src/lib/exec-context.ts index b902eae6..5ddd0910 100644 --- a/src/lib/exec-context.ts +++ b/src/lib/exec-context.ts @@ -85,9 +85,9 @@ const createExecContextGenerator = gensync(function* ( config: ConfigTypes, configHash: string, ) { - const cacheFullDir = getCacheFullDir(cwd, config.cacheDir); + const cacheFullDir = getCacheFullDir(config.cwd, config.cacheDir); const execContext = { - cwd, + cwd: config.cwd, // TODO: Remove and rely on config.cwd; left for now to clarify diff config, configHash, cacheFullDir, diff --git a/src/lib/paths.ts b/src/lib/paths.ts index ab499fd0..d2096f16 100644 --- a/src/lib/paths.ts +++ b/src/lib/paths.ts @@ -34,8 +34,11 @@ export function createPaths( export const SCHEMA_TYPES_BASENAME = '__types__'; export function createSchemaPaths(execContext: ExecContext) { - const { cwd, config, cacheFullDir } = execContext; - const typeInjectFullDir = join(cwd, dirname(config.typeInjectEntrypoint)); + const { config, cacheFullDir } = execContext; + const typeInjectFullDir = join( + config.cwd, + dirname(config.typeInjectEntrypoint), + ); const tsxRelPath = `${SCHEMA_TYPES_BASENAME}.tsx`; const tsxFullPath = join(cacheFullDir, tsxRelPath); diff --git a/src/loader.test.ts b/src/loader.test.ts index 47fb9d5e..cd1efbc1 100644 --- a/src/loader.test.ts +++ b/src/loader.test.ts @@ -180,7 +180,9 @@ describe('graphql-let/loader', () => { ); await acceptsConfigPathInOptionsConfigFile( fixtureDir, - require.resolve('./__fixtures/loader/monorepo/config/.graphql-let.yml'), + require.resolve( + './.__fixtures/loader/monorepo-fullpath/config/.graphql-let.yml', + ), ); }); }); diff --git a/src/loader.ts b/src/loader.ts index c38d0d4a..07cfc82f 100644 --- a/src/loader.ts +++ b/src/loader.ts @@ -47,10 +47,11 @@ const processLoaderForSources = memoize( sourceFullPath: string, sourceContent: string | Buffer, addDependency: (path: string) => void, - cwd: string, - options: GraphQLLetLoaderOptions, + loaderCwd: string, + { configFile }: GraphQLLetLoaderOptions, ): Promise => { - const [config, configHash] = await loadConfig(cwd, options.configFile); + const [config, configHash] = await loadConfig(loaderCwd, configFile); + const cwd = config.cwd; const { silent } = config; const sourceRelPath = relative(cwd, sourceFullPath); if (!silent) updateLog(`Processing ${sourceRelPath}...`); @@ -124,10 +125,11 @@ const processLoaderForDocuments = memoize( gqlFullPath: string, gqlContent: string | Buffer, addDependency: (path: string) => void, - cwd: string, - options: GraphQLLetLoaderOptions, + loaderCwd: string, + { configFile }: GraphQLLetLoaderOptions, ): Promise => { - const [config, configHash] = await loadConfig(cwd, options.configFile); + const [config, configHash] = await loadConfig(loaderCwd, configFile); + const cwd = config.cwd; const { silent } = config; const graphqlRelPath = relative(cwd, gqlFullPath); if (!silent) updateLog(`Processing ${graphqlRelPath}...`);