graphql#concatAST TypeScript Examples

The following examples show how to use graphql#concatAST. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: loading.ts    From amplify-codegen with Apache License 2.0 6 votes vote down vote up
export function loadAndMergeQueryDocuments(inputPaths: string[], tagName: string = 'gql'): DocumentNode {
  const sources = inputPaths
    .map(inputPath => {
      const body = fs.readFileSync(inputPath, 'utf8');
      if (!body) {
        return null;
      }
      return new Source(body, inputPath);
    })
    .filter(source => source);

  return concatAST((sources as Source[]).map(source => parse(source)));
}
Example #2
Source File: loading.ts    From amplify-codegen with Apache License 2.0 6 votes vote down vote up
export function loadAndMergeQueryDocuments(inputPaths: string[], tagName: string = 'gql'): DocumentNode {
  const sources = inputPaths
    .map(inputPath => {
      const body = fs.readFileSync(inputPath, 'utf8');
      if (!body) {
        return null;
      }

      if (inputPath.endsWith('.jsx') || inputPath.endsWith('.js') || inputPath.endsWith('.tsx') || inputPath.endsWith('.ts')) {
        const doc = extractDocumentFromJavascript(body.toString(), tagName);
        return doc ? new Source(doc, inputPath) : null;
      }

      return new Source(body, inputPath);
    })
    .filter((source): source is Source => Boolean(source));

  const parsedSources = sources.map(source => {
    try {
      return parse(source);
    } catch (err) {
      const relativePathToInput = relative(process.cwd(), source.name);
      throw new ToolError(`Could not parse graphql operations in ${relativePathToInput}\n  Failed on : ${source.body}`);
    }
  });
  return concatAST(parsedSources);
}
Example #3
Source File: process.ts    From graphql-mesh with MIT License 4 votes vote down vote up
export async function processConfig(
  config: YamlConfig.Config,
  options?: ConfigProcessOptions
): Promise<ProcessedConfig> {
  if (config.skipSSLValidation) {
    process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
  }

  const importCodes: string[] = [
    `import type { GetMeshOptions } from '@graphql-mesh/runtime';`,
    `import type { YamlConfig } from '@graphql-mesh/types';`,
  ];
  const codes: string[] = [
    `export const rawServeConfig: YamlConfig.Config['serve'] = ${JSON.stringify(config.serve)} as any`,
    `export async function getMeshOptions(): Promise<GetMeshOptions> {`,
  ];

  const {
    dir,
    importFn = defaultImportFn,
    store: providedStore,
    artifactsDir,
    additionalPackagePrefixes,
  } = options || {};

  if (config.require) {
    await Promise.all(config.require.map(mod => importFn(mod)));
    for (const mod of config.require) {
      importCodes.push(`import '${mod}';`);
    }
  }

  const rootStore = providedStore || getDefaultMeshStore(dir, importFn, artifactsDir || '.mesh');

  const {
    pubsub,
    importCode: pubsubImportCode,
    code: pubsubCode,
  } = await resolvePubSub(config.pubsub, importFn, dir, additionalPackagePrefixes);
  importCodes.push(pubsubImportCode);
  codes.push(pubsubCode);

  const {
    cache,
    importCode: cacheImportCode,
    code: cacheCode,
  } = await resolveCache(config.cache, importFn, rootStore, dir, pubsub, additionalPackagePrefixes);
  importCodes.push(cacheImportCode);
  codes.push(cacheCode);

  const sourcesStore = rootStore.child('sources');
  codes.push(`const sourcesStore = rootStore.child('sources');`);

  const {
    logger,
    importCode: loggerImportCode,
    code: loggerCode,
  } = await resolveLogger(config.logger, importFn, dir, additionalPackagePrefixes);
  importCodes.push(loggerImportCode);
  codes.push(loggerCode);

  codes.push(`const sources = [];`);
  codes.push(`const transforms = [];`);
  codes.push(`const additionalEnvelopPlugins = [];`);

  const mergerName = config.merger || (config.sources.length > 1 ? 'stitching' : 'bare');

  const [sources, transforms, additionalEnvelopPlugins, additionalTypeDefs, additionalResolvers, merger, documents] =
    await Promise.all([
      Promise.all(
        config.sources.map<Promise<MeshResolvedSource>>(async (source, sourceIndex) => {
          const handlerName = Object.keys(source.handler)[0].toString();
          const handlerConfig = source.handler[handlerName];
          const handlerVariableName = camelCase(`${source.name}_Handler`);
          const transformsVariableName = camelCase(`${source.name}_Transforms`);
          codes.push(`const ${transformsVariableName} = [];`);
          const [handler, transforms] = await Promise.all([
            await getPackage<MeshHandlerLibrary>({
              name: handlerName,
              type: 'handler',
              importFn,
              cwd: dir,
              additionalPrefixes: additionalPackagePrefixes,
            }).then(({ resolved: HandlerCtor, moduleName }) => {
              if (options.generateCode) {
                const handlerImportName = pascalCase(handlerName + '_Handler');
                importCodes.push(`import ${handlerImportName} from ${JSON.stringify(moduleName)}`);
                codes.push(`const ${handlerVariableName} = new ${handlerImportName}({
              name: ${JSON.stringify(source.name)},
              config: ${JSON.stringify(handlerConfig)},
              baseDir,
              cache,
              pubsub,
              store: sourcesStore.child(${JSON.stringify(source.name)}),
              logger: logger.child(${JSON.stringify(source.name)}),
              importFn
            });`);
              }
              return new HandlerCtor({
                name: source.name,
                config: handlerConfig,
                baseDir: dir,
                cache,
                pubsub,
                store: sourcesStore.child(source.name),
                logger: logger.child(source.name),
                importFn,
              });
            }),
            Promise.all(
              (source.transforms || []).map(async (t, transformIndex) => {
                const transformName = Object.keys(t)[0].toString();
                const transformConfig = t[transformName];
                const { resolved: TransformCtor, moduleName } = await getPackage<MeshTransformLibrary>({
                  name: transformName,
                  type: 'transform',
                  importFn,
                  cwd: dir,
                  additionalPrefixes: additionalPackagePrefixes,
                });

                if (options.generateCode) {
                  const transformImportName = pascalCase(transformName + '_Transform');
                  importCodes.push(`import ${transformImportName} from ${JSON.stringify(moduleName)};`);
                  codes.push(`${transformsVariableName}.push(
                new ${transformImportName}({
                  apiName: ${JSON.stringify(source.name)},
                  config: ${JSON.stringify(transformConfig)},
                  baseDir,
                  cache,
                  pubsub,
                  importFn
                })
              );`);
                }

                return new TransformCtor({
                  apiName: source.name,
                  config: transformConfig,
                  baseDir: dir,
                  cache,
                  pubsub,
                  importFn,
                });
              })
            ),
          ]);

          if (options.generateCode) {
            codes.push(`sources.push({
          name: '${source.name}',
          handler: ${handlerVariableName},
          transforms: ${transformsVariableName}
        })`);
          }

          return {
            name: source.name,
            handler,
            transforms,
          };
        })
      ),
      Promise.all(
        config.transforms?.map(async (t, transformIndex) => {
          const transformName = Object.keys(t)[0].toString();
          const transformConfig = t[transformName];
          const { resolved: TransformLibrary, moduleName } = await getPackage<MeshTransformLibrary>({
            name: transformName,
            type: 'transform',
            importFn,
            cwd: dir,
            additionalPrefixes: additionalPackagePrefixes,
          });

          if (options.generateCode) {
            const transformImportName = pascalCase(transformName + '_Transform');
            importCodes.push(`import ${transformImportName} from ${JSON.stringify(moduleName)};`);

            codes.push(`transforms.push(
          new (${transformImportName} as any)({
            apiName: '',
            config: ${JSON.stringify(transformConfig)},
            baseDir,
            cache,
            pubsub,
            importFn
          })
        )`);
          }
          return new TransformLibrary({
            apiName: '',
            config: transformConfig,
            baseDir: dir,
            cache,
            pubsub,
            importFn,
          });
        }) || []
      ),
      Promise.all(
        config.plugins?.map(async (p, pluginIndex) => {
          const pluginName = Object.keys(p)[0].toString();
          const pluginConfig = p[pluginName];
          if (ENVELOP_CORE_PLUGINS_MAP[pluginName] != null) {
            const { importName, moduleName, pluginFactory } = ENVELOP_CORE_PLUGINS_MAP[pluginName];
            if (options.generateCode) {
              importCodes.push(`import { ${importName} } from ${JSON.stringify(moduleName)};`);
              codes.push(`additionalEnvelopPlugins.push(${importName}(${JSON.stringify(pluginConfig)}))`);
            }
            return pluginFactory(pluginConfig);
          }
          let importName: string;
          const { resolved: possiblePluginFactory, moduleName } = await getPackage<any>({
            name: pluginName,
            type: 'plugin',
            importFn,
            cwd: dir,
            additionalPrefixes: [...additionalPackagePrefixes, '@envelop/'],
          });
          let pluginFactory: MeshPluginFactory<YamlConfig.Plugin[keyof YamlConfig.Plugin]>;
          if (typeof possiblePluginFactory === 'function') {
            pluginFactory = possiblePluginFactory;
            if (options.generateCode) {
              importName = pascalCase('use_' + pluginName);
              importCodes.push(`import ${importName} from ${JSON.stringify(moduleName)};`);
              codes.push(`additionalEnvelopPlugins.push(${importName}({
          ...(${JSON.stringify(pluginConfig)}),
          logger: logger.child(${JSON.stringify(pluginName)}),
        }))`);
            }
          } else {
            Object.keys(possiblePluginFactory).forEach(key => {
              if (key.toString().startsWith('use') && typeof possiblePluginFactory[key] === 'function') {
                pluginFactory = possiblePluginFactory[key];
                if (options.generateCode) {
                  importCodes.push(`import { ${importName} } from ${JSON.stringify(moduleName)};`);
                  codes.push(`additionalEnvelopPlugins.push(${importName}(${JSON.stringify(pluginConfig)}])`);
                }
              }
            });
          }
          return pluginFactory({
            ...pluginConfig,
            logger: logger.child(pluginName),
          });
        }) || []
      ),
      resolveAdditionalTypeDefs(dir, config.additionalTypeDefs).then(additionalTypeDefs => {
        if (options.generateCode) {
          codes.push(
            `const additionalTypeDefs = [${(additionalTypeDefs || []).map(
              parsedTypeDefs => `parse(${JSON.stringify(print(parsedTypeDefs))}),`
            )}] as any[];`
          );
          if (additionalTypeDefs?.length) {
            importCodes.push(`import { parse } from 'graphql';`);
          }
        }
        return additionalTypeDefs;
      }),
      options?.ignoreAdditionalResolvers
        ? []
        : resolveAdditionalResolvers(dir, config.additionalResolvers, importFn, pubsub),
      getPackage<MeshMergerLibrary>({
        name: mergerName,
        type: 'merger',
        importFn,
        cwd: dir,
        additionalPrefixes: additionalPackagePrefixes,
      }).then(({ resolved: Merger, moduleName }) => {
        if (options.generateCode) {
          const mergerImportName = pascalCase(`${mergerName}Merger`);
          importCodes.push(`import ${mergerImportName} from ${JSON.stringify(moduleName)};`);
          codes.push(`const merger = new(${mergerImportName} as any)({
        cache,
        pubsub,
        logger: logger.child('${mergerName}Merger'),
        store: rootStore.child('${mergerName}Merger')
      })`);
        }
        return new Merger({
          cache,
          pubsub,
          logger: logger.child(`${mergerName}Merger`),
          store: rootStore.child(`${mergerName}Merger`),
        });
      }),
      resolveDocuments(config.documents, dir),
    ]);

  if (options.generateCode) {
    if (config.additionalResolvers?.length) {
      importCodes.push(`import { resolveAdditionalResolvers } from '@graphql-mesh/utils';`);

      codes.push(`const additionalResolversRawConfig = [];`);

      for (const additionalResolverDefinitionIndex in config.additionalResolvers) {
        const additionalResolverDefinition = config.additionalResolvers[additionalResolverDefinitionIndex];
        if (typeof additionalResolverDefinition === 'string') {
          importCodes.push(
            `import * as additionalResolvers$${additionalResolverDefinitionIndex} from '${pathModule
              .join('..', additionalResolverDefinition)
              .split('\\')
              .join('/')}';`
          );
          codes.push(
            `additionalResolversRawConfig.push(additionalResolvers$${additionalResolverDefinitionIndex}.resolvers || additionalResolvers$${additionalResolverDefinitionIndex}.default || additionalResolvers$${additionalResolverDefinitionIndex})`
          );
        } else {
          codes.push(`additionalResolversRawConfig.push(${JSON.stringify(additionalResolverDefinition)});`);
        }
      }

      codes.push(`const additionalResolvers = await resolveAdditionalResolvers(
      baseDir,
      additionalResolversRawConfig,
      importFn,
      pubsub
  )`);
    } else {
      codes.push(`const additionalResolvers = [] as any[]`);
    }
  }

  if (config.additionalEnvelopPlugins) {
    importCodes.push(
      `import importedAdditionalEnvelopPlugins from '${pathModule
        .join('..', config.additionalEnvelopPlugins)
        .split('\\')
        .join('/')}';`
    );
    const importedAdditionalEnvelopPlugins = await importFn(
      pathModule.isAbsolute(config.additionalEnvelopPlugins)
        ? config.additionalEnvelopPlugins
        : pathModule.join(dir, config.additionalEnvelopPlugins)
    );
    if (typeof importedAdditionalEnvelopPlugins === 'function') {
      const factoryResult = await importedAdditionalEnvelopPlugins(config);
      if (Array.isArray(factoryResult)) {
        if (options.generateCode) {
          codes.push(`additionalEnvelopPlugins.push(...(await importedAdditionalEnvelopPlugins()));`);
        }
        additionalEnvelopPlugins.push(...factoryResult);
      } else {
        if (options.generateCode) {
          codes.push(`additionalEnvelopPlugins.push(await importedAdditionalEnvelopPlugins());`);
        }
        additionalEnvelopPlugins.push(factoryResult);
      }
    } else {
      if (Array.isArray(importedAdditionalEnvelopPlugins)) {
        if (options.generateCode) {
          codes.push(`additionalEnvelopPlugins.push(...importedAdditionalEnvelopPlugins)`);
        }
        additionalEnvelopPlugins.push(...importedAdditionalEnvelopPlugins);
      } else {
        if (options.generateCode) {
          codes.push(`additionalEnvelopPlugins.push(importedAdditionalEnvelopPlugins)`);
        }
        additionalEnvelopPlugins.push(importedAdditionalEnvelopPlugins);
      }
    }
  }

  if (options.generateCode) {
    importCodes.push(`import { printWithCache } from '@graphql-mesh/utils';`);
    const documentVariableNames: string[] = [];
    if (documents?.length) {
      const allDocumentNodes: DocumentNode = concatAST(
        documents.map(document => document.document || parseWithCache(document.rawSDL))
      );
      visit(allDocumentNodes, {
        OperationDefinition(node) {
          documentVariableNames.push(pascalCase(node.name.value + '_Document'));
        },
      });
    }

    codes.push(`
  return {
    sources,
    transforms,
    additionalTypeDefs,
    additionalResolvers,
    cache,
    pubsub,
    merger,
    logger,
    additionalEnvelopPlugins,
    get documents() {
      return [
      ${documentVariableNames
        .map(
          documentVarName => `{
        document: ${documentVarName},
        get rawSDL() {
          return printWithCache(${documentVarName});
        },
        location: '${documentVarName}.graphql'
      }`
        )
        .join(',')}
    ];
    },
  };
}`);
  }
  return {
    sources,
    transforms,
    additionalTypeDefs,
    additionalResolvers,
    cache,
    merger,
    pubsub,
    config,
    documents,
    logger,
    store: rootStore,
    additionalEnvelopPlugins,
    code: [...new Set([...importCodes, ...codes])].join('\n'),
  };
}