UNPKG

@theguild/editor

Version:

A monaco editor with built-in support for GraphQL Language Service, with features like online parser, syntax highlight, schema-building validations, hover and much more. The integration between Monaco editor and the GraphQL language service is exposed thr

1,318 lines (1,289 loc) • 44.2 kB
// src/editor/enriched-language-service.ts import { getRange as getRange2, getTokenAtPosition, LanguageService } from "graphql-language-service"; // src/editor/utils.ts import { DIAGNOSTIC_SEVERITY, getHoverInformation, getRange, Position } from "graphql-language-service"; import { MarkerSeverity } from "monaco-editor"; function removeFalsey(obj) { return !!obj; } function locToRange(loc) { return { startLineNumber: loc.startToken.line, startColumn: loc.startToken.column, endLineNumber: loc.endToken.line + 1, // Because GraphQL starts with 0, and Monaco starts with 1 endColumn: loc.endToken.column }; } var emptyLocation = { startLineNumber: 0, startColumn: 0, endLineNumber: 0, endColumn: 0 }; var coreDiagnosticsSource = { async forDocument({ model, document: document2, languageService }) { return languageService.getDiagnostics(model.uri.toString(), document2).then((diag) => diag.map(toMarkerData)).catch((e) => { if ("message" in e && "locations" in e) { return [ toMarkerData({ severity: DIAGNOSTIC_SEVERITY.Error, message: e.message, source: "GraphQL: Syntax", range: getRange(e.locations[0], document2) }) ]; } console.warn("GraphQL getDiagnostics failed unexpected error:", e); return []; }); } }; var coreDefinitionSource = { forNode({ schema, model, token }) { var _a, _b; if (((_a = token.state) == null ? void 0 : _a.name) && token.state.kind === "NamedType") { const type = schema.getType(token.state.name); if ((_b = type == null ? void 0 : type.astNode) == null ? void 0 : _b.loc) { return [ { range: { startLineNumber: type.astNode.loc.startToken.line, startColumn: type.astNode.loc.startToken.column, endLineNumber: type.astNode.loc.endToken.line + 1, endColumn: type.astNode.loc.endToken.column }, uri: model.uri } ]; } } return []; } }; var coreHoverSource = { forNode: ({ schema, document: document2, position, token }) => ({ value: getHoverInformation(schema, document2, position, token) }) }; var debugHoverSource = { forNode: ({ token }) => ({ value: `\`\`\`json ${JSON.stringify(token.state, null, 2)} \`\`\`` }) }; function toGraphQLPosition(position) { return new Position(position.lineNumber - 1, position.column - 1); } var DiagnosticSeverityToMarkerSeverity = { 1: MarkerSeverity.Error, 2: MarkerSeverity.Warning, 3: MarkerSeverity.Info, 4: MarkerSeverity.Hint }; function toMarkerData(diagnostic) { return { startLineNumber: diagnostic.range.start.line + 1, endLineNumber: diagnostic.range.end.line + 1, startColumn: diagnostic.range.start.character + 1, endColumn: diagnostic.range.end.character, message: diagnostic.message, severity: diagnostic.severity ? DiagnosticSeverityToMarkerSeverity[diagnostic.severity] : MarkerSeverity.Info, code: diagnostic.code || void 0 }; } function toMonacoRange(range) { return { startLineNumber: range.start.line + 1, startColumn: range.start.character + 1, endLineNumber: range.end.line + 1, endColumn: range.end.character + 1 }; } function showWidgetInPosition(editorInstance, position, htmlElement) { editorInstance.changeViewZones((changeAccessor) => { changeAccessor.addZone({ afterLineNumber: position.line + 1, heightInPx: 60, domNode: htmlElement }); }); } // src/editor/enriched-language-service.ts var EnrichedLanguageService = class extends LanguageService { async getNodeAtPosition(schema, document2, position) { if (schema) { const token = getTokenAtPosition(document2, position); if (token) { return token; } } return null; } async getSchemaSafe() { try { return await this.getSchema(); } catch (e) { console.warn("Failed to get schema:", e); return null; } } async buildBridgeForProviders(model, position) { const graphQLPosition = toGraphQLPosition(position); const document2 = model.getValue(); const schema = await this.getSchemaSafe(); if (!schema) { return null; } const tokenAtPosition = await this.getNodeAtPosition(schema, document2, graphQLPosition); if (!tokenAtPosition) { return null; } return { languageService: this, position: graphQLPosition, document: document2, schema, token: tokenAtPosition, model }; } getDefinitionProvider(rawSources) { const sources = [...rawSources, coreDefinitionSource]; return { provideDefinition: async (model, position) => { const bridge = await this.buildBridgeForProviders(model, position); if (!bridge) { return []; } const nestedArrays = (await Promise.all(sources.map((source) => source.forNode(bridge)))).filter(Boolean); const items = [].concat(...nestedArrays); return items; } }; } getHoverProvider(rawSources) { const sources = [...rawSources, coreHoverSource]; return { provideHover: async (model, position) => { const info = await this.buildBridgeForProviders(model, position); if (!info) { return; } const contents = await Promise.all( sources.map(async (source) => { try { return await source.forNode(info); } catch { return null; } }) ); return { contents: contents.filter(removeFalsey), range: toMonacoRange( getRange2( { column: info.position.character, line: info.position.line + 1 }, info.document ) ) }; } }; } async handleDecorations(decorationSources, model, monacoInstance, editorInstance) { for (const source of decorationSources) { source.forDocument({ monaco: monacoInstance, editor: editorInstance, document: model.getValue(), model, languageService: this }); } } async handleDiagnostics(rawDiagnosticsSources, model, monacoInstance) { const diagnosticsSources = [...rawDiagnosticsSources, coreDiagnosticsSource]; const nestedArrays = (await Promise.all( diagnosticsSources.map(async (source) => { try { return await source.forDocument({ languageService: this, model, document: model.getValue().toString() }); } catch { return null; } }) )).filter(removeFalsey); const markerData = [].concat(...nestedArrays); monacoInstance.editor.setModelMarkers(model, "graphql", markerData); } getModelChangeHandler() { return async (editorInstance, monacoInstance, diagnosticsSources, decorationsSources) => { const model = editorInstance.getModel(); if (!model) { return; } await Promise.all([ this.handleDiagnostics(diagnosticsSources, model, monacoInstance), this.handleDecorations(decorationsSources, model, monacoInstance, editorInstance) ]); }; } trySchema(sdl) { return this.setSchema(sdl).then(() => this.getSchemaSafe()); } }; // src/editor/executable-document-editor.tsx import { useEffect as useEffect2, useRef, useState as useState2 } from "react"; import { getAutocompleteSuggestions } from "graphql-language-service"; // ../../node_modules/.pnpm/next-themes@0.4.3_react-dom@19.0.0_react@19.0.0__react@19.0.0/node_modules/next-themes/dist/index.mjs import * as t from "react"; var L = (e, o, s, u, d, m, l, h) => { let i = document.documentElement, T = ["light", "dark"]; function p(a) { (Array.isArray(e) ? e : [e]).forEach((g) => { let k = g === "class", S = k && m ? d.map((f) => m[f] || f) : d; k ? (i.classList.remove(...S), i.classList.add(a)) : i.setAttribute(g, a); }), R(a); } function R(a) { h && T.includes(a) && (i.style.colorScheme = a); } function c() { return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; } if (u) p(u); else try { let a = localStorage.getItem(o) || s, g = l && a === "system" ? c() : a; p(g); } catch (a) { } }; var E = t.createContext(void 0); var N = { setTheme: (e) => { }, themes: [] }; var z = () => { var e; return (e = t.useContext(E)) != null ? e : N; }; var V = t.memo(({ forcedTheme: e, storageKey: o, attribute: s, enableSystem: u, enableColorScheme: d, defaultTheme: m, value: l, themes: h, nonce: i, scriptProps: T }) => { let p = JSON.stringify([s, o, m, e, h, l, u, d]).slice(1, -1); return t.createElement("script", { ...T, suppressHydrationWarning: true, nonce: typeof window == "undefined" ? i : "", dangerouslySetInnerHTML: { __html: `(${L.toString()})(${p})` } }); }); // src/editor/executable-document-editor.tsx import MonacoEditor, { useMonaco } from "@monaco-editor/react"; // src/editor/enums.ts var CompletionItemKind = /* @__PURE__ */ ((CompletionItemKind2) => { CompletionItemKind2[CompletionItemKind2["Method"] = 0] = "Method"; CompletionItemKind2[CompletionItemKind2["Function"] = 1] = "Function"; CompletionItemKind2[CompletionItemKind2["Constructor"] = 2] = "Constructor"; CompletionItemKind2[CompletionItemKind2["Field"] = 3] = "Field"; CompletionItemKind2[CompletionItemKind2["Variable"] = 4] = "Variable"; CompletionItemKind2[CompletionItemKind2["Class"] = 5] = "Class"; CompletionItemKind2[CompletionItemKind2["Struct"] = 6] = "Struct"; CompletionItemKind2[CompletionItemKind2["Interface"] = 7] = "Interface"; CompletionItemKind2[CompletionItemKind2["Module"] = 8] = "Module"; CompletionItemKind2[CompletionItemKind2["Property"] = 9] = "Property"; CompletionItemKind2[CompletionItemKind2["Event"] = 10] = "Event"; CompletionItemKind2[CompletionItemKind2["Operator"] = 11] = "Operator"; CompletionItemKind2[CompletionItemKind2["Unit"] = 12] = "Unit"; CompletionItemKind2[CompletionItemKind2["Value"] = 13] = "Value"; CompletionItemKind2[CompletionItemKind2["Constant"] = 14] = "Constant"; CompletionItemKind2[CompletionItemKind2["Enum"] = 15] = "Enum"; CompletionItemKind2[CompletionItemKind2["EnumMember"] = 16] = "EnumMember"; CompletionItemKind2[CompletionItemKind2["Keyword"] = 17] = "Keyword"; CompletionItemKind2[CompletionItemKind2["Text"] = 18] = "Text"; CompletionItemKind2[CompletionItemKind2["Color"] = 19] = "Color"; CompletionItemKind2[CompletionItemKind2["File"] = 20] = "File"; CompletionItemKind2[CompletionItemKind2["Reference"] = 21] = "Reference"; CompletionItemKind2[CompletionItemKind2["Customcolor"] = 22] = "Customcolor"; CompletionItemKind2[CompletionItemKind2["Folder"] = 23] = "Folder"; CompletionItemKind2[CompletionItemKind2["TypeParameter"] = 24] = "TypeParameter"; CompletionItemKind2[CompletionItemKind2["User"] = 25] = "User"; CompletionItemKind2[CompletionItemKind2["Issue"] = 26] = "Issue"; CompletionItemKind2[CompletionItemKind2["Snippet"] = 27] = "Snippet"; return CompletionItemKind2; })(CompletionItemKind || {}); // src/editor/executable-document-editor.tsx import { jsx } from "react/jsx-runtime"; var toCompletionItemKind = (kind) => { const CIK = CompletionItemKind; const map = { [1 /* Text */]: CIK.Text, [2 /* Method */]: CIK.Method, [3 /* Function */]: CIK.Function, [4 /* Constructor */]: CIK.Constructor, [5 /* Field */]: CIK.Field, [6 /* Variable */]: CIK.Variable, [7 /* Class */]: CIK.Class, [8 /* Interface */]: CIK.Interface, [9 /* Module */]: CIK.Module, [10 /* Property */]: CIK.Property, [11 /* Unit */]: CIK.Unit, [12 /* Value */]: CIK.Value, [13 /* Enum */]: CIK.Enum, [14 /* Keyword */]: CIK.Keyword, [15 /* Snippet */]: CIK.Snippet, [16 /* Color */]: CIK.Color, [17 /* File */]: CIK.File, [18 /* Reference */]: CIK.Reference, [19 /* Folder */]: CIK.Folder, [20 /* EnumMember */]: CIK.EnumMember, [21 /* Constant */]: CIK.Constant, [22 /* Struct */]: CIK.Struct, [23 /* Event */]: CIK.Event, [24 /* Operator */]: CIK.Operator, [25 /* TypeParameter */]: CIK.TypeParameter }; return map[kind] || CIK.Text; }; var toCompletion = (entry) => { var _a; return { range: entry.range, kind: toCompletionItemKind(entry.kind), label: entry.label, insertText: (_a = entry.insertText) != null ? _a : entry.label, insertTextRules: entry.insertText ? 4 /* InsertAsSnippet */ : void 0, sortText: entry.sortText, filterText: entry.filterText, documentation: entry.documentation, detail: entry.detail, command: entry.command }; }; var GraphQLWorker = class { doComplete(documentModel, position, schema) { const document2 = documentModel.getValue(); if (!document2) { console.log("no document"); return []; } if (!schema) { console.log("no schema"); } const graphQLPosition = toGraphQLPosition(position); const suggestions = getAutocompleteSuggestions(schema, document2, graphQLPosition); return suggestions.map((suggestion) => this.toCompletion(suggestion)); } toCompletion(entry, range) { return { label: entry.label, insertText: entry.insertText, insertTextFormat: entry.insertTextFormat, sortText: entry.sortText, filterText: entry.filterText, documentation: entry.documentation, detail: entry.detail, range: range ? toMonacoRange(range) : void 0, kind: entry.kind, command: entry.command ? { ...entry.command, id: entry.command.command } : void 0 }; } }; var ExecutableDocumentEditor = ({ schema, ...editorProps }) => { const { resolvedTheme } = z(); const monaco = useMonaco(); const [completionProvider, setCompletionProvider] = useState2(null); const editorUriRef = useRef(); useEffect2(() => { if (!monaco || !schema) { return; } if (completionProvider) { completionProvider.dispose(); } const newProvider = monaco.languages.registerCompletionItemProvider("graphql", { triggerCharacters: [":", "$", "\n", " ", "(", "@"], provideCompletionItems(model, position) { const isUriEquals = model.uri.path === editorUriRef.current.path; if (!isUriEquals) { return { suggestions: [] }; } const worker = new GraphQLWorker(); const completionItems = worker.doComplete(model, position, schema); return { incomplete: true, suggestions: completionItems.map((item) => toCompletion(item)) }; } }); setCompletionProvider(newProvider); }, [monaco, schema]); return /* @__PURE__ */ jsx( MonacoEditor, { height: "70vh", theme: resolvedTheme === "dark" ? "vs-dark" : "light", ...editorProps, language: "graphql", onMount: (editor) => { editorUriRef.current = editor.getModel().uri; } } ); }; // src/editor/schema-editor.tsx import { forwardRef, useCallback as useCallback2, useEffect as useEffect4, useImperativeHandle, useState as useState4 } from "react"; // ../../node_modules/.pnpm/graphql@16.9.0/node_modules/graphql/jsutils/devAssert.mjs function devAssert(condition, message) { const booleanCondition = Boolean(condition); if (!booleanCondition) { throw new Error(message); } } // ../../node_modules/.pnpm/graphql@16.9.0/node_modules/graphql/jsutils/isObjectLike.mjs function isObjectLike(value) { return typeof value == "object" && value !== null; } // ../../node_modules/.pnpm/graphql@16.9.0/node_modules/graphql/jsutils/invariant.mjs function invariant(condition, message) { const booleanCondition = Boolean(condition); if (!booleanCondition) { throw new Error( message != null ? message : "Unexpected invariant triggered." ); } } // ../../node_modules/.pnpm/graphql@16.9.0/node_modules/graphql/language/location.mjs var LineRegExp = /\r\n|[\n\r]/g; function getLocation(source, position) { let lastLineStart = 0; let line = 1; for (const match of source.body.matchAll(LineRegExp)) { typeof match.index === "number" || invariant(false); if (match.index >= position) { break; } lastLineStart = match.index + match[0].length; line += 1; } return { line, column: position + 1 - lastLineStart }; } // ../../node_modules/.pnpm/graphql@16.9.0/node_modules/graphql/language/printLocation.mjs function printLocation(location) { return printSourceLocation( location.source, getLocation(location.source, location.start) ); } function printSourceLocation(source, sourceLocation) { const firstLineColumnOffset = source.locationOffset.column - 1; const body = "".padStart(firstLineColumnOffset) + source.body; const lineIndex = sourceLocation.line - 1; const lineOffset = source.locationOffset.line - 1; const lineNum = sourceLocation.line + lineOffset; const columnOffset = sourceLocation.line === 1 ? firstLineColumnOffset : 0; const columnNum = sourceLocation.column + columnOffset; const locationStr = `${source.name}:${lineNum}:${columnNum} `; const lines = body.split(/\r\n|[\n\r]/g); const locationLine = lines[lineIndex]; if (locationLine.length > 120) { const subLineIndex = Math.floor(columnNum / 80); const subLineColumnNum = columnNum % 80; const subLines = []; for (let i = 0; i < locationLine.length; i += 80) { subLines.push(locationLine.slice(i, i + 80)); } return locationStr + printPrefixedLines([ [`${lineNum} |`, subLines[0]], ...subLines.slice(1, subLineIndex + 1).map((subLine) => ["|", subLine]), ["|", "^".padStart(subLineColumnNum)], ["|", subLines[subLineIndex + 1]] ]); } return locationStr + printPrefixedLines([ // Lines specified like this: ["prefix", "string"], [`${lineNum - 1} |`, lines[lineIndex - 1]], [`${lineNum} |`, locationLine], ["|", "^".padStart(columnNum)], [`${lineNum + 1} |`, lines[lineIndex + 1]] ]); } function printPrefixedLines(lines) { const existingLines = lines.filter(([_, line]) => line !== void 0); const padLen = Math.max(...existingLines.map(([prefix]) => prefix.length)); return existingLines.map(([prefix, line]) => prefix.padStart(padLen) + (line ? " " + line : "")).join("\n"); } // ../../node_modules/.pnpm/graphql@16.9.0/node_modules/graphql/error/GraphQLError.mjs function toNormalizedOptions(args) { const firstArg = args[0]; if (firstArg == null || "kind" in firstArg || "length" in firstArg) { return { nodes: firstArg, source: args[1], positions: args[2], path: args[3], originalError: args[4], extensions: args[5] }; } return firstArg; } var GraphQLError = class _GraphQLError extends Error { /** * An array of `{ line, column }` locations within the source GraphQL document * which correspond to this error. * * Errors during validation often contain multiple locations, for example to * point out two things with the same name. Errors during execution include a * single location, the field which produced the error. * * Enumerable, and appears in the result of JSON.stringify(). */ /** * An array describing the JSON-path into the execution response which * corresponds to this error. Only included for errors during execution. * * Enumerable, and appears in the result of JSON.stringify(). */ /** * An array of GraphQL AST Nodes corresponding to this error. */ /** * The source GraphQL document for the first location of this error. * * Note that if this Error represents more than one node, the source may not * represent nodes after the first node. */ /** * An array of character offsets within the source GraphQL document * which correspond to this error. */ /** * The original error thrown from a field resolver during execution. */ /** * Extension fields to add to the formatted error. */ /** * @deprecated Please use the `GraphQLErrorOptions` constructor overload instead. */ constructor(message, ...rawArgs) { var _this$nodes, _nodeLocations$, _ref; const { nodes, source, positions, path, originalError, extensions } = toNormalizedOptions(rawArgs); super(message); this.name = "GraphQLError"; this.path = path !== null && path !== void 0 ? path : void 0; this.originalError = originalError !== null && originalError !== void 0 ? originalError : void 0; this.nodes = undefinedIfEmpty( Array.isArray(nodes) ? nodes : nodes ? [nodes] : void 0 ); const nodeLocations = undefinedIfEmpty( (_this$nodes = this.nodes) === null || _this$nodes === void 0 ? void 0 : _this$nodes.map((node) => node.loc).filter((loc) => loc != null) ); this.source = source !== null && source !== void 0 ? source : nodeLocations === null || nodeLocations === void 0 ? void 0 : (_nodeLocations$ = nodeLocations[0]) === null || _nodeLocations$ === void 0 ? void 0 : _nodeLocations$.source; this.positions = positions !== null && positions !== void 0 ? positions : nodeLocations === null || nodeLocations === void 0 ? void 0 : nodeLocations.map((loc) => loc.start); this.locations = positions && source ? positions.map((pos) => getLocation(source, pos)) : nodeLocations === null || nodeLocations === void 0 ? void 0 : nodeLocations.map((loc) => getLocation(loc.source, loc.start)); const originalExtensions = isObjectLike( originalError === null || originalError === void 0 ? void 0 : originalError.extensions ) ? originalError === null || originalError === void 0 ? void 0 : originalError.extensions : void 0; this.extensions = (_ref = extensions !== null && extensions !== void 0 ? extensions : originalExtensions) !== null && _ref !== void 0 ? _ref : /* @__PURE__ */ Object.create(null); Object.defineProperties(this, { message: { writable: true, enumerable: true }, name: { enumerable: false }, nodes: { enumerable: false }, source: { enumerable: false }, positions: { enumerable: false }, originalError: { enumerable: false } }); if (originalError !== null && originalError !== void 0 && originalError.stack) { Object.defineProperty(this, "stack", { value: originalError.stack, writable: true, configurable: true }); } else if (Error.captureStackTrace) { Error.captureStackTrace(this, _GraphQLError); } else { Object.defineProperty(this, "stack", { value: Error().stack, writable: true, configurable: true }); } } get [Symbol.toStringTag]() { return "GraphQLError"; } toString() { let output = this.message; if (this.nodes) { for (const node of this.nodes) { if (node.loc) { output += "\n\n" + printLocation(node.loc); } } } else if (this.source && this.locations) { for (const location of this.locations) { output += "\n\n" + printSourceLocation(this.source, location); } } return output; } toJSON() { const formattedError = { message: this.message }; if (this.locations != null) { formattedError.locations = this.locations; } if (this.path != null) { formattedError.path = this.path; } if (this.extensions != null && Object.keys(this.extensions).length > 0) { formattedError.extensions = this.extensions; } return formattedError; } }; function undefinedIfEmpty(array) { return array === void 0 || array.length === 0 ? void 0 : array; } // ../../node_modules/.pnpm/graphql@16.9.0/node_modules/graphql/language/characterClasses.mjs function isDigit(code) { return code >= 48 && code <= 57; } function isLetter(code) { return code >= 97 && code <= 122 || // A-Z code >= 65 && code <= 90; } function isNameStart(code) { return isLetter(code) || code === 95; } function isNameContinue(code) { return isLetter(code) || isDigit(code) || code === 95; } // ../../node_modules/.pnpm/graphql@16.9.0/node_modules/graphql/jsutils/inspect.mjs var MAX_ARRAY_LENGTH = 10; var MAX_RECURSIVE_DEPTH = 2; function inspect(value) { return formatValue(value, []); } function formatValue(value, seenValues) { switch (typeof value) { case "string": return JSON.stringify(value); case "function": return value.name ? `[function ${value.name}]` : "[function]"; case "object": return formatObjectValue(value, seenValues); default: return String(value); } } function formatObjectValue(value, previouslySeenValues) { if (value === null) { return "null"; } if (previouslySeenValues.includes(value)) { return "[Circular]"; } const seenValues = [...previouslySeenValues, value]; if (isJSONable(value)) { const jsonValue = value.toJSON(); if (jsonValue !== value) { return typeof jsonValue === "string" ? jsonValue : formatValue(jsonValue, seenValues); } } else if (Array.isArray(value)) { return formatArray(value, seenValues); } return formatObject(value, seenValues); } function isJSONable(value) { return typeof value.toJSON === "function"; } function formatObject(object, seenValues) { const entries = Object.entries(object); if (entries.length === 0) { return "{}"; } if (seenValues.length > MAX_RECURSIVE_DEPTH) { return "[" + getObjectTag(object) + "]"; } const properties = entries.map( ([key, value]) => key + ": " + formatValue(value, seenValues) ); return "{ " + properties.join(", ") + " }"; } function formatArray(array, seenValues) { if (array.length === 0) { return "[]"; } if (seenValues.length > MAX_RECURSIVE_DEPTH) { return "[Array]"; } const len = Math.min(MAX_ARRAY_LENGTH, array.length); const remaining = array.length - len; const items = []; for (let i = 0; i < len; ++i) { items.push(formatValue(array[i], seenValues)); } if (remaining === 1) { items.push("... 1 more item"); } else if (remaining > 1) { items.push(`... ${remaining} more items`); } return "[" + items.join(", ") + "]"; } function getObjectTag(object) { const tag = Object.prototype.toString.call(object).replace(/^\[object /, "").replace(/]$/, ""); if (tag === "Object" && typeof object.constructor === "function") { const name = object.constructor.name; if (typeof name === "string" && name !== "") { return name; } } return tag; } // ../../node_modules/.pnpm/graphql@16.9.0/node_modules/graphql/jsutils/instanceOf.mjs var isProduction = globalThis.process && // eslint-disable-next-line no-undef process.env.NODE_ENV === "production"; var instanceOf = ( /* c8 ignore next 6 */ // FIXME: https://github.com/graphql/graphql-js/issues/2317 isProduction ? function instanceOf2(value, constructor) { return value instanceof constructor; } : function instanceOf3(value, constructor) { if (value instanceof constructor) { return true; } if (typeof value === "object" && value !== null) { var _value$constructor; const className = constructor.prototype[Symbol.toStringTag]; const valueClassName = ( // We still need to support constructor's name to detect conflicts with older versions of this library. Symbol.toStringTag in value ? value[Symbol.toStringTag] : (_value$constructor = value.constructor) === null || _value$constructor === void 0 ? void 0 : _value$constructor.name ); if (className === valueClassName) { const stringifiedValue = inspect(value); throw new Error(`Cannot use ${className} "${stringifiedValue}" from another module or realm. Ensure that there is only one instance of "graphql" in the node_modules directory. If different versions of "graphql" are the dependencies of other relied on modules, use "resolutions" to ensure only one version is installed. https://yarnpkg.com/en/docs/selective-version-resolutions Duplicate "graphql" modules cannot be used at the same time since different versions may have different capabilities and behavior. The data from one version used in the function from another could produce confusing and spurious results.`); } } return false; } ); // ../../node_modules/.pnpm/graphql@16.9.0/node_modules/graphql/jsutils/keyValMap.mjs function keyValMap(list, keyFn, valFn) { const result = /* @__PURE__ */ Object.create(null); for (const item of list) { result[keyFn(item)] = valFn(item); } return result; } // ../../node_modules/.pnpm/graphql@16.9.0/node_modules/graphql/jsutils/mapValue.mjs function mapValue(map, fn) { const result = /* @__PURE__ */ Object.create(null); for (const key of Object.keys(map)) { result[key] = fn(map[key], key); } return result; } // ../../node_modules/.pnpm/graphql@16.9.0/node_modules/graphql/jsutils/toObjMap.mjs function toObjMap(obj) { if (obj == null) { return /* @__PURE__ */ Object.create(null); } if (Object.getPrototypeOf(obj) === null) { return obj; } const map = /* @__PURE__ */ Object.create(null); for (const [key, value] of Object.entries(obj)) { map[key] = value; } return map; } // ../../node_modules/.pnpm/graphql@16.9.0/node_modules/graphql/type/assertName.mjs function assertName(name) { name != null || devAssert(false, "Must provide name."); typeof name === "string" || devAssert(false, "Expected name to be a string."); if (name.length === 0) { throw new GraphQLError("Expected name to be a non-empty string."); } for (let i = 1; i < name.length; ++i) { if (!isNameContinue(name.charCodeAt(i))) { throw new GraphQLError( `Names must only contain [_a-zA-Z0-9] but "${name}" does not.` ); } } if (!isNameStart(name.charCodeAt(0))) { throw new GraphQLError( `Names must start with [_a-zA-Z] but "${name}" does not.` ); } return name; } // ../../node_modules/.pnpm/graphql@16.9.0/node_modules/graphql/type/definition.mjs function isObjectType(type) { return instanceOf(type, GraphQLObjectType); } function isInterfaceType(type) { return instanceOf(type, GraphQLInterfaceType); } function resolveReadonlyArrayThunk(thunk) { return typeof thunk === "function" ? thunk() : thunk; } function resolveObjMapThunk(thunk) { return typeof thunk === "function" ? thunk() : thunk; } var GraphQLObjectType = class { constructor(config) { var _config$extensionASTN2; this.name = assertName(config.name); this.description = config.description; this.isTypeOf = config.isTypeOf; this.extensions = toObjMap(config.extensions); this.astNode = config.astNode; this.extensionASTNodes = (_config$extensionASTN2 = config.extensionASTNodes) !== null && _config$extensionASTN2 !== void 0 ? _config$extensionASTN2 : []; this._fields = () => defineFieldMap(config); this._interfaces = () => defineInterfaces(config); config.isTypeOf == null || typeof config.isTypeOf === "function" || devAssert( false, `${this.name} must provide "isTypeOf" as a function, but got: ${inspect(config.isTypeOf)}.` ); } get [Symbol.toStringTag]() { return "GraphQLObjectType"; } getFields() { if (typeof this._fields === "function") { this._fields = this._fields(); } return this._fields; } getInterfaces() { if (typeof this._interfaces === "function") { this._interfaces = this._interfaces(); } return this._interfaces; } toConfig() { return { name: this.name, description: this.description, interfaces: this.getInterfaces(), fields: fieldsToFieldsConfig(this.getFields()), isTypeOf: this.isTypeOf, extensions: this.extensions, astNode: this.astNode, extensionASTNodes: this.extensionASTNodes }; } toString() { return this.name; } toJSON() { return this.toString(); } }; function defineInterfaces(config) { var _config$interfaces; const interfaces = resolveReadonlyArrayThunk( (_config$interfaces = config.interfaces) !== null && _config$interfaces !== void 0 ? _config$interfaces : [] ); Array.isArray(interfaces) || devAssert( false, `${config.name} interfaces must be an Array or a function which returns an Array.` ); return interfaces; } function defineFieldMap(config) { const fieldMap = resolveObjMapThunk(config.fields); isPlainObj(fieldMap) || devAssert( false, `${config.name} fields must be an object with field names as keys or a function which returns such an object.` ); return mapValue(fieldMap, (fieldConfig, fieldName) => { var _fieldConfig$args; isPlainObj(fieldConfig) || devAssert( false, `${config.name}.${fieldName} field config must be an object.` ); fieldConfig.resolve == null || typeof fieldConfig.resolve === "function" || devAssert( false, `${config.name}.${fieldName} field resolver must be a function if provided, but got: ${inspect(fieldConfig.resolve)}.` ); const argsConfig = (_fieldConfig$args = fieldConfig.args) !== null && _fieldConfig$args !== void 0 ? _fieldConfig$args : {}; isPlainObj(argsConfig) || devAssert( false, `${config.name}.${fieldName} args must be an object with argument names as keys.` ); return { name: assertName(fieldName), description: fieldConfig.description, type: fieldConfig.type, args: defineArguments(argsConfig), resolve: fieldConfig.resolve, subscribe: fieldConfig.subscribe, deprecationReason: fieldConfig.deprecationReason, extensions: toObjMap(fieldConfig.extensions), astNode: fieldConfig.astNode }; }); } function defineArguments(config) { return Object.entries(config).map(([argName, argConfig]) => ({ name: assertName(argName), description: argConfig.description, type: argConfig.type, defaultValue: argConfig.defaultValue, deprecationReason: argConfig.deprecationReason, extensions: toObjMap(argConfig.extensions), astNode: argConfig.astNode })); } function isPlainObj(obj) { return isObjectLike(obj) && !Array.isArray(obj); } function fieldsToFieldsConfig(fields) { return mapValue(fields, (field) => ({ description: field.description, type: field.type, args: argsToArgsConfig(field.args), resolve: field.resolve, subscribe: field.subscribe, deprecationReason: field.deprecationReason, extensions: field.extensions, astNode: field.astNode })); } function argsToArgsConfig(args) { return keyValMap( args, (arg) => arg.name, (arg) => ({ description: arg.description, type: arg.type, defaultValue: arg.defaultValue, deprecationReason: arg.deprecationReason, extensions: arg.extensions, astNode: arg.astNode }) ); } var GraphQLInterfaceType = class { constructor(config) { var _config$extensionASTN3; this.name = assertName(config.name); this.description = config.description; this.resolveType = config.resolveType; this.extensions = toObjMap(config.extensions); this.astNode = config.astNode; this.extensionASTNodes = (_config$extensionASTN3 = config.extensionASTNodes) !== null && _config$extensionASTN3 !== void 0 ? _config$extensionASTN3 : []; this._fields = defineFieldMap.bind(void 0, config); this._interfaces = defineInterfaces.bind(void 0, config); config.resolveType == null || typeof config.resolveType === "function" || devAssert( false, `${this.name} must provide "resolveType" as a function, but got: ${inspect(config.resolveType)}.` ); } get [Symbol.toStringTag]() { return "GraphQLInterfaceType"; } getFields() { if (typeof this._fields === "function") { this._fields = this._fields(); } return this._fields; } getInterfaces() { if (typeof this._interfaces === "function") { this._interfaces = this._interfaces(); } return this._interfaces; } toConfig() { return { name: this.name, description: this.description, interfaces: this.getInterfaces(), fields: fieldsToFieldsConfig(this.getFields()), resolveType: this.resolveType, extensions: this.extensions, astNode: this.astNode, extensionASTNodes: this.extensionASTNodes }; } toString() { return this.name; } toJSON() { return this.toString(); } }; // src/editor/schema-editor.tsx import MonacoEditor2 from "@monaco-editor/react"; // src/editor/use-schema-services.ts import { useEffect as useEffect3, useMemo as useMemo2, useState as useState3 } from "react"; var useSchemaServices = (options = {}) => { const [editorRef, setEditorRef] = useState3(null); const [monacoRef, setMonacoRef] = useState3(null); const languageService = useMemo2( () => options.sharedLanguageService || new EnrichedLanguageService({ schemaString: options.schema, schemaConfig: { buildSchemaOptions: { assumeValid: true, assumeValidSDL: true } } }), [options.sharedLanguageService] ); useEffect3(() => { if (monacoRef && editorRef) { if (options.keyboardShortcuts) { for (const action of options.keyboardShortcuts(editorRef, monacoRef)) { editorRef.addAction(action); } } for (const action of options.actions || []) { editorRef.addAction({ id: action.id, label: action.label, keybindings: action.keybindings, contextMenuGroupId: action.contextMenuGroupId || "navigation", contextMenuOrder: action.contextMenuOrder, async run(editor) { const model = editor.getModel(); const position = editor.getPosition(); if (model && position) { const bridge = await languageService.buildBridgeForProviders(model, position); if (bridge) { action.onRun({ editor: editorRef, monaco: monacoRef, bridge }); } } } }); } const handler = languageService.getModelChangeHandler(); handler( editorRef, monacoRef, options.diagnosticsProviders || [], options.decorationsProviders || [] ); const onChangeDisposable = editorRef.onDidChangeModelContent( () => handler( editorRef, monacoRef, options.diagnosticsProviders || [], options.decorationsProviders || [] ) ); const definitionProviderDisposable = monacoRef.languages.registerDefinitionProvider( "graphql", languageService.getDefinitionProvider(options.definitionProviders || []) ); const hoverDisposable = monacoRef.languages.registerHoverProvider( "graphql", languageService.getHoverProvider(options.hoverProviders || []) ); return () => { hoverDisposable == null ? void 0 : hoverDisposable.dispose(); definitionProviderDisposable == null ? void 0 : definitionProviderDisposable.dispose(); onChangeDisposable == null ? void 0 : onChangeDisposable.dispose(); }; } }, [editorRef, monacoRef]); return { setEditor: setEditorRef, setMonaco: setMonacoRef, editorRef, monacoRef, languageService, setSchema: (newValue) => languageService.trySchema(newValue), editorApi: { jumpToType: (typeName) => { languageService.getSchemaSafe().then((schema) => { var _a; if (schema) { const type = schema.getType(typeName); if ((_a = type == null ? void 0 : type.astNode) == null ? void 0 : _a.loc) { const range = locToRange(type.astNode.loc); editorRef == null ? void 0 : editorRef.setSelection(range); editorRef == null ? void 0 : editorRef.revealPositionInCenter( { column: 0, lineNumber: range.startLineNumber }, 0 ); } } }); }, jumpToField(typeName, fieldName) { languageService.getSchemaSafe().then((schema) => { var _a; if (schema) { const type = schema.getType(typeName); if (type && (isObjectType(type) || isInterfaceType(type))) { const field = type.getFields()[fieldName]; if ((_a = field == null ? void 0 : field.astNode) == null ? void 0 : _a.loc) { const range = locToRange(field.astNode.loc); editorRef == null ? void 0 : editorRef.setSelection(range); editorRef == null ? void 0 : editorRef.revealPositionInCenter( { column: 0, lineNumber: range.startLineNumber }, 0 ); } } } }); }, deselect: () => editorRef == null ? void 0 : editorRef.setSelection(emptyLocation) } }; }; // src/editor/schema-editor.tsx import { jsx as jsx2 } from "react/jsx-runtime"; function BaseSchemaEditor(props, ref) { const { resolvedTheme } = z(); const { languageService, setMonaco, setEditor, editorApi, editorRef, setSchema } = useSchemaServices(props); useImperativeHandle(ref, () => editorApi, [editorRef, languageService]); useEffect4(() => { var _a; if (languageService) { (_a = props.onLanguageServiceReady) == null ? void 0 : _a.call(props, languageService); } }, [languageService, props.onLanguageServiceReady]); const [onBlurHandler, setOnBlurHandler] = useState4(); useEffect4(() => { if (editorRef && props.onBlur) { onBlurHandler == null ? void 0 : onBlurHandler.dispose(); const subscription = editorRef.onDidBlurEditorText(() => { var _a; (_a = props.onBlur) == null ? void 0 : _a.call(props, editorRef.getValue() || ""); }); setOnBlurHandler(subscription); } }, [props.onBlur, editorRef]); const handleBeforeMount = useCallback2( (monaco) => { var _a; setMonaco(monaco); (_a = props.beforeMount) == null ? void 0 : _a.call(props, monaco); }, [props.beforeMount] ); const handleMount = useCallback2( (editor, monaco) => { var _a; setEditor(editor); (_a = props.onMount) == null ? void 0 : _a.call(props, editor, monaco); }, [props.onMount] ); const handleChange = useCallback2( async (newValue, ev) => { var _a, _b; (_a = props.onChange) == null ? void 0 : _a.call(props, newValue, ev); if (!newValue) { return; } try { const schema = await setSchema(newValue); if (schema) { (_b = props.onSchemaChange) == null ? void 0 : _b.call(props, schema, newValue); } } catch (e) { if (!props.onSchemaError) { return; } const error = e instanceof GraphQLError ? e : new GraphQLError( e.message, void 0, void 0, void 0, void 0, e ); props.onSchemaError([error], newValue, languageService); } }, [props.onChange, props.onSchemaChange, props.onSchemaError] ); return /* @__PURE__ */ jsx2( MonacoEditor2, { height: "70vh", theme: resolvedTheme === "dark" ? "vs-dark" : "light", ...props, beforeMount: handleBeforeMount, onMount: handleMount, onChange: handleChange, options: { glyphMargin: true, ...props.options }, language: "graphql", defaultValue: props.defaultValue || props.schema } ); } var SchemaEditor = forwardRef(BaseSchemaEditor); export { EnrichedLanguageService, ExecutableDocumentEditor, SchemaEditor, coreDefinitionSource, coreDiagnosticsSource, coreHoverSource, debugHoverSource, emptyLocation, getRange, locToRange, removeFalsey, showWidgetInPosition, toGraphQLPosition, toMarkerData, toMonacoRange };