Refactor playground to use Vue (#18463)

Co-authored-by: fisker <172584+fisker@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
authored and GitHub committed 2025-12-10 23:48:10 +08:00
1 parent 1cc6367856
commit 8a0f687f6e
21 files changed
+851 -914

No files matched your search

-5
View File
@@ -33,7 +33,6 @@
matchPackageNames: [
"eslint",
"@eslint/*",
"@eslint-react/eslint-plugin",
"@stylistic/eslint-plugin",
"eslint-config-prettier",
"eslint-plugin-compat",
@@ -75,10 +74,6 @@
groupName: "GitHub Actions",
matchManagers: ["github-actions"],
},
{
matchPackageNames: ["react", "react-dom"],
allowedVersions: "^18.0.0",
},
{
groupName: "docusaurus",
matchPackageNames: ["@docusaurus/*"],
+5 -8
View File
@@ -1,6 +1,5 @@
import url from "node:url";
import eslintPluginJs from "@eslint/js";
import eslintPluginEslintReact from "@eslint-react/eslint-plugin";
import eslintPluginStylistic from "@stylistic/eslint-plugin";
import eslintPluginTypescriptEslint from "@typescript-eslint/eslint-plugin";
import { isCI } from "ci-info";
@@ -457,8 +456,11 @@ const configs = [
},
},
{
files: ["website/**/*"],
...eslintPluginEslintReact.configs.recommended,
files: ["website/src/pages/**/*.jsx", "website/playground/**/*.jsx"],
rules: {
// Doesn't know JSX
"no-unused-vars": "off",
},
},
{
files: ["website/**/*"],
@@ -470,11 +472,6 @@ const configs = [
},
},
},
settings: {
"react-x": {
version: "18",
},
},
rules: {
"unicorn/filename-case": "off",
},
-1
View File
@@ -124,7 +124,6 @@
},
"devDependencies": {
"@babel/generator": "8.0.0-beta.3",
"@eslint-react/eslint-plugin": "2.3.9",
"@eslint/js": "9.39.1",
"@stylistic/eslint-plugin": "5.6.1",
"@types/jsesc": "3.0.3",
-12
View File
@@ -156,18 +156,6 @@
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.production.min.js"
integrity="sha512-QVs8Lo43F9lSuBykadDb0oSXDL/BbZ588urWVCRwSIoewQv/Ewg1f84mK3U790bZ0FfhFa1YSQUmIhG+pIRKeg=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js"
integrity="sha512-6a1107rTlA4gYpgHAqbwLAtxmWipBdJFcq8y5S/aTge3Bp+VAklABm2LO+Kg51vOWR9JMZq1Ovjl5tpluNpTeQ=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<link rel="stylesheet" href="./playground/playground.css" />
<!-- Google tag (gtag.js) -->
+6 -3
View File
@@ -21,19 +21,22 @@
"@sandhose/prettier-animated-logo": "1.0.3",
"clsx": "2.1.1",
"codemirror-graphql": "2.2.4",
"graphql": "16.12.0",
"prism-react-renderer": "2.4.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-markdown": "10.1.0",
"react-tweet": "3.2.2"
"react-tweet": "3.2.2",
"vue": "3.5.25"
},
"devDependencies": {
"@docusaurus/faster": "3.9.2",
"@docusaurus/module-type-aliases": "3.9.2",
"@docusaurus/types": "3.9.2",
"@vitejs/plugin-react": "5.1.1",
"@vitejs/plugin-vue": "6.0.2",
"@vitejs/plugin-vue-jsx": "5.1.2",
"concurrently": "9.2.1",
"vite": "7.2.4",
"vite": "7.2.7",
"yaml": "2.8.2"
},
"browserslist": {
+29 -29
View File
@@ -1,12 +1,13 @@
import { shallowEqual, stateToggler } from "./helpers.js";
import { reactive, watch } from "vue";
import * as storage from "./storage.js";
const { React } = window;
export default class EditorState extends React.Component {
constructor() {
super();
this.state = {
export default {
name: "EditorState",
setup(_, { slots }) {
const stateToggler = (property) => () => {
state[property] = !state[property];
};
const state = reactive({
showSidebar: window.innerWidth > window.innerHeight,
showAst: false,
showPreprocessedAst: false,
@@ -16,28 +17,27 @@ export default class EditorState extends React.Component {
showInput: true,
showOutput: true,
rethrowEmbedErrors: false,
toggleSidebar: () => this.setState(stateToggler("showSidebar")),
toggleAst: () => this.setState(stateToggler("showAst")),
togglePreprocessedAst: () =>
this.setState(stateToggler("showPreprocessedAst")),
toggleDoc: () => this.setState(stateToggler("showDoc")),
toggleComments: () => this.setState(stateToggler("showComments")),
toggleSecondFormat: () => this.setState(stateToggler("showSecondFormat")),
toggleInput: () => this.setState(stateToggler("showInput")),
toggleOutput: () => this.setState(stateToggler("showOutput")),
toggleEmbedErrors: () =>
this.setState(stateToggler("rethrowEmbedErrors")),
toggleSidebar: stateToggler("showSidebar"),
toggleAst: stateToggler("showAst"),
togglePreprocessedAst: stateToggler("showPreprocessedAst"),
toggleDoc: stateToggler("showDoc"),
toggleComments: stateToggler("showComments"),
toggleSecondFormat: stateToggler("showSecondFormat"),
toggleInput: stateToggler("showInput"),
toggleOutput: stateToggler("showOutput"),
toggleEmbedErrors: stateToggler("rethrowEmbedErrors"),
...storage.get("editor_state"),
};
}
});
componentDidUpdate(_, prevState) {
if (!shallowEqual(this.state, prevState)) {
storage.set("editor_state", this.state);
}
}
const render = () => slots.default(state);
render() {
return this.props.children(this.state);
}
}
watch(
() => state,
() => {
storage.set("editor_state", state);
},
{ deep: true },
);
return render;
},
};
+156 -156
View File
@@ -1,8 +1,8 @@
import { reactive, watch } from "vue";
import { Button, ClipboardButton } from "./buttons.jsx";
import getCodeSample from "./codeSamples.mjs";
import generateDummyId from "./dummyId.js";
import EditorState from "./EditorState.js";
import { shallowEqual } from "./helpers.js";
import formatMarkdown from "./markdown.js";
import { DebugPanel, InputPanel, OutputPanel } from "./panels.jsx";
import PrettierFormat from "./PrettierFormat.js";
@@ -20,8 +20,6 @@ import {
getDefaults,
} from "./utilities.js";
const { React } = window;
const CATEGORIES_ORDER = [
"Global",
"Common",
@@ -63,124 +61,108 @@ const ENABLED_OPTIONS = [
"experimentalOperatorPosition",
];
class Playground extends React.Component {
constructor(props) {
super();
function setup(props) {
const original = urlHash.read();
const original = urlHash.read();
const defaultOptions = getDefaults(props.availableOptions, ENABLED_OPTIONS);
const defaultOptions = getDefaults(props.availableOptions, ENABLED_OPTIONS);
const options = Object.assign(defaultOptions, original.options);
const options = Object.assign(defaultOptions, original.options);
// 0.0.0 ~ 0.0.10
if (options.parser === "babylon") {
options.parser = "babel";
}
// 0.0.0 ~ 0.0.10
if (options.parser === "babylon") {
options.parser = "babel";
}
// 0.0.0 ~ 0.0.10
if (options.useFlowParser) {
options.parser ??= "flow";
}
// 0.0.0 ~ 0.0.10
if (options.useFlowParser) {
options.parser ??= "flow";
}
// 1.8.2 ~ 1.9.0
if (typeof options.proseWrap === "boolean") {
options.proseWrap = options.proseWrap ? "always" : "never";
}
// 1.8.2 ~ 1.9.0
if (typeof options.proseWrap === "boolean") {
options.proseWrap = options.proseWrap ? "always" : "never";
}
// 0.0.0 ~ 1.9.0
if (typeof options.trailingComma === "boolean") {
options.trailingComma = options.trailingComma ? "es5" : "none";
}
// 0.0.0 ~ 1.9.0
if (typeof options.trailingComma === "boolean") {
options.trailingComma = options.trailingComma ? "es5" : "none";
}
// 0.17.0 ~ 2.4.0
if (options.jsxBracketSameLine) {
delete options.jsxBracketSameLine;
options.bracketSameLine ??= options.jsxBracketSameLine;
}
// 0.17.0 ~ 2.4.0
if (options.jsxBracketSameLine) {
delete options.jsxBracketSameLine;
options.bracketSameLine ??= options.jsxBracketSameLine;
}
const codeSample = getCodeSample(options.parser);
const content = original.content || codeSample;
const codeSample = getCodeSample(options.parser);
const content = original.content || codeSample;
const selection = {};
const state = reactive({ content, options, selection: {} });
this.state = { content, options, selection };
const setContent = (content) => {
state.content = content;
};
this.handleOptionValueChange = this.handleOptionValueChange.bind(this);
const clearContent = () => {
state.content = "";
};
this.setContent = (content) => this.setState({ content });
this.clearContent = this.setContent.bind(this, "");
this.resetOptions = () => this.setState({ options: defaultOptions });
this.setSelection = (selection) => {
this.setState({ selection });
if (this.state.trackCursorOffset) {
this.handleOptionValueChange(
this.cursorOffsetOption,
convertSelectionToRange(selection, this.state.content)[0],
);
}
};
this.setSelectionAsRange = () => {
const { selection, content, options } = this.state;
const [rangeStart, rangeEnd] = convertSelectionToRange(
selection,
content,
const resetOptions = () => {
Object.assign(state, { options: { ...defaultOptions } });
};
const setSelection = (selection) => {
Object.assign(state, { selection });
if (state.trackCursorOffset) {
handleOptionValueChange(
cursorOffsetOption,
convertSelectionToRange(selection, state.content)[0],
);
const updatedOptions = { ...options, rangeStart, rangeEnd };
if (rangeStart === rangeEnd) {
delete updatedOptions.rangeStart;
delete updatedOptions.rangeEnd;
}
this.setState({ options: updatedOptions });
};
this.enabledOptions = orderOptions(props.availableOptions, ENABLED_OPTIONS);
this.rangeStartOption = props.availableOptions.find(
(opt) => opt.name === "rangeStart",
);
this.rangeEndOption = props.availableOptions.find(
(opt) => opt.name === "rangeEnd",
);
this.cursorOffsetOption = props.availableOptions.find(
(opt) => opt.name === "cursorOffset",
);
this.formatInput = this.formatInput.bind(this);
this.insertDummyId = this.insertDummyId.bind(this);
}
componentDidUpdate(_, prevState) {
const { content, options } = this.state;
if (
!shallowEqual(prevState.options, this.state.options) ||
prevState.content !== content
) {
urlHash.replace({ content, options });
}
}
};
handleOptionValueChange(option, value) {
this.setState((state) => {
const options = { ...state.options };
const setSelectionAsRange = () => {
const { selection, content, options } = state;
const [rangeStart, rangeEnd] = convertSelectionToRange(selection, content);
const updatedOptions = { ...options, rangeStart, rangeEnd };
if (rangeStart === rangeEnd) {
delete updatedOptions.rangeStart;
delete updatedOptions.rangeEnd;
}
Object.assign(state, { options: updatedOptions });
};
const enabledOptions = orderOptions(props.availableOptions, ENABLED_OPTIONS);
const rangeStartOption = props.availableOptions.find(
(opt) => opt.name === "rangeStart",
);
const rangeEndOption = props.availableOptions.find(
(opt) => opt.name === "rangeEnd",
);
const cursorOffsetOption = props.availableOptions.find(
(opt) => opt.name === "cursorOffset",
);
if (option.type === "int" && Number.isNaN(value)) {
delete options[option.name];
} else {
options[option.name] = value;
}
const handleOptionValueChange = (option, value) => {
const options = { ...state.options };
const content =
state.content === "" ||
state.content === getCodeSample(state.options.parser)
? getCodeSample(options.parser)
: state.content;
if (option.type === "int" && Number.isNaN(value)) {
delete options[option.name];
} else {
options[option.name] = value;
}
return { options, content };
});
}
const content =
state.content === "" ||
state.content === getCodeSample(state.options.parser)
? getCodeSample(options.parser)
: state.content;
getMarkdown({ formatted, reformatted, full, doc }) {
const { content, options } = this.state;
const { availableOptions, version } = this.props;
return Object.assign(state, { options, content });
};
const getMarkdown = ({ formatted, reformatted, full, doc }) => {
const { content, options } = state;
const { availableOptions, version } = props;
const orderedOptions = orderOptions(availableOptions, [
...ENABLED_OPTIONS,
"rangeStart",
@@ -200,16 +182,16 @@ class Playground extends React.Component {
cliOptions,
full,
});
}
};
formatInput() {
if (this.state.options.parser !== "doc-explorer") {
const formatInput = () => {
if (state.options.parser !== "doc-explorer") {
return;
}
const { content, selection } = this.state;
const { content, selection } = state;
return this.props.worker
return props.worker
.format(content, {
parser: "__js_expression",
cursorOffset: convertSelectionToRange(selection, content)[0],
@@ -219,32 +201,32 @@ class Playground extends React.Component {
return;
}
this.setState({
Object.assign(state, {
content: formatted,
selection: convertOffsetToSelection(cursorOffset, formatted),
});
});
}
};
insertDummyId() {
const { content, selection } = this.state;
const insertDummyId = () => {
const { content, selection } = state;
const dummyId = generateDummyId();
const range = convertSelectionToRange(selection, content);
const modifiedContent =
content.slice(0, range[0]) + dummyId + content.slice(range[1]);
this.setState({
Object.assign(state, {
content: modifiedContent,
selection: convertOffsetToSelection(
range[0] + dummyId.length,
modifiedContent,
),
});
}
};
render() {
const { worker } = this.props;
const { content, options } = this.state;
const render = () => {
const { worker } = props;
const { content, options } = state;
return (
<EditorState>
@@ -261,7 +243,8 @@ class Playground extends React.Component {
rethrowEmbedErrors={editorState.rethrowEmbedErrors}
>
{({ formatted, debug, cursorOffset }) => {
const fullReport = this.getMarkdown({
const { content, options } = state;
const fullReport = getMarkdown({
formatted,
reformatted: debug.reformatted,
full: true,
@@ -272,13 +255,13 @@ class Playground extends React.Component {
return (
<>
<div className="editors-container">
<div class="editors-container">
<Sidebar visible={editorState.showSidebar}>
<SidebarOptions
categories={CATEGORIES_ORDER}
availableOptions={this.enabledOptions}
availableOptions={enabledOptions}
optionValues={options}
onOptionValueChange={this.handleOptionValueChange}
onOption-value-change={handleOptionValueChange}
/>
{isDocExplorer ? null : (
<SidebarCategory title="Range">
@@ -287,26 +270,26 @@ class Playground extends React.Component {
the input editor
</label>
<Option
option={this.rangeStartOption}
option={rangeStartOption}
value={
typeof options.rangeStart === "number"
? options.rangeStart
: ""
: undefined
}
onChange={this.handleOptionValueChange}
onChange={handleOptionValueChange}
/>
<Option
option={this.rangeEndOption}
option={rangeEndOption}
value={
typeof options.rangeEnd === "number"
? options.rangeEnd
: ""
: undefined
}
overrideMax={content.length}
onChange={this.handleOptionValueChange}
onChange={handleOptionValueChange}
/>
<Button onClick={this.setSelectionAsRange}>
<Button onClick={setSelectionAsRange}>
Set selected text as range
</Button>
</SidebarCategory>
@@ -314,13 +297,13 @@ class Playground extends React.Component {
{isDocExplorer ? null : (
<SidebarCategory title="Cursor">
<Option
option={this.cursorOffsetOption}
option={cursorOffsetOption}
value={
options.cursorOffset >= 0
? options.cursorOffset
: ""
: undefined
}
onChange={this.handleOptionValueChange}
onChange={handleOptionValueChange}
/>
<div
style={{
@@ -331,19 +314,18 @@ class Playground extends React.Component {
>
<Checkbox
label="track"
checked={Boolean(this.state.trackCursorOffset)}
onChange={() =>
this.setState((state) => ({
trackCursorOffset: !state.trackCursorOffset,
}))
}
checked={Boolean(state.trackCursorOffset)}
onChange={() => {
state.trackCursorOffset =
!state.trackCursorOffset;
}}
/>
{options.cursorOffset >= 0 ? (
<>
<Button
onClick={() => {
this.handleOptionValueChange(
this.cursorOffsetOption,
handleOptionValueChange(
cursorOffsetOption,
-1,
);
}}
@@ -409,34 +391,34 @@ class Playground extends React.Component {
)}
{editorState.showDoc && !isDocExplorer ? (
<ClipboardButton
copy={() => this.getMarkdown({ doc: debug.doc })}
copy={() => getMarkdown({ doc: debug.doc })}
disabled={!debug.doc}
>
Copy doc
</ClipboardButton>
) : null}
</SidebarCategory>
<div className="sub-options">
<Button onClick={this.resetOptions}>
<div class="sub-options">
<Button onClick={resetOptions}>
Reset to defaults
</Button>
</div>
</Sidebar>
<div className="editors">
<div class="editors">
{editorState.showInput ? (
<InputPanel
mode={getCodemirrorMode(options.parser)}
ruler={options.printWidth}
value={content}
selection={this.state.selection}
selection={state.selection}
codeSample={getCodeSample(options.parser)}
overlayStart={options.rangeStart}
overlayEnd={options.rangeEnd}
onChange={this.setContent}
onSelectionChange={this.setSelection}
onChange={setContent}
onSelectionChange={setSelection}
extraKeys={{
"Shift-Alt-F": this.formatInput,
"Ctrl-Q": this.insertDummyId,
"Shift-Alt-F": formatInput,
"Ctrl-Q": insertDummyId,
}}
foldGutter={options.parser === "doc-explorer"}
/>
@@ -484,12 +466,12 @@ class Playground extends React.Component {
) : null}
</div>
</div>
<div className="bottom-bar">
<div className="bottom-bar-buttons">
<div class="bottom-bar">
<div class="bottom-bar-buttons">
<Button onClick={editorState.toggleSidebar}>
{editorState.showSidebar ? "Hide" : "Show"} options
</Button>
<Button onClick={this.clearContent}>Clear</Button>
<Button onClick={clearContent}>Clear</Button>
<ClipboardButton
copy={JSON.stringify(
// Remove `parser` since people usually paste this
@@ -505,20 +487,20 @@ class Playground extends React.Component {
Copy config JSON
</ClipboardButton>
<Button
onClick={this.insertDummyId}
onMouseDown={(event) => event.preventDefault()} // prevent button from focusing
onClick={insertDummyId}
onMousedown={(event) => event.preventDefault()} // prevent button from focusing
title="Generate a nonsense variable name (Ctrl-Q)"
>
Insert dummy id
</Button>
</div>
<div className="bottom-bar-buttons bottom-bar-buttons-right">
<div class="bottom-bar-buttons bottom-bar-buttons-right">
<ClipboardButton copy={window.location.href}>
Copy link
</ClipboardButton>
<ClipboardButton
copy={() =>
this.getMarkdown({
getMarkdown({
formatted,
reformatted: debug.reformatted,
})
@@ -548,8 +530,26 @@ class Playground extends React.Component {
)}
</EditorState>
);
}
};
watch(
() => [state.content, state.options],
() => {
urlHash.replace({ content: state.content, options: state.options });
},
{ deep: true },
);
return render;
}
const Playground = {
name: "Playground",
props: {
worker: { type: Object, required: true },
availableOptions: { type: Array, required: true },
version: { type: String, required: true },
},
setup,
};
function orderOptions(availableOptions, order) {
const optionsByName = {};
@@ -569,7 +569,7 @@ function getSecondFormat(formatted, reformatted) {
? ""
: formatted === reformatted
? "✓ Second format is unchanged."
: reformatted;
: (reformatted ?? "");
}
export default Playground;
+50 -36
View File
@@ -1,36 +1,14 @@
const { React } = window;
import { onMounted, reactive, toRaw, watch } from "vue";
export default class PrettierFormat extends React.Component {
constructor() {
super();
this.state = { formatted: "", debug: {} };
}
function setup(props, { slots }) {
const state = reactive({ formatted: "", debug: {} });
componentDidMount() {
this.format();
}
const componentDidMount = () => {
format();
};
componentDidUpdate(prevProps) {
for (const key of [
"enabled",
"code",
"options",
"debugAst",
"debugPreprocessedAst",
"debugDoc",
"debugComments",
"reformat",
"rethrowEmbedErrors",
]) {
if (prevProps[key] !== this.props[key]) {
this.format();
break;
}
}
}
async format() {
const {
const format = async () => {
let {
worker,
code,
options,
@@ -40,7 +18,8 @@ export default class PrettierFormat extends React.Component {
debugComments: comments,
reformat,
rethrowEmbedErrors,
} = this.props;
} = props;
options = toRaw(options);
const result = await worker.format(code, options, {
ast,
@@ -51,10 +30,45 @@ export default class PrettierFormat extends React.Component {
rethrowEmbedErrors,
});
this.setState(result);
}
Object.assign(state, result);
};
render() {
return this.props.children(this.state);
}
const render = () => slots.default(state);
onMounted(componentDidMount);
watch(
() =>
[
"enabled",
"code",
"options",
"debugAst",
"debugPreprocessedAst",
"debugDoc",
"debugComments",
"reformat",
"rethrowEmbedErrors",
].map((property) => props[property]),
() => {
format();
},
{ deep: true },
);
return render;
}
export default {
name: "PrettierFormat",
props: {
worker: Object,
code: String,
options: Object,
debugAst: Boolean,
debugPreprocessedAst: Boolean,
debugDoc: Boolean,
debugComments: Boolean,
reformat: Boolean,
rethrowEmbedErrors: Boolean,
},
setup,
};
+15 -15
View File
@@ -1,6 +1,4 @@
const { React, ReactDOM } = window;
const root = document.getElementById("version");
import { Teleport } from "vue";
export default function VersionLink({ version }) {
const match = version.match(/^pr-(\d+)$/u);
@@ -15,18 +13,20 @@ export default function VersionLink({ version }) {
const formattedVersion = match ? `PR #${match[1]}` : `v${version}`;
React.useEffect(() => {
document.title = `Prettier ${formattedVersion}`;
}, [formattedVersion]);
document.title = `Prettier ${formattedVersion}`;
return ReactDOM.createPortal(
<a
href={`https://github.com/prettier/prettier/${href}`}
target="_blank"
rel="noreferrer noopener"
>
{formattedVersion}
</a>,
root,
return (
<Teleport to="#version">
<a
href={`https://github.com/prettier/prettier/${href}`}
target="_blank"
rel="noreferrer noopener"
>
{formattedVersion}
</a>
</Teleport>
);
}
VersionLink.props = {
version: { type: String, required: true },
};
+47 -35
View File
@@ -1,49 +1,61 @@
const { ClipboardJS, React } = window;
import { onMounted, reactive, ref } from "vue";
export const Button = React.forwardRef((props, ref) => (
<button type="button" className="btn" ref={ref} {...props} />
));
const { ClipboardJS } = window;
export class ClipboardButton extends React.Component {
constructor() {
super();
this.state = { showTooltip: false, tooltipText: "" };
this.timer = null;
this.ref = React.createRef();
}
export const Button = (props, { slots, attrs }) => (
<button type="button" class="btn" {...attrs}>
{slots.default()}
</button>
);
componentDidMount() {
this.clipboard = new ClipboardJS(this.ref.current, {
text: () => {
const { copy } = this.props;
function setup(props, { slots, attrs }) {
const state = reactive({ showTooltip: false, tooltipText: "" });
let timer = null;
const buttonRef = ref();
const componentDidMount = () => {
const clipboard = new ClipboardJS(buttonRef.value, {
text() {
const { copy } = props;
return typeof copy === "function" ? copy() : copy;
},
});
this.clipboard.on("success", () => this.showTooltip("Copied!"));
this.clipboard.on("error", () => this.showTooltip("Press ctrl+c to copy"));
}
clipboard.on("success", () => showTooltip("Copied!"));
clipboard.on("error", () => showTooltip("Press ctrl+c to copy"));
};
showTooltip(text) {
this.setState({ showTooltip: true, tooltipText: text }, () => {
if (this.timer) {
clearTimeout(this.timer);
}
this.timer = setTimeout(() => {
this.timer = null;
this.setState({ showTooltip: false });
}, 2000);
});
}
const showTooltip = (text) => {
Object.assign(state, { showTooltip: true, tooltipText: text });
render() {
const { children, copy, ...rest } = this.props;
const { showTooltip, tooltipText } = this.state;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
timer = null;
Object.assign(state, { showTooltip: false });
}, 2000);
};
const render = () => {
const { showTooltip, tooltipText } = state;
const children = slots.default();
return (
<Button ref={this.ref} {...rest}>
{showTooltip ? <span className="tooltip">{tooltipText}</span> : null}
<Button ref={buttonRef} {...attrs}>
{showTooltip ? <span class="tooltip">{tooltipText}</span> : null}
{children}
</Button>
);
}
};
onMounted(componentDidMount);
return render;
}
export const ClipboardButton = {
name: "ClipboardButton",
props: {
copy: { type: [String, Function], required: true },
},
setup,
};
-49
View File
@@ -1,49 +0,0 @@
export function stateToggler(key) {
return (state) => ({ [key]: !state[key] });
}
const { hasOwnProperty } = Object.prototype;
function is(x, y) {
// SameValue algorithm
if (x === y) {
// Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
return x !== 0 || 1 / x === 1 / y;
}
// Step 6.a: NaN == NaN
return x !== x && y !== y;
}
export function shallowEqual(objA, objB) {
if (is(objA, objB)) {
return true;
}
if (
typeof objA !== "object" ||
objA === null ||
typeof objB !== "object" ||
objB === null
) {
return false;
}
const keysA = Object.keys(objA);
const keysB = Object.keys(objB);
if (keysA.length !== keysB.length) {
return false;
}
for (let i = 0; i < keysA.length; i++) {
if (
!hasOwnProperty.call(objB, keysA[i]) ||
!is(objA[keysA[i]], objB[keysA[i]])
) {
return false;
}
}
return true;
}
+82 -81
View File
@@ -1,16 +1,12 @@
import "codemirror-graphql/cm6-legacy/mode.esm.js";
import "./install-service-worker.js";
import { createApp, onMounted, reactive, ref, watch } from "vue";
import Playground from "./Playground.jsx";
import { fixPrettierVersion } from "./utilities.js";
import VersionLink from "./VersionLink.jsx";
import WorkerApi from "./WorkerApi.js";
const {
React,
ReactDOM: { createRoot },
} = window;
function getInitialTheme() {
const saved = localStorage.getItem("theme");
if (saved) {
@@ -27,92 +23,97 @@ function applyTheme(theme) {
}
function ThemeToggle() {
const [theme, setTheme] = React.useState(getInitialTheme);
const theme = ref(getInitialTheme());
const toggleTheme = () => {
const newTheme = theme === "dark" ? "light" : "dark";
setTheme(newTheme);
const newTheme = theme.value === "dark" ? "light" : "dark";
theme.value = newTheme;
localStorage.setItem("theme", newTheme);
applyTheme(newTheme);
};
applyTheme(theme);
return React.createElement(
"button",
{
onClick: toggleTheme,
className: "btn",
"aria-label": `Switch to ${theme === "dark" ? "light" : "dark"} theme`,
},
theme === "dark"
? React.createElement(
"svg",
{
class: "theme-icon",
viewBox: "0 0 24 24",
width: "14",
height: "14",
"aria-hidden": "true",
},
React.createElement("path", {
fill: "currentColor",
d: "M9.37 5.51a7.4 7.4 0 009.12 9.12A7 7 0 119.37 5.51M12 3a9 9 0 108.9 7.64 5.39 5.39 0 01-9.8-3.14 5.4 5.4 0 012.26-4.4Q12.69 3 12 3",
}),
)
: React.createElement(
"svg",
{
class: "theme-icon",
viewBox: "0 0 24 24",
width: "14",
height: "14",
"aria-hidden": "true",
},
React.createElement("path", {
fill: "currentColor",
d: "M12 9a1 1 0 0 1 0 6 1 1 0 0 1 0-6m0-2a5 5 0 1 0 0 10 5 5 0 0 0 0-10M2 13h2a1 1 0 0 0 0-2H2a1 1 0 0 0 0 2m18 0h2a1 1 0 0 0 0-2h-2a1 1 0 0 0 0 2M11 2v2a1 1 0 0 0 2 0V2a1 1 0 0 0-2 0m0 18v2a1 1 0 0 0 2 0v-2a1 1 0 0 0-2 0M5.99 4.58a1 1 0 1 0-1.41 1.41l1.06 1.06a1 1 0 1 0 1.41-1.41zm12.37 12.37a1 1 0 1 0-1.41 1.41l1.06 1.06a1 1 0 1 0 1.41-1.41zm1.06-10.96a1 1 0 1 0-1.41-1.41l-1.06 1.06a1 1 0 1 0 1.41 1.41zM7.05 18.36a1 1 0 1 0-1.41-1.41l-1.06 1.06a1 1 0 1 0 1.41 1.41z",
}),
),
applyTheme(theme.value);
watch(theme, (newTheme) => {
applyTheme(newTheme);
});
return (
<button
onClick={toggleTheme}
class="btn"
aria-label={`Switch to ${theme.value === "dark" ? "light" : "dark"} theme`}
>
{theme.value === "dark" ? (
<svg
class="theme-icon"
viewBox="0 0 24 24"
width="14"
height="14"
aria-hidden="true"
>
<path
fill="currentColor"
d="M9.37 5.51a7.4 7.4 0 009.12 9.12A7 7 0 119.37 5.51M12 3a9 9 0 108.9 7.64 5.39 5.39 0 01-9.8-3.14 5.4 5.4 0 012.26-4.4Q12.69 3 12 3"
/>
</svg>
) : (
<svg
class="theme-icon"
viewBox="0 0 24 24"
width="14"
height="14"
aria-hidden="true"
>
<path
fill="currentColor"
d="M12 9a1 1 0 0 1 0 6 1 1 0 0 1 0-6m0-2a5 5 0 1 0 0 10 5 5 0 0 0 0-10M2 13h2a1 1 0 0 0 0-2H2a1 1 0 0 0 0 2m18 0h2a1 1 0 0 0 0-2h-2a1 1 0 0 0 0 2M11 2v2a1 1 0 0 0 2 0V2a1 1 0 0 0-2 0m0 18v2a1 1 0 0 0 2 0v-2a1 1 0 0 0-2 0M5.99 4.58a1 1 0 1 0-1.41 1.41l1.06 1.06a1 1 0 1 0 1.41-1.41zm12.37 12.37a1 1 0 1 0-1.41 1.41l1.06 1.06a1 1 0 1 0 1.41-1.41zm1.06-10.96a1 1 0 1 0-1.41-1.41l-1.06 1.06a1 1 0 1 0 1.41 1.41zM7.05 18.36a1 1 0 1 0-1.41-1.41l-1.06 1.06a1 1 0 1 0 1.41 1.41z"
/>
</svg>
)}
</button>
);
}
class App extends React.Component {
constructor() {
super();
this.state = { loaded: false };
this.worker = new WorkerApi();
}
const App = {
name: "App",
setup() {
const state = reactive({ loaded: false });
const worker = new WorkerApi();
async componentDidMount() {
const { supportInfo, version } = await this.worker.getMetadata();
const componentDidMount = async () => {
const { supportInfo, version } = await worker.getMetadata();
// eslint-disable-next-line @eslint-react/no-set-state-in-component-did-mount
this.setState({
loaded: true,
availableOptions: supportInfo.options.map(augmentOption),
version: fixPrettierVersion(version),
});
}
Object.assign(state, {
loaded: true,
availableOptions: supportInfo.options.map(augmentOption),
version: fixPrettierVersion(version),
});
};
render() {
const { loaded, availableOptions, version } = this.state;
const render = () => {
const { loaded, availableOptions, version } = state;
if (!loaded) {
return "Loading...";
}
if (!loaded) {
return "Loading...";
}
return (
<>
<VersionLink version={version} />
<Playground
worker={this.worker}
availableOptions={availableOptions}
version={version}
/>
</>
);
}
}
return (
<>
<VersionLink version={version} />
<Playground
worker={worker}
availableOptions={availableOptions}
version={version}
/>
</>
);
};
onMounted(componentDidMount);
return render;
},
};
function augmentOption(option) {
if (option.type === "boolean" && option.default === true) {
@@ -131,10 +132,10 @@ const linksContainer = document.querySelector(".links");
if (linksContainer) {
const themeToggleContainer = document.createElement("div");
linksContainer.appendChild(themeToggleContainer);
const themeToggleRoot = createRoot(themeToggleContainer);
themeToggleRoot.render(<ThemeToggle />);
const themeToggleRoot = createApp(ThemeToggle);
themeToggleRoot.mount(themeToggleContainer);
}
const container = document.getElementById("root");
const root = createRoot(container);
root.render(<App />);
const root = createApp(App);
root.mount(container);
+134 -95
View File
@@ -1,141 +1,180 @@
const { React, CodeMirror } = window;
import { onMounted, onUnmounted, useTemplateRef, watch } from "vue";
class CodeMirrorPanel extends React.Component {
constructor() {
super();
this._textareaRef = React.createRef();
this._codeMirror = null;
this._cached = "";
this._overlay = null;
this.handleChange = this.handleChange.bind(this);
this.handleFocus = this.handleFocus.bind(this);
this.handleSelectionChange = this.handleSelectionChange.bind(this);
}
const { CodeMirror } = window;
componentDidMount() {
const options = { ...this.props };
delete options.ruler;
delete options.rulerColor;
delete options.value;
delete options.selection;
delete options.onChange;
function setup(props, { emit }) {
const textareaRef = useTemplateRef("textarea");
let _codeMirror = null;
let _cached = "";
let _overlay = null;
const onChange = (value) => {
emit("change", value);
};
options.rulers = [makeRuler(this.props)];
options.gutters = makeGutters(this.props);
const componentDidMount = () => {
const options = { ...props };
for (const property of [
"ruler",
"rulerColor",
"value",
"selection",
"onChange",
]) {
delete options[property];
}
this._codeMirror = CodeMirror.fromTextArea(
this._textareaRef.current,
options,
);
this._codeMirror.on("change", this.handleChange);
this._codeMirror.on("focus", this.handleFocus);
this._codeMirror.on("beforeSelectionChange", this.handleSelectionChange);
for (const [key, value] of Object.entries(options)) {
if (value === undefined) {
delete options[key];
}
}
options.rulers = [makeRuler(props)];
options.gutters = makeGutters(props);
options.rulers = [makeRuler(props)];
options.gutters = makeGutters(props);
_codeMirror = CodeMirror.fromTextArea(textareaRef.value, options);
_codeMirror.on("change", handleChange);
_codeMirror.on("focus", handleFocus);
_codeMirror.on("beforeSelectionChange", handleSelectionChange);
window.CodeMirror.keyMap.pcSublime["Ctrl-L"] = false;
window.CodeMirror.keyMap.sublime["Ctrl-L"] = false;
this.updateValue(this.props.value || "");
this.updateSelection();
this.updateOverlay();
}
updateValue(props.value || "");
updateSelection();
updateOverlay();
};
componentWillUnmount() {
this._codeMirror && this._codeMirror.toTextArea();
}
const componentWillUnmount = () => {
_codeMirror?.toTextArea();
};
componentDidUpdate(prevProps) {
if (this.props.value !== this._cached) {
this.updateValue(this.props.value);
const componentDidUpdate = (_, prevProps) => {
if (!_codeMirror) {
return;
}
if (props.value !== _cached) {
updateValue(props.value);
}
if (
!isEqualSelection(this.props.selection, prevProps.selection) &&
!isEqualSelection(
this.props.selection,
this._codeMirror.listSelections()[0],
)
!isEqualSelection(props.selection, prevProps.selection) &&
!isEqualSelection(props.selection, _codeMirror.listSelections()[0])
) {
this.updateSelection();
updateSelection();
}
if (
this.props.overlayStart !== prevProps.overlayStart ||
this.props.overlayEnd !== prevProps.overlayEnd
props.overlayStart !== prevProps.overlayStart ||
props.overlayEnd !== prevProps.overlayEnd
) {
this.updateOverlay();
updateOverlay();
}
if (this.props.mode !== prevProps.mode) {
this._codeMirror.setOption("mode", this.props.mode);
if (props.mode !== prevProps.mode) {
_codeMirror.setOption("mode", props.mode);
}
if (this.props.ruler !== prevProps.ruler) {
this._codeMirror.setOption("rulers", [makeRuler(this.props)]);
if (props.ruler !== prevProps.ruler) {
_codeMirror.setOption("rulers", [makeRuler(props)]);
}
if (this.props.foldGutter !== prevProps.foldGutter) {
this._codeMirror.setOption("gutters", makeGutters(this.props));
if (props.foldGutter !== prevProps.foldGutter) {
_codeMirror.setOption("gutters", makeGutters(props));
}
}
};
updateValue(value) {
this._cached = value;
this._codeMirror.setValue(value);
const updateValue = (value) => {
_cached = value;
_codeMirror.setValue(value);
if (this.props.autoFold instanceof RegExp) {
if (props.autoFold instanceof RegExp) {
const lines = value.split("\n");
// going backwards to prevent unfolding folds created earlier
for (let i = lines.length - 1; i >= 0; i--) {
if (this.props.autoFold.test(lines[i])) {
this._codeMirror.foldCode(i);
if (props.autoFold.test(lines[i])) {
_codeMirror.foldCode(i);
}
}
}
}
};
updateSelection() {
this._codeMirror.setSelection(
this.props.selection?.anchor ?? { line: 0, ch: 0 },
this.props.selection?.head,
const updateSelection = () => {
_codeMirror.setSelection(
props.selection?.anchor ?? { line: 0, ch: 0 },
props.selection?.head,
);
}
};
updateOverlay() {
if (this._overlay) {
this._codeMirror.removeOverlay(this._overlay);
const updateOverlay = () => {
if (_overlay) {
_codeMirror.removeOverlay(_overlay);
}
if (this.props.overlayStart !== undefined) {
const [start, end] = getIndexPosition(this.props.value, [
this.props.overlayStart,
this.props.overlayEnd,
if (props.overlayStart !== undefined) {
const [start, end] = getIndexPosition(props.value, [
props.overlayStart,
props.overlayEnd,
]);
this._overlay = createOverlay(start, end);
this._codeMirror.addOverlay(this._overlay);
_overlay = createOverlay(start, end);
_codeMirror.addOverlay(_overlay);
}
}
};
handleFocus(/* codeMirror, event */) {
if (this._codeMirror.getValue() === this.props.codeSample) {
this._codeMirror.execCommand("selectAll");
const handleFocus = (/* codeMirror, event */) => {
if (_codeMirror.getValue() === props.codeSample) {
_codeMirror.execCommand("selectAll");
}
}
};
handleChange(doc, change) {
const handleChange = (doc, change) => {
if (change.origin !== "setValue") {
this._cached = doc.getValue();
this.props.onChange(this._cached);
this.updateOverlay();
_cached = doc.getValue();
onChange(_cached);
updateOverlay();
}
}
};
handleSelectionChange(doc, change) {
this.props.onSelectionChange?.(change.ranges[0]);
}
const handleSelectionChange = (doc, change) => {
props.onSelectionChange?.(change.ranges[0]);
};
render() {
return (
<div className="editor input">
<textarea ref={this._textareaRef} />
</div>
);
}
const render = () => (
<div class="editor input">
<textarea ref="textarea" />
</div>
);
onMounted(componentDidMount);
onUnmounted(componentWillUnmount);
watch(() => props, componentDidUpdate, { deep: true });
return render;
}
const CodeMirrorPanel = {
name: "CodeMirrorPanel",
props: {
value: { type: String, required: true },
selection: { type: Object, default: undefined },
onSelectionChange: { type: Function, default: undefined },
ruler: { type: Number, default: undefined },
rulerColor: { type: String, default: undefined },
overlayStart: { type: Number, default: undefined },
overlayEnd: { type: Number, default: undefined },
mode: { type: String, required: true },
foldGutter: { type: Boolean, default: undefined },
autoFold: { type: RegExp, default: undefined },
codeSample: { type: String, default: undefined },
lineNumbers: { type: Boolean, default: undefined },
keyMap: { type: String, default: undefined },
autoCloseBrackets: { type: Boolean, default: undefined },
matchBrackets: { type: Boolean, default: undefined },
showCursorWhenSelecting: { type: Boolean, default: undefined },
tabSize: { type: Number, default: undefined },
readOnly: { type: Boolean, default: undefined },
},
emits: ["change"],
setup,
};
function getIndexPosition(text, indexes) {
indexes = [...indexes];
let line = 0;
+12 -6
View File
@@ -18,12 +18,12 @@ function groupBy(array, iteratee) {
return result;
}
export default function SidebarOptions({
categories,
availableOptions,
optionValues,
onOptionValueChange,
}) {
export default function SidebarOptions(
{ categories, availableOptions, optionValues },
{ emit },
) {
const onOptionValueChange = (option, value) =>
emit("option-value-change", option, value);
const options = groupBy(availableOptions, (option) => option.category);
return categories.map((category) =>
options[category] ? (
@@ -40,3 +40,9 @@ export default function SidebarOptions({
) : null,
);
}
SidebarOptions.props = {
categories: { type: Array, required: true },
availableOptions: { type: Array, required: true },
optionValues: { type: Object, required: true },
};
SidebarOptions.emits = ["option-value-change"];
+7 -5
View File
@@ -1,14 +1,16 @@
export function Sidebar({ visible, children }) {
export function Sidebar({ visible }, { slots }) {
const children = slots.default();
return (
<div className={`options-container ${visible ? "open" : ""}`}>
<div className="options">{children}</div>
<div class={`options-container ${visible ? "open" : ""}`}>
<div class="options">{children}</div>
</div>
);
}
export function SidebarCategory({ title, children }) {
export function SidebarCategory({ title }, { slots }) {
const children = slots.default();
return (
<details className="sub-options" open>
<details class="sub-options" open>
<summary>{title}</summary>
{children}
</details>
+31 -11
View File
@@ -1,4 +1,5 @@
export function Checkbox({ label: _label, title, checked, onChange }) {
export function Checkbox({ label: _label, title, checked }, { emit }) {
const onChange = (value) => emit("change", value);
return (
<label title={title}>
<input
@@ -10,8 +11,15 @@ export function Checkbox({ label: _label, title, checked, onChange }) {
</label>
);
}
Checkbox.props = {
label: { type: String, required: true },
title: { type: String, default: "" },
checked: { type: Boolean, required: true },
};
Checkbox.emits = ["change"];
export function Select({ label: _label, title, values, selected, onChange }) {
export function Select({ label: _label, title, values, selected }, { emit }) {
const onChange = (value) => emit("change", value);
return (
<label title={title}>
{_label}{" "}
@@ -25,16 +33,19 @@ export function Select({ label: _label, title, values, selected, onChange }) {
</label>
);
}
Select.props = {
label: { type: String, required: true },
title: { type: String, required: true },
values: { type: Array, required: true },
selected: { type: String, required: true },
};
Select.emits = ["change"];
export function NumberInput({
label: _label,
title,
value,
min,
max,
step,
onChange,
}) {
export function NumberInput(
{ label: _label, title, value, min, max, step },
{ emit },
) {
const onChange = (value) => emit("change", value);
return (
<label title={title}>
{_label}{" "}
@@ -49,3 +60,12 @@ export function NumberInput({
</label>
);
}
NumberInput.props = {
label: { type: String, required: true },
title: { type: String, required: true },
value: { type: Number, default: undefined },
min: { type: Number, default: undefined },
max: { type: Number, default: undefined },
step: { type: Number, default: undefined },
};
NumberInput.emits = ["change"];
+32 -7
View File
@@ -1,6 +1,7 @@
import { Checkbox, NumberInput, Select } from "./inputs.jsx";
function BooleanOption({ option, value, onChange }) {
function BooleanOption({ option, value }, { emit }) {
const onChange = (option, value) => emit("change", option, value);
function maybeInvert(value) {
return option.inverted ? !value : value;
}
@@ -13,8 +14,14 @@ function BooleanOption({ option, value, onChange }) {
/>
);
}
BooleanOption.props = {
option: { type: Object, required: true },
value: { type: Boolean, required: true },
};
BooleanOption.emits = ["change"];
function ChoiceOption({ option, value, onChange }) {
function ChoiceOption({ option, value }, { emit }) {
const onChange = (option, val) => emit("change", option, val);
return (
<Select
label={option.cliName}
@@ -25,8 +32,14 @@ function ChoiceOption({ option, value, onChange }) {
/>
);
}
ChoiceOption.props = {
option: { type: Object, required: true },
value: { type: String, required: true },
};
ChoiceOption.emits = ["change"];
function NumberOption({ option, value, onChange }) {
function NumberOption({ option, value }, { emit }) {
const onChange = (option, val) => emit("change", option, val);
return (
<NumberInput
label={option.cliName}
@@ -39,19 +52,31 @@ function NumberOption({ option, value, onChange }) {
/>
);
}
NumberOption.props = {
option: { type: Object, required: true },
value: { type: Number, default: undefined },
};
NumberOption.emits = ["change"];
export default function Option(props, { emit }) {
const onChange = (option, value) => emit("change", option, value);
export default function Option(props) {
switch (props.option.type) {
case "boolean":
return <BooleanOption {...props} />;
return <BooleanOption {...props} onChange={onChange} />;
case "int":
return <NumberOption {...props} />;
return <NumberOption {...props} onChange={onChange} />;
case "choice":
return <ChoiceOption {...props} />;
return <ChoiceOption {...props} onChange={onChange} />;
default:
throw new Error("unsupported type");
}
}
Option.props = {
option: { type: Object, required: true },
value: { type: [Boolean, String, Number], default: undefined },
};
Option.emits = ["change"];
function getDescription(option) {
const description = option.inverted
-2
View File
@@ -37,8 +37,6 @@ toolbox.precache([
"https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.11/clipboard.min.js",
"https://cdnjs.cloudflare.com/ajax/libs/lz-string/1.4.4/lz-string.min.js",
"https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js",
"https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js",
// Images
"/prettier.png",
+5 -2
View File
@@ -1,14 +1,17 @@
import react from "@vitejs/plugin-react";
import vitePluginVue from "@vitejs/plugin-vue";
import vitePluginVueJsx from "@vitejs/plugin-vue-jsx";
import { defineConfig } from "vite";
const IS_PRODUCTION = process.env.NODE_ENV === "production";
const IS_CI = Boolean(process.env.CI);
// https://vite.dev/config/
export default defineConfig({
base: IS_PRODUCTION ? "/playground/" : undefined,
publicDir: IS_PRODUCTION ? undefined : "./static/",
plugins: [react()],
plugins: [vitePluginVue(), vitePluginVueJsx()],
build: {
outDir: "./static/playground/",
minify: IS_CI,
},
});
+232 -95
View File
@@ -505,7 +505,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.5":
"@babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.4, @babel/parser@npm:^7.28.5":
version: 7.28.5
resolution: "@babel/parser@npm:7.28.5"
dependencies:
@@ -1148,28 +1148,6 @@ __metadata:
languageName: node
linkType: hard
"@babel/plugin-transform-react-jsx-self@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-react-jsx-self@npm:7.27.1"
dependencies:
"@babel/helper-plugin-utils": "npm:^7.27.1"
peerDependencies:
"@babel/core": ^7.0.0-0
checksum: 10/72cbae66a58c6c36f7e12e8ed79f292192d858dd4bb00e9e89d8b695e4c5cb6ef48eec84bffff421a5db93fd10412c581f1cccdb00264065df76f121995bdb68
languageName: node
linkType: hard
"@babel/plugin-transform-react-jsx-source@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-react-jsx-source@npm:7.27.1"
dependencies:
"@babel/helper-plugin-utils": "npm:^7.27.1"
peerDependencies:
"@babel/core": ^7.0.0-0
checksum: 10/e2843362adb53692be5ee9fa07a386d2d8883daad2063a3575b3c373fc14cdf4ea7978c67a183cb631b4c9c8d77b2f48c24c088f8e65cc3600cb8e97d72a7161
languageName: node
linkType: hard
"@babel/plugin-transform-react-jsx@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-react-jsx@npm:7.27.1"
@@ -1531,7 +1509,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.28.5, @babel/types@npm:^7.4.4":
"@babel/types@npm:^7.21.3, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.28.5, @babel/types@npm:^7.4.4":
version: 7.28.5
resolution: "@babel/types@npm:7.28.5"
dependencies:
@@ -3087,7 +3065,7 @@ __metadata:
languageName: node
linkType: hard
"@jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0":
"@jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5":
version: 1.5.5
resolution: "@jridgewell/sourcemap-codec@npm:1.5.5"
checksum: 10/5d9d207b462c11e322d71911e55e21a4e2772f71ffe8d6f1221b8eb5ae6774458c1d242f897fb0814e8714ca9a6b498abfa74dfe4f434493342902b1a48b33a5
@@ -3381,10 +3359,17 @@ __metadata:
languageName: node
linkType: hard
"@rolldown/pluginutils@npm:1.0.0-beta.47":
version: 1.0.0-beta.47
resolution: "@rolldown/pluginutils@npm:1.0.0-beta.47"
checksum: 10/c1794cb39642e644dc7194043543780fd9f83e58052f1e5608d9d063a74592577bcb3b1283e3928db99ff52b208f7d5c47342f376de823f9fd584f189a371ed4
"@rolldown/pluginutils@npm:1.0.0-beta.50":
version: 1.0.0-beta.50
resolution: "@rolldown/pluginutils@npm:1.0.0-beta.50"
checksum: 10/7a44cafb5d6875d6fccca378cc0f72f0ae2c24fea198e532e6d754429956ada548634153acef05b9dceb09fea0655119b9b11a81a447d7efa72d4fe104ad33a3
languageName: node
linkType: hard
"@rolldown/pluginutils@npm:^1.0.0-beta.50":
version: 1.0.0-beta.9-commit.d91dfb5
resolution: "@rolldown/pluginutils@npm:1.0.0-beta.9-commit.d91dfb5"
checksum: 10/35039ac154f8288ca8740e078382cab14856581ca95fae15a54dd7250fabc798d266b0edc46eed3029ba93ae2b6c10ef377c697884daaf63185e994a08d5c81b
languageName: node
linkType: hard
@@ -4180,47 +4165,6 @@ __metadata:
languageName: node
linkType: hard
"@types/babel__core@npm:^7.20.5":
version: 7.20.5
resolution: "@types/babel__core@npm:7.20.5"
dependencies:
"@babel/parser": "npm:^7.20.7"
"@babel/types": "npm:^7.20.7"
"@types/babel__generator": "npm:*"
"@types/babel__template": "npm:*"
"@types/babel__traverse": "npm:*"
checksum: 10/c32838d280b5ab59d62557f9e331d3831f8e547ee10b4f85cb78753d97d521270cebfc73ce501e9fb27fe71884d1ba75e18658692c2f4117543f0fc4e3e118b3
languageName: node
linkType: hard
"@types/babel__generator@npm:*":
version: 7.27.0
resolution: "@types/babel__generator@npm:7.27.0"
dependencies:
"@babel/types": "npm:^7.0.0"
checksum: 10/f572e67a9a39397664350a4437d8a7fbd34acc83ff4887a8cf08349e39f8aeb5ad2f70fb78a0a0a23a280affe3a5f4c25f50966abdce292bcf31237af1c27b1a
languageName: node
linkType: hard
"@types/babel__template@npm:*":
version: 7.4.4
resolution: "@types/babel__template@npm:7.4.4"
dependencies:
"@babel/parser": "npm:^7.1.0"
"@babel/types": "npm:^7.0.0"
checksum: 10/d7a02d2a9b67e822694d8e6a7ddb8f2b71a1d6962dfd266554d2513eefbb205b33ca71a0d163b1caea3981ccf849211f9964d8bd0727124d18ace45aa6c9ae29
languageName: node
linkType: hard
"@types/babel__traverse@npm:*":
version: 7.28.0
resolution: "@types/babel__traverse@npm:7.28.0"
dependencies:
"@babel/types": "npm:^7.28.2"
checksum: 10/371c5e1b40399ef17570e630b2943617b84fafde2860a56f0ebc113d8edb1d0534ade0175af89eda1ae35160903c33057ed42457e165d4aa287fedab2c82abcf
languageName: node
linkType: hard
"@types/body-parser@npm:*":
version: 1.19.6
resolution: "@types/body-parser@npm:1.19.6"
@@ -4688,19 +4632,175 @@ __metadata:
languageName: node
linkType: hard
"@vitejs/plugin-react@npm:5.1.1":
version: 5.1.1
resolution: "@vitejs/plugin-react@npm:5.1.1"
"@vitejs/plugin-vue-jsx@npm:5.1.2":
version: 5.1.2
resolution: "@vitejs/plugin-vue-jsx@npm:5.1.2"
dependencies:
"@babel/core": "npm:^7.28.5"
"@babel/plugin-transform-react-jsx-self": "npm:^7.27.1"
"@babel/plugin-transform-react-jsx-source": "npm:^7.27.1"
"@rolldown/pluginutils": "npm:1.0.0-beta.47"
"@types/babel__core": "npm:^7.20.5"
react-refresh: "npm:^0.18.0"
"@babel/plugin-syntax-typescript": "npm:^7.27.1"
"@babel/plugin-transform-typescript": "npm:^7.28.5"
"@rolldown/pluginutils": "npm:^1.0.0-beta.50"
"@vue/babel-plugin-jsx": "npm:^2.0.1"
peerDependencies:
vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
checksum: 10/e975ccb9f8e258b91d9a3ff58a3864053b0b7f63d641b070508bb38f6ffb93015fd2421d36cee7b90fd123da962ceb3d2951df359fc906c920037923854a621d
vite: ^5.0.0 || ^6.0.0 || ^7.0.0
vue: ^3.0.0
checksum: 10/2f3327335cbbdd91cc11e0c7416281a28359063940cdf31b20cef6678e6b53309c90d547b06c9d933b8727bb8861f00196af63663d32c4681a101c7a7124c871
languageName: node
linkType: hard
"@vitejs/plugin-vue@npm:6.0.2":
version: 6.0.2
resolution: "@vitejs/plugin-vue@npm:6.0.2"
dependencies:
"@rolldown/pluginutils": "npm:1.0.0-beta.50"
peerDependencies:
vite: ^5.0.0 || ^6.0.0 || ^7.0.0
vue: ^3.2.25
checksum: 10/db610f70191ddcac88a945064ecadc24c4349fe51b62e176ba1ddf6877f57b09bfad7a46ead6e561b92deb1ddde9af69da6e3bb7097540bd5fb4a0f99f3b402a
languageName: node
linkType: hard
"@vue/babel-helper-vue-transform-on@npm:2.0.1":
version: 2.0.1
resolution: "@vue/babel-helper-vue-transform-on@npm:2.0.1"
checksum: 10/4968d69eabad8ab91a9de31463c17551605b415e65bc64102d1aa1a5b53db82923c13e0a6f735e03b4f7b0787419cb394467d7e34fc0eb9fd7e31f912278cd53
languageName: node
linkType: hard
"@vue/babel-plugin-jsx@npm:^2.0.1":
version: 2.0.1
resolution: "@vue/babel-plugin-jsx@npm:2.0.1"
dependencies:
"@babel/helper-module-imports": "npm:^7.27.1"
"@babel/helper-plugin-utils": "npm:^7.27.1"
"@babel/plugin-syntax-jsx": "npm:^7.27.1"
"@babel/template": "npm:^7.27.2"
"@babel/traverse": "npm:^7.28.4"
"@babel/types": "npm:^7.28.4"
"@vue/babel-helper-vue-transform-on": "npm:2.0.1"
"@vue/babel-plugin-resolve-type": "npm:2.0.1"
"@vue/shared": "npm:^3.5.22"
peerDependencies:
"@babel/core": ^7.0.0-0
peerDependenciesMeta:
"@babel/core":
optional: true
checksum: 10/f8f7237321c769e946b0b12e00c1d28af82dac9df67c376fb585821fd0a5604a4902bbb3915ced29c5c9cc461dc3d6abe264ec0d7d5eaf552a3a6534778dd55b
languageName: node
linkType: hard
"@vue/babel-plugin-resolve-type@npm:2.0.1":
version: 2.0.1
resolution: "@vue/babel-plugin-resolve-type@npm:2.0.1"
dependencies:
"@babel/code-frame": "npm:^7.27.1"
"@babel/helper-module-imports": "npm:^7.27.1"
"@babel/helper-plugin-utils": "npm:^7.27.1"
"@babel/parser": "npm:^7.28.4"
"@vue/compiler-sfc": "npm:^3.5.22"
peerDependencies:
"@babel/core": ^7.0.0-0
checksum: 10/b0d727363084124065e00efb69292ff43e28da2540ecfb16efbd5f8415d21bb5941bfe205d0547d07dea05770e3875e67e617584d009f7eaef92a0895261c8c3
languageName: node
linkType: hard
"@vue/compiler-core@npm:3.5.25":
version: 3.5.25
resolution: "@vue/compiler-core@npm:3.5.25"
dependencies:
"@babel/parser": "npm:^7.28.5"
"@vue/shared": "npm:3.5.25"
entities: "npm:^4.5.0"
estree-walker: "npm:^2.0.2"
source-map-js: "npm:^1.2.1"
checksum: 10/7a35088a6d25ff7cbfd777df7e61da72bad6c26ac59cb66774e3669745f185632c11acebec2412f6a3e91b713aad2262654a92ce8da20acd629d3a2244820374
languageName: node
linkType: hard
"@vue/compiler-dom@npm:3.5.25":
version: 3.5.25
resolution: "@vue/compiler-dom@npm:3.5.25"
dependencies:
"@vue/compiler-core": "npm:3.5.25"
"@vue/shared": "npm:3.5.25"
checksum: 10/aa04f8c87e5f3333375e546fb8dd77e5afba159965ba8f3c8b8216b95f2202bb08acdf014185ac81afdbf69c31c56cefda85a40a14233355ea1ac63aa9f146c2
languageName: node
linkType: hard
"@vue/compiler-sfc@npm:3.5.25, @vue/compiler-sfc@npm:^3.5.22":
version: 3.5.25
resolution: "@vue/compiler-sfc@npm:3.5.25"
dependencies:
"@babel/parser": "npm:^7.28.5"
"@vue/compiler-core": "npm:3.5.25"
"@vue/compiler-dom": "npm:3.5.25"
"@vue/compiler-ssr": "npm:3.5.25"
"@vue/shared": "npm:3.5.25"
estree-walker: "npm:^2.0.2"
magic-string: "npm:^0.30.21"
postcss: "npm:^8.5.6"
source-map-js: "npm:^1.2.1"
checksum: 10/08bafc59929ba1841a94bd9e2cdd22d494a8db34d6fa1c00e66cb6ae437e3567387da778551ea3424b8aca6e2ddc0e17202288d473ea0c0554448da4ac8eafd6
languageName: node
linkType: hard
"@vue/compiler-ssr@npm:3.5.25":
version: 3.5.25
resolution: "@vue/compiler-ssr@npm:3.5.25"
dependencies:
"@vue/compiler-dom": "npm:3.5.25"
"@vue/shared": "npm:3.5.25"
checksum: 10/9a485194747ebf38232453173d84eb3f69e59e378d6e81fba61f4999d72226ecc496c1cdbafc3b977786add9f7cab27e40e2a456089f6edbf2164b416375b43f
languageName: node
linkType: hard
"@vue/reactivity@npm:3.5.25":
version: 3.5.25
resolution: "@vue/reactivity@npm:3.5.25"
dependencies:
"@vue/shared": "npm:3.5.25"
checksum: 10/50d5cb1f4e0619fd77393a307b59cc1ba682e89a5052acb1703d33cb521ddc97702b8539fc1c7ebcc9ff38a145dccd469e7187bb7337dacb85c53329e72ea7df
languageName: node
linkType: hard
"@vue/runtime-core@npm:3.5.25":
version: 3.5.25
resolution: "@vue/runtime-core@npm:3.5.25"
dependencies:
"@vue/reactivity": "npm:3.5.25"
"@vue/shared": "npm:3.5.25"
checksum: 10/4491495fdbf2bc24e73aefbba6756ecf22d42bf5a611c1a84418328e724af3b1ae2a2083e7347a0215db8ebe9a07920286cafc1e66d3c56baa133091046df816
languageName: node
linkType: hard
"@vue/runtime-dom@npm:3.5.25":
version: 3.5.25
resolution: "@vue/runtime-dom@npm:3.5.25"
dependencies:
"@vue/reactivity": "npm:3.5.25"
"@vue/runtime-core": "npm:3.5.25"
"@vue/shared": "npm:3.5.25"
csstype: "npm:^3.1.3"
checksum: 10/07eb65bff96c3bb9cab9f4b52896d804a2fe811d8056d3dc1ea1b8b751d0b72f5b9f6eeac65ce16dc0f593c633f6c31f54bc61698d83e3b888dbb7832a1807b3
languageName: node
linkType: hard
"@vue/server-renderer@npm:3.5.25":
version: 3.5.25
resolution: "@vue/server-renderer@npm:3.5.25"
dependencies:
"@vue/compiler-ssr": "npm:3.5.25"
"@vue/shared": "npm:3.5.25"
peerDependencies:
vue: 3.5.25
checksum: 10/065d80301f891a49928aa60e3145748d5e1bfb967979d17c2417b5d1b746964c31121271d6ca24d0db978a51cfa66d96db0659da9da0cf863eda27b4b934826c
languageName: node
linkType: hard
"@vue/shared@npm:3.5.25, @vue/shared@npm:^3.5.22":
version: 3.5.25
resolution: "@vue/shared@npm:3.5.25"
checksum: 10/8f5102be5e8dec105df6409e048549c7887bd09a23b4253e26bf14ddcafa9648783785c2334d243c6b54fbbfc297ce5c254c6646a7ef2b42899e3784155be277
languageName: node
linkType: hard
@@ -6317,7 +6417,7 @@ __metadata:
languageName: node
linkType: hard
"csstype@npm:^3.2.2":
"csstype@npm:^3.1.3, csstype@npm:^3.2.2":
version: 3.2.3
resolution: "csstype@npm:3.2.3"
checksum: 10/ad41baf7e2ffac65ab544d79107bf7cd1a4bb9bab9ac3302f59ab4ba655d5e30942a8ae46e10ba160c6f4ecea464cc95b975ca2fefbdeeacd6ac63f12f99fe1f
@@ -6744,7 +6844,7 @@ __metadata:
languageName: node
linkType: hard
"entities@npm:^4.2.0, entities@npm:^4.4.0":
"entities@npm:^4.2.0, entities@npm:^4.4.0, entities@npm:^4.5.0":
version: 4.5.0
resolution: "entities@npm:4.5.0"
checksum: 10/ede2a35c9bce1aeccd055a1b445d41c75a14a2bb1cd22e242f20cf04d236cdcd7f9c859eb83f76885327bfae0c25bf03303665ee1ce3d47c5927b98b0e3e3d48
@@ -7077,6 +7177,13 @@ __metadata:
languageName: node
linkType: hard
"estree-walker@npm:^2.0.2":
version: 2.0.2
resolution: "estree-walker@npm:2.0.2"
checksum: 10/b02109c5d46bc2ed47de4990eef770f7457b1159a229f0999a09224d2b85ffeed2d7679cffcff90aeb4448e94b0168feb5265b209cdec29aad50a3d6e93d21e2
languageName: node
linkType: hard
"estree-walker@npm:^3.0.0":
version: 3.0.3
resolution: "estree-walker@npm:3.0.3"
@@ -7688,6 +7795,13 @@ __metadata:
languageName: node
linkType: hard
"graphql@npm:16.12.0":
version: 16.12.0
resolution: "graphql@npm:16.12.0"
checksum: 10/e299bc97cca178e549c8c1ed4cb164f631f07be987d3657f76cdf18c0250040cc0d456d4b6d41c87b855cac97b15a62ed345557527efcb0546492895a893bb87
languageName: node
linkType: hard
"gray-matter@npm:^4.0.3":
version: 4.0.3
resolution: "gray-matter@npm:4.0.3"
@@ -9035,6 +9149,15 @@ __metadata:
languageName: node
linkType: hard
"magic-string@npm:^0.30.21":
version: 0.30.21
resolution: "magic-string@npm:0.30.21"
dependencies:
"@jridgewell/sourcemap-codec": "npm:^1.5.5"
checksum: 10/57d5691f41ed40d962d8bd300148114f53db67fadbff336207db10a99f2bdf4a1be9cac3a68ee85dba575912ee1d4402e4396408196ec2d3afd043b076156221
languageName: node
linkType: hard
"make-fetch-happen@npm:^15.0.0":
version: 15.0.3
resolution: "make-fetch-happen@npm:15.0.3"
@@ -11832,13 +11955,6 @@ __metadata:
languageName: node
linkType: hard
"react-refresh@npm:^0.18.0":
version: 0.18.0
resolution: "react-refresh@npm:0.18.0"
checksum: 10/504c331c19776bf8320c23bad7f80b3a28de03301ed7523b0dd21d3f02bf2b53bbdd5aa52469b187bc90f358614b2ba303c088a0765c95f4f0a68c43a7d67b1d
languageName: node
linkType: hard
"react-router-config@npm:^5.1.1":
version: 5.1.1
resolution: "react-router-config@npm:5.1.1"
@@ -12415,16 +12531,19 @@ __metadata:
"@docusaurus/types": "npm:3.9.2"
"@mdx-js/react": "npm:3.1.1"
"@sandhose/prettier-animated-logo": "npm:1.0.3"
"@vitejs/plugin-react": "npm:5.1.1"
"@vitejs/plugin-vue": "npm:6.0.2"
"@vitejs/plugin-vue-jsx": "npm:5.1.2"
clsx: "npm:2.1.1"
codemirror-graphql: "npm:2.2.4"
concurrently: "npm:9.2.1"
graphql: "npm:16.12.0"
prism-react-renderer: "npm:2.4.1"
react: "npm:18.3.1"
react-dom: "npm:18.3.1"
react-markdown: "npm:10.1.0"
react-tweet: "npm:3.2.2"
vite: "npm:7.2.4"
vite: "npm:7.2.7"
vue: "npm:3.5.25"
yaml: "npm:2.8.2"
languageName: unknown
linkType: soft
@@ -13752,9 +13871,9 @@ __metadata:
languageName: node
linkType: hard
"vite@npm:7.2.4":
version: 7.2.4
resolution: "vite@npm:7.2.4"
"vite@npm:7.2.7":
version: 7.2.7
resolution: "vite@npm:7.2.7"
dependencies:
esbuild: "npm:^0.25.0"
fdir: "npm:^6.5.0"
@@ -13803,7 +13922,7 @@ __metadata:
optional: true
bin:
vite: bin/vite.js
checksum: 10/25962e65159e62fa6b643ac5bc79457c61c9b2cec9a1a17763b067b1e5ecac6483ad84247d6d457d81e25c5d1f8c553372bedf71dee09d8c1bd41af6c7b016a5
checksum: 10/ec7c588db66c8a3e50a24fc26422c6ef27c2e08a0ceccd200162e45be90d7d12c0a06d8ccc8c88139a657d51be5e10ddc83df9807daf6a1362c2e5ecdaf2a07e
languageName: node
linkType: hard
@@ -13814,6 +13933,24 @@ __metadata:
languageName: node
linkType: hard
"vue@npm:3.5.25":
version: 3.5.25
resolution: "vue@npm:3.5.25"
dependencies:
"@vue/compiler-dom": "npm:3.5.25"
"@vue/compiler-sfc": "npm:3.5.25"
"@vue/runtime-dom": "npm:3.5.25"
"@vue/server-renderer": "npm:3.5.25"
"@vue/shared": "npm:3.5.25"
peerDependencies:
typescript: "*"
peerDependenciesMeta:
typescript:
optional: true
checksum: 10/3c3ec68747f31d52095365f37e548c8d7488ccd0d6a9ea0aabf2d619e6f62b9c0673766411b3574c1229e08640349f1eb6eab1f7766e269c8f221d1de5d1f06d
languageName: node
linkType: hard
"watchpack@npm:^2.4.4":
version: 2.4.4
resolution: "watchpack@npm:2.4.4"
+8 -261
View File
@@ -1294,104 +1294,6 @@ __metadata:
languageName: node
linkType: hard
"@eslint-react/ast@npm:2.3.9":
version: 2.3.9
resolution: "@eslint-react/ast@npm:2.3.9"
dependencies:
"@eslint-react/eff": "npm:2.3.9"
"@typescript-eslint/types": "npm:^8.48.0"
"@typescript-eslint/typescript-estree": "npm:^8.48.0"
"@typescript-eslint/utils": "npm:^8.48.0"
string-ts: "npm:^2.2.1"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <6.0.0"
checksum: 10/c33ceaa9ab24ccdb8d19cd4ed0d1e52256b911ffa3651f7bba4d52cedb03830f7f6ebf561900924de4e602a30294be3e4062cac8441f368901b05c52ef65ba99
languageName: node
linkType: hard
"@eslint-react/core@npm:2.3.9":
version: 2.3.9
resolution: "@eslint-react/core@npm:2.3.9"
dependencies:
"@eslint-react/ast": "npm:2.3.9"
"@eslint-react/eff": "npm:2.3.9"
"@eslint-react/shared": "npm:2.3.9"
"@eslint-react/var": "npm:2.3.9"
"@typescript-eslint/scope-manager": "npm:^8.48.0"
"@typescript-eslint/types": "npm:^8.48.0"
"@typescript-eslint/utils": "npm:^8.48.0"
birecord: "npm:^0.1.1"
ts-pattern: "npm:^5.9.0"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <6.0.0"
checksum: 10/a921c6db57eec6706a0cab25b426ec734a2cec2aaa70c35bfd1f138394281bb9ede08132527ebe2b8e2efbbdd1c9eb58552abb086e5aa588dfb1e937dea68d73
languageName: node
linkType: hard
"@eslint-react/eff@npm:2.3.9":
version: 2.3.9
resolution: "@eslint-react/eff@npm:2.3.9"
checksum: 10/70fe48cf6d392a27d543564894aa924f2b5e53b24ad2a313858596a189b49c140a76ffb360458c58129ddfb9db95709b239228a04e383ca6377559d42cfe821f
languageName: node
linkType: hard
"@eslint-react/eslint-plugin@npm:2.3.9":
version: 2.3.9
resolution: "@eslint-react/eslint-plugin@npm:2.3.9"
dependencies:
"@eslint-react/eff": "npm:2.3.9"
"@eslint-react/shared": "npm:2.3.9"
"@typescript-eslint/scope-manager": "npm:^8.48.0"
"@typescript-eslint/type-utils": "npm:^8.48.0"
"@typescript-eslint/types": "npm:^8.48.0"
"@typescript-eslint/utils": "npm:^8.48.0"
eslint-plugin-react-dom: "npm:2.3.9"
eslint-plugin-react-hooks-extra: "npm:2.3.9"
eslint-plugin-react-naming-convention: "npm:2.3.9"
eslint-plugin-react-web-api: "npm:2.3.9"
eslint-plugin-react-x: "npm:2.3.9"
ts-api-utils: "npm:^2.1.0"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <6.0.0"
checksum: 10/52dea58c52d7c5829ccb30d54e0cef53e41835fe354d3c54a99260b06fb7816df73409e50132f3c3ac434f060a02e1a2c78d47c5e05d6f109e3649689c342362
languageName: node
linkType: hard
"@eslint-react/shared@npm:2.3.9":
version: 2.3.9
resolution: "@eslint-react/shared@npm:2.3.9"
dependencies:
"@eslint-react/eff": "npm:2.3.9"
"@typescript-eslint/utils": "npm:^8.48.0"
ts-pattern: "npm:^5.9.0"
zod: "npm:^4.1.13"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <6.0.0"
checksum: 10/2f02de515fb7f8be098b35364cfb04c6f3c73abc8891cfb682aec431af2b15c39224cc74817502955a171ee3c4a202ccd6940e9c88727fcb0f5f18174e399657
languageName: node
linkType: hard
"@eslint-react/var@npm:2.3.9":
version: 2.3.9
resolution: "@eslint-react/var@npm:2.3.9"
dependencies:
"@eslint-react/ast": "npm:2.3.9"
"@eslint-react/eff": "npm:2.3.9"
"@typescript-eslint/scope-manager": "npm:^8.48.0"
"@typescript-eslint/types": "npm:^8.48.0"
"@typescript-eslint/utils": "npm:^8.48.0"
ts-pattern: "npm:^5.9.0"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <6.0.0"
checksum: 10/3ef583506f7da2ff7263024c22ccd02094b528b91064ada58539b1475dacda725b5c28fa9e66d6d6dc15db2ef62758e886e7f062c67c95246996477019d933ee
languageName: node
linkType: hard
"@eslint/config-array@npm:^0.21.1":
version: 0.21.1
resolution: "@eslint/config-array@npm:0.21.1"
@@ -2580,7 +2482,7 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/scope-manager@npm:8.48.1, @typescript-eslint/scope-manager@npm:^8.48.0":
"@typescript-eslint/scope-manager@npm:8.48.1":
version: 8.48.1
resolution: "@typescript-eslint/scope-manager@npm:8.48.1"
dependencies:
@@ -2599,7 +2501,7 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/type-utils@npm:8.48.1, @typescript-eslint/type-utils@npm:^8.0.0, @typescript-eslint/type-utils@npm:^8.48.0":
"@typescript-eslint/type-utils@npm:8.48.1":
version: 8.48.1
resolution: "@typescript-eslint/type-utils@npm:8.48.1"
dependencies:
@@ -2615,14 +2517,14 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/types@npm:8.48.1, @typescript-eslint/types@npm:^8.47.0, @typescript-eslint/types@npm:^8.48.0, @typescript-eslint/types@npm:^8.48.1":
"@typescript-eslint/types@npm:8.48.1, @typescript-eslint/types@npm:^8.47.0, @typescript-eslint/types@npm:^8.48.1":
version: 8.48.1
resolution: "@typescript-eslint/types@npm:8.48.1"
checksum: 10/1aa1e3f25b429bcebd9eb45b5252d950f1b24dbc6014a47dff8d00547e2e1ac47f351846fb996b6ebd49da37a85394051d36191cbbbf2c431b8db9d95afd198d
languageName: node
linkType: hard
"@typescript-eslint/typescript-estree@npm:8.48.1, @typescript-eslint/typescript-estree@npm:^8.48.0":
"@typescript-eslint/typescript-estree@npm:8.48.1":
version: 8.48.1
resolution: "@typescript-eslint/typescript-estree@npm:8.48.1"
dependencies:
@@ -2641,7 +2543,7 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/utils@npm:8.48.1, @typescript-eslint/utils@npm:^8.0.0, @typescript-eslint/utils@npm:^8.48.0":
"@typescript-eslint/utils@npm:8.48.1, @typescript-eslint/utils@npm:^8.0.0":
version: 8.48.1
resolution: "@typescript-eslint/utils@npm:8.48.1"
dependencies:
@@ -3141,13 +3043,6 @@ __metadata:
languageName: node
linkType: hard
"birecord@npm:^0.1.1":
version: 0.1.1
resolution: "birecord@npm:0.1.1"
checksum: 10/9169bd57a9b15d08ebd8f936dcd249cebaf67bd21fae36e38723b0d40ebafa97b9b4253e4f0c58beca3446b4eff65824578803ea80fa0071495d1ce37d8da062
languageName: node
linkType: hard
"brace-expansion@npm:^1.1.7":
version: 1.1.12
resolution: "brace-expansion@npm:1.1.12"
@@ -3578,13 +3473,6 @@ __metadata:
languageName: node
linkType: hard
"compare-versions@npm:^6.1.1":
version: 6.1.1
resolution: "compare-versions@npm:6.1.1"
checksum: 10/9325c0fadfba81afa0ec17e6fc2ef823ba785c693089698b8d9374e5460509f1916a88591644d4cb4045c9a58e47fafbcc0724fe8bf446d2a875a3d6eeddf165
languageName: node
linkType: hard
"concat-map@npm:0.0.1":
version: 0.0.1
resolution: "concat-map@npm:0.0.1"
@@ -4267,118 +4155,6 @@ __metadata:
languageName: node
linkType: hard
"eslint-plugin-react-dom@npm:2.3.9":
version: 2.3.9
resolution: "eslint-plugin-react-dom@npm:2.3.9"
dependencies:
"@eslint-react/ast": "npm:2.3.9"
"@eslint-react/core": "npm:2.3.9"
"@eslint-react/eff": "npm:2.3.9"
"@eslint-react/shared": "npm:2.3.9"
"@eslint-react/var": "npm:2.3.9"
"@typescript-eslint/scope-manager": "npm:^8.48.0"
"@typescript-eslint/types": "npm:^8.48.0"
"@typescript-eslint/utils": "npm:^8.48.0"
compare-versions: "npm:^6.1.1"
string-ts: "npm:^2.2.1"
ts-pattern: "npm:^5.9.0"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <6.0.0"
checksum: 10/c270cc9e06669f88175125a9a0758f66bc04cdfcbfb3a69188bcde3769e5c56eb33d8e44b7f77d2509d5c341f8a71a3230e19d3755aa54b49b6e47885e5f11d0
languageName: node
linkType: hard
"eslint-plugin-react-hooks-extra@npm:2.3.9":
version: 2.3.9
resolution: "eslint-plugin-react-hooks-extra@npm:2.3.9"
dependencies:
"@eslint-react/ast": "npm:2.3.9"
"@eslint-react/core": "npm:2.3.9"
"@eslint-react/eff": "npm:2.3.9"
"@eslint-react/shared": "npm:2.3.9"
"@eslint-react/var": "npm:2.3.9"
"@typescript-eslint/scope-manager": "npm:^8.48.0"
"@typescript-eslint/type-utils": "npm:^8.48.0"
"@typescript-eslint/types": "npm:^8.48.0"
"@typescript-eslint/utils": "npm:^8.48.0"
string-ts: "npm:^2.2.1"
ts-pattern: "npm:^5.9.0"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <6.0.0"
checksum: 10/d3c4d7aefd66e2095863350d9d3f1283646338a43b5c586ad42025d6e808d7c0eba94aa191063f5eebc129efae59f186d1aa4ef137284ff76671c66d8977357c
languageName: node
linkType: hard
"eslint-plugin-react-naming-convention@npm:2.3.9":
version: 2.3.9
resolution: "eslint-plugin-react-naming-convention@npm:2.3.9"
dependencies:
"@eslint-react/ast": "npm:2.3.9"
"@eslint-react/core": "npm:2.3.9"
"@eslint-react/eff": "npm:2.3.9"
"@eslint-react/shared": "npm:2.3.9"
"@eslint-react/var": "npm:2.3.9"
"@typescript-eslint/scope-manager": "npm:^8.48.0"
"@typescript-eslint/type-utils": "npm:^8.48.0"
"@typescript-eslint/types": "npm:^8.48.0"
"@typescript-eslint/utils": "npm:^8.48.0"
string-ts: "npm:^2.2.1"
ts-pattern: "npm:^5.9.0"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <6.0.0"
checksum: 10/cf14ae88640ca452a9c3ed6cd6c9f858422c6cf6af5f66ef5fc538a2c0d9ad930189ba11f4a476521d9ea9135af15a6a4d48cae27338a494fe8de1ee0c20f4e2
languageName: node
linkType: hard
"eslint-plugin-react-web-api@npm:2.3.9":
version: 2.3.9
resolution: "eslint-plugin-react-web-api@npm:2.3.9"
dependencies:
"@eslint-react/ast": "npm:2.3.9"
"@eslint-react/core": "npm:2.3.9"
"@eslint-react/eff": "npm:2.3.9"
"@eslint-react/shared": "npm:2.3.9"
"@eslint-react/var": "npm:2.3.9"
"@typescript-eslint/scope-manager": "npm:^8.48.0"
"@typescript-eslint/types": "npm:^8.48.0"
"@typescript-eslint/utils": "npm:^8.48.0"
string-ts: "npm:^2.2.1"
ts-pattern: "npm:^5.9.0"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <6.0.0"
checksum: 10/f1187c43b06cc3765439a1b50db49b6557f4945df2216fbfe24209211786f59d56c9c0712d0cee3615a539c5a8025c873c8506839d132d3c5e4dfdf36fea44f6
languageName: node
linkType: hard
"eslint-plugin-react-x@npm:2.3.9":
version: 2.3.9
resolution: "eslint-plugin-react-x@npm:2.3.9"
dependencies:
"@eslint-react/ast": "npm:2.3.9"
"@eslint-react/core": "npm:2.3.9"
"@eslint-react/eff": "npm:2.3.9"
"@eslint-react/shared": "npm:2.3.9"
"@eslint-react/var": "npm:2.3.9"
"@typescript-eslint/scope-manager": "npm:^8.48.0"
"@typescript-eslint/type-utils": "npm:^8.48.0"
"@typescript-eslint/types": "npm:^8.48.0"
"@typescript-eslint/utils": "npm:^8.48.0"
compare-versions: "npm:^6.1.1"
is-immutable-type: "npm:^5.0.1"
string-ts: "npm:^2.2.1"
ts-api-utils: "npm:^2.1.0"
ts-pattern: "npm:^5.9.0"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <6.0.0"
checksum: 10/e292ec3c1206ff6e652d3baeb329be56c0fb5aeaacf53b6d20558fc21d8e1b90d518266c63e1f170456ba5709dbd9b5818af5a590a6823d5a29a73bf3a178390
languageName: node
linkType: hard
"eslint-plugin-regexp@npm:2.10.0":
version: 2.10.0
resolution: "eslint-plugin-regexp@npm:2.10.0"
@@ -5562,20 +5338,6 @@ __metadata:
languageName: node
linkType: hard
"is-immutable-type@npm:^5.0.1":
version: 5.0.1
resolution: "is-immutable-type@npm:5.0.1"
dependencies:
"@typescript-eslint/type-utils": "npm:^8.0.0"
ts-api-utils: "npm:^2.0.0"
ts-declaration-location: "npm:^1.0.4"
peerDependencies:
eslint: "*"
typescript: ">=4.7.4"
checksum: 10/4aa22000e4ca1182faeaf2d705016ebf2a4eaccd303b8adcb4e9a1621b0b4d8e48dcba9c7683cd168a45f3782b8de61beae94c9d5ac17448af94f572b9e66edd
languageName: node
linkType: hard
"is-in-ssh@npm:^1.0.0":
version: 1.0.0
resolution: "is-in-ssh@npm:1.0.0"
@@ -7514,7 +7276,6 @@ __metadata:
"@babel/generator": "npm:8.0.0-beta.3"
"@babel/parser": "npm:8.0.0-beta.3"
"@babel/types": "npm:8.0.0-beta.3"
"@eslint-react/eslint-plugin": "npm:2.3.9"
"@eslint/js": "npm:9.39.1"
"@glimmer/syntax": "npm:0.95.0"
"@prettier/cli": "npm:0.10.0"
@@ -8260,13 +8021,6 @@ __metadata:
languageName: node
linkType: hard
"string-ts@npm:^2.2.1":
version: 2.2.1
resolution: "string-ts@npm:2.2.1"
checksum: 10/08fd90ff78ee6f0c3a4cb394bcaf0b11571d1191a7489bd7117983a3b0d99c070f35ee7a52427685afdcec8174e25715af5dde99f08cdfe81b2791c7dcdc0d1b
languageName: node
linkType: hard
"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3":
version: 4.2.3
resolution: "string-width@npm:4.2.3"
@@ -8669,7 +8423,7 @@ __metadata:
languageName: node
linkType: hard
"ts-api-utils@npm:^2.0.0, ts-api-utils@npm:^2.1.0":
"ts-api-utils@npm:^2.1.0":
version: 2.1.0
resolution: "ts-api-utils@npm:2.1.0"
peerDependencies:
@@ -8678,7 +8432,7 @@ __metadata:
languageName: node
linkType: hard
"ts-declaration-location@npm:^1.0.4, ts-declaration-location@npm:^1.0.6":
"ts-declaration-location@npm:^1.0.6":
version: 1.0.7
resolution: "ts-declaration-location@npm:1.0.7"
dependencies:
@@ -8696,13 +8450,6 @@ __metadata:
languageName: node
linkType: hard
"ts-pattern@npm:^5.9.0":
version: 5.9.0
resolution: "ts-pattern@npm:5.9.0"
checksum: 10/0df8cc63d731a596f3541a305eff10f055c9a761d1a8b3776781dc6d6430c6bd8be8cd333fac62138c5d88e1209b4d8dccf1f40041091b634e5018908281417b
languageName: node
linkType: hard
"tslib@npm:^2.3.0, tslib@npm:^2.4.0":
version: 2.8.1
resolution: "tslib@npm:2.8.1"
@@ -9362,7 +9109,7 @@ __metadata:
languageName: node
linkType: hard
"zod@npm:^4.1.11, zod@npm:^4.1.13":
"zod@npm:^4.1.11":
version: 4.1.13
resolution: "zod@npm:4.1.13"
checksum: 10/0679190318928f69fcb07751063719de232c663b13955fcdb55db59839569d39f3f29b955cb0cba7af0b724233f88c06b3e84c550397ad4e68f8088fa6799d88