Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

graphql-language-service-utils

Package Overview
Dependencies
Maintainers
13
Versions
92
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

graphql-language-service-utils - npm Package Compare versions

Comparing version 2.7.0-canary-fae7d199.0 to 2.7.0

179

dist/getVariablesJSONSchema.js

@@ -5,55 +5,2 @@ "use strict";

const graphql_1 = require("graphql");
const scalarTypesMap = {
Int: 'integer',
String: 'string',
Float: 'number',
ID: 'string',
Boolean: 'boolean',
DateTime: 'string',
};
const scalarType = (definition, type) => {
var _a;
definition.type = (_a = scalarTypesMap[type.name]) !== null && _a !== void 0 ? _a : 'any';
};
const listType = (definition, type, definitions) => {
definition.type = 'array';
const { definition: def, definitions: defs } = getJSONSchemaFromGraphQLType(type.ofType);
definition.items = { $ref: def.$ref };
definitions = Object.assign(Object.assign({}, definitions), defs);
};
const enumType = (definition, type) => {
definition.type = 'string';
definition.enum = type.getValues().map(val => val.name);
};
const inputObjectType = (definition, type, definitions, options) => {
definition.$ref = `#/definitions/${type.name}`;
definition.description = undefined;
if (!definitions || !definitions[type.name]) {
const fields = type.getFields();
const fieldDef = {
type: 'object',
properties: {},
required: [],
};
if (type.description) {
fieldDef.description = type.description;
}
if (options === null || options === void 0 ? void 0 : options.useMarkdownDescription) {
fieldDef.markdownDescription = type.description;
}
Object.keys(fields).forEach(fieldName => {
const field = fields[fieldName];
const { required, definition: typeDefinition, } = getJSONSchemaFromGraphQLType(field.type, options);
const { definition: fieldDefinition } = getJSONSchemaFromGraphQLType(fields[fieldName], options);
fieldDef.properties[fieldName] = Object.assign(Object.assign({}, typeDefinition), fieldDefinition);
if (required) {
fieldDef.required.push(fieldName);
}
});
definitions[type.name] = fieldDef;
}
else {
return;
}
};
exports.defaultJSONSchemaOptions = {

@@ -66,5 +13,2 @@ useMarkdownDescription: false,

function renderType(into, t) {
if (!t) {
return;
}
if (graphql_1.isNonNullType(t)) {

@@ -86,39 +30,47 @@ renderType(into, t.ofType);

if (useMarkdown) {
text(into, '\n```graphql\n');
text(into, '```graphql\n');
}
renderType(into, t);
if (useMarkdown) {
text(into, '\n```\n');
text(into, '\n```');
}
return into.join('');
}
const scalarTypesMap = {
Int: 'integer',
String: 'string',
Float: 'number',
ID: 'string',
Boolean: 'boolean',
DateTime: 'string',
};
function getJSONSchemaFromGraphQLType(type, options) {
var _a;
let required = false;
let definition = {};
let definitions = {};
definition.description = renderTypeToString(type);
const hasDescription = 'description' in type && type.description;
if ('description' in type && type.description) {
definition.description += type.description;
}
if (options === null || options === void 0 ? void 0 : options.useMarkdownDescription) {
definition.markdownDescription = renderTypeToString(type, true);
if (hasDescription) {
definition.markdownDescription += type.description;
}
}
if ('defaultValue' in type) {
let definition = Object.create(null);
const definitions = Object.create(null);
if ('defaultValue' in type && type.defaultValue !== undefined) {
definition.default = type.defaultValue;
}
if (graphql_1.isEnumType(type)) {
enumType(definition, type);
definition.type = 'string';
definition.enum = type.getValues().map(val => val.name);
}
if (graphql_1.isInputObjectType(type)) {
inputObjectType(definition, type, definitions, options);
}
if (graphql_1.isScalarType(type)) {
scalarType(definition, type);
definition.type = (_a = scalarTypesMap[type.name]) !== null && _a !== void 0 ? _a : 'any';
}
if (graphql_1.isListType(type)) {
listType(definition, type, definitions);
definition.type = 'array';
const { definition: def, definitions: defs } = getJSONSchemaFromGraphQLType(type.ofType, options);
if (def.$ref) {
definition.items = { $ref: def.$ref };
}
else {
definition.items = def;
}
if (defs) {
Object.keys(defs).forEach(defName => {
definitions[defName] = defs[defName];
});
}
}

@@ -129,4 +81,71 @@ if (graphql_1.isNonNullType(type)) {

definition = def;
definitions = Object.assign(Object.assign({}, definitions), defs);
if (defs) {
Object.keys(defs).forEach(defName => {
definitions[defName] = defs[defName];
});
}
}
if (graphql_1.isInputObjectType(type)) {
definition.$ref = `#/definitions/${type.name}`;
const fields = type.getFields();
const fieldDef = {
type: 'object',
properties: {},
required: [],
};
if (type.description) {
fieldDef.description = type.description + `\n` + renderTypeToString(type);
if (options === null || options === void 0 ? void 0 : options.useMarkdownDescription) {
fieldDef.markdownDescription =
type.description + `\n` + renderTypeToString(type, true);
}
}
else {
fieldDef.description = renderTypeToString(type);
if (options === null || options === void 0 ? void 0 : options.useMarkdownDescription) {
fieldDef.markdownDescription = renderTypeToString(type, true);
}
}
Object.keys(fields).forEach(fieldName => {
const field = fields[fieldName];
const { required: fieldRequired, definition: typeDefinition, definitions: typeDefinitions, } = getJSONSchemaFromGraphQLType(field.type, options);
const { definition: fieldDefinition, } = getJSONSchemaFromGraphQLType(field, options);
fieldDef.properties[fieldName] = Object.assign(Object.assign({}, typeDefinition), fieldDefinition);
const renderedField = renderTypeToString(field.type);
fieldDef.properties[fieldName].description = field.description
? field.description + '\n' + renderedField
: renderedField;
if (options === null || options === void 0 ? void 0 : options.useMarkdownDescription) {
const renderedFieldMarkdown = renderTypeToString(field.type, true);
fieldDef.properties[fieldName].markdownDescription = field.description
? field.description + '\n' + renderedFieldMarkdown
: renderedFieldMarkdown;
}
if (fieldRequired) {
fieldDef.required.push(fieldName);
}
if (typeDefinitions) {
Object.keys(typeDefinitions).map(defName => {
definitions[defName] = typeDefinitions[defName];
});
}
});
definitions[type.name] = fieldDef;
}
if ('description' in type &&
!graphql_1.isScalarType(type) &&
type.description &&
!definition.description) {
definition.description = type.description + '\n' + renderTypeToString(type);
if (options === null || options === void 0 ? void 0 : options.useMarkdownDescription) {
definition.markdownDescription =
type.description + '\n' + renderTypeToString(type, true);
}
}
else {
definition.description = renderTypeToString(type);
if (options === null || options === void 0 ? void 0 : options.useMarkdownDescription) {
definition.markdownDescription = renderTypeToString(type, true);
}
}
return { required, definition, definitions };

@@ -150,3 +169,3 @@ }

if (definitions) {
jsonSchema.definitions = definitions;
jsonSchema.definitions = Object.assign(Object.assign({}, jsonSchema === null || jsonSchema === void 0 ? void 0 : jsonSchema.definitions), definitions);
}

@@ -153,0 +172,0 @@ });

export { getFragmentDependencies, getFragmentDependenciesForAST, } from './fragmentDependencies';
export { getVariablesJSONSchema, JSONSchema6, JSONSchema6TypeName, } from './getVariablesJSONSchema';
export { getVariablesJSONSchema, JSONSchema6, JSONSchema6TypeName, JSONSchemaOptions, } from './getVariablesJSONSchema';
export { getASTNodeAtPosition, pointToOffset } from './getASTNodeAtPosition';

@@ -7,4 +7,3 @@ export { Position, Range, locToRange, offsetToPosition } from './Range';

export { collectVariables, VariableToType } from './collectVariables';
export { fillLeafs, GetDefaultFieldNamesFn, buildSelectionSet, defaultGetDefaultFieldNames, } from './fillLeafs';
export { default as getOperationFacts, getOperationASTFacts, getQueryFacts, OperationFacts, QueryFacts, } from './getOperationFacts';
//# sourceMappingURL=index.d.ts.map

@@ -6,3 +6,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getQueryFacts = exports.getOperationASTFacts = exports.getOperationFacts = exports.defaultGetDefaultFieldNames = exports.buildSelectionSet = exports.fillLeafs = exports.collectVariables = exports.validateWithCustomRules = exports.offsetToPosition = exports.locToRange = exports.Range = exports.Position = exports.pointToOffset = exports.getASTNodeAtPosition = exports.getVariablesJSONSchema = exports.getFragmentDependenciesForAST = exports.getFragmentDependencies = void 0;
exports.getQueryFacts = exports.getOperationASTFacts = exports.getOperationFacts = exports.collectVariables = exports.validateWithCustomRules = exports.offsetToPosition = exports.locToRange = exports.Range = exports.Position = exports.pointToOffset = exports.getASTNodeAtPosition = exports.getVariablesJSONSchema = exports.getFragmentDependenciesForAST = exports.getFragmentDependencies = void 0;
var fragmentDependencies_1 = require("./fragmentDependencies");

@@ -25,6 +25,2 @@ Object.defineProperty(exports, "getFragmentDependencies", { enumerable: true, get: function () { return fragmentDependencies_1.getFragmentDependencies; } });

Object.defineProperty(exports, "collectVariables", { enumerable: true, get: function () { return collectVariables_1.collectVariables; } });
var fillLeafs_1 = require("./fillLeafs");
Object.defineProperty(exports, "fillLeafs", { enumerable: true, get: function () { return fillLeafs_1.fillLeafs; } });
Object.defineProperty(exports, "buildSelectionSet", { enumerable: true, get: function () { return fillLeafs_1.buildSelectionSet; } });
Object.defineProperty(exports, "defaultGetDefaultFieldNames", { enumerable: true, get: function () { return fillLeafs_1.defaultGetDefaultFieldNames; } });
var getOperationFacts_1 = require("./getOperationFacts");

@@ -31,0 +27,0 @@ Object.defineProperty(exports, "getOperationFacts", { enumerable: true, get: function () { return __importDefault(getOperationFacts_1).default; } });

import { GraphQLList, isEnumType, isInputObjectType, isListType, isNonNullType, isScalarType, } from 'graphql';
const scalarTypesMap = {
Int: 'integer',
String: 'string',
Float: 'number',
ID: 'string',
Boolean: 'boolean',
DateTime: 'string',
};
const scalarType = (definition, type) => {
var _a;
definition.type = (_a = scalarTypesMap[type.name]) !== null && _a !== void 0 ? _a : 'any';
};
const listType = (definition, type, definitions) => {
definition.type = 'array';
const { definition: def, definitions: defs } = getJSONSchemaFromGraphQLType(type.ofType);
definition.items = { $ref: def.$ref };
definitions = Object.assign(Object.assign({}, definitions), defs);
};
const enumType = (definition, type) => {
definition.type = 'string';
definition.enum = type.getValues().map(val => val.name);
};
const inputObjectType = (definition, type, definitions, options) => {
definition.$ref = `#/definitions/${type.name}`;
definition.description = undefined;
if (!definitions || !definitions[type.name]) {
const fields = type.getFields();
const fieldDef = {
type: 'object',
properties: {},
required: [],
};
if (type.description) {
fieldDef.description = type.description;
}
if (options === null || options === void 0 ? void 0 : options.useMarkdownDescription) {
fieldDef.markdownDescription = type.description;
}
Object.keys(fields).forEach(fieldName => {
const field = fields[fieldName];
const { required, definition: typeDefinition, } = getJSONSchemaFromGraphQLType(field.type, options);
const { definition: fieldDefinition } = getJSONSchemaFromGraphQLType(fields[fieldName], options);
fieldDef.properties[fieldName] = Object.assign(Object.assign({}, typeDefinition), fieldDefinition);
if (required) {
fieldDef.required.push(fieldName);
}
});
definitions[type.name] = fieldDef;
}
else {
return;
}
};
export const defaultJSONSchemaOptions = {

@@ -62,5 +9,2 @@ useMarkdownDescription: false,

function renderType(into, t) {
if (!t) {
return;
}
if (isNonNullType(t)) {

@@ -82,39 +26,47 @@ renderType(into, t.ofType);

if (useMarkdown) {
text(into, '\n```graphql\n');
text(into, '```graphql\n');
}
renderType(into, t);
if (useMarkdown) {
text(into, '\n```\n');
text(into, '\n```');
}
return into.join('');
}
const scalarTypesMap = {
Int: 'integer',
String: 'string',
Float: 'number',
ID: 'string',
Boolean: 'boolean',
DateTime: 'string',
};
function getJSONSchemaFromGraphQLType(type, options) {
var _a;
let required = false;
let definition = {};
let definitions = {};
definition.description = renderTypeToString(type);
const hasDescription = 'description' in type && type.description;
if ('description' in type && type.description) {
definition.description += type.description;
}
if (options === null || options === void 0 ? void 0 : options.useMarkdownDescription) {
definition.markdownDescription = renderTypeToString(type, true);
if (hasDescription) {
definition.markdownDescription += type.description;
}
}
if ('defaultValue' in type) {
let definition = Object.create(null);
const definitions = Object.create(null);
if ('defaultValue' in type && type.defaultValue !== undefined) {
definition.default = type.defaultValue;
}
if (isEnumType(type)) {
enumType(definition, type);
definition.type = 'string';
definition.enum = type.getValues().map(val => val.name);
}
if (isInputObjectType(type)) {
inputObjectType(definition, type, definitions, options);
}
if (isScalarType(type)) {
scalarType(definition, type);
definition.type = (_a = scalarTypesMap[type.name]) !== null && _a !== void 0 ? _a : 'any';
}
if (isListType(type)) {
listType(definition, type, definitions);
definition.type = 'array';
const { definition: def, definitions: defs } = getJSONSchemaFromGraphQLType(type.ofType, options);
if (def.$ref) {
definition.items = { $ref: def.$ref };
}
else {
definition.items = def;
}
if (defs) {
Object.keys(defs).forEach(defName => {
definitions[defName] = defs[defName];
});
}
}

@@ -125,4 +77,71 @@ if (isNonNullType(type)) {

definition = def;
definitions = Object.assign(Object.assign({}, definitions), defs);
if (defs) {
Object.keys(defs).forEach(defName => {
definitions[defName] = defs[defName];
});
}
}
if (isInputObjectType(type)) {
definition.$ref = `#/definitions/${type.name}`;
const fields = type.getFields();
const fieldDef = {
type: 'object',
properties: {},
required: [],
};
if (type.description) {
fieldDef.description = type.description + `\n` + renderTypeToString(type);
if (options === null || options === void 0 ? void 0 : options.useMarkdownDescription) {
fieldDef.markdownDescription =
type.description + `\n` + renderTypeToString(type, true);
}
}
else {
fieldDef.description = renderTypeToString(type);
if (options === null || options === void 0 ? void 0 : options.useMarkdownDescription) {
fieldDef.markdownDescription = renderTypeToString(type, true);
}
}
Object.keys(fields).forEach(fieldName => {
const field = fields[fieldName];
const { required: fieldRequired, definition: typeDefinition, definitions: typeDefinitions, } = getJSONSchemaFromGraphQLType(field.type, options);
const { definition: fieldDefinition, } = getJSONSchemaFromGraphQLType(field, options);
fieldDef.properties[fieldName] = Object.assign(Object.assign({}, typeDefinition), fieldDefinition);
const renderedField = renderTypeToString(field.type);
fieldDef.properties[fieldName].description = field.description
? field.description + '\n' + renderedField
: renderedField;
if (options === null || options === void 0 ? void 0 : options.useMarkdownDescription) {
const renderedFieldMarkdown = renderTypeToString(field.type, true);
fieldDef.properties[fieldName].markdownDescription = field.description
? field.description + '\n' + renderedFieldMarkdown
: renderedFieldMarkdown;
}
if (fieldRequired) {
fieldDef.required.push(fieldName);
}
if (typeDefinitions) {
Object.keys(typeDefinitions).map(defName => {
definitions[defName] = typeDefinitions[defName];
});
}
});
definitions[type.name] = fieldDef;
}
if ('description' in type &&
!isScalarType(type) &&
type.description &&
!definition.description) {
definition.description = type.description + '\n' + renderTypeToString(type);
if (options === null || options === void 0 ? void 0 : options.useMarkdownDescription) {
definition.markdownDescription =
type.description + '\n' + renderTypeToString(type, true);
}
}
else {
definition.description = renderTypeToString(type);
if (options === null || options === void 0 ? void 0 : options.useMarkdownDescription) {
definition.markdownDescription = renderTypeToString(type, true);
}
}
return { required, definition, definitions };

@@ -146,3 +165,3 @@ }

if (definitions) {
jsonSchema.definitions = definitions;
jsonSchema.definitions = Object.assign(Object.assign({}, jsonSchema === null || jsonSchema === void 0 ? void 0 : jsonSchema.definitions), definitions);
}

@@ -149,0 +168,0 @@ });

export { getFragmentDependencies, getFragmentDependenciesForAST, } from './fragmentDependencies';
export { getVariablesJSONSchema, JSONSchema6, JSONSchema6TypeName, } from './getVariablesJSONSchema';
export { getVariablesJSONSchema, JSONSchema6, JSONSchema6TypeName, JSONSchemaOptions, } from './getVariablesJSONSchema';
export { getASTNodeAtPosition, pointToOffset } from './getASTNodeAtPosition';

@@ -7,4 +7,3 @@ export { Position, Range, locToRange, offsetToPosition } from './Range';

export { collectVariables, VariableToType } from './collectVariables';
export { fillLeafs, GetDefaultFieldNamesFn, buildSelectionSet, defaultGetDefaultFieldNames, } from './fillLeafs';
export { default as getOperationFacts, getOperationASTFacts, getQueryFacts, OperationFacts, QueryFacts, } from './getOperationFacts';
//# sourceMappingURL=index.d.ts.map

@@ -7,4 +7,3 @@ export { getFragmentDependencies, getFragmentDependenciesForAST, } from './fragmentDependencies';

export { collectVariables } from './collectVariables';
export { fillLeafs, buildSelectionSet, defaultGetDefaultFieldNames, } from './fillLeafs';
export { default as getOperationFacts, getOperationASTFacts, getQueryFacts, } from './getOperationFacts';
//# sourceMappingURL=index.js.map
{
"name": "graphql-language-service-utils",
"version": "2.7.0-canary-fae7d199.0",
"version": "2.7.0",
"description": "Utilities to support the GraphQL Language Service",

@@ -5,0 +5,0 @@ "contributors": [

@@ -10,11 +10,3 @@ /**

import { readFileSync } from 'fs';
import {
buildSchema,
GraphQLSchema,
GraphQLBoolean,
GraphQLString,
GraphQLInt,
GraphQLFloat,
parse,
} from 'graphql';
import { buildSchema, GraphQLSchema, parse } from 'graphql';

@@ -51,14 +43,14 @@ import { join } from 'path';

type: 'boolean',
description: GraphQLBoolean.description,
description: 'Boolean',
},
string: {
type: 'string',
description: GraphQLString.description,
description: 'String!',
},
number: {
type: 'integer',
description: GraphQLInt.description,
description: 'Int!',
},
price: {
description: GraphQLFloat.description,
description: 'Float',
type: 'number',

@@ -86,5 +78,7 @@ },

$ref: '#/definitions/InputType',
description: 'InputType!',
},
anotherInput: {
$ref: '#/definitions/InputType',
description: 'example input type\nInputType',
},

@@ -95,10 +89,10 @@ });

type: 'object',
description: 'example input type',
description: 'example input type\nInputType',
properties: {
key: {
description: 'example key `String!`',
description: 'example key\nString!',
type: 'string',
},
value: {
description: 'example value `Int`',
description: 'example value\nInt',
type: 'integer',

@@ -108,4 +102,4 @@ default: 42,

exampleObject: {
description: 'nesting a whole object! `ChildInputType!`',
$ref: '#/definitions/ChildInputType',
description: 'nesting a whole object!\nChildInputType!',
},

@@ -117,15 +111,156 @@ exampleList: {

},
description: 'list type with fancy default `[ChildInputType]`',
description: 'list type with default\n[ChildInputType]',
default: [
{
isBaby: false,
favoriteBook: 'Goosebumps',
isChild: false,
favoriteBook: 'Binti',
},
],
},
exampleScalarList: {
type: 'array',
description: '[String]!',
items: {
type: 'string',
description: 'String',
},
default: ['something'],
},
},
required: ['key', 'exampleObject'],
required: ['key', 'exampleObject', 'exampleScalarList'],
},
ChildInputType: {
type: 'object',
description: 'ChildInputType',
properties: {
isChild: {
type: 'boolean',
description: 'Boolean!',
default: true,
},
favoriteBook: {
type: 'string',
description: 'favorite book\nString',
default: 'Where the wild things are',
},
},
required: ['isChild'],
},
});
});
const mdTicks = (name: string) => `\`\`\`graphql\n${name}\n\`\`\``;
it('should handle input object types with markdown', () => {
const variableToType = collectVariables(
schema,
parse(`query($input: InputType!, $anotherInput: InputType, $episode: Episode) {
characters {
name
}
}`),
);
const jsonSchema = getVariablesJSONSchema(variableToType, {
useMarkdownDescription: true,
});
expect(jsonSchema.required).toEqual(['input']);
expect(jsonSchema.properties).toEqual({
input: {
$ref: '#/definitions/InputType',
description: 'InputType!',
markdownDescription: mdTicks('InputType!'),
},
anotherInput: {
$ref: '#/definitions/InputType',
// description: 'example input type',
// TODO: fix this for non-nulls?
description: 'example input type\nInputType',
markdownDescription: 'example input type\n```graphql\nInputType\n```',
},
episode: {
enum: ['NEWHOPE', 'EMPIRE', 'JEDI'],
description: 'Episode',
type: 'string',
markdownDescription: mdTicks('Episode'),
},
});
expect(jsonSchema.definitions).toEqual({
InputType: {
type: 'object',
description: 'example input type\nInputType',
markdownDescription: `example input type\n${mdTicks('InputType')}`,
properties: {
key: {
description: 'example key\nString!',
markdownDescription: `example key\n${mdTicks('String!')}`,
type: 'string',
},
value: {
description: 'example value\nInt',
markdownDescription: `example value\n${mdTicks('Int')}`,
type: 'integer',
default: 42,
},
exampleObject: {
description: 'nesting a whole object!\nChildInputType!',
markdownDescription: `nesting a whole object!\n${mdTicks(
'ChildInputType!',
)}`,
$ref: '#/definitions/ChildInputType',
},
exampleList: {
type: 'array',
items: {
$ref: '#/definitions/ChildInputType',
},
description: `list type with default\n[ChildInputType]`,
markdownDescription: `list type with default\n${mdTicks(
'[ChildInputType]',
)}`,
default: [
{
isChild: false,
favoriteBook: 'Binti',
},
],
},
exampleScalarList: {
type: 'array',
description: '[String]!',
markdownDescription: mdTicks('[String]!'),
items: {
type: 'string',
description: 'String',
markdownDescription: mdTicks('String'),
},
default: ['something'],
},
},
required: ['key', 'exampleObject', 'exampleScalarList'],
},
ChildInputType: {
description: 'ChildInputType',
markdownDescription: `${mdTicks('ChildInputType')}`,
properties: {
favoriteBook: {
default: 'Where the wild things are',
description: 'favorite book\nString',
markdownDescription: 'favorite book\n```graphql\nString\n```',
type: 'string',
},
isChild: {
default: true,
description: 'Boolean!',
markdownDescription: '```graphql\nBoolean!\n```',
type: 'boolean',
},
},
required: ['isChild'],
type: 'object',
},
});
});
});

@@ -0,1 +1,8 @@

/**
* Copyright (c) 2021 GraphQL Contributors.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { DocumentNode, FragmentDefinitionNode, parse, visit } from 'graphql';

@@ -2,0 +9,0 @@ import nullthrows from 'nullthrows';

@@ -0,8 +1,12 @@

/**
* Copyright (c) 2021 GraphQL Contributors.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {
GraphQLEnumType,
GraphQLInputField,
GraphQLInputObjectType,
GraphQLInputType,
GraphQLList,
GraphQLScalarType,
isEnumType,

@@ -16,2 +20,3 @@ isInputObjectType,

import type {
JSONSchema4Type,
JSONSchema6,

@@ -32,88 +37,8 @@ JSONSchema6Definition,

const scalarTypesMap: { [key: string]: JSONSchema6TypeName } = {
Int: 'integer',
String: 'string',
Float: 'number',
ID: 'string',
Boolean: 'boolean',
// { "type": "string", "format": "date" } is not compatible with proposed DateTime GraphQL-Scalars.com spec
DateTime: 'string',
};
const scalarType = (definition: JSONSchema6, type: GraphQLScalarType) => {
// I think this makes sense for custom scalars?
definition.type = scalarTypesMap[type.name] ?? 'any';
};
const listType = (
definition: JSONSchema6,
type: GraphQLList<any>,
definitions: Definitions,
) => {
definition.type = 'array';
const { definition: def, definitions: defs } = getJSONSchemaFromGraphQLType(
type.ofType,
);
definition.items = { $ref: def.$ref };
definitions = {
...definitions,
...defs,
type PropertiedJSON6 = JSONSchema6 & {
properties: {
[k: string]: JSONSchema6;
};
};
const enumType = (definition: JSONSchema6, type: GraphQLEnumType) => {
definition.type = 'string';
definition.enum = type.getValues().map(val => val.name);
};
const inputObjectType = (
definition: CombinedSchema,
type: GraphQLInputObjectType,
definitions: Definitions,
options?: JsonSchemaOptions,
) => {
definition.$ref = `#/definitions/${type.name}`;
definition.description = undefined;
if (!definitions || !definitions[type.name]) {
const fields = type.getFields();
const fieldDef: JSONSchema6 = {
type: 'object',
properties: {},
required: [],
};
if (type.description) {
fieldDef.description = type.description;
}
if (options?.useMarkdownDescription) {
// @ts-expect-error
fieldDef.markdownDescription = type.description;
}
Object.keys(fields).forEach(fieldName => {
const field = fields[fieldName];
const {
required,
definition: typeDefinition,
} = getJSONSchemaFromGraphQLType(field.type, options);
const { definition: fieldDefinition } = getJSONSchemaFromGraphQLType(
fields[fieldName],
options,
);
fieldDef.properties![fieldName] = {
...typeDefinition,
...fieldDefinition,
};
if (required) {
fieldDef.required!.push(fieldName);
}
});
definitions![type.name] = fieldDef;
} else {
return;
}
// definition.type = 'object';
// if (!definition.properties) {
// definition.properties = {};
// }
// definition.required = [];
};
export type JSONSchemaOptions = {

@@ -149,5 +74,2 @@ /**

function renderType(into: string[], t: GraphQLInputType | GraphQLInputField) {
if (!t) {
return;
}
if (isNonNullType(t)) {

@@ -171,7 +93,7 @@ renderType(into, t.ofType);

if (useMarkdown) {
text(into, '\n```graphql\n');
text(into, '```graphql\n');
}
renderType(into, t);
if (useMarkdown) {
text(into, '\n```\n');
text(into, '\n```');
}

@@ -181,2 +103,12 @@ return into.join('');

const scalarTypesMap: { [key: string]: JSONSchema6TypeName } = {
Int: 'integer',
String: 'string',
Float: 'number',
ID: 'string',
Boolean: 'boolean',
// { "type": "string", "format": "date" } is not compatible with proposed DateTime GraphQL-Scalars.com spec
DateTime: 'string',
};
/**

@@ -192,36 +124,34 @@ *

let required = false;
let definition: CombinedSchema = {};
let definitions: Definitions = {};
let definition: CombinedSchema = Object.create(null);
const definitions: Definitions = Object.create(null);
definition.description = renderTypeToString(type);
const hasDescription = 'description' in type && type.description;
if ('description' in type && type.description) {
definition.description += type.description;
}
if (options?.useMarkdownDescription) {
// @ts-expect-error
definition.markdownDescription = renderTypeToString(type, true);
if (hasDescription) {
// @ts-expect-error
definition.markdownDescription += type.description;
}
}
// TODO: test that this works?
if ('defaultValue' in type) {
// @ts-ignore
definition.default = type.defaultValue;
if ('defaultValue' in type && type.defaultValue !== undefined) {
definition.default = type.defaultValue as JSONSchema4Type | undefined;
}
if (isEnumType(type)) {
enumType(definition, type);
definition.type = 'string';
definition.enum = type.getValues().map(val => val.name);
}
if (isInputObjectType(type)) {
inputObjectType(definition, type, definitions, options);
}
if (isScalarType(type)) {
scalarType(definition, type);
// I think this makes sense for custom scalars?
definition.type = scalarTypesMap[type.name] ?? 'any';
}
if (isListType(type)) {
listType(definition, type, definitions);
definition.type = 'array';
const { definition: def, definitions: defs } = getJSONSchemaFromGraphQLType(
type.ofType,
options,
);
if (def.$ref) {
definition.items = { $ref: def.$ref };
} else {
definition.items = def;
}
if (defs) {
Object.keys(defs).forEach(defName => {
definitions[defName] = defs[defName];
});
}
}

@@ -235,7 +165,95 @@ if (isNonNullType(type)) {

definition = def;
definitions = {
...definitions,
...defs,
if (defs) {
Object.keys(defs).forEach(defName => {
definitions[defName] = defs[defName];
});
}
}
if (isInputObjectType(type)) {
definition.$ref = `#/definitions/${type.name}`;
const fields = type.getFields();
const fieldDef: PropertiedJSON6 = {
type: 'object',
properties: {},
required: [],
};
if (type.description) {
fieldDef.description = type.description + `\n` + renderTypeToString(type);
if (options?.useMarkdownDescription) {
// @ts-expect-error
fieldDef.markdownDescription =
type.description + `\n` + renderTypeToString(type, true);
}
} else {
fieldDef.description = renderTypeToString(type);
if (options?.useMarkdownDescription) {
// @ts-expect-error
fieldDef.markdownDescription = renderTypeToString(type, true);
}
}
Object.keys(fields).forEach(fieldName => {
const field = fields[fieldName];
const {
required: fieldRequired,
definition: typeDefinition,
definitions: typeDefinitions,
} = getJSONSchemaFromGraphQLType(field.type, options);
const {
definition: fieldDefinition,
// definitions: fieldDefinitions,
} = getJSONSchemaFromGraphQLType(field, options);
fieldDef.properties[fieldName] = {
...typeDefinition,
...fieldDefinition,
} as JSONSchema6;
const renderedField = renderTypeToString(field.type);
fieldDef.properties[fieldName].description = field.description
? field.description + '\n' + renderedField
: renderedField;
if (options?.useMarkdownDescription) {
const renderedFieldMarkdown = renderTypeToString(field.type, true);
fieldDef.properties[
fieldName
// @ts-expect-error
].markdownDescription = field.description
? field.description + '\n' + renderedFieldMarkdown
: renderedFieldMarkdown;
}
if (fieldRequired) {
fieldDef.required!.push(fieldName);
}
if (typeDefinitions) {
Object.keys(typeDefinitions).map(defName => {
definitions[defName] = typeDefinitions[defName];
});
}
});
definitions![type.name] = fieldDef;
}
// append descriptions
if (
'description' in type &&
!isScalarType(type) &&
type.description &&
!definition.description
) {
definition.description = type.description + '\n' + renderTypeToString(type);
if (options?.useMarkdownDescription) {
// @ts-expect-error
definition.markdownDescription =
type.description + '\n' + renderTypeToString(type, true);
}
} else {
definition.description = renderTypeToString(type);
if (options?.useMarkdownDescription) {
// @ts-expect-error
definition.markdownDescription = renderTypeToString(type, true);
}
}

@@ -257,3 +275,3 @@ return { required, definition, definitions };

): JSONSchema6 {
const jsonSchema: JSONSchema6 = {
const jsonSchema: PropertiedJSON6 = {
$schema: 'https://json-schema.org/draft/2020-12/schema',

@@ -273,3 +291,3 @@ type: 'object',

} = getJSONSchemaFromGraphQLType(type, options);
jsonSchema.properties![variableName] = definition;
jsonSchema.properties[variableName] = definition;
if (required) {

@@ -279,3 +297,3 @@ jsonSchema.required?.push(variableName);

if (definitions) {
jsonSchema.definitions = definitions;
jsonSchema.definitions = { ...jsonSchema?.definitions, ...definitions };
}

@@ -282,0 +300,0 @@ });

@@ -19,2 +19,3 @@ /**

JSONSchema6TypeName,
JSONSchemaOptions,
} from './getVariablesJSONSchema';

@@ -31,9 +32,2 @@

export {
fillLeafs,
GetDefaultFieldNamesFn,
buildSelectionSet,
defaultGetDefaultFieldNames,
} from './fillLeafs';
export {
default as getOperationFacts,

@@ -40,0 +34,0 @@ getOperationASTFacts,

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc