@graphiql/plugin-doc-explorer
Version:
280 lines (279 loc) • 7.47 kB
JavaScript
import { jsx } from "react/jsx-runtime";
import { c } from "react-compiler-runtime";
import { isNamedType, isObjectType, isInputObjectType, isScalarType, isEnumType, isInterfaceType, isUnionType } from "graphql";
import { useEffect } from "react";
import { pick, useGraphiQL, createBoundedUseStore, DocsFilledIcon, DocsIcon, isMacOs } from "@graphiql/react";
import { createStore } from "zustand";
import { getSchemaReference } from "./schema-reference.js";
import { DocExplorer } from "./components/doc-explorer.js";
const DOC_EXPLORER_PLUGIN = {
title: "Documentation Explorer",
icon: function Icon() {
const visiblePlugin = useGraphiQL((state) => state.visiblePlugin);
return visiblePlugin === DOC_EXPLORER_PLUGIN ? /* @__PURE__ */ jsx(DocsFilledIcon, {}) : /* @__PURE__ */ jsx(DocsIcon, {});
},
content: DocExplorer
};
const INITIAL_NAV_STACK = [{
name: "Docs"
}];
const docExplorerStore = createStore((set, get) => ({
explorerNavStack: INITIAL_NAV_STACK,
actions: {
push(item) {
set((state) => {
const curr = state.explorerNavStack;
const lastItem = curr.at(-1);
const explorerNavStack = (
// Avoid pushing duplicate items
lastItem.def === item.def ? curr : [...curr, item]
);
return {
explorerNavStack
};
});
},
pop() {
set((state) => {
const curr = state.explorerNavStack;
const explorerNavStack = curr.length > 1 ? curr.slice(0, -1) : curr;
return {
explorerNavStack
};
});
},
reset() {
set((state) => {
const curr = state.explorerNavStack;
const explorerNavStack = curr.length === 1 ? curr : INITIAL_NAV_STACK;
return {
explorerNavStack
};
});
},
resolveSchemaReferenceToNavItem(schemaReference) {
if (!schemaReference) {
return;
}
const {
kind,
typeInfo
} = schemaReference;
const ref = getSchemaReference(kind, typeInfo);
if (!ref) {
return;
}
const {
push
} = get().actions;
switch (ref.kind) {
case "Type": {
push({
name: ref.type.name,
def: ref.type
});
break;
}
case "Field": {
if (ref.type) {
push({
name: ref.type.name,
def: ref.type
});
}
push({
name: ref.field.name,
def: ref.field
});
break;
}
case "Argument": {
if (ref.field) {
push({
name: ref.field.name,
def: ref.field
});
}
break;
}
case "EnumValue": {
if (ref.type) {
push({
name: ref.type.name,
def: ref.type
});
}
break;
}
}
},
rebuildNavStackWithSchema(schema) {
set((state) => {
const oldNavStack = state.explorerNavStack;
if (oldNavStack.length === 1) {
return state;
}
const newNavStack = [...INITIAL_NAV_STACK];
let lastEntity = null;
for (const item of oldNavStack) {
if (item === INITIAL_NAV_STACK[0]) {
continue;
}
if (item.def) {
if (isNamedType(item.def)) {
const newType = schema.getType(item.def.name);
if (newType) {
newNavStack.push({
name: item.name,
def: newType
});
lastEntity = newType;
} else {
break;
}
} else if (lastEntity === null) {
break;
} else if (isObjectType(lastEntity) || isInputObjectType(lastEntity)) {
const field = lastEntity.getFields()[item.name];
if (field) {
newNavStack.push({
name: item.name,
def: field
});
} else {
break;
}
} else if (isScalarType(lastEntity) || isEnumType(lastEntity) || isInterfaceType(lastEntity) || isUnionType(lastEntity)) {
break;
} else {
const field = lastEntity;
if (field.args.some((a) => a.name === item.name)) {
newNavStack.push({
name: item.name,
def: field
});
} else {
break;
}
}
} else {
lastEntity = null;
newNavStack.push(item);
}
}
return {
explorerNavStack: newNavStack
};
});
}
}
}));
const DocExplorerStore = (t0) => {
const $ = c(9);
const {
children
} = t0;
let t1;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t1 = pick("schema", "validationErrors", "schemaReference");
$[0] = t1;
} else {
t1 = $[0];
}
const {
schema,
validationErrors,
schemaReference
} = useGraphiQL(t1);
let t2;
let t3;
if ($[1] !== schemaReference) {
t2 = () => {
const {
resolveSchemaReferenceToNavItem
} = docExplorerStore.getState().actions;
resolveSchemaReferenceToNavItem(schemaReference);
};
t3 = [schemaReference];
$[1] = schemaReference;
$[2] = t2;
$[3] = t3;
} else {
t2 = $[2];
t3 = $[3];
}
useEffect(t2, t3);
let t4;
let t5;
if ($[4] !== schema || $[5] !== validationErrors) {
t4 = () => {
const {
reset,
rebuildNavStackWithSchema
} = docExplorerStore.getState().actions;
if (schema == null || validationErrors.length > 0) {
reset();
} else {
rebuildNavStackWithSchema(schema);
}
};
t5 = [schema, validationErrors];
$[4] = schema;
$[5] = validationErrors;
$[6] = t4;
$[7] = t5;
} else {
t4 = $[6];
t5 = $[7];
}
useEffect(t4, t5);
let t6;
if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
t6 = [];
$[8] = t6;
} else {
t6 = $[8];
}
useEffect(_temp2, t6);
return children;
};
const useDocExplorerStore = createBoundedUseStore(docExplorerStore);
const useDocExplorer = () => {
return useDocExplorerStore(_temp3);
};
const useDocExplorerActions = () => {
return useDocExplorerStore(_temp4);
};
function _temp() {
const el = document.querySelector(".graphiql-doc-explorer-search-input");
el == null ? void 0 : el.click();
}
function _temp2() {
const handleKeyDown = function handleKeyDown2(event) {
const shouldFocusInput = event.altKey && event[isMacOs ? "metaKey" : "ctrlKey"] && event.code === "KeyK";
if (!shouldFocusInput) {
return;
}
const button = document.querySelector('.graphiql-sidebar button[aria-label="Show Documentation Explorer"]');
button == null ? void 0 : button.click();
requestAnimationFrame(_temp);
};
window.addEventListener("keydown", handleKeyDown);
return () => {
window.removeEventListener("keydown", handleKeyDown);
};
}
function _temp3(state) {
return state.explorerNavStack;
}
function _temp4(state) {
return state.actions;
}
export {
DOC_EXPLORER_PLUGIN,
DocExplorerStore,
docExplorerStore,
useDocExplorer,
useDocExplorerActions
};
//# sourceMappingURL=context.js.map