@ardatan/relay-compiler
Version:
A compiler tool for building GraphQL-driven applications.
270 lines (218 loc) • 10.5 kB
JavaScript
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
* @format
*/
// flowlint ambiguous-object-type:error
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _asyncToGenerator = require("@babel/runtime/helpers/asyncToGenerator");
var _createForOfIteratorHelper2 = _interopRequireDefault(require("@babel/runtime/helpers/createForOfIteratorHelper"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var ASTConvert = require('../core/ASTConvert');
var CodegenDirectory = require('./CodegenDirectory');
var CompilerContext = require('../core/CompilerContext');
var Profiler = require('../core/GraphQLCompilerProfiler');
var RelayParser = require('../core/RelayParser');
var compileRelayArtifacts = require('./compileRelayArtifacts');
var graphql = require('graphql');
var invariant = require('invariant');
var md5 = require('../util/md5');
var nullthrows = require('nullthrows');
var path = require('path');
var writeRelayGeneratedFile = require('./writeRelayGeneratedFile');
var _require = require('../core/GraphQLDerivedFromMetadata'),
getReaderSourceDefinitionName = _require.getReaderSourceDefinitionName;
var _require2 = require('../core/SchemaUtils'),
isExecutableDefinitionAST = _require2.isExecutableDefinitionAST;
var _require3 = require('immutable'),
ImmutableMap = _require3.Map;
function compileAll(_ref) {
var baseDir = _ref.baseDir,
baseDocuments = _ref.baseDocuments,
schema = _ref.schema,
compilerTransforms = _ref.compilerTransforms,
documents = _ref.documents,
reporter = _ref.reporter,
typeGenerator = _ref.typeGenerator;
var definitions = ASTConvert.convertASTDocumentsWithBase(schema, baseDocuments, documents, RelayParser.transform);
var compilerContext = new CompilerContext(schema).addAll(definitions);
var transformedTypeContext = compilerContext.applyTransforms(typeGenerator.transforms, reporter);
var transformedQueryContext = compilerContext.applyTransforms([].concat((0, _toConsumableArray2["default"])(compilerTransforms.commonTransforms), (0, _toConsumableArray2["default"])(compilerTransforms.queryTransforms)), reporter);
var artifacts = compileRelayArtifacts(compilerContext, compilerTransforms, reporter);
return {
artifacts: artifacts,
definitions: definitions,
transformedQueryContext: transformedQueryContext,
transformedTypeContext: transformedTypeContext
};
}
function writeAll(_ref2) {
var writerConfig = _ref2.config,
onlyValidate = _ref2.onlyValidate,
baseDocuments = _ref2.baseDocuments,
documents = _ref2.documents,
schema = _ref2.schema,
reporter = _ref2.reporter,
sourceControl = _ref2.sourceControl,
languagePlugin = _ref2.languagePlugin;
return Profiler.asyncContext('RelayFileWriter.writeAll', /*#__PURE__*/_asyncToGenerator(function* () {
var _compileAll = compileAll({
schema: schema,
baseDir: writerConfig.baseDir,
baseDocuments: baseDocuments.valueSeq().toArray(),
compilerTransforms: writerConfig.compilerTransforms,
documents: documents.valueSeq().toArray(),
reporter: reporter,
typeGenerator: writerConfig.typeGenerator
}),
artifactsWithBase = _compileAll.artifacts,
transformedTypeContext = _compileAll.transformedTypeContext,
transformedQueryContext = _compileAll.transformedQueryContext; // Build a context from all the documents
var baseDefinitionNames = new Set();
baseDocuments.forEach(function (doc) {
doc.definitions.forEach(function (def) {
if (isExecutableDefinitionAST(def) && def.name) {
baseDefinitionNames.add(def.name.value);
}
});
}); // remove nodes that are present in the base or that derive from nodes
// in the base
var artifacts = artifactsWithBase.filter(function (_ref3) {
var _definition = _ref3[0],
node = _ref3[1];
var sourceName = getReaderSourceDefinitionName(node);
return !baseDefinitionNames.has(sourceName);
});
var artifactMap = new Map(artifacts.map(function (_ref4) {
var _definition = _ref4[0],
node = _ref4[1];
return [node.kind === 'Request' ? node.params.name : node.name, node];
}));
var definitionsMeta = new Map();
var getDefinitionMeta = function getDefinitionMeta(definitionName) {
var artifact = nullthrows(artifactMap.get(definitionName));
var sourceName = getReaderSourceDefinitionName(artifact);
var definitionMeta = definitionsMeta.get(sourceName);
!definitionMeta ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayFileWriter: Could not determine source for definition: `%s`.', definitionName) : invariant(false) : void 0;
return definitionMeta;
};
documents.forEach(function (doc, filePath) {
doc.definitions.forEach(function (def) {
if (def.name) {
definitionsMeta.set(def.name.value, {
dir: path.join(writerConfig.baseDir, path.dirname(filePath)),
ast: def
});
}
});
});
var allOutputDirectories = new Map();
var addCodegenDir = function addCodegenDir(dirPath) {
var codegenDir = new CodegenDirectory(dirPath, {
onlyValidate: onlyValidate,
filesystem: writerConfig.filesystem
});
allOutputDirectories.set(dirPath, codegenDir);
return codegenDir;
};
var _iterator = (0, _createForOfIteratorHelper2["default"])(writerConfig.generatedDirectories || []),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var existingDirectory = _step.value;
addCodegenDir(existingDirectory);
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
var configOutputDirectory;
if (writerConfig.outputDir) {
configOutputDirectory = addCodegenDir(writerConfig.outputDir);
}
var getGeneratedDirectory = function getGeneratedDirectory(definitionName) {
if (configOutputDirectory) {
return configOutputDirectory;
}
var generatedPath = path.join(getDefinitionMeta(definitionName).dir, '__generated__');
var cachedDir = allOutputDirectories.get(generatedPath);
if (!cachedDir) {
cachedDir = addCodegenDir(generatedPath);
}
return cachedDir;
};
var formatModule = Profiler.instrument(writerConfig.formatModule, 'RelayFileWriter:formatModule');
var persistQuery = writerConfig.persistQuery ? Profiler.instrumentWait(writerConfig.persistQuery, 'RelayFileWriter:persistQuery') : null;
try {
yield Promise.all(artifacts.map( /*#__PURE__*/function () {
var _ref7 = _asyncToGenerator(function* (_ref5) {
var _writerConfig$repersi, _writerConfig$writeQu;
var definition = _ref5[0],
node = _ref5[1];
var nodeName = node.kind === 'Request' ? node.params.name : node.name;
if (baseDefinitionNames.has(nodeName)) {
// don't add definitions that were part of base context
return;
}
var typeNode = transformedTypeContext.get(nodeName);
var typeText = typeNode ? writerConfig.typeGenerator.generate(schema, typeNode, {
customScalars: writerConfig.customScalars,
enumsHasteModule: writerConfig.enumsHasteModule,
optionalInputFields: writerConfig.optionalInputFieldsForFlow,
useHaste: writerConfig.useHaste,
useSingleArtifactDirectory: !!writerConfig.outputDir,
noFutureProofEnums: writerConfig.noFutureProofEnums,
normalizationIR: definition.kind === 'Request' ? definition.root : undefined
}) : '';
var sourceHash = Profiler.run('hashGraphQL', function () {
return md5(graphql.print(getDefinitionMeta(nodeName).ast));
});
yield writeRelayGeneratedFile(schema, getGeneratedDirectory(nodeName), definition, node, formatModule, typeText, persistQuery, sourceHash, writerConfig.extension, writerConfig.printModuleDependency, (_writerConfig$repersi = writerConfig.repersist) !== null && _writerConfig$repersi !== void 0 ? _writerConfig$repersi : false, (_writerConfig$writeQu = writerConfig.writeQueryParameters) !== null && _writerConfig$writeQu !== void 0 ? _writerConfig$writeQu : function noop() {}, languagePlugin);
});
return function (_x) {
return _ref7.apply(this, arguments);
};
}()));
var generateExtraFiles = writerConfig.generateExtraFiles;
if (generateExtraFiles) {
Profiler.run('RelayFileWriter:generateExtraFiles', function () {
var configDirectory = writerConfig.outputDir;
generateExtraFiles(function (dir) {
var outputDirectory = dir || configDirectory;
!outputDirectory ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayFileWriter: cannot generate extra files without specifying ' + 'an outputDir in the config or passing it in.') : invariant(false) : void 0;
var outputDir = allOutputDirectories.get(outputDirectory);
if (!outputDir) {
outputDir = addCodegenDir(outputDirectory);
}
return outputDir;
}, transformedQueryContext, getGeneratedDirectory);
});
}
allOutputDirectories.forEach(function (dir) {
dir.deleteExtraFiles(languagePlugin === null || languagePlugin === void 0 ? void 0 : languagePlugin.keepExtraFile);
});
if (sourceControl && !onlyValidate) {
yield CodegenDirectory.sourceControlAddRemove(sourceControl, Array.from(allOutputDirectories.values()));
}
} catch (error) {
var details;
try {
details = JSON.parse(error.message);
} catch (_) {} // eslint-disable-line lint/no-unused-catch-bindings
if (details && details.name === 'GraphQL2Exception' && details.message) {
throw new Error('GraphQL error writing modules:\n' + details.message);
}
throw new Error('Error writing modules:\n' + String(error.stack || error));
}
return allOutputDirectories;
}));
}
module.exports = {
writeAll: writeAll
};