graphql-typescript-definitions
Version:
Generate TypeScript definition files from .graphql documents
143 lines (112 loc) • 6.86 kB
JavaScript
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
import * as t from '@babel/types';
import { pascalCase, camelCase, snakeCase } from 'change-case';
import { isEnumType, isInputType, isScalarType, isNonNullType, isListType } from 'graphql';
import { scalarTypeMap } from "../utilities.mjs";
import { EnumFormat } from "../../types.mjs"; // eslint-disable-next-line @typescript-eslint/no-var-requires
var generate = require('@babel/generator')["default"];
export function generateSchemaTypes(schema) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var importFileBody = [];
var exportFileBody = [];
var definitions = new Map();
for (var _i = 0, _Object$values = Object.values(schema.getTypeMap()); _i < _Object$values.length; _i++) {
var type = _Object$values[_i];
if (!isInputType(type) || type.name.startsWith('__')) {
continue;
}
if (isScalarType(type) && Object.prototype.hasOwnProperty.call(scalarTypeMap, type.name)) {
continue;
}
if (isEnumType(type)) {
var enumType = tsEnumForType(type, options);
definitions.set("".concat(enumType.id.name, ".ts"), generate(t.file(t.program([t.exportNamedDeclaration(enumType, [])]), [], [])).code);
importFileBody.unshift(t.importDeclaration([t.importSpecifier(enumType.id, enumType.id)], t.stringLiteral("./".concat(enumType.id.name))));
exportFileBody.unshift(t.exportNamedDeclaration(null, [t.exportSpecifier(enumType.id, enumType.id)]));
} else if (isScalarType(type)) {
var _options$customScalar = options.customScalars,
customScalars = _options$customScalar === void 0 ? {} : _options$customScalar;
var customScalarDefinition = customScalars[type.name];
var scalarType = tsScalarForType(type, customScalarDefinition);
if (customScalarDefinition && customScalarDefinition["package"]) {
importFileBody.unshift(t.importDeclaration([t.importSpecifier(t.identifier(makeCustomScalarImportNameSafe(customScalarDefinition.name, type.name)), t.identifier(customScalarDefinition.name))], t.stringLiteral(customScalarDefinition["package"])));
exportFileBody.unshift(t.exportNamedDeclaration(scalarType, []));
} else {
exportFileBody.push(t.exportNamedDeclaration(scalarType, []));
}
} else {
exportFileBody.push(t.exportNamedDeclaration(tsInputObjectForType(type), []));
}
} // A blank file is ambiguous - its not clear if it is a script or a module.
// If the file would be blank then give it an empty `export {}` to make in
// unambiguously an es module file.
// This ensures the generated files passes TypeScript type checking in
// "isolatedModules" mode.
if (exportFileBody.length === 0) {
exportFileBody.push(t.exportNamedDeclaration(null, []));
}
return definitions.set('index.ts', generate(t.file(t.program(importFileBody.concat(exportFileBody)), [], [])).code);
}
function tsTypeForInputType(type) {
var unwrappedType = isNonNullType(type) ? type.ofType : type;
var tsType;
if (isListType(unwrappedType)) {
var tsTypeOfContainedType = tsTypeForInputType(unwrappedType.ofType);
tsType = t.tsArrayType(t.isTSUnionType(tsTypeOfContainedType) ? t.tsParenthesizedType(tsTypeOfContainedType) : tsTypeOfContainedType);
} else if (isScalarType(unwrappedType)) {
tsType = scalarTypeMap[unwrappedType.name] || t.tsTypeReference(t.identifier(unwrappedType.name));
} else {
tsType = t.tsTypeReference(t.identifier(unwrappedType.name));
}
return isNonNullType(type) ? tsType : t.tsUnionType([tsType, t.tsNullKeyword()]);
}
function tsInputObjectForType(type) {
var fields = Object.entries(type.getFields()).map(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
name = _ref2[0],
field = _ref2[1];
var property = t.tsPropertySignature(t.identifier(name), t.tsTypeAnnotation(tsTypeForInputType(field.type)));
property.optional = !isNonNullType(field.type);
return property;
});
return t.tsInterfaceDeclaration(t.identifier(type.name), null, null, t.tsInterfaceBody(fields));
}
function tsScalarForType(type, customScalarDefinition) {
var alias;
if (customScalarDefinition && customScalarDefinition["package"]) {
alias = t.tsTypeReference(t.identifier(makeCustomScalarImportNameSafe(customScalarDefinition.name, type.name)));
} else if (customScalarDefinition) {
alias = t.tsTypeReference(t.identifier(customScalarDefinition.name));
} else {
alias = t.tsStringKeyword();
}
return t.tsTypeAliasDeclaration(t.identifier(type.name), null, alias);
}
function makeCustomScalarImportNameSafe(importName, typeName) {
return "__".concat(typeName, "__").concat(importName);
}
function tsEnumForType(type, _ref3) {
var enumFormat = _ref3.enumFormat;
return t.tsEnumDeclaration(t.identifier(type.name), type.getValues().map(function (value) {
return t.tsEnumMember(t.identifier(enumMemberName(value.name, enumFormat)), t.stringLiteral(value.name));
}));
}
function enumMemberName(name, format) {
switch (format) {
case EnumFormat.CamelCase:
return camelCase(name);
case EnumFormat.PascalCase:
return pascalCase(name);
case EnumFormat.SnakeCase:
return snakeCase(name);
case EnumFormat.ScreamingSnakeCase:
return snakeCase(name).toUpperCase();
default:
return name;
}
}