relay-compiler 12.0.0 → 13.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (262) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +108 -0
  3. package/cli.js +23 -0
  4. package/index.js +22 -4
  5. package/linux-x64/relay +0 -0
  6. package/macos-arm64/relay +0 -0
  7. package/macos-x64/relay +0 -0
  8. package/package.json +2 -26
  9. package/win-x64/relay.exe +0 -0
  10. package/bin/RelayCompilerBin.js.flow +0 -169
  11. package/bin/RelayCompilerMain.js.flow +0 -515
  12. package/bin/__fixtures__/plugin-module.js.flow +0 -17
  13. package/bin/relay-compiler +0 -19066
  14. package/codegen/CodegenDirectory.js.flow +0 -375
  15. package/codegen/CodegenRunner.js.flow +0 -432
  16. package/codegen/CodegenTypes.js.flow +0 -28
  17. package/codegen/CodegenWatcher.js.flow +0 -254
  18. package/codegen/NormalizationCodeGenerator.js.flow +0 -566
  19. package/codegen/ReaderCodeGenerator.js.flow +0 -512
  20. package/codegen/RelayCodeGenerator.js.flow +0 -85
  21. package/codegen/RelayFileWriter.js.flow +0 -367
  22. package/codegen/SourceControl.js.flow +0 -58
  23. package/codegen/compileRelayArtifacts.js.flow +0 -182
  24. package/codegen/createPrintRequireModuleDependency.js.flow +0 -19
  25. package/codegen/sortObjectByKey.js.flow +0 -25
  26. package/codegen/writeRelayGeneratedFile.js.flow +0 -239
  27. package/core/ASTCache.js.flow +0 -74
  28. package/core/ASTConvert.js.flow +0 -233
  29. package/core/CompilerContext.js.flow +0 -191
  30. package/core/CompilerError.js.flow +0 -255
  31. package/core/DotGraphQLParser.js.flow +0 -39
  32. package/core/GraphQLCompilerProfiler.js.flow +0 -341
  33. package/core/GraphQLDerivedFromMetadata.js.flow +0 -36
  34. package/core/GraphQLWatchmanClient.js.flow +0 -111
  35. package/core/IR.js.flow +0 -326
  36. package/core/IRPrinter.js.flow +0 -478
  37. package/core/IRTransformer.js.flow +0 -377
  38. package/core/IRValidator.js.flow +0 -260
  39. package/core/IRVisitor.js.flow +0 -150
  40. package/core/JSModuleParser.js.flow +0 -24
  41. package/core/RelayCompilerScope.js.flow +0 -199
  42. package/core/RelayFindGraphQLTags.js.flow +0 -119
  43. package/core/RelayGraphQLEnumsGenerator.js.flow +0 -55
  44. package/core/RelayIRTransforms.js.flow +0 -138
  45. package/core/RelayParser.js.flow +0 -1734
  46. package/core/RelaySourceModuleParser.js.flow +0 -135
  47. package/core/Schema.js.flow +0 -2037
  48. package/core/SchemaUtils.js.flow +0 -120
  49. package/core/filterContextForNode.js.flow +0 -50
  50. package/core/getFieldDefinition.js.flow +0 -156
  51. package/core/getIdentifierForArgumentValue.js.flow +0 -49
  52. package/core/getIdentifierForSelection.js.flow +0 -69
  53. package/core/getLiteralArgumentValues.js.flow +0 -32
  54. package/core/getNormalizationOperationName.js.flow +0 -19
  55. package/core/inferRootArgumentDefinitions.js.flow +0 -323
  56. package/index.js.flow +0 -200
  57. package/language/RelayLanguagePluginInterface.js.flow +0 -283
  58. package/language/javascript/FindGraphQLTags.js.flow +0 -137
  59. package/language/javascript/RelayFlowBabelFactories.js.flow +0 -176
  60. package/language/javascript/RelayFlowGenerator.js.flow +0 -1100
  61. package/language/javascript/RelayFlowTypeTransformers.js.flow +0 -184
  62. package/language/javascript/RelayLanguagePluginJavaScript.js.flow +0 -34
  63. package/language/javascript/formatGeneratedModule.js.flow +0 -65
  64. package/lib/bin/RelayCompilerBin.js +0 -143
  65. package/lib/bin/RelayCompilerMain.js +0 -486
  66. package/lib/bin/__fixtures__/plugin-module.js +0 -16
  67. package/lib/codegen/CodegenDirectory.js +0 -336
  68. package/lib/codegen/CodegenRunner.js +0 -433
  69. package/lib/codegen/CodegenTypes.js +0 -11
  70. package/lib/codegen/CodegenWatcher.js +0 -271
  71. package/lib/codegen/NormalizationCodeGenerator.js +0 -480
  72. package/lib/codegen/ReaderCodeGenerator.js +0 -472
  73. package/lib/codegen/RelayCodeGenerator.js +0 -68
  74. package/lib/codegen/RelayFileWriter.js +0 -270
  75. package/lib/codegen/SourceControl.js +0 -60
  76. package/lib/codegen/compileRelayArtifacts.js +0 -157
  77. package/lib/codegen/createPrintRequireModuleDependency.js +0 -19
  78. package/lib/codegen/sortObjectByKey.js +0 -41
  79. package/lib/codegen/writeRelayGeneratedFile.js +0 -208
  80. package/lib/core/ASTCache.js +0 -70
  81. package/lib/core/ASTConvert.js +0 -198
  82. package/lib/core/CompilerContext.js +0 -165
  83. package/lib/core/CompilerError.js +0 -251
  84. package/lib/core/DotGraphQLParser.js +0 -40
  85. package/lib/core/GraphQLCompilerProfiler.js +0 -299
  86. package/lib/core/GraphQLDerivedFromMetadata.js +0 -31
  87. package/lib/core/GraphQLWatchmanClient.js +0 -150
  88. package/lib/core/IR.js +0 -11
  89. package/lib/core/IRPrinter.js +0 -389
  90. package/lib/core/IRTransformer.js +0 -345
  91. package/lib/core/IRValidator.js +0 -226
  92. package/lib/core/IRVisitor.js +0 -45
  93. package/lib/core/JSModuleParser.js +0 -18
  94. package/lib/core/RelayCompilerScope.js +0 -149
  95. package/lib/core/RelayFindGraphQLTags.js +0 -79
  96. package/lib/core/RelayGraphQLEnumsGenerator.js +0 -50
  97. package/lib/core/RelayIRTransforms.js +0 -109
  98. package/lib/core/RelayParser.js +0 -1382
  99. package/lib/core/RelaySourceModuleParser.js +0 -104
  100. package/lib/core/Schema.js +0 -1877
  101. package/lib/core/SchemaUtils.js +0 -98
  102. package/lib/core/filterContextForNode.js +0 -49
  103. package/lib/core/getFieldDefinition.js +0 -145
  104. package/lib/core/getIdentifierForArgumentValue.js +0 -53
  105. package/lib/core/getIdentifierForSelection.js +0 -48
  106. package/lib/core/getLiteralArgumentValues.js +0 -26
  107. package/lib/core/getNormalizationOperationName.js +0 -17
  108. package/lib/core/inferRootArgumentDefinitions.js +0 -351
  109. package/lib/index.js +0 -178
  110. package/lib/language/RelayLanguagePluginInterface.js +0 -14
  111. package/lib/language/javascript/FindGraphQLTags.js +0 -126
  112. package/lib/language/javascript/RelayFlowBabelFactories.js +0 -160
  113. package/lib/language/javascript/RelayFlowGenerator.js +0 -857
  114. package/lib/language/javascript/RelayFlowTypeTransformers.js +0 -119
  115. package/lib/language/javascript/RelayLanguagePluginJavaScript.js +0 -30
  116. package/lib/language/javascript/formatGeneratedModule.js +0 -36
  117. package/lib/reporters/ConsoleReporter.js +0 -61
  118. package/lib/reporters/MultiReporter.js +0 -45
  119. package/lib/reporters/Reporter.js +0 -11
  120. package/lib/runner/Artifacts.js +0 -323
  121. package/lib/runner/BufferedFilesystem.js +0 -261
  122. package/lib/runner/GraphQLASTNodeGroup.js +0 -256
  123. package/lib/runner/GraphQLASTUtils.js +0 -23
  124. package/lib/runner/GraphQLNodeMap.js +0 -81
  125. package/lib/runner/Sources.js +0 -271
  126. package/lib/runner/StrictMap.js +0 -134
  127. package/lib/runner/compileArtifacts.js +0 -39
  128. package/lib/runner/extractAST.js +0 -77
  129. package/lib/runner/getChangedNodeNames.js +0 -82
  130. package/lib/runner/getSchemaInstance.js +0 -30
  131. package/lib/runner/types.js +0 -12
  132. package/lib/transforms/ApplyFragmentArgumentTransform.js +0 -393
  133. package/lib/transforms/ClientExtensionsTransform.js +0 -222
  134. package/lib/transforms/ConnectionTransform.js +0 -643
  135. package/lib/transforms/DeclarativeConnectionMutationTransform.js +0 -221
  136. package/lib/transforms/DeferStreamTransform.js +0 -247
  137. package/lib/transforms/DisallowIdAsAlias.js +0 -41
  138. package/lib/transforms/DisallowTypenameOnRoot.js +0 -53
  139. package/lib/transforms/FieldHandleTransform.js +0 -81
  140. package/lib/transforms/FilterCompilerDirectivesTransform.js +0 -29
  141. package/lib/transforms/FilterDirectivesTransform.js +0 -41
  142. package/lib/transforms/FlattenTransform.js +0 -308
  143. package/lib/transforms/GenerateIDFieldTransform.js +0 -137
  144. package/lib/transforms/GenerateTypeNameTransform.js +0 -155
  145. package/lib/transforms/InlineDataFragmentTransform.js +0 -104
  146. package/lib/transforms/InlineFragmentsTransform.js +0 -63
  147. package/lib/transforms/MaskTransform.js +0 -121
  148. package/lib/transforms/MatchTransform.js +0 -438
  149. package/lib/transforms/ReactFlightComponentTransform.js +0 -161
  150. package/lib/transforms/RefetchableFragmentTransform.js +0 -249
  151. package/lib/transforms/RelayDirectiveTransform.js +0 -85
  152. package/lib/transforms/RequiredFieldTransform.js +0 -373
  153. package/lib/transforms/SkipClientExtensionsTransform.js +0 -49
  154. package/lib/transforms/SkipHandleFieldTransform.js +0 -45
  155. package/lib/transforms/SkipRedundantNodesTransform.js +0 -255
  156. package/lib/transforms/SkipSplitOperationTransform.js +0 -32
  157. package/lib/transforms/SkipUnreachableNodeTransform.js +0 -158
  158. package/lib/transforms/SkipUnusedVariablesTransform.js +0 -74
  159. package/lib/transforms/SplitModuleImportTransform.js +0 -85
  160. package/lib/transforms/TestOperationTransform.js +0 -145
  161. package/lib/transforms/TransformUtils.js +0 -21
  162. package/lib/transforms/ValidateGlobalVariablesTransform.js +0 -91
  163. package/lib/transforms/ValidateRequiredArgumentsTransform.js +0 -118
  164. package/lib/transforms/ValidateServerOnlyDirectivesTransform.js +0 -111
  165. package/lib/transforms/ValidateUnusedVariablesTransform.js +0 -96
  166. package/lib/transforms/query-generators/FetchableQueryGenerator.js +0 -157
  167. package/lib/transforms/query-generators/NodeQueryGenerator.js +0 -166
  168. package/lib/transforms/query-generators/QueryQueryGenerator.js +0 -48
  169. package/lib/transforms/query-generators/ViewerQueryGenerator.js +0 -77
  170. package/lib/transforms/query-generators/index.js +0 -60
  171. package/lib/transforms/query-generators/utils.js +0 -92
  172. package/lib/util/CodeMarker.js +0 -80
  173. package/lib/util/DefaultHandleKey.js +0 -15
  174. package/lib/util/RelayCompilerCache.js +0 -98
  175. package/lib/util/Rollout.js +0 -40
  176. package/lib/util/TimeReporter.js +0 -83
  177. package/lib/util/areEqualArgValues.js +0 -135
  178. package/lib/util/argumentContainsVariables.js +0 -37
  179. package/lib/util/dedupeJSONStringify.js +0 -160
  180. package/lib/util/generateAbstractTypeRefinementKey.js +0 -24
  181. package/lib/util/getDefinitionNodeHash.js +0 -22
  182. package/lib/util/getModuleName.js +0 -32
  183. package/lib/util/joinArgumentDefinitions.js +0 -66
  184. package/lib/util/md5.js +0 -17
  185. package/lib/util/murmurHash.js +0 -86
  186. package/lib/util/nullthrowsOSS.js +0 -23
  187. package/lib/util/orList.js +0 -36
  188. package/lib/util/partitionArray.js +0 -35
  189. package/relay-compiler.js +0 -17
  190. package/relay-compiler.min.js +0 -22
  191. package/reporters/ConsoleReporter.js.flow +0 -81
  192. package/reporters/MultiReporter.js.flow +0 -43
  193. package/reporters/Reporter.js.flow +0 -19
  194. package/runner/Artifacts.js.flow +0 -219
  195. package/runner/BufferedFilesystem.js.flow +0 -194
  196. package/runner/GraphQLASTNodeGroup.js.flow +0 -176
  197. package/runner/GraphQLASTUtils.js.flow +0 -26
  198. package/runner/GraphQLNodeMap.js.flow +0 -55
  199. package/runner/Sources.js.flow +0 -228
  200. package/runner/StrictMap.js.flow +0 -96
  201. package/runner/compileArtifacts.js.flow +0 -76
  202. package/runner/extractAST.js.flow +0 -100
  203. package/runner/getChangedNodeNames.js.flow +0 -48
  204. package/runner/getSchemaInstance.js.flow +0 -36
  205. package/runner/types.js.flow +0 -37
  206. package/transforms/ApplyFragmentArgumentTransform.js.flow +0 -526
  207. package/transforms/ClientExtensionsTransform.js.flow +0 -226
  208. package/transforms/ConnectionTransform.js.flow +0 -859
  209. package/transforms/DeclarativeConnectionMutationTransform.js.flow +0 -250
  210. package/transforms/DeferStreamTransform.js.flow +0 -266
  211. package/transforms/DisallowIdAsAlias.js.flow +0 -48
  212. package/transforms/DisallowTypenameOnRoot.js.flow +0 -45
  213. package/transforms/FieldHandleTransform.js.flow +0 -81
  214. package/transforms/FilterCompilerDirectivesTransform.js.flow +0 -33
  215. package/transforms/FilterDirectivesTransform.js.flow +0 -45
  216. package/transforms/FlattenTransform.js.flow +0 -462
  217. package/transforms/GenerateIDFieldTransform.js.flow +0 -154
  218. package/transforms/GenerateTypeNameTransform.js.flow +0 -167
  219. package/transforms/InlineDataFragmentTransform.js.flow +0 -129
  220. package/transforms/InlineFragmentsTransform.js.flow +0 -73
  221. package/transforms/MaskTransform.js.flow +0 -130
  222. package/transforms/MatchTransform.js.flow +0 -593
  223. package/transforms/ReactFlightComponentTransform.js.flow +0 -198
  224. package/transforms/RefetchableFragmentTransform.js.flow +0 -272
  225. package/transforms/RelayDirectiveTransform.js.flow +0 -99
  226. package/transforms/RequiredFieldTransform.js.flow +0 -419
  227. package/transforms/SkipClientExtensionsTransform.js.flow +0 -57
  228. package/transforms/SkipHandleFieldTransform.js.flow +0 -45
  229. package/transforms/SkipRedundantNodesTransform.js.flow +0 -259
  230. package/transforms/SkipSplitOperationTransform.js.flow +0 -37
  231. package/transforms/SkipUnreachableNodeTransform.js.flow +0 -149
  232. package/transforms/SkipUnusedVariablesTransform.js.flow +0 -59
  233. package/transforms/SplitModuleImportTransform.js.flow +0 -101
  234. package/transforms/TestOperationTransform.js.flow +0 -143
  235. package/transforms/TransformUtils.js.flow +0 -26
  236. package/transforms/ValidateGlobalVariablesTransform.js.flow +0 -81
  237. package/transforms/ValidateRequiredArgumentsTransform.js.flow +0 -131
  238. package/transforms/ValidateServerOnlyDirectivesTransform.js.flow +0 -115
  239. package/transforms/ValidateUnusedVariablesTransform.js.flow +0 -89
  240. package/transforms/query-generators/FetchableQueryGenerator.js.flow +0 -189
  241. package/transforms/query-generators/NodeQueryGenerator.js.flow +0 -219
  242. package/transforms/query-generators/QueryQueryGenerator.js.flow +0 -57
  243. package/transforms/query-generators/ViewerQueryGenerator.js.flow +0 -97
  244. package/transforms/query-generators/index.js.flow +0 -90
  245. package/transforms/query-generators/utils.js.flow +0 -76
  246. package/util/CodeMarker.js.flow +0 -79
  247. package/util/DefaultHandleKey.js.flow +0 -17
  248. package/util/RelayCompilerCache.js.flow +0 -88
  249. package/util/Rollout.js.flow +0 -39
  250. package/util/TimeReporter.js.flow +0 -79
  251. package/util/areEqualArgValues.js.flow +0 -126
  252. package/util/argumentContainsVariables.js.flow +0 -38
  253. package/util/dedupeJSONStringify.js.flow +0 -152
  254. package/util/generateAbstractTypeRefinementKey.js.flow +0 -29
  255. package/util/getDefinitionNodeHash.js.flow +0 -25
  256. package/util/getModuleName.js.flow +0 -39
  257. package/util/joinArgumentDefinitions.js.flow +0 -105
  258. package/util/md5.js.flow +0 -22
  259. package/util/murmurHash.js.flow +0 -94
  260. package/util/nullthrowsOSS.js.flow +0 -25
  261. package/util/orList.js.flow +0 -37
  262. package/util/partitionArray.js.flow +0 -37
@@ -1,432 +0,0 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow strict-local
8
- * @format
9
- */
10
-
11
- // flowlint ambiguous-object-type:error
12
-
13
- 'use strict';
14
-
15
- const CodegenDirectory = require('./CodegenDirectory');
16
- const CodegenWatcher = require('./CodegenWatcher');
17
- const GraphQLWatchmanClient = require('../core/GraphQLWatchmanClient');
18
- const Profiler = require('../core/GraphQLCompilerProfiler');
19
-
20
- const invariant = require('invariant');
21
- const path = require('path');
22
-
23
- const {create: createSchema} = require('../core/Schema');
24
- /* $FlowFixMe[untyped-import] - importing immutable, which is untyped (and flow
25
- * is sad about it) */
26
- const {Map: ImmutableMap} = require('immutable');
27
-
28
- import type ASTCache from '../core/ASTCache';
29
- import type {Schema} from '../core/Schema';
30
- import type {Reporter} from '../reporters/Reporter';
31
- import type {CompileResult, File} from './CodegenTypes';
32
- import type {FileFilter, WatchmanExpression} from './CodegenWatcher';
33
- import type {SourceControl} from './SourceControl';
34
- import type {DocumentNode, Source} from 'graphql';
35
-
36
- export type ParserConfig = {|
37
- baseDir: string,
38
- getFileFilter?: (baseDir: string) => FileFilter,
39
- getParser: (baseDir: string) => ASTCache,
40
- getSchemaSource: () => Source,
41
- schemaExtensions: $ReadOnlyArray<string>,
42
- generatedDirectoriesWatchmanExpression?: ?WatchmanExpression,
43
- watchmanExpression?: ?WatchmanExpression,
44
- filepaths?: ?Array<string>,
45
- |};
46
-
47
- type ParserConfigs = {[parser: string]: ParserConfig, ...};
48
- type Parsers = {[parser: string]: ASTCache, ...};
49
-
50
- export type IsGeneratedFileFn = (filePath: string) => boolean;
51
- export type KeepExtraFileFn = (filePath: string) => boolean;
52
-
53
- export type WriterConfig = {|
54
- parser: string,
55
- baseParsers?: Array<string>,
56
- isGeneratedFile: IsGeneratedFileFn,
57
- writeFiles: WriteFiles,
58
- |};
59
-
60
- type WriterConfigs = {[writer: string]: WriterConfig, ...};
61
-
62
- export type WriteFilesOptions = {|
63
- onlyValidate: boolean,
64
- schema: Schema,
65
- documents: ImmutableMap<string, DocumentNode>,
66
- baseDocuments: ImmutableMap<string, DocumentNode>,
67
- sourceControl: ?SourceControl,
68
- reporter: Reporter,
69
- generatedDirectories?: Array<string>,
70
- |};
71
-
72
- export type WriteFiles = WriteFilesOptions => Promise<
73
- Map<string, CodegenDirectory>,
74
- >;
75
-
76
- type OnCompleteCallback = (
77
- codegenDirs: $ReadOnlyArray<CodegenDirectory>,
78
- ) => void;
79
-
80
- class CodegenRunner {
81
- parserConfigs: ParserConfigs;
82
- writerConfigs: WriterConfigs;
83
- onlyValidate: boolean;
84
- parsers: Parsers;
85
- onComplete: ?OnCompleteCallback;
86
-
87
- // parser => writers that are affected by it
88
- parserWriters: {[parser: string]: Set<string>, ...};
89
- _reporter: Reporter;
90
- _sourceControl: ?SourceControl;
91
-
92
- constructor(options: {
93
- parserConfigs: ParserConfigs,
94
- writerConfigs: WriterConfigs,
95
- onlyValidate: boolean,
96
- reporter: Reporter,
97
- sourceControl: ?SourceControl,
98
- onComplete?: OnCompleteCallback,
99
- ...
100
- }) {
101
- this.parsers = {};
102
- this.parserConfigs = options.parserConfigs;
103
- this.writerConfigs = options.writerConfigs;
104
- this.onlyValidate = options.onlyValidate;
105
- this.onComplete = options.onComplete;
106
- this._reporter = options.reporter;
107
- this._sourceControl = options.sourceControl;
108
-
109
- this.parserWriters = {};
110
- for (const parser in options.parserConfigs) {
111
- this.parserWriters[parser] = new Set();
112
- }
113
-
114
- for (const writer in options.writerConfigs) {
115
- const config = options.writerConfigs[writer];
116
- config.baseParsers &&
117
- config.baseParsers.forEach(parser =>
118
- this.parserWriters[parser].add(writer),
119
- );
120
- this.parserWriters[config.parser].add(writer);
121
- }
122
- }
123
-
124
- async compileAll(): Promise<CompileResult> {
125
- // reset the parsers
126
- this.parsers = {};
127
- for (const parserName in this.parserConfigs) {
128
- try {
129
- await this.parseEverything(parserName);
130
- } catch (e) {
131
- this._reporter.reportError('CodegenRunner.compileAll', e);
132
- return 'ERROR';
133
- }
134
- }
135
-
136
- let hasChanges = false;
137
- for (const writerName in this.writerConfigs) {
138
- const result = await this.write(writerName);
139
- if (result === 'ERROR') {
140
- return 'ERROR';
141
- }
142
- if (result === 'HAS_CHANGES') {
143
- hasChanges = true;
144
- }
145
- }
146
- return hasChanges ? 'HAS_CHANGES' : 'NO_CHANGES';
147
- }
148
-
149
- async compile(writerName: string): Promise<CompileResult> {
150
- const writerConfig = this.writerConfigs[writerName];
151
-
152
- const parsers = [writerConfig.parser];
153
- if (writerConfig.baseParsers) {
154
- writerConfig.baseParsers.forEach(parser => parsers.push(parser));
155
- }
156
- // Don't bother resetting the parsers
157
- await Profiler.asyncContext('CodegenRunner:parseEverything', () =>
158
- Promise.all(parsers.map(parser => this.parseEverything(parser))),
159
- );
160
-
161
- return await this.write(writerName);
162
- }
163
-
164
- getDirtyWriters(filePaths: Array<string>): Promise<Set<string>> {
165
- return Profiler.asyncContext('CodegenRunner:getDirtyWriters', async () => {
166
- const dirtyWriters = new Set();
167
-
168
- // Check if any files are in the output
169
- for (const configName in this.writerConfigs) {
170
- const config = this.writerConfigs[configName];
171
- for (const filePath of filePaths) {
172
- if (config.isGeneratedFile(filePath)) {
173
- dirtyWriters.add(configName);
174
- }
175
- }
176
- }
177
-
178
- // Check for files in the input
179
- await Promise.all(
180
- Object.keys(this.parserConfigs).map(parserConfigName =>
181
- Profiler.waitFor('Watchman:query', async () => {
182
- const client = new GraphQLWatchmanClient();
183
- const config = this.parserConfigs[parserConfigName];
184
- const dirs = await client.watchProject(config.baseDir);
185
-
186
- const relativeFilePaths = filePaths.map(filePath =>
187
- path.relative(config.baseDir, filePath),
188
- );
189
-
190
- const query = {
191
- expression: [
192
- 'allof',
193
- config.watchmanExpression,
194
- ['name', relativeFilePaths, 'wholename'],
195
- ],
196
- fields: ['exists'],
197
- relative_root: dirs.relativePath,
198
- };
199
-
200
- const result = await client.command('query', dirs.root, query);
201
- client.end();
202
-
203
- if (result.files.length > 0) {
204
- this.parserWriters[parserConfigName].forEach(writerName =>
205
- dirtyWriters.add(writerName),
206
- );
207
- }
208
- }),
209
- ),
210
- );
211
-
212
- return dirtyWriters;
213
- });
214
- }
215
-
216
- async parseEverything(parserName: string): Promise<void> {
217
- if (this.parsers[parserName]) {
218
- // no need to parse
219
- return;
220
- }
221
-
222
- const parserConfig = this.parserConfigs[parserName];
223
- this.parsers[parserName] = parserConfig.getParser(parserConfig.baseDir);
224
- const filter = parserConfig.getFileFilter
225
- ? parserConfig.getFileFilter(parserConfig.baseDir)
226
- : anyFileFilter;
227
-
228
- if (parserConfig.filepaths && parserConfig.watchmanExpression) {
229
- throw new Error(
230
- 'Provide either `watchmanExpression` or `filepaths` but not both.',
231
- );
232
- }
233
-
234
- let files;
235
- if (parserConfig.watchmanExpression) {
236
- files = await CodegenWatcher.queryFiles(
237
- parserConfig.baseDir,
238
- parserConfig.watchmanExpression,
239
- filter,
240
- );
241
- } else if (parserConfig.filepaths) {
242
- files = await CodegenWatcher.queryFilepaths(
243
- parserConfig.baseDir,
244
- parserConfig.filepaths,
245
- filter,
246
- );
247
- } else {
248
- throw new Error(
249
- 'Either `watchmanExpression` or `filepaths` is required to query files',
250
- );
251
- }
252
- this.parseFileChanges(parserName, files);
253
- }
254
-
255
- parseFileChanges(parserName: string, files: Set<File>): void {
256
- return Profiler.run('CodegenRunner.parseFileChanges', () => {
257
- const parser = this.parsers[parserName];
258
- // this maybe should be await parser.parseFiles(files);
259
- parser.parseFiles(files);
260
- });
261
- }
262
-
263
- // We cannot do incremental writes right now.
264
- // When we can, this could be writeChanges(writerName, parserName, parsedDefinitions)
265
- write(writerName: string): Promise<CompileResult> {
266
- return Profiler.asyncContext('CodegenRunner.write', async () => {
267
- try {
268
- this._reporter.reportMessage(`\nWriting ${writerName}`);
269
- const {
270
- writeFiles,
271
- parser,
272
- baseParsers,
273
- isGeneratedFile,
274
- } = this.writerConfigs[writerName];
275
-
276
- let baseDocuments = ImmutableMap();
277
- if (baseParsers) {
278
- baseParsers.forEach(baseParserName => {
279
- invariant(
280
- this.parsers[baseParserName] != null,
281
- 'Trying to access an uncompiled base parser config: %s',
282
- baseParserName,
283
- );
284
- baseDocuments = baseDocuments.merge(
285
- this.parsers[baseParserName].documents(),
286
- );
287
- });
288
- }
289
-
290
- const {
291
- baseDir,
292
- generatedDirectoriesWatchmanExpression,
293
- } = this.parserConfigs[parser];
294
- let generatedDirectories = [];
295
- if (generatedDirectoriesWatchmanExpression) {
296
- const relativePaths = await CodegenWatcher.queryDirectories(
297
- baseDir,
298
- generatedDirectoriesWatchmanExpression,
299
- );
300
- generatedDirectories = relativePaths.map(x => path.join(baseDir, x));
301
- }
302
-
303
- // always create a new writer: we have to write everything anyways
304
- const documents = this.parsers[parser].documents();
305
- const schema = Profiler.run('getSchema', () =>
306
- createSchema(
307
- this.parserConfigs[parser].getSchemaSource(),
308
- baseDocuments.toArray(),
309
- this.parserConfigs[parser].schemaExtensions,
310
- ),
311
- );
312
-
313
- const outputDirectories = await writeFiles({
314
- onlyValidate: this.onlyValidate,
315
- schema,
316
- documents,
317
- baseDocuments,
318
- generatedDirectories,
319
- sourceControl: this._sourceControl,
320
- reporter: this._reporter,
321
- });
322
-
323
- for (const dir of outputDirectories.values()) {
324
- const all = [
325
- ...dir.changes.created,
326
- ...dir.changes.updated,
327
- ...dir.changes.deleted,
328
- ...dir.changes.unchanged,
329
- ];
330
- for (const filename of all) {
331
- const filePath = dir.getPath(filename);
332
- invariant(
333
- isGeneratedFile(filePath),
334
- 'CodegenRunner: %s returned false for isGeneratedFile, ' +
335
- 'but was in generated directory',
336
- filePath,
337
- );
338
- }
339
- }
340
-
341
- const onCompleteCallback = this.onComplete;
342
- if (onCompleteCallback != null) {
343
- onCompleteCallback(Array.from(outputDirectories.values()));
344
- }
345
-
346
- const combinedChanges = CodegenDirectory.combineChanges(
347
- Array.from(outputDirectories.values()),
348
- );
349
-
350
- this._reporter.reportMessage(
351
- CodegenDirectory.formatChanges(combinedChanges, {
352
- onlyValidate: this.onlyValidate,
353
- }),
354
- );
355
-
356
- return CodegenDirectory.hasChanges(combinedChanges)
357
- ? 'HAS_CHANGES'
358
- : 'NO_CHANGES';
359
- } catch (e) {
360
- this._reporter.reportError('CodegenRunner.write', e);
361
- return 'ERROR';
362
- }
363
- });
364
- }
365
-
366
- async watchAll(): Promise<void> {
367
- // get everything set up for watching
368
- await this.compileAll();
369
-
370
- for (const parserName in this.parserConfigs) {
371
- await this.watch(parserName);
372
- }
373
- }
374
-
375
- async watch(parserName: string): Promise<void> {
376
- const parserConfig = this.parserConfigs[parserName];
377
-
378
- if (!parserConfig.watchmanExpression) {
379
- throw new Error('`watchmanExpression` is required to watch files');
380
- }
381
-
382
- // watchCompile starts with a full set of files as the changes
383
- // But as we need to set everything up due to potential parser dependencies,
384
- // we should prevent the first watch callback from doing anything.
385
- let firstChange = true;
386
-
387
- await CodegenWatcher.watchCompile(
388
- parserConfig.baseDir,
389
- parserConfig.watchmanExpression,
390
- parserConfig.getFileFilter
391
- ? parserConfig.getFileFilter(parserConfig.baseDir)
392
- : anyFileFilter,
393
- async files => {
394
- invariant(
395
- this.parsers[parserName] != null,
396
- 'Trying to watch an uncompiled parser config: %s',
397
- parserName,
398
- );
399
- if (firstChange) {
400
- firstChange = false;
401
- return;
402
- }
403
- const dependentWriters = [];
404
- this.parserWriters[parserName].forEach(writer =>
405
- dependentWriters.push(writer),
406
- );
407
-
408
- try {
409
- if (!this.parsers[parserName]) {
410
- // have to load the parser and make sure all of its dependents are set
411
- await this.parseEverything(parserName);
412
- } else {
413
- this.parseFileChanges(parserName, files);
414
- }
415
- await Promise.all(dependentWriters.map(writer => this.write(writer)));
416
- } catch (error) {
417
- this._reporter.reportError('CodegenRunner.watch', error);
418
- }
419
- this._reporter.reportMessage(
420
- `Watching for changes to ${parserName}...`,
421
- );
422
- },
423
- );
424
- this._reporter.reportMessage(`Watching for changes to ${parserName}...`);
425
- }
426
- }
427
-
428
- function anyFileFilter(file: File): boolean {
429
- return true;
430
- }
431
-
432
- module.exports = CodegenRunner;
@@ -1,28 +0,0 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow strict
8
- * @format
9
- */
10
-
11
- // flowlint ambiguous-object-type:error
12
-
13
- 'use strict';
14
-
15
- export type CompileResult = 'HAS_CHANGES' | 'NO_CHANGES' | 'ERROR';
16
-
17
- export type File =
18
- | {
19
- exists: false,
20
- relPath: string,
21
- ...
22
- }
23
- | {
24
- exists: true,
25
- relPath: string,
26
- hash: string,
27
- ...
28
- };
@@ -1,254 +0,0 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- * @format
9
- */
10
-
11
- // flowlint ambiguous-object-type:error
12
-
13
- 'use strict';
14
-
15
- const GraphQLWatchmanClient = require('../core/GraphQLWatchmanClient');
16
- const Profiler = require('../core/GraphQLCompilerProfiler');
17
-
18
- const crypto = require('crypto');
19
- const fs = require('fs');
20
- const path = require('path');
21
-
22
- import type {File} from './CodegenTypes';
23
-
24
- const SUBSCRIPTION_NAME = 'graphql-codegen';
25
- const QUERY_RETRIES = 3;
26
-
27
- export type WatchmanExpression = $ReadOnlyArray<string | WatchmanExpression>;
28
-
29
- export type FileFilter = (file: File) => boolean;
30
-
31
- type WatchmanChange = {|
32
- name: string,
33
- exists: boolean,
34
- 'content.sha1hex': ?string,
35
- |};
36
- type WatchmanChanges = {
37
- files?: $ReadOnlyArray<WatchmanChange>,
38
- ...
39
- };
40
-
41
- async function queryFiles(
42
- baseDir: string,
43
- expression: WatchmanExpression,
44
- filter: FileFilter,
45
- ): Promise<Set<File>> {
46
- return await Profiler.waitFor('Watchman:query', async () => {
47
- const client = new GraphQLWatchmanClient(QUERY_RETRIES);
48
- const [watchResp, fields] = await Promise.all([
49
- client.watchProject(baseDir),
50
- getFields(client),
51
- ]);
52
- const resp = await client.command('query', watchResp.root, {
53
- expression,
54
- fields: fields,
55
- relative_root: watchResp.relativePath,
56
- });
57
- client.end();
58
- return updateFiles(new Set(), baseDir, filter, resp.files);
59
- });
60
- }
61
-
62
- async function queryDirectories(
63
- baseDir: string,
64
- expression: WatchmanExpression,
65
- ): Promise<$ReadOnlyArray<string>> {
66
- return await Profiler.waitFor('Watchman:query', async () => {
67
- const client = new GraphQLWatchmanClient();
68
- const watchResp = await client.watchProject(baseDir);
69
- const resp = await client.command('query', watchResp.root, {
70
- expression,
71
- fields: ['name'],
72
- relative_root: watchResp.relativePath,
73
- });
74
- client.end();
75
- return resp.files;
76
- });
77
- }
78
-
79
- async function getFields(
80
- client: GraphQLWatchmanClient,
81
- ): Promise<$ReadOnlyArray<string>> {
82
- const fields = ['name', 'exists'];
83
- if (await client.hasCapability('field-content.sha1hex')) {
84
- fields.push('content.sha1hex');
85
- }
86
- return fields;
87
- }
88
-
89
- // For use when not using Watchman.
90
- async function queryFilepaths(
91
- baseDir: string,
92
- filepaths: $ReadOnlyArray<string>,
93
- filter: FileFilter,
94
- ): Promise<Set<File>> {
95
- // Construct WatchmanChange objects as an intermediate step before
96
- // calling updateFiles to produce file content.
97
- const files = filepaths.map(filepath => ({
98
- name: filepath,
99
- exists: true,
100
- 'content.sha1hex': null,
101
- }));
102
- return updateFiles(new Set(), baseDir, filter, files);
103
- }
104
-
105
- /**
106
- * Provides a simplified API to the watchman API.
107
- * Given some base directory and a list of subdirectories it calls the callback
108
- * with watchman change events on file changes.
109
- */
110
- async function watch(
111
- baseDir: string,
112
- expression: WatchmanExpression,
113
- callback: (changes: WatchmanChanges) => mixed,
114
- ): Promise<void> {
115
- return await Profiler.waitFor('Watchman:subscribe', async () => {
116
- const client = new GraphQLWatchmanClient();
117
- const watchResp = await client.watchProject(baseDir);
118
-
119
- await makeSubscription(
120
- client,
121
- watchResp.root,
122
- watchResp.relativePath,
123
- expression,
124
- callback,
125
- );
126
- });
127
- }
128
-
129
- async function makeSubscription(
130
- client: GraphQLWatchmanClient,
131
- root: string,
132
- relativePath: string,
133
- expression: WatchmanExpression,
134
- callback,
135
- ): Promise<void> {
136
- client.on('subscription', resp => {
137
- if (resp.subscription === SUBSCRIPTION_NAME) {
138
- callback(resp);
139
- }
140
- });
141
- const fields = await getFields(client);
142
- await client.command('subscribe', root, SUBSCRIPTION_NAME, {
143
- expression,
144
- fields: fields,
145
- relative_root: relativePath,
146
- });
147
- }
148
-
149
- /**
150
- * Further simplifies `watch` and calls the callback on every change with a
151
- * full list of files that match the conditions.
152
- */
153
- async function watchFiles(
154
- baseDir: string,
155
- expression: WatchmanExpression,
156
- filter: FileFilter,
157
- callback: (files: Set<File>) => any,
158
- ): Promise<void> {
159
- let files = new Set();
160
- await watch(baseDir, expression, changes => {
161
- if (!changes.files) {
162
- // Watchmen fires a change without files when a watchman state changes,
163
- // for example during an hg update.
164
- return;
165
- }
166
- files = updateFiles(files, baseDir, filter, changes.files);
167
- callback(files);
168
- });
169
- }
170
-
171
- /**
172
- * Similar to watchFiles, but takes an async function. The `compile` function
173
- * is awaited and not called in parallel. If multiple changes are triggered
174
- * before a compile finishes, the latest version is called after the compile
175
- * finished.
176
- *
177
- * TODO: Consider changing from a Promise to abortable, so we can abort mid
178
- * compilation.
179
- */
180
- async function watchCompile(
181
- baseDir: string,
182
- expression: WatchmanExpression,
183
- filter: FileFilter,
184
- compile: (files: Set<File>) => Promise<any>,
185
- ): Promise<void> {
186
- let compiling = false;
187
- let needsCompiling = false;
188
- let latestFiles = null;
189
-
190
- watchFiles(baseDir, expression, filter, async files => {
191
- needsCompiling = true;
192
- latestFiles = files;
193
- if (compiling) {
194
- return;
195
- }
196
- compiling = true;
197
- while (needsCompiling) {
198
- needsCompiling = false;
199
- await compile(latestFiles);
200
- }
201
- compiling = false;
202
- });
203
- }
204
-
205
- function updateFiles(
206
- files: Set<File>,
207
- baseDir: string,
208
- filter: FileFilter,
209
- fileChanges: $ReadOnlyArray<WatchmanChange>,
210
- ): Set<File> {
211
- const fileMap = new Map();
212
- files.forEach(file => {
213
- file.exists && fileMap.set(file.relPath, file);
214
- });
215
-
216
- fileChanges.forEach(({name, exists, 'content.sha1hex': hash}) => {
217
- let shouldRemove = !exists;
218
- if (!shouldRemove) {
219
- const file = {
220
- exists: true,
221
- relPath: name,
222
- hash: hash || hashFile(path.join(baseDir, name)),
223
- };
224
- if (filter(file)) {
225
- fileMap.set(name, file);
226
- } else {
227
- shouldRemove = true;
228
- }
229
- }
230
- shouldRemove &&
231
- fileMap.set(name, {
232
- exists: false,
233
- relPath: name,
234
- });
235
- });
236
- return new Set(fileMap.values());
237
- }
238
-
239
- function hashFile(filename: string): string {
240
- const content = fs.readFileSync(filename);
241
- return crypto
242
- .createHash('sha1')
243
- .update(content)
244
- .digest('hex');
245
- }
246
-
247
- module.exports = {
248
- queryDirectories,
249
- queryFiles,
250
- queryFilepaths,
251
- watch,
252
- watchFiles,
253
- watchCompile,
254
- };