@graphql-codegen/cli 2.4.0-alpha-23d229715.0 → 2.4.1-alpha-05252ae4a.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin.js CHANGED
@@ -676,10 +676,6 @@ function buildOptions() {
676
676
  describe: 'Only print errors',
677
677
  type: 'boolean',
678
678
  },
679
- profile: {
680
- describe: 'Use profiler to measure performance',
681
- type: 'boolean',
682
- },
683
679
  p: {
684
680
  alias: 'project',
685
681
  describe: 'Name of a project in GraphQL Config',
@@ -721,9 +717,6 @@ function updateContextWithCliFlags(context, cliFlags) {
721
717
  if (cliFlags.project) {
722
718
  context.useProject(cliFlags.project);
723
719
  }
724
- if (cliFlags.profile === true) {
725
- context.useProfiler();
726
- }
727
720
  context.updateConfig(config);
728
721
  }
729
722
  class CodegenContext {
@@ -733,7 +726,6 @@ class CodegenContext {
733
726
  this._graphqlConfig = graphqlConfig;
734
727
  this.filepath = this._graphqlConfig ? this._graphqlConfig.filepath : filepath;
735
728
  this.cwd = this._graphqlConfig ? this._graphqlConfig.dirpath : process.cwd();
736
- this.profiler = pluginHelpers.createNoopProfiler();
737
729
  }
738
730
  useProject(name) {
739
731
  this._project = name;
@@ -764,13 +756,6 @@ class CodegenContext {
764
756
  ...config,
765
757
  };
766
758
  }
767
- useProfiler() {
768
- this.profiler = pluginHelpers.createProfiler();
769
- const now = new Date(); // 2011-10-05T14:48:00.000Z
770
- const datetime = now.toISOString().split('.')[0]; // 2011-10-05T14:48:00
771
- const datetimeNormalized = datetime.replace(/-|:/g, ''); // 20111005T144800
772
- this.profilerOutput = `codegen-${datetimeNormalized}.json`;
773
- }
774
759
  getPluginContext() {
775
760
  return this._pluginContext;
776
761
  }
@@ -805,7 +790,34 @@ const makeDefaultLoader = (from) => {
805
790
  return new Promise(function (resolve) { resolve(_interopNamespace(require(relativeRequire.resolve(mod)))); });
806
791
  };
807
792
  };
793
+ // TODO: Replace any with types
794
+ function createCache(loader) {
795
+ const cache = new Map();
796
+ return {
797
+ load(key) {
798
+ if (cache.has(key)) {
799
+ return cache.get(key);
800
+ }
801
+ const value = loader(key);
802
+ cache.set(key, value);
803
+ return value;
804
+ },
805
+ };
806
+ }
808
807
  async function executeCodegen(input) {
808
+ function wrapTask(task, source) {
809
+ return async () => {
810
+ try {
811
+ await Promise.resolve().then(() => task());
812
+ }
813
+ catch (error) {
814
+ if (source && !(error instanceof graphql.GraphQLError)) {
815
+ error.source = source;
816
+ }
817
+ throw error;
818
+ }
819
+ };
820
+ }
809
821
  const context = ensureContext(input);
810
822
  const config = context.getConfig();
811
823
  const pluginContext = context.getPluginContext();
@@ -841,21 +853,20 @@ async function executeCodegen(input) {
841
853
  let rootSchemas;
842
854
  let rootDocuments;
843
855
  const generates = {};
844
- function wrapTask(task, source, taskName) {
845
- return () => {
846
- return context.profiler.run(async () => {
847
- try {
848
- await Promise.resolve().then(() => task());
849
- }
850
- catch (error) {
851
- if (source && !(error instanceof graphql.GraphQLError)) {
852
- error.source = source;
853
- }
854
- throw error;
855
- }
856
- }, taskName);
856
+ const schemaLoadingCache = createCache(async function (hash) {
857
+ const outputSchemaAst = await context.loadSchema(JSON.parse(hash));
858
+ const outputSchema = pluginHelpers.getCachedDocumentNodeFromSchema(outputSchemaAst);
859
+ return {
860
+ outputSchemaAst: outputSchemaAst,
861
+ outputSchema: outputSchema,
857
862
  };
858
- }
863
+ });
864
+ const documentsLoadingCache = createCache(async function (hash) {
865
+ const documents = await context.loadDocuments(JSON.parse(hash));
866
+ return {
867
+ documents: documents,
868
+ };
869
+ });
859
870
  async function normalize() {
860
871
  /* Load Require extensions */
861
872
  const requireExtensions = pluginHelpers.normalizeInstanceOrArray(config.require);
@@ -957,20 +968,27 @@ async function executeCodegen(input) {
957
968
  Object.assign(schemaPointerMap, unnormalizedPtr);
958
969
  }
959
970
  }
960
- outputSchemaAst = await context.loadSchema(schemaPointerMap);
961
- outputSchema = pluginHelpers.getCachedDocumentNodeFromSchema(outputSchemaAst);
962
- }, filename, `Load GraphQL schemas: ${filename}`),
971
+ const hash = JSON.stringify(schemaPointerMap);
972
+ const result = await schemaLoadingCache.load(hash);
973
+ outputSchemaAst = await result.outputSchemaAst;
974
+ outputSchema = result.outputSchema;
975
+ }, filename),
963
976
  },
964
977
  {
965
978
  title: 'Load GraphQL documents',
966
979
  task: wrapTask(async () => {
967
980
  debugLog(`[CLI] Loading Documents`);
968
- const allDocuments = [...rootDocuments, ...outputSpecificDocuments];
969
- const documents = await context.loadDocuments(allDocuments);
981
+ // get different cache for shared docs and output specific docs
982
+ const results = await Promise.all([rootDocuments, outputSpecificDocuments].map(docs => {
983
+ const hash = JSON.stringify(docs);
984
+ return documentsLoadingCache.load(hash);
985
+ }));
986
+ const documents = [];
987
+ results.forEach(source => documents.push(...source.documents));
970
988
  if (documents.length > 0) {
971
989
  outputDocuments.push(...documents);
972
990
  }
973
- }, filename, `Load GraphQL documents: ${filename}`),
991
+ }, filename),
974
992
  },
975
993
  {
976
994
  title: 'Generate',
@@ -998,7 +1016,7 @@ async function executeCodegen(input) {
998
1016
  };
999
1017
  let outputs = [];
1000
1018
  if (hasPreset) {
1001
- outputs = await context.profiler.run(async () => preset.buildGeneratesSection({
1019
+ outputs = await preset.buildGeneratesSection({
1002
1020
  baseOutputDir: filename,
1003
1021
  presetConfig: outputConfig.presetConfig || {},
1004
1022
  plugins: normalizedPluginsArray,
@@ -1008,8 +1026,7 @@ async function executeCodegen(input) {
1008
1026
  config: mergedConfig,
1009
1027
  pluginMap,
1010
1028
  pluginContext,
1011
- profiler: context.profiler,
1012
- }), `Build Generates Section: ${filename}`);
1029
+ });
1013
1030
  }
1014
1031
  else {
1015
1032
  outputs = [
@@ -1022,7 +1039,6 @@ async function executeCodegen(input) {
1022
1039
  config: mergedConfig,
1023
1040
  pluginMap,
1024
1041
  pluginContext,
1025
- profiler: context.profiler,
1026
1042
  },
1027
1043
  ];
1028
1044
  }
@@ -1034,8 +1050,8 @@ async function executeCodegen(input) {
1034
1050
  hooks: outputConfig.hooks || {},
1035
1051
  });
1036
1052
  };
1037
- await context.profiler.run(() => Promise.all(outputs.map(process)), `Codegen: ${filename}`);
1038
- }, filename, `Generate: ${filename}`),
1053
+ await Promise.all(outputs.map(process));
1054
+ }, filename),
1039
1055
  },
1040
1056
  ], {
1041
1057
  // it stops when one of tasks failed
@@ -1202,7 +1218,7 @@ const hash = (content) => crypto.createHash('sha1').update(content).digest('base
1202
1218
  async function generate(input, saveToFile = true) {
1203
1219
  const context = ensureContext(input);
1204
1220
  const config = context.getConfig();
1205
- await context.profiler.run(() => lifecycleHooks(config.hooks).afterStart(), 'Lifecycle: afterStart');
1221
+ await lifecycleHooks(config.hooks).afterStart();
1206
1222
  let previouslyGeneratedFilenames = [];
1207
1223
  function removeStaleFiles(config, generationResult) {
1208
1224
  const filenames = generationResult.map(o => o.filename);
@@ -1231,8 +1247,8 @@ async function generate(input, saveToFile = true) {
1231
1247
  if (config.watch) {
1232
1248
  removeStaleFiles(config, generationResult);
1233
1249
  }
1234
- await context.profiler.run(() => lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: beforeAllFileWrite');
1235
- await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
1250
+ await lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename));
1251
+ await Promise.all(generationResult.map(async (result) => {
1236
1252
  const exists = fileExists(result.filename);
1237
1253
  if (!shouldOverwrite(config, result.filename) && exists) {
1238
1254
  return;
@@ -1244,7 +1260,7 @@ async function generate(input, saveToFile = true) {
1244
1260
  previousHash = hash(readSync(result.filename));
1245
1261
  }
1246
1262
  if (previousHash && currentHash === previousHash) {
1247
- debugLog(`Skipping file (${result.filename}) writing due to identical hash...`);
1263
+ debugLog(`Skipping file (${result.filename}) writing due to indentical hash...`);
1248
1264
  return;
1249
1265
  }
1250
1266
  if (content.length === 0) {
@@ -1261,20 +1277,17 @@ async function generate(input, saveToFile = true) {
1261
1277
  writeSync(absolutePath, result.content);
1262
1278
  await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
1263
1279
  await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
1264
- })), 'Write files');
1265
- await context.profiler.run(() => lifecycleHooks(config.hooks).afterAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: afterAllFileWrite');
1280
+ }));
1281
+ await lifecycleHooks(config.hooks).afterAllFileWrite(generationResult.map(r => r.filename));
1266
1282
  return generationResult;
1267
1283
  }
1268
1284
  // watch mode
1269
1285
  if (config.watch) {
1270
1286
  return createWatcher(context, writeOutput);
1271
1287
  }
1272
- const outputFiles = await context.profiler.run(() => executeCodegen(context), 'executeCodegen');
1273
- await context.profiler.run(() => writeOutput(outputFiles), 'writeOutput');
1274
- await context.profiler.run(() => lifecycleHooks(config.hooks).beforeDone(), 'Lifecycle: beforeDone');
1275
- if (context.profilerOutput) {
1276
- writeSync(path.join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
1277
- }
1288
+ const outputFiles = await executeCodegen(context);
1289
+ await writeOutput(outputFiles);
1290
+ lifecycleHooks(config.hooks).beforeDone();
1278
1291
  return outputFiles;
1279
1292
  }
1280
1293
  function shouldOverwrite(config, outputPath) {
package/config.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Types, Profiler } from '@graphql-codegen/plugin-helpers';
1
+ import { Types } from '@graphql-codegen/plugin-helpers';
2
2
  import { GraphQLConfig } from 'graphql-config';
3
3
  import { GraphQLSchema } from 'graphql';
4
4
  export declare type YamlCliFlags = {
@@ -9,7 +9,6 @@ export declare type YamlCliFlags = {
9
9
  project: string;
10
10
  silent: boolean;
11
11
  errorsOnly: boolean;
12
- profile: boolean;
13
12
  };
14
13
  export declare function generateSearchPlaces(moduleName: string): string[];
15
14
  export interface LoadCodegenConfigOptions {
@@ -75,10 +74,6 @@ export declare function buildOptions(): {
75
74
  describe: string;
76
75
  type: "boolean";
77
76
  };
78
- profile: {
79
- describe: string;
80
- type: "boolean";
81
- };
82
77
  p: {
83
78
  alias: string;
84
79
  describe: string;
@@ -96,8 +91,6 @@ export declare class CodegenContext {
96
91
  private _pluginContext;
97
92
  cwd: string;
98
93
  filepath: string;
99
- profiler: Profiler;
100
- profilerOutput?: string;
101
94
  constructor({ config, graphqlConfig, filepath, }: {
102
95
  config?: Types.Config;
103
96
  graphqlConfig?: GraphQLConfig;
@@ -106,7 +99,6 @@ export declare class CodegenContext {
106
99
  useProject(name?: string): void;
107
100
  getConfig<T>(extraConfig?: T): T & Types.Config;
108
101
  updateConfig(config: Partial<Types.Config>): void;
109
- useProfiler(): void;
110
102
  getPluginContext(): {
111
103
  [key: string]: any;
112
104
  };
package/index.js CHANGED
@@ -594,10 +594,6 @@ function buildOptions() {
594
594
  describe: 'Only print errors',
595
595
  type: 'boolean',
596
596
  },
597
- profile: {
598
- describe: 'Use profiler to measure performance',
599
- type: 'boolean',
600
- },
601
597
  p: {
602
598
  alias: 'project',
603
599
  describe: 'Name of a project in GraphQL Config',
@@ -639,9 +635,6 @@ function updateContextWithCliFlags(context, cliFlags) {
639
635
  if (cliFlags.project) {
640
636
  context.useProject(cliFlags.project);
641
637
  }
642
- if (cliFlags.profile === true) {
643
- context.useProfiler();
644
- }
645
638
  context.updateConfig(config);
646
639
  }
647
640
  class CodegenContext {
@@ -651,7 +644,6 @@ class CodegenContext {
651
644
  this._graphqlConfig = graphqlConfig;
652
645
  this.filepath = this._graphqlConfig ? this._graphqlConfig.filepath : filepath;
653
646
  this.cwd = this._graphqlConfig ? this._graphqlConfig.dirpath : process.cwd();
654
- this.profiler = pluginHelpers.createNoopProfiler();
655
647
  }
656
648
  useProject(name) {
657
649
  this._project = name;
@@ -682,13 +674,6 @@ class CodegenContext {
682
674
  ...config,
683
675
  };
684
676
  }
685
- useProfiler() {
686
- this.profiler = pluginHelpers.createProfiler();
687
- const now = new Date(); // 2011-10-05T14:48:00.000Z
688
- const datetime = now.toISOString().split('.')[0]; // 2011-10-05T14:48:00
689
- const datetimeNormalized = datetime.replace(/-|:/g, ''); // 20111005T144800
690
- this.profilerOutput = `codegen-${datetimeNormalized}.json`;
691
- }
692
677
  getPluginContext() {
693
678
  return this._pluginContext;
694
679
  }
@@ -723,7 +708,34 @@ const makeDefaultLoader = (from) => {
723
708
  return new Promise(function (resolve) { resolve(_interopNamespace(require(relativeRequire.resolve(mod)))); });
724
709
  };
725
710
  };
711
+ // TODO: Replace any with types
712
+ function createCache(loader) {
713
+ const cache = new Map();
714
+ return {
715
+ load(key) {
716
+ if (cache.has(key)) {
717
+ return cache.get(key);
718
+ }
719
+ const value = loader(key);
720
+ cache.set(key, value);
721
+ return value;
722
+ },
723
+ };
724
+ }
726
725
  async function executeCodegen(input) {
726
+ function wrapTask(task, source) {
727
+ return async () => {
728
+ try {
729
+ await Promise.resolve().then(() => task());
730
+ }
731
+ catch (error) {
732
+ if (source && !(error instanceof graphql.GraphQLError)) {
733
+ error.source = source;
734
+ }
735
+ throw error;
736
+ }
737
+ };
738
+ }
727
739
  const context = ensureContext(input);
728
740
  const config = context.getConfig();
729
741
  const pluginContext = context.getPluginContext();
@@ -759,21 +771,20 @@ async function executeCodegen(input) {
759
771
  let rootSchemas;
760
772
  let rootDocuments;
761
773
  const generates = {};
762
- function wrapTask(task, source, taskName) {
763
- return () => {
764
- return context.profiler.run(async () => {
765
- try {
766
- await Promise.resolve().then(() => task());
767
- }
768
- catch (error) {
769
- if (source && !(error instanceof graphql.GraphQLError)) {
770
- error.source = source;
771
- }
772
- throw error;
773
- }
774
- }, taskName);
774
+ const schemaLoadingCache = createCache(async function (hash) {
775
+ const outputSchemaAst = await context.loadSchema(JSON.parse(hash));
776
+ const outputSchema = pluginHelpers.getCachedDocumentNodeFromSchema(outputSchemaAst);
777
+ return {
778
+ outputSchemaAst: outputSchemaAst,
779
+ outputSchema: outputSchema,
775
780
  };
776
- }
781
+ });
782
+ const documentsLoadingCache = createCache(async function (hash) {
783
+ const documents = await context.loadDocuments(JSON.parse(hash));
784
+ return {
785
+ documents: documents,
786
+ };
787
+ });
777
788
  async function normalize() {
778
789
  /* Load Require extensions */
779
790
  const requireExtensions = pluginHelpers.normalizeInstanceOrArray(config.require);
@@ -875,20 +886,27 @@ async function executeCodegen(input) {
875
886
  Object.assign(schemaPointerMap, unnormalizedPtr);
876
887
  }
877
888
  }
878
- outputSchemaAst = await context.loadSchema(schemaPointerMap);
879
- outputSchema = pluginHelpers.getCachedDocumentNodeFromSchema(outputSchemaAst);
880
- }, filename, `Load GraphQL schemas: ${filename}`),
889
+ const hash = JSON.stringify(schemaPointerMap);
890
+ const result = await schemaLoadingCache.load(hash);
891
+ outputSchemaAst = await result.outputSchemaAst;
892
+ outputSchema = result.outputSchema;
893
+ }, filename),
881
894
  },
882
895
  {
883
896
  title: 'Load GraphQL documents',
884
897
  task: wrapTask(async () => {
885
898
  debugLog(`[CLI] Loading Documents`);
886
- const allDocuments = [...rootDocuments, ...outputSpecificDocuments];
887
- const documents = await context.loadDocuments(allDocuments);
899
+ // get different cache for shared docs and output specific docs
900
+ const results = await Promise.all([rootDocuments, outputSpecificDocuments].map(docs => {
901
+ const hash = JSON.stringify(docs);
902
+ return documentsLoadingCache.load(hash);
903
+ }));
904
+ const documents = [];
905
+ results.forEach(source => documents.push(...source.documents));
888
906
  if (documents.length > 0) {
889
907
  outputDocuments.push(...documents);
890
908
  }
891
- }, filename, `Load GraphQL documents: ${filename}`),
909
+ }, filename),
892
910
  },
893
911
  {
894
912
  title: 'Generate',
@@ -916,7 +934,7 @@ async function executeCodegen(input) {
916
934
  };
917
935
  let outputs = [];
918
936
  if (hasPreset) {
919
- outputs = await context.profiler.run(async () => preset.buildGeneratesSection({
937
+ outputs = await preset.buildGeneratesSection({
920
938
  baseOutputDir: filename,
921
939
  presetConfig: outputConfig.presetConfig || {},
922
940
  plugins: normalizedPluginsArray,
@@ -926,8 +944,7 @@ async function executeCodegen(input) {
926
944
  config: mergedConfig,
927
945
  pluginMap,
928
946
  pluginContext,
929
- profiler: context.profiler,
930
- }), `Build Generates Section: ${filename}`);
947
+ });
931
948
  }
932
949
  else {
933
950
  outputs = [
@@ -940,7 +957,6 @@ async function executeCodegen(input) {
940
957
  config: mergedConfig,
941
958
  pluginMap,
942
959
  pluginContext,
943
- profiler: context.profiler,
944
960
  },
945
961
  ];
946
962
  }
@@ -952,8 +968,8 @@ async function executeCodegen(input) {
952
968
  hooks: outputConfig.hooks || {},
953
969
  });
954
970
  };
955
- await context.profiler.run(() => Promise.all(outputs.map(process)), `Codegen: ${filename}`);
956
- }, filename, `Generate: ${filename}`),
971
+ await Promise.all(outputs.map(process));
972
+ }, filename),
957
973
  },
958
974
  ], {
959
975
  // it stops when one of tasks failed
@@ -1203,7 +1219,7 @@ const hash = (content) => crypto.createHash('sha1').update(content).digest('base
1203
1219
  async function generate(input, saveToFile = true) {
1204
1220
  const context = ensureContext(input);
1205
1221
  const config = context.getConfig();
1206
- await context.profiler.run(() => lifecycleHooks(config.hooks).afterStart(), 'Lifecycle: afterStart');
1222
+ await lifecycleHooks(config.hooks).afterStart();
1207
1223
  let previouslyGeneratedFilenames = [];
1208
1224
  function removeStaleFiles(config, generationResult) {
1209
1225
  const filenames = generationResult.map(o => o.filename);
@@ -1232,8 +1248,8 @@ async function generate(input, saveToFile = true) {
1232
1248
  if (config.watch) {
1233
1249
  removeStaleFiles(config, generationResult);
1234
1250
  }
1235
- await context.profiler.run(() => lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: beforeAllFileWrite');
1236
- await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
1251
+ await lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename));
1252
+ await Promise.all(generationResult.map(async (result) => {
1237
1253
  const exists = fileExists(result.filename);
1238
1254
  if (!shouldOverwrite(config, result.filename) && exists) {
1239
1255
  return;
@@ -1245,7 +1261,7 @@ async function generate(input, saveToFile = true) {
1245
1261
  previousHash = hash(readSync(result.filename));
1246
1262
  }
1247
1263
  if (previousHash && currentHash === previousHash) {
1248
- debugLog(`Skipping file (${result.filename}) writing due to identical hash...`);
1264
+ debugLog(`Skipping file (${result.filename}) writing due to indentical hash...`);
1249
1265
  return;
1250
1266
  }
1251
1267
  if (content.length === 0) {
@@ -1262,20 +1278,17 @@ async function generate(input, saveToFile = true) {
1262
1278
  writeSync(absolutePath, result.content);
1263
1279
  await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
1264
1280
  await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
1265
- })), 'Write files');
1266
- await context.profiler.run(() => lifecycleHooks(config.hooks).afterAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: afterAllFileWrite');
1281
+ }));
1282
+ await lifecycleHooks(config.hooks).afterAllFileWrite(generationResult.map(r => r.filename));
1267
1283
  return generationResult;
1268
1284
  }
1269
1285
  // watch mode
1270
1286
  if (config.watch) {
1271
1287
  return createWatcher(context, writeOutput);
1272
1288
  }
1273
- const outputFiles = await context.profiler.run(() => executeCodegen(context), 'executeCodegen');
1274
- await context.profiler.run(() => writeOutput(outputFiles), 'writeOutput');
1275
- await context.profiler.run(() => lifecycleHooks(config.hooks).beforeDone(), 'Lifecycle: beforeDone');
1276
- if (context.profilerOutput) {
1277
- writeSync(path.join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
1278
- }
1289
+ const outputFiles = await executeCodegen(context);
1290
+ await writeOutput(outputFiles);
1291
+ lifecycleHooks(config.hooks).beforeDone();
1279
1292
  return outputFiles;
1280
1293
  }
1281
1294
  function shouldOverwrite(config, outputPath) {
package/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { isDetailedError, DetailedError, createNoopProfiler, createProfiler, normalizeInstanceOrArray, normalizeConfig, normalizeOutputParam, getCachedDocumentNodeFromSchema } from '@graphql-codegen/plugin-helpers';
1
+ import { isDetailedError, DetailedError, normalizeInstanceOrArray, normalizeConfig, normalizeOutputParam, getCachedDocumentNodeFromSchema } from '@graphql-codegen/plugin-helpers';
2
2
  import { codegen } from '@graphql-codegen/core';
3
3
  import chalk from 'chalk';
4
4
  import logSymbols from 'log-symbols';
@@ -24,7 +24,7 @@ import { JsonFileLoader } from '@graphql-tools/json-file-loader';
24
24
  import { UrlLoader } from '@graphql-tools/url-loader';
25
25
  import yaml from 'yaml';
26
26
  import { createRequire } from 'module';
27
- import fs, { promises, writeFileSync, readFileSync, statSync, unlink } from 'fs';
27
+ import fs, { promises, readFileSync, writeFileSync, statSync, unlink } from 'fs';
28
28
  import Listr from 'listr';
29
29
  import { exec } from 'child_process';
30
30
  import isGlob from 'is-glob';
@@ -567,10 +567,6 @@ function buildOptions() {
567
567
  describe: 'Only print errors',
568
568
  type: 'boolean',
569
569
  },
570
- profile: {
571
- describe: 'Use profiler to measure performance',
572
- type: 'boolean',
573
- },
574
570
  p: {
575
571
  alias: 'project',
576
572
  describe: 'Name of a project in GraphQL Config',
@@ -612,9 +608,6 @@ function updateContextWithCliFlags(context, cliFlags) {
612
608
  if (cliFlags.project) {
613
609
  context.useProject(cliFlags.project);
614
610
  }
615
- if (cliFlags.profile === true) {
616
- context.useProfiler();
617
- }
618
611
  context.updateConfig(config);
619
612
  }
620
613
  class CodegenContext {
@@ -624,7 +617,6 @@ class CodegenContext {
624
617
  this._graphqlConfig = graphqlConfig;
625
618
  this.filepath = this._graphqlConfig ? this._graphqlConfig.filepath : filepath;
626
619
  this.cwd = this._graphqlConfig ? this._graphqlConfig.dirpath : process.cwd();
627
- this.profiler = createNoopProfiler();
628
620
  }
629
621
  useProject(name) {
630
622
  this._project = name;
@@ -655,13 +647,6 @@ class CodegenContext {
655
647
  ...config,
656
648
  };
657
649
  }
658
- useProfiler() {
659
- this.profiler = createProfiler();
660
- const now = new Date(); // 2011-10-05T14:48:00.000Z
661
- const datetime = now.toISOString().split('.')[0]; // 2011-10-05T14:48:00
662
- const datetimeNormalized = datetime.replace(/-|:/g, ''); // 20111005T144800
663
- this.profilerOutput = `codegen-${datetimeNormalized}.json`;
664
- }
665
650
  getPluginContext() {
666
651
  return this._pluginContext;
667
652
  }
@@ -696,7 +681,34 @@ const makeDefaultLoader = (from) => {
696
681
  return import(relativeRequire.resolve(mod));
697
682
  };
698
683
  };
684
+ // TODO: Replace any with types
685
+ function createCache(loader) {
686
+ const cache = new Map();
687
+ return {
688
+ load(key) {
689
+ if (cache.has(key)) {
690
+ return cache.get(key);
691
+ }
692
+ const value = loader(key);
693
+ cache.set(key, value);
694
+ return value;
695
+ },
696
+ };
697
+ }
699
698
  async function executeCodegen(input) {
699
+ function wrapTask(task, source) {
700
+ return async () => {
701
+ try {
702
+ await Promise.resolve().then(() => task());
703
+ }
704
+ catch (error) {
705
+ if (source && !(error instanceof GraphQLError)) {
706
+ error.source = source;
707
+ }
708
+ throw error;
709
+ }
710
+ };
711
+ }
700
712
  const context = ensureContext(input);
701
713
  const config = context.getConfig();
702
714
  const pluginContext = context.getPluginContext();
@@ -732,21 +744,20 @@ async function executeCodegen(input) {
732
744
  let rootSchemas;
733
745
  let rootDocuments;
734
746
  const generates = {};
735
- function wrapTask(task, source, taskName) {
736
- return () => {
737
- return context.profiler.run(async () => {
738
- try {
739
- await Promise.resolve().then(() => task());
740
- }
741
- catch (error) {
742
- if (source && !(error instanceof GraphQLError)) {
743
- error.source = source;
744
- }
745
- throw error;
746
- }
747
- }, taskName);
747
+ const schemaLoadingCache = createCache(async function (hash) {
748
+ const outputSchemaAst = await context.loadSchema(JSON.parse(hash));
749
+ const outputSchema = getCachedDocumentNodeFromSchema(outputSchemaAst);
750
+ return {
751
+ outputSchemaAst: outputSchemaAst,
752
+ outputSchema: outputSchema,
748
753
  };
749
- }
754
+ });
755
+ const documentsLoadingCache = createCache(async function (hash) {
756
+ const documents = await context.loadDocuments(JSON.parse(hash));
757
+ return {
758
+ documents: documents,
759
+ };
760
+ });
750
761
  async function normalize() {
751
762
  /* Load Require extensions */
752
763
  const requireExtensions = normalizeInstanceOrArray(config.require);
@@ -848,20 +859,27 @@ async function executeCodegen(input) {
848
859
  Object.assign(schemaPointerMap, unnormalizedPtr);
849
860
  }
850
861
  }
851
- outputSchemaAst = await context.loadSchema(schemaPointerMap);
852
- outputSchema = getCachedDocumentNodeFromSchema(outputSchemaAst);
853
- }, filename, `Load GraphQL schemas: ${filename}`),
862
+ const hash = JSON.stringify(schemaPointerMap);
863
+ const result = await schemaLoadingCache.load(hash);
864
+ outputSchemaAst = await result.outputSchemaAst;
865
+ outputSchema = result.outputSchema;
866
+ }, filename),
854
867
  },
855
868
  {
856
869
  title: 'Load GraphQL documents',
857
870
  task: wrapTask(async () => {
858
871
  debugLog(`[CLI] Loading Documents`);
859
- const allDocuments = [...rootDocuments, ...outputSpecificDocuments];
860
- const documents = await context.loadDocuments(allDocuments);
872
+ // get different cache for shared docs and output specific docs
873
+ const results = await Promise.all([rootDocuments, outputSpecificDocuments].map(docs => {
874
+ const hash = JSON.stringify(docs);
875
+ return documentsLoadingCache.load(hash);
876
+ }));
877
+ const documents = [];
878
+ results.forEach(source => documents.push(...source.documents));
861
879
  if (documents.length > 0) {
862
880
  outputDocuments.push(...documents);
863
881
  }
864
- }, filename, `Load GraphQL documents: ${filename}`),
882
+ }, filename),
865
883
  },
866
884
  {
867
885
  title: 'Generate',
@@ -889,7 +907,7 @@ async function executeCodegen(input) {
889
907
  };
890
908
  let outputs = [];
891
909
  if (hasPreset) {
892
- outputs = await context.profiler.run(async () => preset.buildGeneratesSection({
910
+ outputs = await preset.buildGeneratesSection({
893
911
  baseOutputDir: filename,
894
912
  presetConfig: outputConfig.presetConfig || {},
895
913
  plugins: normalizedPluginsArray,
@@ -899,8 +917,7 @@ async function executeCodegen(input) {
899
917
  config: mergedConfig,
900
918
  pluginMap,
901
919
  pluginContext,
902
- profiler: context.profiler,
903
- }), `Build Generates Section: ${filename}`);
920
+ });
904
921
  }
905
922
  else {
906
923
  outputs = [
@@ -913,7 +930,6 @@ async function executeCodegen(input) {
913
930
  config: mergedConfig,
914
931
  pluginMap,
915
932
  pluginContext,
916
- profiler: context.profiler,
917
933
  },
918
934
  ];
919
935
  }
@@ -925,8 +941,8 @@ async function executeCodegen(input) {
925
941
  hooks: outputConfig.hooks || {},
926
942
  });
927
943
  };
928
- await context.profiler.run(() => Promise.all(outputs.map(process)), `Codegen: ${filename}`);
929
- }, filename, `Generate: ${filename}`),
944
+ await Promise.all(outputs.map(process));
945
+ }, filename),
930
946
  },
931
947
  ], {
932
948
  // it stops when one of tasks failed
@@ -1176,7 +1192,7 @@ const hash = (content) => createHash('sha1').update(content).digest('base64');
1176
1192
  async function generate(input, saveToFile = true) {
1177
1193
  const context = ensureContext(input);
1178
1194
  const config = context.getConfig();
1179
- await context.profiler.run(() => lifecycleHooks(config.hooks).afterStart(), 'Lifecycle: afterStart');
1195
+ await lifecycleHooks(config.hooks).afterStart();
1180
1196
  let previouslyGeneratedFilenames = [];
1181
1197
  function removeStaleFiles(config, generationResult) {
1182
1198
  const filenames = generationResult.map(o => o.filename);
@@ -1205,8 +1221,8 @@ async function generate(input, saveToFile = true) {
1205
1221
  if (config.watch) {
1206
1222
  removeStaleFiles(config, generationResult);
1207
1223
  }
1208
- await context.profiler.run(() => lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: beforeAllFileWrite');
1209
- await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
1224
+ await lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename));
1225
+ await Promise.all(generationResult.map(async (result) => {
1210
1226
  const exists = fileExists(result.filename);
1211
1227
  if (!shouldOverwrite(config, result.filename) && exists) {
1212
1228
  return;
@@ -1218,7 +1234,7 @@ async function generate(input, saveToFile = true) {
1218
1234
  previousHash = hash(readSync(result.filename));
1219
1235
  }
1220
1236
  if (previousHash && currentHash === previousHash) {
1221
- debugLog(`Skipping file (${result.filename}) writing due to identical hash...`);
1237
+ debugLog(`Skipping file (${result.filename}) writing due to indentical hash...`);
1222
1238
  return;
1223
1239
  }
1224
1240
  if (content.length === 0) {
@@ -1235,20 +1251,17 @@ async function generate(input, saveToFile = true) {
1235
1251
  writeSync(absolutePath, result.content);
1236
1252
  await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
1237
1253
  await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
1238
- })), 'Write files');
1239
- await context.profiler.run(() => lifecycleHooks(config.hooks).afterAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: afterAllFileWrite');
1254
+ }));
1255
+ await lifecycleHooks(config.hooks).afterAllFileWrite(generationResult.map(r => r.filename));
1240
1256
  return generationResult;
1241
1257
  }
1242
1258
  // watch mode
1243
1259
  if (config.watch) {
1244
1260
  return createWatcher(context, writeOutput);
1245
1261
  }
1246
- const outputFiles = await context.profiler.run(() => executeCodegen(context), 'executeCodegen');
1247
- await context.profiler.run(() => writeOutput(outputFiles), 'writeOutput');
1248
- await context.profiler.run(() => lifecycleHooks(config.hooks).beforeDone(), 'Lifecycle: beforeDone');
1249
- if (context.profilerOutput) {
1250
- writeSync(join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
1251
- }
1262
+ const outputFiles = await executeCodegen(context);
1263
+ await writeOutput(outputFiles);
1264
+ lifecycleHooks(config.hooks).beforeDone();
1252
1265
  return outputFiles;
1253
1266
  }
1254
1267
  function shouldOverwrite(config, outputPath) {
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@graphql-codegen/cli",
3
- "version": "2.4.0-alpha-23d229715.0",
3
+ "version": "2.4.1-alpha-05252ae4a.0",
4
4
  "peerDependencies": {
5
5
  "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
6
6
  },
7
7
  "dependencies": {
8
- "@graphql-codegen/core": "2.4.0-alpha-23d229715.0",
9
- "@graphql-codegen/plugin-helpers": "2.4.0-alpha-23d229715.0",
8
+ "@graphql-codegen/core": "2.4.0",
9
+ "@graphql-codegen/plugin-helpers": "^2.3.2",
10
10
  "@graphql-tools/apollo-engine-loader": "^7.0.5",
11
11
  "@graphql-tools/code-file-loader": "^7.0.6",
12
12
  "@graphql-tools/git-loader": "^7.0.5",