Skip to content

Commit

Permalink
fix(cli/config): deduplicate imports in the artifacts (#4434)
Browse files Browse the repository at this point in the history
* fix(cli/config): deduplicate imports in the artifacts

* Go

* Fix TS
  • Loading branch information
ardatan committed Sep 5, 2022
1 parent 5a90ff9 commit 14c2c48
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 61 deletions.
6 changes: 6 additions & 0 deletions .changeset/moody-pets-retire.md
@@ -0,0 +1,6 @@
---
'@graphql-mesh/cli': patch
'@graphql-mesh/config': patch
---

Deduplicate imports in the artifacts to prevent `Identifier 'X' has already been declared.` error
14 changes: 7 additions & 7 deletions packages/cli/src/commands/ts-artifacts.ts
Expand Up @@ -169,8 +169,8 @@ export async function generateTsArtifacts(
flattenTypes: boolean;
importedModulesSet: Set<string>;
baseDir: string;
meshConfigImportCodes: string[];
meshConfigCodes: string[];
meshConfigImportCodes: Set<string>;
meshConfigCodes: Set<string>;
logger: Logger;
sdkConfig: YamlConfig.SDKConfig;
fileType: 'ts' | 'json' | 'js';
Expand Down Expand Up @@ -248,12 +248,12 @@ export async function generateTsArtifacts(
resolvers: tsResolversPlugin,
contextSdk: {
plugin: async () => {
const importCodes = [
const importCodes = new Set([
...meshConfigImportCodes,
`import { getMesh, ExecuteMeshFn, SubscribeMeshFn, MeshContext as BaseMeshContext, MeshInstance } from '@graphql-mesh/runtime';`,
`import { MeshStore, FsStoreStorageAdapter } from '@graphql-mesh/store';`,
`import { path as pathModule } from '@graphql-mesh/cross-helpers';`,
];
]);
const results = await Promise.all(
rawSources.map(async source => {
const sourceMap = unifiedSchema.extensions.sourceMap as Map<RawSourceOutput, GraphQLSchema>;
Expand All @@ -268,7 +268,7 @@ export async function generateTsArtifacts(
const content = item.sdk.codeAst + '\n' + item.context.codeAst;
await writeFile(pathModule.join(artifactsDir, `sources/${source.name}/types.ts`), content);
if (item.imports) {
importCodes.push(
importCodes.add(
`import type { ${item.imports.join(', ')} } from './sources/${source.name}/types';`
);
}
Expand Down Expand Up @@ -318,7 +318,7 @@ const rootStore = new MeshStore('${cliParams.artifactsDir}', new FsStoreStorageA
validate: false
});
${meshConfigCodes.join('\n')}
${[...meshConfigCodes].join('\n')}
let meshInstance$: Promise<MeshInstance<MeshContext>>;
Expand Down Expand Up @@ -352,7 +352,7 @@ export function ${cliParams.builtMeshSDKFactoryName}<TGlobalContext = any, TOper
}

return {
prepend: [importCodes.join('\n'), '\n\n'],
prepend: [[...importCodes].join('\n'), '\n\n'],
content: [contextType, meshMethods].join('\n\n'),
};
},
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/src/index.ts
Expand Up @@ -163,8 +163,8 @@ export async function graphqlMesh(
flattenTypes: false,
importedModulesSet: new Set(),
baseDir,
meshConfigImportCodes: [`import { findAndParseConfig } from '@graphql-mesh/cli';`],
meshConfigCodes: [
meshConfigImportCodes: new Set([`import { findAndParseConfig } from '@graphql-mesh/cli';`]),
meshConfigCodes: new Set([
`
function getMeshOptions() {
console.warn('WARNING: These artifacts are built for development mode. Please run "${
Expand All @@ -179,7 +179,7 @@ function getMeshOptions() {
});
}
`.trim(),
],
]),
logger,
sdkConfig: meshConfig.config.sdk,
fileType: 'ts',
Expand Down
102 changes: 51 additions & 51 deletions packages/config/src/process.ts
Expand Up @@ -56,8 +56,8 @@ export type ProcessedConfig = GetMeshOptions & {
config: YamlConfig.Config;
documents: Source[];
store: MeshStore;
importCodes: string[];
codes: string[];
importCodes: Set<string>;
codes: Set<string>;
};

function getDefaultMeshStore(dir: string, importFn: ImportFn, artifactsDir: string) {
Expand Down Expand Up @@ -90,14 +90,14 @@ export async function processConfig(
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
}

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

const {
dir,
Expand All @@ -110,7 +110,7 @@ export async function processConfig(
if (config.require) {
await Promise.all(config.require.map(mod => importFn(mod)));
for (const mod of config.require) {
importCodes.push(`import '${mod}';`);
importCodes.add(`import '${mod}';`);
}
}

Expand All @@ -121,27 +121,27 @@ export async function processConfig(
importCode: pubsubImportCode,
code: pubsubCode,
} = await resolvePubSub(config.pubsub, importFn, dir, additionalPackagePrefixes);
importCodes.push(pubsubImportCode);
codes.push(pubsubCode);
importCodes.add(pubsubImportCode);
codes.add(pubsubCode);

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

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

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

const {
fetchFn,
Expand All @@ -155,12 +155,12 @@ export async function processConfig(
additionalPackagePrefixes,
});

importCodes.push(fetchFnImportCode);
codes.push(fetchFnCode);
importCodes.add(fetchFnImportCode);
codes.add(fetchFnCode);

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

const [sources, transforms, additionalEnvelopPlugins, additionalTypeDefs, additionalResolvers, documents] =
await Promise.all([
Expand All @@ -170,7 +170,7 @@ export async function processConfig(
const handlerConfig = source.handler[handlerName];
const handlerVariableName = camelCase(`${source.name}_Handler`);
const transformsVariableName = camelCase(`${source.name}_Transforms`);
codes.push(`const ${transformsVariableName} = [];`);
codes.add(`const ${transformsVariableName} = [];`);
const [handler, transforms] = await Promise.all([
await getPackage<MeshHandlerLibrary>({
name: handlerName,
Expand All @@ -181,8 +181,8 @@ export async function processConfig(
}).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}({
importCodes.add(`import ${handlerImportName} from ${JSON.stringify(moduleName)}`);
codes.add(`const ${handlerVariableName} = new ${handlerImportName}({
name: ${JSON.stringify(source.name)},
config: ${JSON.stringify(handlerConfig)},
baseDir,
Expand Down Expand Up @@ -218,8 +218,8 @@ export async function processConfig(

if (options.generateCode) {
const transformImportName = pascalCase(transformName + '_Transform');
importCodes.push(`import ${transformImportName} from ${JSON.stringify(moduleName)};`);
codes.push(`${transformsVariableName}[${transformIndex}] = new ${transformImportName}({
importCodes.add(`import ${transformImportName} from ${JSON.stringify(moduleName)};`);
codes.add(`${transformsVariableName}[${transformIndex}] = new ${transformImportName}({
apiName: ${JSON.stringify(source.name)},
config: ${JSON.stringify(transformConfig)},
baseDir,
Expand All @@ -242,7 +242,7 @@ export async function processConfig(
]);

if (options.generateCode) {
codes.push(`sources[${sourceIndex}] = {
codes.add(`sources[${sourceIndex}] = {
name: '${source.name}',
handler: ${handlerVariableName},
transforms: ${transformsVariableName}
Expand Down Expand Up @@ -270,9 +270,9 @@ export async function processConfig(

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

codes.push(`transforms[${transformIndex}] = new (${transformImportName} as any)({
codes.add(`transforms[${transformIndex}] = new (${transformImportName} as any)({
apiName: '',
config: ${JSON.stringify(transformConfig)},
baseDir,
Expand All @@ -298,8 +298,8 @@ export async function processConfig(
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(
importCodes.add(`import { ${importName} } from ${JSON.stringify(moduleName)};`);
codes.add(
`additionalEnvelopPlugins[${pluginIndex}] = await ${importName}(${JSON.stringify(
pluginConfig,
null,
Expand All @@ -322,8 +322,8 @@ export async function processConfig(
pluginFactory = possiblePluginFactory;
if (options.generateCode) {
importName = pascalCase('use_' + pluginName);
importCodes.push(`import ${importName} from ${JSON.stringify(moduleName)};`);
codes.push(`additionalEnvelopPlugins[${pluginIndex}] = await ${importName}({
importCodes.add(`import ${importName} from ${JSON.stringify(moduleName)};`);
codes.add(`additionalEnvelopPlugins[${pluginIndex}] = await ${importName}({
...(${JSON.stringify(pluginConfig, null, 2)}),
logger: logger.child(${JSON.stringify(pluginName)}),
cache,
Expand All @@ -337,8 +337,8 @@ export async function processConfig(
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(
importCodes.add(`import { ${importName} } from ${JSON.stringify(moduleName)};`);
codes.add(
`additionalEnvelopPlugins[${pluginIndex}] = await ${importName}(${JSON.stringify(
pluginConfig,
null,
Expand All @@ -361,13 +361,13 @@ export async function processConfig(
),
resolveAdditionalTypeDefs(dir, config.additionalTypeDefs).then(additionalTypeDefs => {
if (options.generateCode) {
codes.push(
codes.add(
`const additionalTypeDefs = [${(additionalTypeDefs || []).map(
parsedTypeDefs => `parse(${JSON.stringify(print(parsedTypeDefs))}),`
)}] as any[];`
);
if (additionalTypeDefs?.length) {
importCodes.push(`import { parse } from 'graphql';`);
importCodes.add(`import { parse } from 'graphql';`);
}
}
return additionalTypeDefs;
Expand All @@ -380,9 +380,9 @@ export async function processConfig(

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

codes.push(`const additionalResolvers = await Promise.all([
codes.add(`const additionalResolvers = await Promise.all([
${config.additionalResolvers
.map(additionalResolverDefinition => {
if (typeof additionalResolverDefinition === 'string') {
Expand All @@ -399,7 +399,7 @@ export async function processConfig(
.join(',\n')}
]);`);
} else {
codes.push(`const additionalResolvers = [] as any[]`);
codes.add(`const additionalResolvers = [] as any[]`);
}
}

Expand Down Expand Up @@ -433,15 +433,15 @@ export async function processConfig(
additionalTypeDefs.unshift(parse(resolveToDirectiveDefinition));
additionalResolvers.push(...resolvedAdditionalResolvers);
if (options.generateCode && resolvedAdditionalResolvers.length) {
importCodes.push(`import { resolveAdditionalResolvers } from '@graphql-mesh/utils';`);
codes.push(`additionalTypeDefs.unshift(parse(/* GraphQL */\`${resolveToDirectiveDefinition}\`))`);
codes.push(`const additionalResolversFromTypeDefs = await resolveAdditionalResolvers(
importCodes.add(`import { resolveAdditionalResolvers } from '@graphql-mesh/utils';`);
codes.add(`additionalTypeDefs.unshift(parse(/* GraphQL */\`${resolveToDirectiveDefinition}\`))`);
codes.add(`const additionalResolversFromTypeDefs = await resolveAdditionalResolvers(
baseDir,
${JSON.stringify(additionalResolversConfigFromTypeDefs)},
importFn,
pubsub
);`);
codes.push(`additionalResolvers.push(additionalResolversFromTypeDefs)`);
codes.add(`additionalResolvers.push(additionalResolversFromTypeDefs)`);
}
}
}
Expand Down Expand Up @@ -488,8 +488,8 @@ export async function processConfig(

if (options.generateCode) {
const mergerImportName = pascalCase(`${mergerName}Merger`);
importCodes.push(`import ${mergerImportName} from ${JSON.stringify(mergerModuleName)};`);
codes.push(`const merger = new(${mergerImportName} as any)({
importCodes.add(`import ${mergerImportName} from ${JSON.stringify(mergerModuleName)};`);
codes.add(`const merger = new(${mergerImportName} as any)({
cache,
pubsub,
logger: logger.child('${mergerName}Merger'),
Expand All @@ -505,7 +505,7 @@ export async function processConfig(
});

if (config.additionalEnvelopPlugins) {
codes.push(
codes.add(
`const importedAdditionalEnvelopPlugins = await import(${JSON.stringify(
pathModule.join('..', config.additionalEnvelopPlugins).split('\\').join('/')
)}).then(m => m.default || m);`
Expand All @@ -519,32 +519,32 @@ export async function processConfig(
const factoryResult = await importedAdditionalEnvelopPlugins(config);
if (Array.isArray(factoryResult)) {
if (options.generateCode) {
codes.push(`additionalEnvelopPlugins.push(...(await importedAdditionalEnvelopPlugins()));`);
codes.add(`additionalEnvelopPlugins.push(...(await importedAdditionalEnvelopPlugins()));`);
}
additionalEnvelopPlugins.push(...factoryResult);
} else {
if (options.generateCode) {
codes.push(`additionalEnvelopPlugins.push(await importedAdditionalEnvelopPlugins());`);
codes.add(`additionalEnvelopPlugins.push(await importedAdditionalEnvelopPlugins());`);
}
additionalEnvelopPlugins.push(factoryResult);
}
} else {
if (Array.isArray(importedAdditionalEnvelopPlugins)) {
if (options.generateCode) {
codes.push(`additionalEnvelopPlugins.push(...importedAdditionalEnvelopPlugins)`);
codes.add(`additionalEnvelopPlugins.push(...importedAdditionalEnvelopPlugins)`);
}
additionalEnvelopPlugins.push(...importedAdditionalEnvelopPlugins);
} else {
if (options.generateCode) {
codes.push(`additionalEnvelopPlugins.push(importedAdditionalEnvelopPlugins)`);
codes.add(`additionalEnvelopPlugins.push(importedAdditionalEnvelopPlugins)`);
}
additionalEnvelopPlugins.push(importedAdditionalEnvelopPlugins);
}
}
}

if (options.generateCode) {
importCodes.push(`import { printWithCache } from '@graphql-mesh/utils';`);
importCodes.add(`import { printWithCache } from '@graphql-mesh/utils';`);
const documentVariableNames: string[] = [];
if (documents?.length) {
const allDocumentNodes: DocumentNode = concatAST(
Expand All @@ -557,7 +557,7 @@ export async function processConfig(
});
}

codes.push(`
codes.add(`
return {
sources,
transforms,
Expand Down

1 comment on commit 14c2c48

@vercel
Copy link

@vercel vercel bot commented on 14c2c48 Sep 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.