@graphql-codegen/cli 2.4.1-alpha-05252ae4a.0 → 2.5.0-alpha-fc06eb8e7.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 +54 -35
- package/config.d.ts +9 -1
- package/index.js +54 -35
- package/index.mjs +56 -37
- package/package.json +3 -3
package/bin.js
CHANGED
|
@@ -676,6 +676,10 @@ 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
|
+
},
|
|
679
683
|
p: {
|
|
680
684
|
alias: 'project',
|
|
681
685
|
describe: 'Name of a project in GraphQL Config',
|
|
@@ -717,6 +721,9 @@ function updateContextWithCliFlags(context, cliFlags) {
|
|
|
717
721
|
if (cliFlags.project) {
|
|
718
722
|
context.useProject(cliFlags.project);
|
|
719
723
|
}
|
|
724
|
+
if (cliFlags.profile === true) {
|
|
725
|
+
context.useProfiler();
|
|
726
|
+
}
|
|
720
727
|
context.updateConfig(config);
|
|
721
728
|
}
|
|
722
729
|
class CodegenContext {
|
|
@@ -726,6 +733,7 @@ class CodegenContext {
|
|
|
726
733
|
this._graphqlConfig = graphqlConfig;
|
|
727
734
|
this.filepath = this._graphqlConfig ? this._graphqlConfig.filepath : filepath;
|
|
728
735
|
this.cwd = this._graphqlConfig ? this._graphqlConfig.dirpath : process.cwd();
|
|
736
|
+
this.profiler = pluginHelpers.createNoopProfiler();
|
|
729
737
|
}
|
|
730
738
|
useProject(name) {
|
|
731
739
|
this._project = name;
|
|
@@ -756,6 +764,13 @@ class CodegenContext {
|
|
|
756
764
|
...config,
|
|
757
765
|
};
|
|
758
766
|
}
|
|
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
|
+
}
|
|
759
774
|
getPluginContext() {
|
|
760
775
|
return this._pluginContext;
|
|
761
776
|
}
|
|
@@ -805,19 +820,6 @@ function createCache(loader) {
|
|
|
805
820
|
};
|
|
806
821
|
}
|
|
807
822
|
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
|
-
}
|
|
821
823
|
const context = ensureContext(input);
|
|
822
824
|
const config = context.getConfig();
|
|
823
825
|
const pluginContext = context.getPluginContext();
|
|
@@ -867,6 +869,21 @@ async function executeCodegen(input) {
|
|
|
867
869
|
documents: documents,
|
|
868
870
|
};
|
|
869
871
|
});
|
|
872
|
+
function wrapTask(task, source, taskName) {
|
|
873
|
+
return () => {
|
|
874
|
+
return context.profiler.run(async () => {
|
|
875
|
+
try {
|
|
876
|
+
await Promise.resolve().then(() => task());
|
|
877
|
+
}
|
|
878
|
+
catch (error) {
|
|
879
|
+
if (source && !(error instanceof graphql.GraphQLError)) {
|
|
880
|
+
error.source = source;
|
|
881
|
+
}
|
|
882
|
+
throw error;
|
|
883
|
+
}
|
|
884
|
+
}, taskName);
|
|
885
|
+
};
|
|
886
|
+
}
|
|
870
887
|
async function normalize() {
|
|
871
888
|
/* Load Require extensions */
|
|
872
889
|
const requireExtensions = pluginHelpers.normalizeInstanceOrArray(config.require);
|
|
@@ -972,23 +989,20 @@ async function executeCodegen(input) {
|
|
|
972
989
|
const result = await schemaLoadingCache.load(hash);
|
|
973
990
|
outputSchemaAst = await result.outputSchemaAst;
|
|
974
991
|
outputSchema = result.outputSchema;
|
|
975
|
-
}, filename),
|
|
992
|
+
}, filename, `Load GraphQL schemas: ${filename}`),
|
|
976
993
|
},
|
|
977
994
|
{
|
|
978
995
|
title: 'Load GraphQL documents',
|
|
979
996
|
task: wrapTask(async () => {
|
|
980
997
|
debugLog(`[CLI] Loading Documents`);
|
|
981
|
-
|
|
982
|
-
const
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
}));
|
|
986
|
-
const documents = [];
|
|
987
|
-
results.forEach(source => documents.push(...source.documents));
|
|
998
|
+
const allDocuments = [...rootDocuments, ...outputSpecificDocuments];
|
|
999
|
+
const hash = JSON.stringify(allDocuments);
|
|
1000
|
+
const result = await documentsLoadingCache.load(hash);
|
|
1001
|
+
const documents = result.documents;
|
|
988
1002
|
if (documents.length > 0) {
|
|
989
1003
|
outputDocuments.push(...documents);
|
|
990
1004
|
}
|
|
991
|
-
}, filename),
|
|
1005
|
+
}, filename, `Load GraphQL documents: ${filename}`),
|
|
992
1006
|
},
|
|
993
1007
|
{
|
|
994
1008
|
title: 'Generate',
|
|
@@ -1016,7 +1030,7 @@ async function executeCodegen(input) {
|
|
|
1016
1030
|
};
|
|
1017
1031
|
let outputs = [];
|
|
1018
1032
|
if (hasPreset) {
|
|
1019
|
-
outputs = await preset.buildGeneratesSection({
|
|
1033
|
+
outputs = await context.profiler.run(async () => preset.buildGeneratesSection({
|
|
1020
1034
|
baseOutputDir: filename,
|
|
1021
1035
|
presetConfig: outputConfig.presetConfig || {},
|
|
1022
1036
|
plugins: normalizedPluginsArray,
|
|
@@ -1026,7 +1040,8 @@ async function executeCodegen(input) {
|
|
|
1026
1040
|
config: mergedConfig,
|
|
1027
1041
|
pluginMap,
|
|
1028
1042
|
pluginContext,
|
|
1029
|
-
|
|
1043
|
+
profiler: context.profiler,
|
|
1044
|
+
}), `Build Generates Section: ${filename}`);
|
|
1030
1045
|
}
|
|
1031
1046
|
else {
|
|
1032
1047
|
outputs = [
|
|
@@ -1039,6 +1054,7 @@ async function executeCodegen(input) {
|
|
|
1039
1054
|
config: mergedConfig,
|
|
1040
1055
|
pluginMap,
|
|
1041
1056
|
pluginContext,
|
|
1057
|
+
profiler: context.profiler,
|
|
1042
1058
|
},
|
|
1043
1059
|
];
|
|
1044
1060
|
}
|
|
@@ -1050,8 +1066,8 @@ async function executeCodegen(input) {
|
|
|
1050
1066
|
hooks: outputConfig.hooks || {},
|
|
1051
1067
|
});
|
|
1052
1068
|
};
|
|
1053
|
-
await Promise.all(outputs.map(process));
|
|
1054
|
-
}, filename),
|
|
1069
|
+
await context.profiler.run(() => Promise.all(outputs.map(process)), `Codegen: ${filename}`);
|
|
1070
|
+
}, filename, `Generate: ${filename}`),
|
|
1055
1071
|
},
|
|
1056
1072
|
], {
|
|
1057
1073
|
// it stops when one of tasks failed
|
|
@@ -1218,7 +1234,7 @@ const hash = (content) => crypto.createHash('sha1').update(content).digest('base
|
|
|
1218
1234
|
async function generate(input, saveToFile = true) {
|
|
1219
1235
|
const context = ensureContext(input);
|
|
1220
1236
|
const config = context.getConfig();
|
|
1221
|
-
await lifecycleHooks(config.hooks).afterStart();
|
|
1237
|
+
await context.profiler.run(() => lifecycleHooks(config.hooks).afterStart(), 'Lifecycle: afterStart');
|
|
1222
1238
|
let previouslyGeneratedFilenames = [];
|
|
1223
1239
|
function removeStaleFiles(config, generationResult) {
|
|
1224
1240
|
const filenames = generationResult.map(o => o.filename);
|
|
@@ -1247,8 +1263,8 @@ async function generate(input, saveToFile = true) {
|
|
|
1247
1263
|
if (config.watch) {
|
|
1248
1264
|
removeStaleFiles(config, generationResult);
|
|
1249
1265
|
}
|
|
1250
|
-
await lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename));
|
|
1251
|
-
await Promise.all(generationResult.map(async (result) => {
|
|
1266
|
+
await context.profiler.run(() => lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: beforeAllFileWrite');
|
|
1267
|
+
await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
|
|
1252
1268
|
const exists = fileExists(result.filename);
|
|
1253
1269
|
if (!shouldOverwrite(config, result.filename) && exists) {
|
|
1254
1270
|
return;
|
|
@@ -1260,7 +1276,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1260
1276
|
previousHash = hash(readSync(result.filename));
|
|
1261
1277
|
}
|
|
1262
1278
|
if (previousHash && currentHash === previousHash) {
|
|
1263
|
-
debugLog(`Skipping file (${result.filename}) writing due to
|
|
1279
|
+
debugLog(`Skipping file (${result.filename}) writing due to identical hash...`);
|
|
1264
1280
|
return;
|
|
1265
1281
|
}
|
|
1266
1282
|
if (content.length === 0) {
|
|
@@ -1277,17 +1293,20 @@ async function generate(input, saveToFile = true) {
|
|
|
1277
1293
|
writeSync(absolutePath, result.content);
|
|
1278
1294
|
await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
|
|
1279
1295
|
await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
|
|
1280
|
-
}));
|
|
1281
|
-
await lifecycleHooks(config.hooks).afterAllFileWrite(generationResult.map(r => r.filename));
|
|
1296
|
+
})), 'Write files');
|
|
1297
|
+
await context.profiler.run(() => lifecycleHooks(config.hooks).afterAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: afterAllFileWrite');
|
|
1282
1298
|
return generationResult;
|
|
1283
1299
|
}
|
|
1284
1300
|
// watch mode
|
|
1285
1301
|
if (config.watch) {
|
|
1286
1302
|
return createWatcher(context, writeOutput);
|
|
1287
1303
|
}
|
|
1288
|
-
const outputFiles = await executeCodegen(context);
|
|
1289
|
-
await writeOutput(outputFiles);
|
|
1290
|
-
lifecycleHooks(config.hooks).beforeDone();
|
|
1304
|
+
const outputFiles = await context.profiler.run(() => executeCodegen(context), 'executeCodegen');
|
|
1305
|
+
await context.profiler.run(() => writeOutput(outputFiles), 'writeOutput');
|
|
1306
|
+
await context.profiler.run(() => lifecycleHooks(config.hooks).beforeDone(), 'Lifecycle: beforeDone');
|
|
1307
|
+
if (context.profilerOutput) {
|
|
1308
|
+
writeSync(path.join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
|
|
1309
|
+
}
|
|
1291
1310
|
return outputFiles;
|
|
1292
1311
|
}
|
|
1293
1312
|
function shouldOverwrite(config, outputPath) {
|
package/config.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Types } from '@graphql-codegen/plugin-helpers';
|
|
1
|
+
import { Types, Profiler } 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,6 +9,7 @@ export declare type YamlCliFlags = {
|
|
|
9
9
|
project: string;
|
|
10
10
|
silent: boolean;
|
|
11
11
|
errorsOnly: boolean;
|
|
12
|
+
profile: boolean;
|
|
12
13
|
};
|
|
13
14
|
export declare function generateSearchPlaces(moduleName: string): string[];
|
|
14
15
|
export interface LoadCodegenConfigOptions {
|
|
@@ -74,6 +75,10 @@ export declare function buildOptions(): {
|
|
|
74
75
|
describe: string;
|
|
75
76
|
type: "boolean";
|
|
76
77
|
};
|
|
78
|
+
profile: {
|
|
79
|
+
describe: string;
|
|
80
|
+
type: "boolean";
|
|
81
|
+
};
|
|
77
82
|
p: {
|
|
78
83
|
alias: string;
|
|
79
84
|
describe: string;
|
|
@@ -91,6 +96,8 @@ export declare class CodegenContext {
|
|
|
91
96
|
private _pluginContext;
|
|
92
97
|
cwd: string;
|
|
93
98
|
filepath: string;
|
|
99
|
+
profiler: Profiler;
|
|
100
|
+
profilerOutput?: string;
|
|
94
101
|
constructor({ config, graphqlConfig, filepath, }: {
|
|
95
102
|
config?: Types.Config;
|
|
96
103
|
graphqlConfig?: GraphQLConfig;
|
|
@@ -99,6 +106,7 @@ export declare class CodegenContext {
|
|
|
99
106
|
useProject(name?: string): void;
|
|
100
107
|
getConfig<T>(extraConfig?: T): T & Types.Config;
|
|
101
108
|
updateConfig(config: Partial<Types.Config>): void;
|
|
109
|
+
useProfiler(): void;
|
|
102
110
|
getPluginContext(): {
|
|
103
111
|
[key: string]: any;
|
|
104
112
|
};
|
package/index.js
CHANGED
|
@@ -594,6 +594,10 @@ 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
|
+
},
|
|
597
601
|
p: {
|
|
598
602
|
alias: 'project',
|
|
599
603
|
describe: 'Name of a project in GraphQL Config',
|
|
@@ -635,6 +639,9 @@ function updateContextWithCliFlags(context, cliFlags) {
|
|
|
635
639
|
if (cliFlags.project) {
|
|
636
640
|
context.useProject(cliFlags.project);
|
|
637
641
|
}
|
|
642
|
+
if (cliFlags.profile === true) {
|
|
643
|
+
context.useProfiler();
|
|
644
|
+
}
|
|
638
645
|
context.updateConfig(config);
|
|
639
646
|
}
|
|
640
647
|
class CodegenContext {
|
|
@@ -644,6 +651,7 @@ class CodegenContext {
|
|
|
644
651
|
this._graphqlConfig = graphqlConfig;
|
|
645
652
|
this.filepath = this._graphqlConfig ? this._graphqlConfig.filepath : filepath;
|
|
646
653
|
this.cwd = this._graphqlConfig ? this._graphqlConfig.dirpath : process.cwd();
|
|
654
|
+
this.profiler = pluginHelpers.createNoopProfiler();
|
|
647
655
|
}
|
|
648
656
|
useProject(name) {
|
|
649
657
|
this._project = name;
|
|
@@ -674,6 +682,13 @@ class CodegenContext {
|
|
|
674
682
|
...config,
|
|
675
683
|
};
|
|
676
684
|
}
|
|
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
|
+
}
|
|
677
692
|
getPluginContext() {
|
|
678
693
|
return this._pluginContext;
|
|
679
694
|
}
|
|
@@ -723,19 +738,6 @@ function createCache(loader) {
|
|
|
723
738
|
};
|
|
724
739
|
}
|
|
725
740
|
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
|
-
}
|
|
739
741
|
const context = ensureContext(input);
|
|
740
742
|
const config = context.getConfig();
|
|
741
743
|
const pluginContext = context.getPluginContext();
|
|
@@ -785,6 +787,21 @@ async function executeCodegen(input) {
|
|
|
785
787
|
documents: documents,
|
|
786
788
|
};
|
|
787
789
|
});
|
|
790
|
+
function wrapTask(task, source, taskName) {
|
|
791
|
+
return () => {
|
|
792
|
+
return context.profiler.run(async () => {
|
|
793
|
+
try {
|
|
794
|
+
await Promise.resolve().then(() => task());
|
|
795
|
+
}
|
|
796
|
+
catch (error) {
|
|
797
|
+
if (source && !(error instanceof graphql.GraphQLError)) {
|
|
798
|
+
error.source = source;
|
|
799
|
+
}
|
|
800
|
+
throw error;
|
|
801
|
+
}
|
|
802
|
+
}, taskName);
|
|
803
|
+
};
|
|
804
|
+
}
|
|
788
805
|
async function normalize() {
|
|
789
806
|
/* Load Require extensions */
|
|
790
807
|
const requireExtensions = pluginHelpers.normalizeInstanceOrArray(config.require);
|
|
@@ -890,23 +907,20 @@ async function executeCodegen(input) {
|
|
|
890
907
|
const result = await schemaLoadingCache.load(hash);
|
|
891
908
|
outputSchemaAst = await result.outputSchemaAst;
|
|
892
909
|
outputSchema = result.outputSchema;
|
|
893
|
-
}, filename),
|
|
910
|
+
}, filename, `Load GraphQL schemas: ${filename}`),
|
|
894
911
|
},
|
|
895
912
|
{
|
|
896
913
|
title: 'Load GraphQL documents',
|
|
897
914
|
task: wrapTask(async () => {
|
|
898
915
|
debugLog(`[CLI] Loading Documents`);
|
|
899
|
-
|
|
900
|
-
const
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
}));
|
|
904
|
-
const documents = [];
|
|
905
|
-
results.forEach(source => documents.push(...source.documents));
|
|
916
|
+
const allDocuments = [...rootDocuments, ...outputSpecificDocuments];
|
|
917
|
+
const hash = JSON.stringify(allDocuments);
|
|
918
|
+
const result = await documentsLoadingCache.load(hash);
|
|
919
|
+
const documents = result.documents;
|
|
906
920
|
if (documents.length > 0) {
|
|
907
921
|
outputDocuments.push(...documents);
|
|
908
922
|
}
|
|
909
|
-
}, filename),
|
|
923
|
+
}, filename, `Load GraphQL documents: ${filename}`),
|
|
910
924
|
},
|
|
911
925
|
{
|
|
912
926
|
title: 'Generate',
|
|
@@ -934,7 +948,7 @@ async function executeCodegen(input) {
|
|
|
934
948
|
};
|
|
935
949
|
let outputs = [];
|
|
936
950
|
if (hasPreset) {
|
|
937
|
-
outputs = await preset.buildGeneratesSection({
|
|
951
|
+
outputs = await context.profiler.run(async () => preset.buildGeneratesSection({
|
|
938
952
|
baseOutputDir: filename,
|
|
939
953
|
presetConfig: outputConfig.presetConfig || {},
|
|
940
954
|
plugins: normalizedPluginsArray,
|
|
@@ -944,7 +958,8 @@ async function executeCodegen(input) {
|
|
|
944
958
|
config: mergedConfig,
|
|
945
959
|
pluginMap,
|
|
946
960
|
pluginContext,
|
|
947
|
-
|
|
961
|
+
profiler: context.profiler,
|
|
962
|
+
}), `Build Generates Section: ${filename}`);
|
|
948
963
|
}
|
|
949
964
|
else {
|
|
950
965
|
outputs = [
|
|
@@ -957,6 +972,7 @@ async function executeCodegen(input) {
|
|
|
957
972
|
config: mergedConfig,
|
|
958
973
|
pluginMap,
|
|
959
974
|
pluginContext,
|
|
975
|
+
profiler: context.profiler,
|
|
960
976
|
},
|
|
961
977
|
];
|
|
962
978
|
}
|
|
@@ -968,8 +984,8 @@ async function executeCodegen(input) {
|
|
|
968
984
|
hooks: outputConfig.hooks || {},
|
|
969
985
|
});
|
|
970
986
|
};
|
|
971
|
-
await Promise.all(outputs.map(process));
|
|
972
|
-
}, filename),
|
|
987
|
+
await context.profiler.run(() => Promise.all(outputs.map(process)), `Codegen: ${filename}`);
|
|
988
|
+
}, filename, `Generate: ${filename}`),
|
|
973
989
|
},
|
|
974
990
|
], {
|
|
975
991
|
// it stops when one of tasks failed
|
|
@@ -1219,7 +1235,7 @@ const hash = (content) => crypto.createHash('sha1').update(content).digest('base
|
|
|
1219
1235
|
async function generate(input, saveToFile = true) {
|
|
1220
1236
|
const context = ensureContext(input);
|
|
1221
1237
|
const config = context.getConfig();
|
|
1222
|
-
await lifecycleHooks(config.hooks).afterStart();
|
|
1238
|
+
await context.profiler.run(() => lifecycleHooks(config.hooks).afterStart(), 'Lifecycle: afterStart');
|
|
1223
1239
|
let previouslyGeneratedFilenames = [];
|
|
1224
1240
|
function removeStaleFiles(config, generationResult) {
|
|
1225
1241
|
const filenames = generationResult.map(o => o.filename);
|
|
@@ -1248,8 +1264,8 @@ async function generate(input, saveToFile = true) {
|
|
|
1248
1264
|
if (config.watch) {
|
|
1249
1265
|
removeStaleFiles(config, generationResult);
|
|
1250
1266
|
}
|
|
1251
|
-
await lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename));
|
|
1252
|
-
await Promise.all(generationResult.map(async (result) => {
|
|
1267
|
+
await context.profiler.run(() => lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: beforeAllFileWrite');
|
|
1268
|
+
await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
|
|
1253
1269
|
const exists = fileExists(result.filename);
|
|
1254
1270
|
if (!shouldOverwrite(config, result.filename) && exists) {
|
|
1255
1271
|
return;
|
|
@@ -1261,7 +1277,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1261
1277
|
previousHash = hash(readSync(result.filename));
|
|
1262
1278
|
}
|
|
1263
1279
|
if (previousHash && currentHash === previousHash) {
|
|
1264
|
-
debugLog(`Skipping file (${result.filename}) writing due to
|
|
1280
|
+
debugLog(`Skipping file (${result.filename}) writing due to identical hash...`);
|
|
1265
1281
|
return;
|
|
1266
1282
|
}
|
|
1267
1283
|
if (content.length === 0) {
|
|
@@ -1278,17 +1294,20 @@ async function generate(input, saveToFile = true) {
|
|
|
1278
1294
|
writeSync(absolutePath, result.content);
|
|
1279
1295
|
await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
|
|
1280
1296
|
await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
|
|
1281
|
-
}));
|
|
1282
|
-
await lifecycleHooks(config.hooks).afterAllFileWrite(generationResult.map(r => r.filename));
|
|
1297
|
+
})), 'Write files');
|
|
1298
|
+
await context.profiler.run(() => lifecycleHooks(config.hooks).afterAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: afterAllFileWrite');
|
|
1283
1299
|
return generationResult;
|
|
1284
1300
|
}
|
|
1285
1301
|
// watch mode
|
|
1286
1302
|
if (config.watch) {
|
|
1287
1303
|
return createWatcher(context, writeOutput);
|
|
1288
1304
|
}
|
|
1289
|
-
const outputFiles = await executeCodegen(context);
|
|
1290
|
-
await writeOutput(outputFiles);
|
|
1291
|
-
lifecycleHooks(config.hooks).beforeDone();
|
|
1305
|
+
const outputFiles = await context.profiler.run(() => executeCodegen(context), 'executeCodegen');
|
|
1306
|
+
await context.profiler.run(() => writeOutput(outputFiles), 'writeOutput');
|
|
1307
|
+
await context.profiler.run(() => lifecycleHooks(config.hooks).beforeDone(), 'Lifecycle: beforeDone');
|
|
1308
|
+
if (context.profilerOutput) {
|
|
1309
|
+
writeSync(path.join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
|
|
1310
|
+
}
|
|
1292
1311
|
return outputFiles;
|
|
1293
1312
|
}
|
|
1294
1313
|
function shouldOverwrite(config, outputPath) {
|
package/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isDetailedError, DetailedError, normalizeInstanceOrArray, normalizeConfig, normalizeOutputParam, getCachedDocumentNodeFromSchema } from '@graphql-codegen/plugin-helpers';
|
|
1
|
+
import { isDetailedError, DetailedError, createNoopProfiler, createProfiler, 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,
|
|
27
|
+
import fs, { promises, writeFileSync, readFileSync, 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,6 +567,10 @@ 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
|
+
},
|
|
570
574
|
p: {
|
|
571
575
|
alias: 'project',
|
|
572
576
|
describe: 'Name of a project in GraphQL Config',
|
|
@@ -608,6 +612,9 @@ function updateContextWithCliFlags(context, cliFlags) {
|
|
|
608
612
|
if (cliFlags.project) {
|
|
609
613
|
context.useProject(cliFlags.project);
|
|
610
614
|
}
|
|
615
|
+
if (cliFlags.profile === true) {
|
|
616
|
+
context.useProfiler();
|
|
617
|
+
}
|
|
611
618
|
context.updateConfig(config);
|
|
612
619
|
}
|
|
613
620
|
class CodegenContext {
|
|
@@ -617,6 +624,7 @@ class CodegenContext {
|
|
|
617
624
|
this._graphqlConfig = graphqlConfig;
|
|
618
625
|
this.filepath = this._graphqlConfig ? this._graphqlConfig.filepath : filepath;
|
|
619
626
|
this.cwd = this._graphqlConfig ? this._graphqlConfig.dirpath : process.cwd();
|
|
627
|
+
this.profiler = createNoopProfiler();
|
|
620
628
|
}
|
|
621
629
|
useProject(name) {
|
|
622
630
|
this._project = name;
|
|
@@ -647,6 +655,13 @@ class CodegenContext {
|
|
|
647
655
|
...config,
|
|
648
656
|
};
|
|
649
657
|
}
|
|
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
|
+
}
|
|
650
665
|
getPluginContext() {
|
|
651
666
|
return this._pluginContext;
|
|
652
667
|
}
|
|
@@ -696,19 +711,6 @@ function createCache(loader) {
|
|
|
696
711
|
};
|
|
697
712
|
}
|
|
698
713
|
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
|
-
}
|
|
712
714
|
const context = ensureContext(input);
|
|
713
715
|
const config = context.getConfig();
|
|
714
716
|
const pluginContext = context.getPluginContext();
|
|
@@ -758,6 +760,21 @@ async function executeCodegen(input) {
|
|
|
758
760
|
documents: documents,
|
|
759
761
|
};
|
|
760
762
|
});
|
|
763
|
+
function wrapTask(task, source, taskName) {
|
|
764
|
+
return () => {
|
|
765
|
+
return context.profiler.run(async () => {
|
|
766
|
+
try {
|
|
767
|
+
await Promise.resolve().then(() => task());
|
|
768
|
+
}
|
|
769
|
+
catch (error) {
|
|
770
|
+
if (source && !(error instanceof GraphQLError)) {
|
|
771
|
+
error.source = source;
|
|
772
|
+
}
|
|
773
|
+
throw error;
|
|
774
|
+
}
|
|
775
|
+
}, taskName);
|
|
776
|
+
};
|
|
777
|
+
}
|
|
761
778
|
async function normalize() {
|
|
762
779
|
/* Load Require extensions */
|
|
763
780
|
const requireExtensions = normalizeInstanceOrArray(config.require);
|
|
@@ -863,23 +880,20 @@ async function executeCodegen(input) {
|
|
|
863
880
|
const result = await schemaLoadingCache.load(hash);
|
|
864
881
|
outputSchemaAst = await result.outputSchemaAst;
|
|
865
882
|
outputSchema = result.outputSchema;
|
|
866
|
-
}, filename),
|
|
883
|
+
}, filename, `Load GraphQL schemas: ${filename}`),
|
|
867
884
|
},
|
|
868
885
|
{
|
|
869
886
|
title: 'Load GraphQL documents',
|
|
870
887
|
task: wrapTask(async () => {
|
|
871
888
|
debugLog(`[CLI] Loading Documents`);
|
|
872
|
-
|
|
873
|
-
const
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
}));
|
|
877
|
-
const documents = [];
|
|
878
|
-
results.forEach(source => documents.push(...source.documents));
|
|
889
|
+
const allDocuments = [...rootDocuments, ...outputSpecificDocuments];
|
|
890
|
+
const hash = JSON.stringify(allDocuments);
|
|
891
|
+
const result = await documentsLoadingCache.load(hash);
|
|
892
|
+
const documents = result.documents;
|
|
879
893
|
if (documents.length > 0) {
|
|
880
894
|
outputDocuments.push(...documents);
|
|
881
895
|
}
|
|
882
|
-
}, filename),
|
|
896
|
+
}, filename, `Load GraphQL documents: ${filename}`),
|
|
883
897
|
},
|
|
884
898
|
{
|
|
885
899
|
title: 'Generate',
|
|
@@ -907,7 +921,7 @@ async function executeCodegen(input) {
|
|
|
907
921
|
};
|
|
908
922
|
let outputs = [];
|
|
909
923
|
if (hasPreset) {
|
|
910
|
-
outputs = await preset.buildGeneratesSection({
|
|
924
|
+
outputs = await context.profiler.run(async () => preset.buildGeneratesSection({
|
|
911
925
|
baseOutputDir: filename,
|
|
912
926
|
presetConfig: outputConfig.presetConfig || {},
|
|
913
927
|
plugins: normalizedPluginsArray,
|
|
@@ -917,7 +931,8 @@ async function executeCodegen(input) {
|
|
|
917
931
|
config: mergedConfig,
|
|
918
932
|
pluginMap,
|
|
919
933
|
pluginContext,
|
|
920
|
-
|
|
934
|
+
profiler: context.profiler,
|
|
935
|
+
}), `Build Generates Section: ${filename}`);
|
|
921
936
|
}
|
|
922
937
|
else {
|
|
923
938
|
outputs = [
|
|
@@ -930,6 +945,7 @@ async function executeCodegen(input) {
|
|
|
930
945
|
config: mergedConfig,
|
|
931
946
|
pluginMap,
|
|
932
947
|
pluginContext,
|
|
948
|
+
profiler: context.profiler,
|
|
933
949
|
},
|
|
934
950
|
];
|
|
935
951
|
}
|
|
@@ -941,8 +957,8 @@ async function executeCodegen(input) {
|
|
|
941
957
|
hooks: outputConfig.hooks || {},
|
|
942
958
|
});
|
|
943
959
|
};
|
|
944
|
-
await Promise.all(outputs.map(process));
|
|
945
|
-
}, filename),
|
|
960
|
+
await context.profiler.run(() => Promise.all(outputs.map(process)), `Codegen: ${filename}`);
|
|
961
|
+
}, filename, `Generate: ${filename}`),
|
|
946
962
|
},
|
|
947
963
|
], {
|
|
948
964
|
// it stops when one of tasks failed
|
|
@@ -1192,7 +1208,7 @@ const hash = (content) => createHash('sha1').update(content).digest('base64');
|
|
|
1192
1208
|
async function generate(input, saveToFile = true) {
|
|
1193
1209
|
const context = ensureContext(input);
|
|
1194
1210
|
const config = context.getConfig();
|
|
1195
|
-
await lifecycleHooks(config.hooks).afterStart();
|
|
1211
|
+
await context.profiler.run(() => lifecycleHooks(config.hooks).afterStart(), 'Lifecycle: afterStart');
|
|
1196
1212
|
let previouslyGeneratedFilenames = [];
|
|
1197
1213
|
function removeStaleFiles(config, generationResult) {
|
|
1198
1214
|
const filenames = generationResult.map(o => o.filename);
|
|
@@ -1221,8 +1237,8 @@ async function generate(input, saveToFile = true) {
|
|
|
1221
1237
|
if (config.watch) {
|
|
1222
1238
|
removeStaleFiles(config, generationResult);
|
|
1223
1239
|
}
|
|
1224
|
-
await lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename));
|
|
1225
|
-
await Promise.all(generationResult.map(async (result) => {
|
|
1240
|
+
await context.profiler.run(() => lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: beforeAllFileWrite');
|
|
1241
|
+
await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
|
|
1226
1242
|
const exists = fileExists(result.filename);
|
|
1227
1243
|
if (!shouldOverwrite(config, result.filename) && exists) {
|
|
1228
1244
|
return;
|
|
@@ -1234,7 +1250,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1234
1250
|
previousHash = hash(readSync(result.filename));
|
|
1235
1251
|
}
|
|
1236
1252
|
if (previousHash && currentHash === previousHash) {
|
|
1237
|
-
debugLog(`Skipping file (${result.filename}) writing due to
|
|
1253
|
+
debugLog(`Skipping file (${result.filename}) writing due to identical hash...`);
|
|
1238
1254
|
return;
|
|
1239
1255
|
}
|
|
1240
1256
|
if (content.length === 0) {
|
|
@@ -1251,17 +1267,20 @@ async function generate(input, saveToFile = true) {
|
|
|
1251
1267
|
writeSync(absolutePath, result.content);
|
|
1252
1268
|
await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
|
|
1253
1269
|
await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
|
|
1254
|
-
}));
|
|
1255
|
-
await lifecycleHooks(config.hooks).afterAllFileWrite(generationResult.map(r => r.filename));
|
|
1270
|
+
})), 'Write files');
|
|
1271
|
+
await context.profiler.run(() => lifecycleHooks(config.hooks).afterAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: afterAllFileWrite');
|
|
1256
1272
|
return generationResult;
|
|
1257
1273
|
}
|
|
1258
1274
|
// watch mode
|
|
1259
1275
|
if (config.watch) {
|
|
1260
1276
|
return createWatcher(context, writeOutput);
|
|
1261
1277
|
}
|
|
1262
|
-
const outputFiles = await executeCodegen(context);
|
|
1263
|
-
await writeOutput(outputFiles);
|
|
1264
|
-
lifecycleHooks(config.hooks).beforeDone();
|
|
1278
|
+
const outputFiles = await context.profiler.run(() => executeCodegen(context), 'executeCodegen');
|
|
1279
|
+
await context.profiler.run(() => writeOutput(outputFiles), 'writeOutput');
|
|
1280
|
+
await context.profiler.run(() => lifecycleHooks(config.hooks).beforeDone(), 'Lifecycle: beforeDone');
|
|
1281
|
+
if (context.profilerOutput) {
|
|
1282
|
+
writeSync(join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
|
|
1283
|
+
}
|
|
1265
1284
|
return outputFiles;
|
|
1266
1285
|
}
|
|
1267
1286
|
function shouldOverwrite(config, outputPath) {
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphql-codegen/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0-alpha-fc06eb8e7.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.
|
|
9
|
-
"@graphql-codegen/plugin-helpers": "
|
|
8
|
+
"@graphql-codegen/core": "2.5.0-alpha-fc06eb8e7.0",
|
|
9
|
+
"@graphql-codegen/plugin-helpers": "2.4.0-alpha-fc06eb8e7.0",
|
|
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",
|