UNPKG

@backland/schema

Version:

TypeScript schema declaration and validation library with static type inference

459 lines (458 loc) 19 kB
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } 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) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } import { formatGraphQL } from '@backland/utils'; import { getByPath } from '@backland/utils'; import { hashString } from '@backland/utils'; import { isListType, isNonNullType, isObjectType, isUnionType } from 'graphql'; import { resolverKinds } from '../createGraphQLSchema'; import { LiteralField } from '../fields/LiteralField'; export function getSchemaQueryTemplates(schema) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var _options$depthLimit = options.depthLimit, depthLimit = _options$depthLimit === void 0 ? 5000 : _options$depthLimit, _options$includeDepre = options.includeDeprecatedFields, includeDeprecatedFields = _options$includeDepre === void 0 ? true : _options$includeDepre; var query = schema.getQueryType(); var mutation = schema.getMutationType(); var subscription = schema.getSubscriptionType(); var fullQuery = ''; var queryByResolver = { mutation: {}, query: {}, subscription: {} }; var items = [query ? { kind: resolverKinds.query, value: query } : undefined, mutation ? { kind: resolverKinds.mutation, value: mutation } : undefined, subscription ? { kind: resolverKinds.subscription, value: subscription } : undefined].filter(Boolean); items.forEach(function (item) { if (!item) return; var value = item.value, kind = item.kind; Object.values(value.getFields()).forEach(function (graphQLField) { var item = getQueryTemplates({ depthLimit: depthLimit, graphQLField: graphQLField, includeDeprecatedFields: includeDeprecatedFields, kind: kind, queryKind: 'mainQuery' }); queryByResolver[kind][graphQLField.name] = item; fullQuery += "".concat(item.fullQuery); }); }); return { fullQuery: fullQuery.trim(), queryByResolver: queryByResolver }; } /** * Generate the query for the specified field * @param params */ export function getQueryTemplates(params) { var _params$kind = params.kind, kind = _params$kind === void 0 ? 'query' : _params$kind; var name = params.graphQLField.name; var _params$breadcrumb = params.breadcrumb, breadcrumb = _params$breadcrumb === void 0 ? [name] : _params$breadcrumb, graphQLField = params.graphQLField, queryKind = params.queryKind, _params$includeDeprec = params.includeDeprecatedFields, includeDeprecatedFields = _params$includeDeprec === void 0 ? true : _params$includeDeprec, _params$format = params.format, format = _params$format === void 0 ? true : _params$format; var cache = {}; var _processField = processField({ cache: cache, graphQLField: graphQLField, includeDeprecatedFields: includeDeprecatedFields }), payload = _processField.payload; var fieldStrings = fieldsToString({ breadcrumb: breadcrumb, cache: cache, field: payload, isTopQuery: false }); var innerQuery = payload.isObject ? "{".concat(fieldStrings.query, "}") : ''; var fullQuery = ''; var fieldQuery = "".concat(name, " ").concat(fieldStrings.argsParsed.strings.innerArgsString, " ").concat(innerQuery); if (queryKind === 'mainQuery') { var allArgs = fieldStrings.allArgs; var argValues = Object.values(allArgs); var topArgs = argValues.map(function (el) { return el.strings.topArgsStringPart; }).filter(Boolean); var innerArgs = argValues.map(function (el) { return el.strings.innerArgsStringPart; }).filter(Boolean); var topArgsString = topArgs.length ? "(".concat(topArgs.join(','), ")") : ''; var innerArgsString = innerArgs.length ? "(".concat(innerArgs.join(','), ")") : ''; fullQuery += "".concat(kind, " ").concat(name).concat(topArgsString, " { ").concat(name, " ").concat(innerArgsString, " ").concat(innerQuery, "}"); } else { fullQuery += "".concat(kind, " ").concat(fieldQuery); } if (format) { fullQuery = prettifyQuery(fullQuery, 'mainQuery'); fieldQuery = prettifyQuery(fieldQuery, 'fieldQuery'); } fullQuery += "\n"; return _objectSpread(_objectSpread({}, fieldStrings), {}, { fieldQuery: fieldQuery, fields: payload, fullQuery: fullQuery }); } function getFieldPayload(_ref) { var graphQLField = _ref.graphQLField, cache = _ref.cache; var args = graphQLField.args, type = graphQLField.type; var _getInnerType = getInnerType(type), innerType = _getInnerType.innerType; var innerTypeString = innerType.toJSON(); var _hashField = hashField(graphQLField), key = _hashField.hash, readableHash = _hashField.readableHash; if (cache[key]) return cache[key]; var payload = cache[key] = { args: args, children: [], deprecationReason: getByPath(innerType, 'deprecationReason'), description: getByPath(innerType, 'description'), fields: {}, hash: key, innerTypeString: innerTypeString, isObject: false, isUnion: false, readableHash: readableHash }; if (isObjectType(innerType)) { payload.isObject = true; Object.entries(innerType.getFields()).forEach(function (_ref2) { var _ref3 = _slicedToArray(_ref2, 2), name = _ref3[0], field = _ref3[1]; payload.fields[name] = getFieldPayload({ cache: cache, graphQLField: field }); }); } if (isUnionType(innerType)) { var unionTypes = innerType.getTypes(); payload.isUnion = true; unionTypes.forEach(function (unionType) { var unionItem = getFieldPayload({ cache: cache, graphQLField: { args: [], astNode: unionType.astNode, deprecationReason: getByPath(unionType, 'deprecationReason'), description: unionType.description, extensions: unionType.extensions, name: unionType.name, type: unionType } }); payload.children.push(unionItem); }); } return payload; } export function processField(config) { var includeDeprecatedFields = config.includeDeprecatedFields, _config$cache = config.cache, cache = _config$cache === void 0 ? {} : _config$cache, graphQLField = config.graphQLField; var _getInnerType2 = getInnerType(graphQLField.type), type = _getInnerType2.innerType; var _hashField2 = hashField(graphQLField), key = _hashField2.hash; if (cache[key] !== undefined) { return { cache: cache, payload: cache[key] }; } var payload = getFieldPayload({ cache: cache, graphQLField: graphQLField }); if (isObjectType(type)) { var gqlTypeFields = type.getFields(); var fields = Object.entries(gqlTypeFields).filter(function (_ref4) { var _ref5 = _slicedToArray(_ref4, 2), _ = _ref5[0], child = _ref5[1]; return includeDeprecatedFields || !child.deprecationReason; }); fields.forEach(function (_ref6) { var _ref7 = _slicedToArray(_ref6, 2), _ = _ref7[0], field = _ref7[1]; var item = getFieldPayload({ cache: cache, graphQLField: field }); if (!item.isObject) { return; } processField({ cache: cache, graphQLField: field, includeDeprecatedFields: includeDeprecatedFields }); }); } return { cache: cache, payload: payload }; } function fieldsToString(config) { var field = config.field, cache = config.cache, breadcrumb = config.breadcrumb, _config$fieldsToStrin = config.fieldsToStringCache, fieldsToStringCache = _config$fieldsToStrin === void 0 ? {} : _config$fieldsToStrin; var fields = field.fields, args = field.args, hash = field.hash; if (fieldsToStringCache[hash]) { return fieldsToStringCache[hash]; } var allArgs = config.allArgs || {}; var argsParsed = parseArgs({ args: args, breadcrumb: breadcrumb }); allArgs[hash] = argsParsed; var self = { allArgs: allArgs, argsParsed: argsParsed, query: '' }; fieldsToStringCache[hash] = self; if (field.isObject) { Object.entries(fields || {}).forEach(function (_ref8) { var _ref9 = _slicedToArray(_ref8, 2), name = _ref9[0], field = _ref9[1]; var _breadcrumb = [].concat(_toConsumableArray(breadcrumb), [name]); if (!field.isObject && !field.isUnion) { var _fieldsToString = fieldsToString({ allArgs: allArgs, breadcrumb: _breadcrumb, cache: cache, field: field, fieldsToStringCache: fieldsToStringCache, isTopQuery: false }), innerArgsString = _fieldsToString.argsParsed.strings.innerArgsString; self.query += " ".concat(name).concat(innerArgsString, " "); return; } if (field.isObject) { var child = fieldsToString({ allArgs: allArgs, breadcrumb: _breadcrumb, cache: cache, field: field, fieldsToStringCache: fieldsToStringCache, isTopQuery: false }); var _innerArgsString = child.argsParsed.strings.innerArgsString; self.query += " ".concat(name).concat(_innerArgsString, " { "); self.query += child.query; self.query += " } "; } if (field.isUnion) { var childQuery = ''; var argsStrings = []; var topArgsStrings = []; field.children.forEach(function (item) { var u_field = cache[item.hash]; var child = fieldsToString({ breadcrumb: _breadcrumb, cache: cache, field: u_field, fieldsToStringCache: fieldsToStringCache, isTopQuery: false }); var _child$argsParsed$str = child.argsParsed.strings, innerArgsStringPart = _child$argsParsed$str.innerArgsStringPart, topArgsStringPart = _child$argsParsed$str.topArgsStringPart; argsStrings.push(innerArgsStringPart); topArgsStrings.push(topArgsStringPart); childQuery += "... on ".concat(item.innerTypeString, " { ").concat(child.query, " }"); }); self.query += " ".concat(name).concat(argsStrings ? "".concat(argsStrings.join()) : '', " { "); self.query += childQuery; self.query += " } "; } }); } else { var _fieldsToString2 = fieldsToString({ allArgs: allArgs, breadcrumb: breadcrumb, cache: cache, field: field, fieldsToStringCache: fieldsToStringCache, isTopQuery: false }), innerArgsString = _fieldsToString2.argsParsed.strings.innerArgsString; self.query += "".concat(innerArgsString); } return self; } function parseArgs(config) { var args = config.args, breadcrumb = config.breadcrumb; var vars = []; if (!(args !== null && args !== void 0 && args.length)) { return { strings: parsedArgsToString(vars), vars: vars }; } var prefix = breadcrumb.length ? breadcrumb.join('_') + '_' : ''; args.forEach(function (arg) { var type = arg.type, description = arg.description, deprecationReason = arg.deprecationReason, defaultValue = arg.defaultValue, name = arg.name; var varName = "$".concat(prefix).concat(name); var comments = descriptionsToComments(deprecationReason, description); var _defaultValue = arg.defaultValue !== undefined ? LiteralField.utils.serialize(defaultValue) : undefined; if (typeof defaultValue === 'string') { _defaultValue = JSON.stringify(_defaultValue); } vars.push({ comments: comments, defaultValue: _defaultValue, name: name, type: type.toString(), varName: varName }); }); return { strings: parsedArgsToString(vars), vars: vars }; } function parsedArgsToString(parsed) { var innerParts = []; var topParts = []; parsed.forEach(function (_ref10) { var type = _ref10.type, defaultValue = _ref10.defaultValue, name = _ref10.name, varName = _ref10.varName, comments = _ref10.comments; topParts.push("".concat(comments).concat(varName, ": ").concat(type)); innerParts.push("".concat(comments).concat(name, ": ").concat(varName)); if (defaultValue !== undefined) { topParts.push("= ".concat(defaultValue)); } }); var topArgsStringPart = topParts.join(',').replace(',=', ' = '); var innerArgsStringPart = innerParts.join(',').replace(',=', ' = '); return { innerArgsString: innerArgsStringPart.length ? "(".concat(innerArgsStringPart, ")") : '', innerArgsStringPart: innerArgsStringPart, topArgsString: topArgsStringPart.length ? "(".concat(topArgsStringPart, ")") : '', topArgsStringPart: topArgsStringPart }; } export function getInnerType(graphqlType) { var wrappers = []; while ('ofType' in graphqlType) { if (isUnionType(graphqlType)) { wrappers.push('union'); } if (!isNonNullType(graphqlType)) { wrappers.push('optional'); } if (isListType(graphqlType)) { wrappers.push('list'); } graphqlType = graphqlType.ofType; } var wrappersPath = wrappers.join(''); var innerTypeJSON = graphqlType.toJSON(); return { innerType: graphqlType, innerTypeJSON: innerTypeJSON, wrappers: wrappers, wrappersPath: wrappersPath }; } function hashField(graphQLField) { var _getInnerType3 = getInnerType(graphQLField.type), wrappersPath = _getInnerType3.wrappersPath, innerType = _getInnerType3.innerType; var argString = ''; graphQLField.args.forEach(function (_ref11) { var type = _ref11.type, description = _ref11.description, deprecationReason = _ref11.deprecationReason, defaultValue = _ref11.defaultValue, name = _ref11.name; argString += [name, type.toString(), description, deprecationReason, defaultValue].filter(function (el) { return el !== null && el !== undefined; }).join(''); }); var suffix = "".concat(wrappersPath).concat(argString); var hash = hashString(suffix); return { hash: "".concat(innerType).concat(hash), readableHash: "".concat(innerType).concat(suffix) }; } function descriptionsToComments() { for (var _len = arguments.length, list = new Array(_len), _key = 0; _key < _len; _key++) { list[_key] = arguments[_key]; } var commentsList = [].concat(list).filter(Boolean); var comments = ''; if (commentsList.length) { return "\n#".concat(commentsList.join('\n#'), "\n"); } return comments; } function prettifyQuery(value, queryKind) { var isMainQuery = queryKind === 'mainQuery'; value = value.trim(); try { value = formatGraphQL(isMainQuery ? value : "{".concat(value, "}")); } catch (e) { // throw new Error(`Failed to prettify:\n${value}\n\n\n${e.stack}`); } if (isMainQuery) return value; return value.trim() // .replace(/^{/, '').replace(/}$/, ''); } //# sourceMappingURL=getQueryTemplates.js.map