Initialisation
Added the packages and files for the backend server
This commit is contained in:
158
node_modules/@graphql-tools/utils/cjs/prune.js
generated
vendored
Normal file
158
node_modules/@graphql-tools/utils/cjs/prune.js
generated
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.pruneSchema = void 0;
|
||||
const graphql_1 = require("graphql");
|
||||
const mapSchema_js_1 = require("./mapSchema.js");
|
||||
const Interfaces_js_1 = require("./Interfaces.js");
|
||||
const rootTypes_js_1 = require("./rootTypes.js");
|
||||
const get_implementing_types_js_1 = require("./get-implementing-types.js");
|
||||
/**
|
||||
* Prunes the provided schema, removing unused and empty types
|
||||
* @param schema The schema to prune
|
||||
* @param options Additional options for removing unused types from the schema
|
||||
*/
|
||||
function pruneSchema(schema, options = {}) {
|
||||
const { skipEmptyCompositeTypePruning, skipEmptyUnionPruning, skipPruning, skipUnimplementedInterfacesPruning, skipUnusedTypesPruning, } = options;
|
||||
let prunedTypes = []; // Pruned types during mapping
|
||||
let prunedSchema = schema;
|
||||
do {
|
||||
let visited = visitSchema(prunedSchema);
|
||||
// Custom pruning was defined, so we need to pre-emptively revisit the schema accounting for this
|
||||
if (skipPruning) {
|
||||
const revisit = [];
|
||||
for (const typeName in prunedSchema.getTypeMap()) {
|
||||
if (typeName.startsWith('__')) {
|
||||
continue;
|
||||
}
|
||||
const type = prunedSchema.getType(typeName);
|
||||
// if we want to skip pruning for this type, add it to the list of types to revisit
|
||||
if (type && skipPruning(type)) {
|
||||
revisit.push(typeName);
|
||||
}
|
||||
}
|
||||
visited = visitQueue(revisit, prunedSchema, visited); // visit again
|
||||
}
|
||||
prunedTypes = [];
|
||||
prunedSchema = (0, mapSchema_js_1.mapSchema)(prunedSchema, {
|
||||
[Interfaces_js_1.MapperKind.TYPE]: type => {
|
||||
if (!visited.has(type.name) && !(0, graphql_1.isSpecifiedScalarType)(type)) {
|
||||
if ((0, graphql_1.isUnionType)(type) ||
|
||||
(0, graphql_1.isInputObjectType)(type) ||
|
||||
(0, graphql_1.isInterfaceType)(type) ||
|
||||
(0, graphql_1.isObjectType)(type) ||
|
||||
(0, graphql_1.isScalarType)(type)) {
|
||||
// skipUnusedTypesPruning: skip pruning unused types
|
||||
if (skipUnusedTypesPruning) {
|
||||
return type;
|
||||
}
|
||||
// skipEmptyUnionPruning: skip pruning empty unions
|
||||
if ((0, graphql_1.isUnionType)(type) && skipEmptyUnionPruning && !Object.keys(type.getTypes()).length) {
|
||||
return type;
|
||||
}
|
||||
if ((0, graphql_1.isInputObjectType)(type) || (0, graphql_1.isInterfaceType)(type) || (0, graphql_1.isObjectType)(type)) {
|
||||
// skipEmptyCompositeTypePruning: skip pruning object types or interfaces with no fields
|
||||
if (skipEmptyCompositeTypePruning && !Object.keys(type.getFields()).length) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
// skipUnimplementedInterfacesPruning: skip pruning interfaces that are not implemented by any other types
|
||||
if ((0, graphql_1.isInterfaceType)(type) && skipUnimplementedInterfacesPruning) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
prunedTypes.push(type.name);
|
||||
visited.delete(type.name);
|
||||
return null;
|
||||
}
|
||||
return type;
|
||||
},
|
||||
});
|
||||
} while (prunedTypes.length); // Might have empty types and need to prune again
|
||||
return prunedSchema;
|
||||
}
|
||||
exports.pruneSchema = pruneSchema;
|
||||
function visitSchema(schema) {
|
||||
const queue = []; // queue of nodes to visit
|
||||
// Grab the root types and start there
|
||||
for (const type of (0, rootTypes_js_1.getRootTypes)(schema)) {
|
||||
queue.push(type.name);
|
||||
}
|
||||
return visitQueue(queue, schema);
|
||||
}
|
||||
function visitQueue(queue, schema, visited = new Set()) {
|
||||
// Interfaces encountered that are field return types need to be revisited to add their implementations
|
||||
const revisit = new Map();
|
||||
// Navigate all types starting with pre-queued types (root types)
|
||||
while (queue.length) {
|
||||
const typeName = queue.pop();
|
||||
// Skip types we already visited unless it is an interface type that needs revisiting
|
||||
if (visited.has(typeName) && revisit[typeName] !== true) {
|
||||
continue;
|
||||
}
|
||||
const type = schema.getType(typeName);
|
||||
if (type) {
|
||||
// Get types for union
|
||||
if ((0, graphql_1.isUnionType)(type)) {
|
||||
queue.push(...type.getTypes().map(type => type.name));
|
||||
}
|
||||
// If it is an interface and it is a returned type, grab all implementations so we can use proper __typename in fragments
|
||||
if ((0, graphql_1.isInterfaceType)(type) && revisit[typeName] === true) {
|
||||
queue.push(...(0, get_implementing_types_js_1.getImplementingTypes)(type.name, schema));
|
||||
// No need to revisit this interface again
|
||||
revisit[typeName] = false;
|
||||
}
|
||||
if ((0, graphql_1.isEnumType)(type)) {
|
||||
// Visit enum values directives argument types
|
||||
queue.push(...type.getValues().flatMap(value => {
|
||||
if (value.astNode) {
|
||||
return getDirectivesArgumentsTypeNames(schema, value.astNode);
|
||||
}
|
||||
return [];
|
||||
}));
|
||||
}
|
||||
// Visit interfaces this type is implementing if they haven't been visited yet
|
||||
if ('getInterfaces' in type) {
|
||||
// Only pushes to queue to visit but not return types
|
||||
queue.push(...type.getInterfaces().map(iface => iface.name));
|
||||
}
|
||||
// If the type has fields visit those field types
|
||||
if ('getFields' in type) {
|
||||
const fields = type.getFields();
|
||||
const entries = Object.entries(fields);
|
||||
if (!entries.length) {
|
||||
continue;
|
||||
}
|
||||
for (const [, field] of entries) {
|
||||
if ((0, graphql_1.isObjectType)(type)) {
|
||||
// Visit arg types and arg directives arguments types
|
||||
queue.push(...field.args.flatMap(arg => {
|
||||
const typeNames = [(0, graphql_1.getNamedType)(arg.type).name];
|
||||
if (arg.astNode) {
|
||||
typeNames.push(...getDirectivesArgumentsTypeNames(schema, arg.astNode));
|
||||
}
|
||||
return typeNames;
|
||||
}));
|
||||
}
|
||||
const namedType = (0, graphql_1.getNamedType)(field.type);
|
||||
queue.push(namedType.name);
|
||||
if (field.astNode) {
|
||||
queue.push(...getDirectivesArgumentsTypeNames(schema, field.astNode));
|
||||
}
|
||||
// Interfaces returned on fields need to be revisited to add their implementations
|
||||
if ((0, graphql_1.isInterfaceType)(namedType) && !(namedType.name in revisit)) {
|
||||
revisit[namedType.name] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type.astNode) {
|
||||
queue.push(...getDirectivesArgumentsTypeNames(schema, type.astNode));
|
||||
}
|
||||
visited.add(typeName); // Mark as visited (and therefore it is used and should be kept)
|
||||
}
|
||||
}
|
||||
return visited;
|
||||
}
|
||||
function getDirectivesArgumentsTypeNames(schema, astNode) {
|
||||
var _a;
|
||||
return ((_a = astNode.directives) !== null && _a !== void 0 ? _a : []).flatMap(directive => { var _a, _b; return (_b = (_a = schema.getDirective(directive.name.value)) === null || _a === void 0 ? void 0 : _a.args.map(arg => (0, graphql_1.getNamedType)(arg.type).name)) !== null && _b !== void 0 ? _b : []; });
|
||||
}
|
||||
Reference in New Issue
Block a user