HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/shop.komma.nl/node_modules/apollo-language-server/lib/project/client.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const base_1 = require("./base");
const graphql_1 = require("graphql");
const vscode_languageserver_1 = require("vscode-languageserver");
const source_1 = require("../utilities/source");
const format_1 = require("../format");
const fileSet_1 = require("../fileSet");
const defaultClientSchema_1 = require("./defaultClientSchema");
const graphql_2 = require("../utilities/graphql");
const validation_1 = require("../errors/validation");
const diagnostics_1 = require("../diagnostics");
function schemaHasASTNodes(schema) {
    const queryType = schema && schema.getQueryType();
    return !!(queryType && queryType.astNode);
}
function augmentSchemaWithGeneratedSDLIfNeeded(schema) {
    if (schemaHasASTNodes(schema))
        return schema;
    const sdl = graphql_1.printSchema(schema);
    return graphql_1.buildSchema(new graphql_1.Source(sdl, `graphql-schema:/schema.graphql?${encodeURIComponent(sdl)}`));
}
function isClientProject(project) {
    return project instanceof GraphQLClientProject;
}
exports.isClientProject = isClientProject;
class GraphQLClientProject extends base_1.GraphQLProject {
    constructor({ config, loadingHandler, rootURI, clientIdentity }) {
        const fileSet = new fileSet_1.FileSet({
            rootURI: config.configDirURI || rootURI,
            includes: [...config.client.includes, ".env", "apollo.config.js"],
            excludes: config.client.excludes,
            configURI: config.configURI
        });
        super({ config, fileSet, loadingHandler, clientIdentity });
        this.rootURI = rootURI;
        this.serviceID = config.graph;
        const filterConfigAndEnvFiles = (path) => !(path.includes("apollo.config") ||
            path.includes(".env") ||
            (config.configURI && path === config.configURI.fsPath));
        if (fileSet.allFiles().filter(filterConfigAndEnvFiles).length === 0) {
            console.warn("⚠️  It looks like there are 0 files associated with this Apollo Project. " +
                "This may be because you don't have any files yet, or your includes/excludes " +
                "fields are configured incorrectly, and Apollo can't find your files. " +
                "For help configuring Apollo projects, see this guide: https://go.apollo.dev/t/config");
        }
        const { validationRules } = this.config.client;
        if (typeof validationRules === "function") {
            this._validationRules = validation_1.defaultValidationRules.filter(validationRules);
        }
        else {
            this._validationRules = validationRules;
        }
        this.loadEngineData();
    }
    get displayName() {
        return this.config.graph || "Unnamed Project";
    }
    initialize() {
        return [this.scanAllIncludedFiles(), this.loadServiceSchema()];
    }
    getProjectStats() {
        const filterTypes = (type) => !/^__|Boolean|ID|Int|String|Float/.test(type);
        const serviceTypes = this.serviceSchema
            ? Object.keys(this.serviceSchema.getTypeMap()).filter(filterTypes).length
            : 0;
        const totalTypes = this.schema
            ? Object.keys(this.schema.getTypeMap()).filter(filterTypes).length
            : 0;
        return {
            type: "client",
            serviceId: this.serviceID,
            types: {
                service: serviceTypes,
                client: totalTypes - serviceTypes,
                total: totalTypes
            },
            tag: this.config.variant,
            loaded: Boolean(this.schema || this.serviceSchema),
            lastFetch: this.lastLoadDate
        };
    }
    onDecorations(handler) {
        this._onDecorations = handler;
    }
    onSchemaTags(handler) {
        this._onSchemaTags = handler;
    }
    async updateSchemaTag(tag) {
        await this.loadServiceSchema(tag);
        this.invalidate();
    }
    async loadServiceSchema(tag) {
        await this.loadingHandler.handle(`Loading schema for ${this.displayName}`, (async () => {
            this.serviceSchema = augmentSchemaWithGeneratedSDLIfNeeded(await this.schemaProvider.resolveSchema({
                tag: tag || this.config.variant,
                force: true
            }));
            this.schema = graphql_1.extendSchema(this.serviceSchema, this.clientSchema);
        })());
    }
    async resolveSchema() {
        if (!this.schema)
            throw new Error();
        return this.schema;
    }
    get clientSchema() {
        return {
            kind: graphql_1.Kind.DOCUMENT,
            definitions: [
                ...this.typeSystemDefinitionsAndExtensions,
                ...this.missingApolloClientDirectives
            ]
        };
    }
    get missingApolloClientDirectives() {
        const { serviceSchema } = this;
        const serviceDirectives = serviceSchema
            ? serviceSchema.getDirectives().map(directive => directive.name)
            : [];
        const clientDirectives = this.typeSystemDefinitionsAndExtensions
            .filter(graphql_2.isDirectiveDefinitionNode)
            .map(def => def.name.value);
        const existingDirectives = serviceDirectives.concat(clientDirectives);
        const apolloAst = defaultClientSchema_1.apolloClientSchemaDocument.ast;
        if (!apolloAst)
            return [];
        const apolloDirectives = apolloAst.definitions
            .filter(graphql_2.isDirectiveDefinitionNode)
            .map(def => def.name.value);
        for (const existingDirective of existingDirectives) {
            if (apolloDirectives.includes(existingDirective)) {
                return [];
            }
        }
        return apolloAst.definitions;
    }
    addClientMetadataToSchemaNodes() {
        const { schema, serviceSchema } = this;
        if (!schema || !serviceSchema)
            return;
        graphql_1.visit(this.clientSchema, {
            ObjectTypeExtension(node) {
                const type = schema.getType(node.name.value);
                const { fields } = node;
                if (!fields || !type)
                    return;
                const localInfo = type.clientSchema || {};
                localInfo.localFields = [
                    ...(localInfo.localFields || []),
                    ...fields.map(field => field.name.value)
                ];
                type.clientSchema = localInfo;
            }
        });
    }
    async validate() {
        if (!this._onDiagnostics)
            return;
        if (!this.serviceSchema)
            return;
        const diagnosticSet = new diagnostics_1.DiagnosticSet();
        try {
            this.schema = graphql_1.extendSchema(this.serviceSchema, this.clientSchema);
            this.addClientMetadataToSchemaNodes();
        }
        catch (error) {
            if (error instanceof graphql_1.GraphQLError) {
                const uri = error.source && error.source.name;
                if (uri) {
                    diagnosticSet.addDiagnostics(uri, diagnostics_1.diagnosticsFromError(error, vscode_languageserver_1.DiagnosticSeverity.Error, "Validation"));
                }
            }
            else {
                console.error(error);
            }
            this.schema = this.serviceSchema;
        }
        const fragments = this.fragments;
        for (const [uri, documentsForFile] of this.documentsByFile) {
            for (const document of documentsForFile) {
                diagnosticSet.addDiagnostics(uri, diagnostics_1.collectExecutableDefinitionDiagnositics(this.schema, document, fragments, this._validationRules));
            }
        }
        for (const [uri, diagnostics] of diagnosticSet.entries()) {
            this._onDiagnostics({ uri, diagnostics });
        }
        this.diagnosticSet = diagnosticSet;
        this.generateDecorations();
    }
    async loadEngineData() {
        const engineClient = this.engineClient;
        if (!engineClient)
            return;
        const serviceID = this.serviceID;
        if (!serviceID)
            return;
        await this.loadingHandler.handle(`Loading Apollo data for ${this.displayName}`, (async () => {
            try {
                const { schemaTags, fieldStats } = await engineClient.loadSchemaTagsAndFieldStats(serviceID);
                this._onSchemaTags && this._onSchemaTags([serviceID, schemaTags]);
                this.fieldStats = fieldStats;
                this.lastLoadDate = +new Date();
                this.generateDecorations();
            }
            catch (e) {
                console.error(e);
            }
        })());
    }
    generateDecorations() {
        if (!this._onDecorations)
            return;
        if (!this.schema)
            return;
        const decorations = [];
        for (const [uri, queryDocumentsForFile] of this.documentsByFile) {
            for (const queryDocument of queryDocumentsForFile) {
                if (queryDocument.ast && this.fieldStats) {
                    const fieldStats = this.fieldStats;
                    const typeInfo = new graphql_1.TypeInfo(this.schema);
                    graphql_1.visit(queryDocument.ast, graphql_1.visitWithTypeInfo(typeInfo, {
                        enter: node => {
                            if (node.kind == "Field" && typeInfo.getParentType()) {
                                const parentName = typeInfo.getParentType().name;
                                const parentEngineStat = fieldStats.get(parentName);
                                const engineStat = parentEngineStat
                                    ? parentEngineStat.get(node.name.value)
                                    : undefined;
                                if (engineStat && engineStat > 1) {
                                    decorations.push({
                                        document: uri,
                                        message: `~${format_1.formatMS(engineStat, 0)}`,
                                        range: source_1.rangeForASTNode(node)
                                    });
                                }
                            }
                        }
                    }));
                }
            }
        }
        this._onDecorations(decorations);
    }
    get fragments() {
        const fragments = Object.create(null);
        for (const document of this.documents) {
            if (!document.ast)
                continue;
            for (const definition of document.ast.definitions) {
                if (definition.kind === graphql_1.Kind.FRAGMENT_DEFINITION) {
                    fragments[definition.name.value] = definition;
                }
            }
        }
        return fragments;
    }
    get operations() {
        const operations = Object.create(null);
        for (const document of this.documents) {
            if (!document.ast)
                continue;
            for (const definition of document.ast.definitions) {
                if (definition.kind === graphql_1.Kind.OPERATION_DEFINITION) {
                    if (!definition.name) {
                        throw new graphql_1.GraphQLError("Apollo does not support anonymous operations", [definition]);
                    }
                    operations[definition.name.value] = definition;
                }
            }
        }
        return operations;
    }
    get mergedOperationsAndFragments() {
        return graphql_1.separateOperations({
            kind: graphql_1.Kind.DOCUMENT,
            definitions: [
                ...Object.values(this.fragments),
                ...Object.values(this.operations)
            ]
        });
    }
    get mergedOperationsAndFragmentsForService() {
        const { clientOnlyDirectives, clientSchemaDirectives, addTypename } = this.config.client;
        const current = this.mergedOperationsAndFragments;
        if ((!clientOnlyDirectives || !clientOnlyDirectives.length) &&
            (!clientSchemaDirectives || !clientSchemaDirectives.length))
            return current;
        const filtered = Object.create(null);
        for (const operationName in current) {
            const document = current[operationName];
            let serviceOnly = graphql_2.removeDirectiveAnnotatedFields(graphql_2.removeDirectives(document, clientOnlyDirectives), clientSchemaDirectives);
            if (addTypename)
                serviceOnly = graphql_2.withTypenameFieldAddedWhereNeeded(serviceOnly);
            if (serviceOnly.definitions.filter(Boolean).length) {
                filtered[operationName] = serviceOnly;
            }
        }
        return filtered;
    }
    getOperationFieldsFromFieldDefinition(fieldName, parent) {
        if (!this.schema || !parent)
            return [];
        const fields = [];
        const typeInfo = new graphql_1.TypeInfo(this.schema);
        for (const document of this.documents) {
            if (!document.ast)
                continue;
            graphql_1.visit(document.ast, graphql_1.visitWithTypeInfo(typeInfo, {
                Field(node) {
                    if (node.name.value !== fieldName)
                        return;
                    const parentType = typeInfo.getParentType();
                    if (parentType && parentType.name === parent.name.value) {
                        fields.push(node);
                    }
                    return;
                }
            }));
        }
        return fields;
    }
    fragmentSpreadsForFragment(fragmentName) {
        const fragmentSpreads = [];
        for (const document of this.documents) {
            if (!document.ast)
                continue;
            graphql_1.visit(document.ast, {
                FragmentSpread(node) {
                    if (node.name.value === fragmentName) {
                        fragmentSpreads.push(node);
                    }
                }
            });
        }
        return fragmentSpreads;
    }
}
exports.GraphQLClientProject = GraphQLClientProject;
//# sourceMappingURL=client.js.map