mirror of
https://github.com/jakejarvis/stanza.git
synced 2026-07-16 18:05:58 -04:00
fix: simplify file-preview sync, project-setup state, and remove unused deps
- Replace `file-preview`'s `useEffect`-based tree→URL sync with an `onSelectionChange` callback so the URL hash is the sole source of truth for `activePath`; drop `useFileTreeSelector` and the last-file latch ref in favor of a direct `hash && filePaths.includes(hash)` guard - Simplify `ProjectSetup` to a nullable `draft` (null until first keystroke) + `useDebouncedCallback` so no sync effect or `lastSyncedRef` is needed to avoid echo-back from the URL-backed prop - Remove `@tanstack/react-router-ssr-query`, `@tanstack/router-plugin`, `handlebars`, and `web-vitals` from `apps/web` deps — none were imported - Delete the re-exported `summaryFor` helper from `adapter-switcher` (callers use `findModule` from `@stanza/registry` directly) - Fix `PreviewBlock` code padding (`[&_pre]:p-4` → `[&_pre]:p-0`, add `mt-4` top margin) - Fix intra-doc anchor in `getting-started.mdx` to use a relative `#` fragment instead of an absolute `/docs/getting-started#` path
This commit is contained in:
@@ -25,7 +25,7 @@ npm create stanza@latest -- my-app
|
||||
bun create stanza@latest my-app
|
||||
```
|
||||
|
||||
To run it without the wizard — in CI, for example — see [Non-interactive setup](/docs/getting-started#non-interactive-setup) below.
|
||||
To run it without the wizard — in CI, for example — see [Non-interactive setup](#non-interactive-setup) below.
|
||||
|
||||
## What you get
|
||||
|
||||
|
||||
@@ -26,20 +26,17 @@
|
||||
"@tanstack/react-pacer": "^0.22.1",
|
||||
"@tanstack/react-router": "^1.170.8",
|
||||
"@tanstack/react-router-devtools": "^1.167.0",
|
||||
"@tanstack/react-router-ssr-query": "^1.167.0",
|
||||
"@tanstack/react-start": "^1.168.13",
|
||||
"@tanstack/router-plugin": "^1.168.11",
|
||||
"@vercel/functions": "^3.6.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"fumadocs-core": "^16.9.1",
|
||||
"fumadocs-mdx": "^15.0.8",
|
||||
"fumadocs-mdx": "^15.0.9",
|
||||
"fumadocs-ui": "npm:@fumadocs/base-ui@^16.9.1",
|
||||
"handlebars": "^4.7.9",
|
||||
"lru-cache": "^11.5.0",
|
||||
"nitro": "^3.0.260522-beta",
|
||||
"posthog-js": "^1.376.0",
|
||||
"posthog-node": "^5.35.1",
|
||||
"posthog-js": "^1.376.2",
|
||||
"posthog-node": "^5.35.4",
|
||||
"react": "^19.2.6",
|
||||
"react-dom": "^19.2.6",
|
||||
"react-resizable-panels": "^4.11.2",
|
||||
@@ -66,7 +63,6 @@
|
||||
"typescript": "^6.0.3",
|
||||
"vite": "catalog:",
|
||||
"vite-plus": "catalog:",
|
||||
"vitest": "catalog:",
|
||||
"web-vitals": "^5.2.0"
|
||||
"vitest": "catalog:"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { themeToTreeStyles } from "@pierre/trees";
|
||||
import { FileTree, useFileTree, useFileTreeSelector } from "@pierre/trees/react";
|
||||
import { FileTree, useFileTree } from "@pierre/trees/react";
|
||||
import { IconLoader2 } from "@tabler/icons-react";
|
||||
import { useLocation, useNavigate } from "@tanstack/react-router";
|
||||
import type { ReactNode } from "react";
|
||||
import { useEffect, useMemo, useRef } from "react";
|
||||
import { useCallback, useEffect, useMemo, useRef } from "react";
|
||||
|
||||
import { useTheme } from "@/components/theme-provider";
|
||||
import { Card } from "@/components/ui/card";
|
||||
@@ -73,47 +73,64 @@ export function FilePreview({
|
||||
/** Rendered into the pane's header bar (the install command row). */
|
||||
header: ReactNode;
|
||||
}) {
|
||||
// URL hash mirrors the open file ("apps/web/src/index.tsx" etc.) so refreshes
|
||||
// and shared links land on the same selection. Slashes are valid in a URL
|
||||
// fragment, so paths go in raw — no encoding needed.
|
||||
const hash = useLocation({ select: (l) => l.hash });
|
||||
const navigate = useNavigate({ from: "/" });
|
||||
const defaultPath = useMemo(() => defaultPathFor(filePaths), [filePaths]);
|
||||
|
||||
// The URL hash is the source of truth for "currently open file": folder
|
||||
// clicks don't change it (handled in `onSelectionChange` below), so the
|
||||
// preview pane keeps the last user-selected file even while a folder is
|
||||
// visually selected in the tree.
|
||||
const activePath = hash && filePaths.includes(hash) ? hash : defaultPath;
|
||||
const preview = activePath ? previews[activePath] : undefined;
|
||||
|
||||
// `useFileTree` is lazy-init and reads its options once, so the selection
|
||||
// handler bound at init must read latest navigate/hash/defaultPath via refs.
|
||||
const navigateRef = useRef(navigate);
|
||||
navigateRef.current = navigate;
|
||||
const hashRef = useRef(hash);
|
||||
hashRef.current = hash;
|
||||
const defaultPathRef = useRef(defaultPath);
|
||||
defaultPathRef.current = defaultPath;
|
||||
const modelRef = useRef<ReturnType<typeof useFileTree>["model"] | null>(null);
|
||||
|
||||
// Tree → URL: fired by `@pierre/trees` on every selection change (user clicks
|
||||
// OR programmatic `select()` from our reseed/hash-sync effects below). Skip
|
||||
// folder selections so latching survives folder expansion, and skip no-op
|
||||
// pushes so programmatic selects don't bounce back.
|
||||
const onSelectionChange = useCallback((selectedPaths: readonly string[]) => {
|
||||
const sel = selectedPaths[0];
|
||||
if (!sel) return;
|
||||
const item = modelRef.current?.getItem(sel);
|
||||
if (!item || item.isDirectory()) return;
|
||||
|
||||
const nextHash = sel !== defaultPathRef.current ? sel : "";
|
||||
if (nextHash === hashRef.current) return;
|
||||
void navigateRef.current({
|
||||
search: (prev) => prev,
|
||||
hash: nextHash,
|
||||
replace: true,
|
||||
resetScroll: false,
|
||||
hashScrollIntoView: false,
|
||||
});
|
||||
}, []);
|
||||
|
||||
// `useFileTree` builds the model once (lazy init) and doesn't react to later
|
||||
// `paths` changes — we re-seed manually in the effect below.
|
||||
const { model } = useFileTree({
|
||||
paths: filePaths,
|
||||
search: false,
|
||||
unsafeCSS: TRUNCATE_FIX_CSS,
|
||||
onSelectionChange,
|
||||
});
|
||||
|
||||
// URL hash mirrors the open file ("apps/web/src/index.tsx" etc.) so refreshes
|
||||
// and shared links land on the same selection. Slashes are valid in a URL
|
||||
// fragment, so paths go in raw — no encoding needed.
|
||||
const hash = useLocation({ select: (l) => l.hash });
|
||||
// Read inside the reseed effect without making it a dep — otherwise every
|
||||
// back/forward would collapse + re-expand the whole tree.
|
||||
const hashRef = useRef(hash);
|
||||
hashRef.current = hash;
|
||||
const navigate = useNavigate({ from: "/" });
|
||||
const defaultPath = useMemo(() => defaultPathFor(filePaths), [filePaths]);
|
||||
|
||||
// Project to "current file selection (undefined for nothing/folder)". The
|
||||
// selector pattern lets the tree skip re-rendering us on unrelated state
|
||||
// changes, and `isDirectory()` is the canonical file/folder discriminator.
|
||||
const fileSelection = useFileTreeSelector(model, (m) => {
|
||||
const sel = m.getSelectedPaths()[0];
|
||||
if (!sel) return undefined;
|
||||
return m.getItem(sel)?.isDirectory() === false ? sel : undefined;
|
||||
});
|
||||
// Folder clicks in @pierre/trees both expand AND select, dropping the file
|
||||
// selection. Latch the last file so folder expansion leaves the preview
|
||||
// and the URL hash on the user's chosen file. Invalidate when the latched
|
||||
// file disappears from filePaths (e.g. its owning module was deselected).
|
||||
const lastFileRef = useRef<string | undefined>(undefined);
|
||||
if (lastFileRef.current && !filePaths.includes(lastFileRef.current)) {
|
||||
lastFileRef.current = undefined;
|
||||
}
|
||||
if (fileSelection !== undefined) lastFileRef.current = fileSelection;
|
||||
const activePath = lastFileRef.current ?? defaultPath;
|
||||
const preview = activePath ? previews[activePath] : undefined;
|
||||
modelRef.current = model;
|
||||
|
||||
// Re-seed the model when `filePaths` changes. `resetPaths` collapses
|
||||
// everything and clears selection, so we replay both manually.
|
||||
// everything and clears selection, so we replay both manually. Tree → URL
|
||||
// sync happens automatically via `onSelectionChange` when we call `select()`.
|
||||
const prevPathsRef = useRef(filePaths);
|
||||
useEffect(() => {
|
||||
const expandedSet = new Set(
|
||||
@@ -136,16 +153,10 @@ export function FilePreview({
|
||||
}
|
||||
return true;
|
||||
});
|
||||
// Prefer the hash (deep link / refresh), then the latched last file,
|
||||
// then the default. Hash is read via ref so its changes don't reseed.
|
||||
// Prefer the hash (deep link / refresh), else the default. Hash is read
|
||||
// via ref so its changes don't reseed.
|
||||
const initialHash = hashRef.current;
|
||||
const previous = lastFileRef.current;
|
||||
const next =
|
||||
initialHash && filePaths.includes(initialHash)
|
||||
? initialHash
|
||||
: previous && filePaths.includes(previous)
|
||||
? previous
|
||||
: defaultPath;
|
||||
const next = initialHash && filePaths.includes(initialHash) ? initialHash : defaultPath;
|
||||
// Reveal the selected file by expanding its ancestor chain — otherwise
|
||||
// the tree selects a row that's collapsed out of view.
|
||||
const expanded = [
|
||||
@@ -157,8 +168,8 @@ export function FilePreview({
|
||||
}, [model, filePaths, defaultPath]);
|
||||
|
||||
// URL → tree: back/forward (and intra-app links) drop a new hash; reflect
|
||||
// it in the tree. Skipped on the initial reseed since that effect already
|
||||
// honors the hash via `hashRef`.
|
||||
// it in the tree. The resulting programmatic `select()` fires
|
||||
// `onSelectionChange`, which short-circuits on the matching hash.
|
||||
useEffect(() => {
|
||||
if (!hash || !filePaths.includes(hash)) return;
|
||||
if (model.getSelectedPaths()[0] === hash) return;
|
||||
@@ -170,23 +181,6 @@ export function FilePreview({
|
||||
model.getItem(hash)?.select();
|
||||
}, [hash, filePaths, model]);
|
||||
|
||||
// Tree → URL: keep the hash in sync with the open file. The hash is empty
|
||||
// when the active file is the implicit default (so shareable URLs stay
|
||||
// clean) or when there's no valid file at all (so a stale hash gets
|
||||
// cleared after the owning module is deselected).
|
||||
useEffect(() => {
|
||||
const nextHash =
|
||||
activePath && filePaths.includes(activePath) && activePath !== defaultPath ? activePath : "";
|
||||
if (nextHash === hash) return;
|
||||
void navigate({
|
||||
search: (prev) => prev,
|
||||
hash: nextHash,
|
||||
replace: true,
|
||||
resetScroll: false,
|
||||
hashScrollIntoView: false,
|
||||
});
|
||||
}, [activePath, hash, filePaths, defaultPath, navigate]);
|
||||
|
||||
// Drive the tree's palette from the app theme; otherwise it auto-detects via
|
||||
// `prefers-color-scheme` and mismatches when the user overrides the OS theme.
|
||||
const { resolvedTheme } = useTheme();
|
||||
|
||||
@@ -126,7 +126,7 @@ export function Builder({ state, search }: { state: BuilderState; search: Builde
|
||||
onToggle={toggle}
|
||||
/>
|
||||
</section>
|
||||
<section className="min-w-0 space-y-6 lg:sticky lg:top-20 lg:flex lg:h-[calc(100vh-6rem)] lg:flex-col lg:gap-6 lg:space-y-0 lg:self-start">
|
||||
<section className="flex min-w-0 flex-col gap-6 lg:sticky lg:top-20 lg:h-[calc(100vh-6rem)] lg:self-start">
|
||||
<div className="hidden lg:block">{commandBar}</div>
|
||||
<FilePreview
|
||||
filePaths={state.filePaths}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { validateProjectName } from "@stanza/registry";
|
||||
import { IconAlertCircle } from "@tabler/icons-react";
|
||||
import { useDebouncedValue } from "@tanstack/react-pacer";
|
||||
import { useDebouncedCallback } from "@tanstack/react-pacer";
|
||||
import type { ChangeEvent } from "react";
|
||||
import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
|
||||
import { useId, useState } from "react";
|
||||
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { Field, FieldError } from "@/components/ui/field";
|
||||
@@ -18,40 +18,34 @@ export function ProjectSetup({
|
||||
defaultName: string;
|
||||
onNameChange: (name: string) => void;
|
||||
}) {
|
||||
// `lastSyncedRef` ignores the echo of our own pushes — otherwise
|
||||
// `setDraft(name)` would clobber characters the user typed between the
|
||||
// debounce firing and the new `name` prop arriving.
|
||||
const [draft, setDraft] = useState(name);
|
||||
const lastSyncedRef = useRef(name);
|
||||
// `draft` is null until the user types; the input then renders draft instead
|
||||
// of the URL-backed prop so each keystroke is visible immediately while the
|
||||
// debounced commit lags behind. We never echo the prop back into draft — no
|
||||
// sync effect needed.
|
||||
const [draft, setDraft] = useState<string | null>(null);
|
||||
const display = draft ?? name;
|
||||
|
||||
const inputId = useId();
|
||||
const errorId = `${inputId}-error`;
|
||||
|
||||
useEffect(() => {
|
||||
if (name === lastSyncedRef.current) return;
|
||||
lastSyncedRef.current = name;
|
||||
setDraft(name);
|
||||
}, [name]);
|
||||
|
||||
const validation = useMemo(() => validateProjectName(draft), [draft]);
|
||||
const validation = validateProjectName(display);
|
||||
// The placeholder telegraphs the `defaultName` fallback, so an empty field
|
||||
// shouldn't render a "required" error.
|
||||
const showError = !validation.ok && draft.trim().length > 0;
|
||||
const showError = !validation.ok && display.trim().length > 0;
|
||||
|
||||
const [debouncedDraft] = useDebouncedValue(draft, { wait: 300 });
|
||||
|
||||
useEffect(() => {
|
||||
if (debouncedDraft === lastSyncedRef.current) return;
|
||||
if (!validateProjectName(debouncedDraft).ok) return;
|
||||
lastSyncedRef.current = debouncedDraft;
|
||||
onNameChange(debouncedDraft);
|
||||
}, [debouncedDraft, onNameChange]);
|
||||
|
||||
const onDraftChange = useCallback(
|
||||
(e: ChangeEvent<HTMLInputElement>) => setDraft(e.target.value),
|
||||
[],
|
||||
const commit = useDebouncedCallback(
|
||||
(value: string) => {
|
||||
if (validateProjectName(value).ok) onNameChange(value);
|
||||
},
|
||||
{ wait: 300 },
|
||||
);
|
||||
|
||||
const onDraftChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.value;
|
||||
setDraft(value);
|
||||
commit(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<Card className="gap-0 px-3 py-3.5">
|
||||
<Label htmlFor={inputId} className="mb-1.5 text-[13px] font-medium text-muted-foreground">
|
||||
@@ -61,7 +55,7 @@ export function ProjectSetup({
|
||||
<Input
|
||||
id={inputId}
|
||||
name="project-name"
|
||||
value={draft}
|
||||
value={display}
|
||||
placeholder={defaultName}
|
||||
onChange={onDraftChange}
|
||||
autoComplete="off"
|
||||
|
||||
@@ -81,11 +81,3 @@ export function AdapterSwitcher({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function summaryFor(
|
||||
index: RegistryIndex,
|
||||
slot: CategoryId,
|
||||
id: string,
|
||||
): ModuleSummary | undefined {
|
||||
return index.modules.find((m) => m.category === slot && m.id === id);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ function PreviewBlock({ preview }: { preview: Preview }) {
|
||||
);
|
||||
return (
|
||||
<div
|
||||
className="overflow-auto border-t border-border text-xs leading-relaxed [&_pre]:bg-transparent! [&_pre]:p-4!"
|
||||
className="mt-4 overflow-auto border-t border-border text-xs leading-relaxed [&_pre]:bg-transparent! [&_pre]:p-0!"
|
||||
dangerouslySetInnerHTML={inner}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -8,8 +8,6 @@ export function getMDXComponents(components?: MDXComponents) {
|
||||
} satisfies MDXComponents;
|
||||
}
|
||||
|
||||
export const useMDXComponents = getMDXComponents;
|
||||
|
||||
declare global {
|
||||
type MDXProvidedComponents = ReturnType<typeof getMDXComponents>;
|
||||
}
|
||||
|
||||
@@ -4,11 +4,11 @@ import type { ModuleSummary, RegistryIndex } from "@stanza/registry";
|
||||
import { categoryLabel } from "@stanza/registry";
|
||||
import { IconBookmark, IconSearch } from "@tabler/icons-react";
|
||||
import { formatForDisplay, useHotkey } from "@tanstack/react-hotkeys";
|
||||
import { useDebouncedValue } from "@tanstack/react-pacer";
|
||||
import { useDebouncedCallback } from "@tanstack/react-pacer";
|
||||
import { useNavigate } from "@tanstack/react-router";
|
||||
import type { SortedResult } from "fumadocs-core/search";
|
||||
import { useDocsSearch } from "fumadocs-core/search/client";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
||||
|
||||
import { ModuleLogo } from "@/components/module-logo";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -27,6 +27,13 @@ import type { DocsIndex } from "@/server/docs-index.functions";
|
||||
const HOTKEY = "Mod+K";
|
||||
const DEBOUNCE_MS = 150;
|
||||
|
||||
// Platform is fixed for the page's lifetime, so the subscribe callback is a
|
||||
// no-op. Server snapshot hard-codes mac for SSR; the client snapshot reads
|
||||
// navigator on hydration.
|
||||
const subscribeNoop = () => () => {};
|
||||
const getHotkeyLabel = () => formatForDisplay(HOTKEY);
|
||||
const getServerHotkeyLabel = () => formatForDisplay(HOTKEY, { platform: "mac" });
|
||||
|
||||
/**
|
||||
* One row's worth of docs result. Unified for empty-state pages (which carry
|
||||
* a plain `description`) and searched hits (which carry `excerptHtml`, the
|
||||
@@ -62,10 +69,7 @@ export function SiteSearch({ registry, docs }: { registry: RegistryIndex; docs:
|
||||
const { isTouchDevice } = usePointerCapability();
|
||||
|
||||
useHotkey(HOTKEY, () => setOpen((o) => !o));
|
||||
const [hotkeyLabel, setHotkeyLabel] = useState(() =>
|
||||
formatForDisplay(HOTKEY, { platform: "mac" }),
|
||||
);
|
||||
useEffect(() => setHotkeyLabel(formatForDisplay(HOTKEY)), []);
|
||||
const hotkeyLabel = useSyncExternalStore(subscribeNoop, getHotkeyLabel, getServerHotkeyLabel);
|
||||
|
||||
// Docs: Fumadocs' hook handles debounce + abort + caching internally.
|
||||
const docsSearch = useDocsSearch({
|
||||
@@ -73,33 +77,32 @@ export function SiteSearch({ registry, docs }: { registry: RegistryIndex; docs:
|
||||
api: "/api/search/docs",
|
||||
delayMs: DEBOUNCE_MS,
|
||||
});
|
||||
useEffect(() => {
|
||||
docsSearch.setSearch(query);
|
||||
}, [query, docsSearch]);
|
||||
|
||||
// Modules: debounce the query, then fetch with an abort signal for any
|
||||
// request that's still in-flight when the debounced value changes again.
|
||||
const [moduleResults, setModuleResults] = useState<ModuleSummary[] | null>(null);
|
||||
const [debouncedQuery] = useDebouncedValue(query, { wait: DEBOUNCE_MS });
|
||||
useEffect(() => {
|
||||
if (!debouncedQuery.trim()) {
|
||||
setModuleResults(null);
|
||||
return () => {};
|
||||
}
|
||||
const controller = new AbortController();
|
||||
fetch(`/api/search/modules?q=${encodeURIComponent(debouncedQuery)}`, {
|
||||
signal: controller.signal,
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((data: unknown) => setModuleResults(parseModuleResults(data)))
|
||||
.catch((err: unknown) => {
|
||||
if (err instanceof DOMException && err.name === "AbortError") return;
|
||||
// Surface network/parse failures as "no matches" rather than blanking
|
||||
// the dialog or throwing past React's render loop.
|
||||
setModuleResults([]);
|
||||
});
|
||||
return () => controller.abort();
|
||||
}, [debouncedQuery]);
|
||||
const moduleFetchRef = useRef<AbortController | null>(null);
|
||||
const fetchModules = useDebouncedCallback(
|
||||
(q: string) => {
|
||||
moduleFetchRef.current?.abort();
|
||||
if (!q.trim()) {
|
||||
setModuleResults(null);
|
||||
return;
|
||||
}
|
||||
const controller = new AbortController();
|
||||
moduleFetchRef.current = controller;
|
||||
fetch(`/api/search/modules?q=${encodeURIComponent(q)}`, { signal: controller.signal })
|
||||
.then((res) => res.json())
|
||||
.then((data: unknown) => setModuleResults(parseModuleResults(data)))
|
||||
.catch((err: unknown) => {
|
||||
if (err instanceof DOMException && err.name === "AbortError") return;
|
||||
// Surface network/parse failures as "no matches" rather than blanking
|
||||
// the dialog or throwing past React's render loop.
|
||||
setModuleResults([]);
|
||||
});
|
||||
},
|
||||
{ wait: DEBOUNCE_MS },
|
||||
);
|
||||
|
||||
const pageTitlesByUrl = useMemo(
|
||||
() => new Map(docs.pages.map((p) => [p.url, p.title])),
|
||||
@@ -146,7 +149,12 @@ export function SiteSearch({ registry, docs }: { registry: RegistryIndex; docs:
|
||||
|
||||
const flat: Hit[] = useMemo(() => groups.flatMap((g) => g.hits), [groups]);
|
||||
|
||||
useEffect(() => setActiveIndex(0), [query]);
|
||||
const onQueryChange = (value: string) => {
|
||||
setQuery(value);
|
||||
setActiveIndex(0);
|
||||
docsSearch.setSearch(value);
|
||||
fetchModules(value);
|
||||
};
|
||||
|
||||
const select = useCallback(
|
||||
(hit: Hit) => {
|
||||
@@ -163,13 +171,19 @@ export function SiteSearch({ registry, docs }: { registry: RegistryIndex; docs:
|
||||
[navigate],
|
||||
);
|
||||
|
||||
const onOpenChange = useCallback((next: boolean) => {
|
||||
setOpen(next);
|
||||
if (next) {
|
||||
setQuery("");
|
||||
setActiveIndex(0);
|
||||
}
|
||||
}, []);
|
||||
const onOpenChange = useCallback(
|
||||
(next: boolean) => {
|
||||
setOpen(next);
|
||||
if (next) {
|
||||
setQuery("");
|
||||
setActiveIndex(0);
|
||||
docsSearch.setSearch("");
|
||||
moduleFetchRef.current?.abort();
|
||||
setModuleResults(null);
|
||||
}
|
||||
},
|
||||
[docsSearch],
|
||||
);
|
||||
|
||||
const onKeyDown = useCallback(
|
||||
(e: React.KeyboardEvent) => {
|
||||
@@ -221,7 +235,7 @@ export function SiteSearch({ registry, docs }: { registry: RegistryIndex; docs:
|
||||
autoFocus={!isTouchDevice}
|
||||
type="search"
|
||||
value={query}
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
onChange={(e) => onQueryChange(e.target.value)}
|
||||
onKeyDown={onKeyDown}
|
||||
placeholder="Search docs and modules…"
|
||||
aria-label="Search docs and modules"
|
||||
@@ -333,7 +347,7 @@ function SearchRow({
|
||||
data-selected={active || undefined}
|
||||
onClick={handleSelect}
|
||||
onPointerMove={handlePointerMove}
|
||||
className="flex w-full cursor-pointer items-center gap-2 rounded-none px-2 py-2 text-left text-xs outline-hidden data-[selected]:bg-muted data-[selected]:text-foreground"
|
||||
className="flex w-full cursor-pointer items-center gap-2 rounded-none p-2 text-left text-xs outline-hidden data-[selected]:bg-muted data-[selected]:text-foreground"
|
||||
>
|
||||
<RowContent hit={hit} />
|
||||
</button>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import { useMemo } from "react";
|
||||
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
@@ -172,34 +171,26 @@ function FieldError({
|
||||
}: React.ComponentProps<"div"> & {
|
||||
errors?: Array<{ message?: string } | undefined>;
|
||||
}) {
|
||||
const content = useMemo(() => {
|
||||
if (children) {
|
||||
return children;
|
||||
}
|
||||
|
||||
if (!errors?.length) {
|
||||
return null;
|
||||
}
|
||||
if (!children && !errors?.length) return null;
|
||||
|
||||
let content: React.ReactNode = children;
|
||||
if (!content && errors?.length) {
|
||||
const uniqueErrors = [...new Map(errors.map((error) => [error?.message, error])).values()];
|
||||
|
||||
if (uniqueErrors?.length == 1) {
|
||||
return uniqueErrors[0]?.message;
|
||||
}
|
||||
|
||||
return (
|
||||
<ul className="ml-4 flex list-disc flex-col gap-1">
|
||||
{uniqueErrors.map(
|
||||
(error, index) => error?.message && <li key={error.message ?? index}>{error.message}</li>,
|
||||
)}
|
||||
</ul>
|
||||
);
|
||||
}, [children, errors]);
|
||||
|
||||
if (!content) {
|
||||
return null;
|
||||
content =
|
||||
uniqueErrors.length === 1 ? (
|
||||
uniqueErrors[0]?.message
|
||||
) : (
|
||||
<ul className="ml-4 flex list-disc flex-col gap-1">
|
||||
{uniqueErrors.map(
|
||||
(error, index) =>
|
||||
error?.message && <li key={error.message ?? index}>{error.message}</li>,
|
||||
)}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
if (!content) return null;
|
||||
|
||||
return (
|
||||
<div
|
||||
role="alert"
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Toggle as TogglePrimitive } from "@base-ui/react/toggle";
|
||||
import { ToggleGroup as ToggleGroupPrimitive } from "@base-ui/react/toggle-group";
|
||||
import { type VariantProps } from "class-variance-authority";
|
||||
import * as React from "react";
|
||||
import { useMemo } from "react";
|
||||
|
||||
import { toggleVariants } from "@/components/ui/toggle";
|
||||
import { cn } from "@/lib/utils";
|
||||
@@ -33,6 +34,10 @@ function ToggleGroup({
|
||||
spacing?: number;
|
||||
orientation?: "horizontal" | "vertical";
|
||||
}) {
|
||||
const contextValue = useMemo(
|
||||
() => ({ variant, size, spacing, orientation }),
|
||||
[variant, size, spacing, orientation],
|
||||
);
|
||||
return (
|
||||
<ToggleGroupPrimitive
|
||||
data-slot="toggle-group"
|
||||
@@ -49,9 +54,7 @@ function ToggleGroup({
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<ToggleGroupContext.Provider value={{ variant, size, spacing, orientation }}>
|
||||
{children}
|
||||
</ToggleGroupContext.Provider>
|
||||
<ToggleGroupContext.Provider value={contextValue}>{children}</ToggleGroupContext.Provider>
|
||||
</ToggleGroupPrimitive>
|
||||
);
|
||||
}
|
||||
@@ -63,7 +66,7 @@ function ToggleGroupItem({
|
||||
size = "default",
|
||||
...props
|
||||
}: TogglePrimitive.Props & VariantProps<typeof toggleVariants>) {
|
||||
const context = React.useContext(ToggleGroupContext);
|
||||
const context = React.use(ToggleGroupContext);
|
||||
|
||||
return (
|
||||
<TogglePrimitive
|
||||
|
||||
@@ -92,7 +92,7 @@ function TooltipContent({
|
||||
}
|
||||
|
||||
function useTooltipContext(componentName: string) {
|
||||
const ctx = React.useContext(TooltipContext);
|
||||
const ctx = React.use(TooltipContext);
|
||||
|
||||
if (!ctx) {
|
||||
throw new Error(`${componentName} must be used within <Tooltip>.`);
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
import type {
|
||||
AppSpec,
|
||||
CategoryId,
|
||||
InstallHome,
|
||||
Module,
|
||||
Resolved,
|
||||
ResolvedEntry,
|
||||
TemplateRef,
|
||||
} from "@stanza/registry";
|
||||
import type { AppSpec, CategoryId, Module, Resolved, ResolvedEntry } from "@stanza/registry";
|
||||
import {
|
||||
categoryHome,
|
||||
categoryOrder,
|
||||
defaultWebApp,
|
||||
emptyManifest,
|
||||
@@ -46,10 +37,10 @@ export function parseSelections(search: BuilderSearch): {
|
||||
for (const category of KNOWN_CATEGORIES) {
|
||||
const value = search[category];
|
||||
if (typeof value === "string" && value.length > 0) {
|
||||
const ids = value
|
||||
.split(",")
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean);
|
||||
const ids = value.split(",").flatMap((s) => {
|
||||
const trimmed = s.trim();
|
||||
return trimmed ? [trimmed] : [];
|
||||
});
|
||||
if (ids.length > 0) selections[category] = ids;
|
||||
}
|
||||
}
|
||||
@@ -160,65 +151,12 @@ export function pruneUnresolved(
|
||||
}
|
||||
}
|
||||
|
||||
export type SelectedFile = {
|
||||
path: string;
|
||||
template: TemplateRef;
|
||||
owner: { category: CategoryId; module: string };
|
||||
};
|
||||
|
||||
/**
|
||||
* Default app list for the web builder. Single-app today (matches what
|
||||
* `stanza init` produces); multi-app builder UX is a planned follow-up.
|
||||
*/
|
||||
export const DEFAULT_BUILDER_APPS: readonly AppSpec[] = [defaultWebApp()];
|
||||
|
||||
/**
|
||||
* Derive the full file list stanza will write for the current selection.
|
||||
* Mirrors codemod-runner's resolution via `categoryHome`:
|
||||
* - repo → repo root · app → each app's dir · package → `packages/<dir>/`.
|
||||
* Categories are emitted in `categoryOrder`. Each `scope: "app"` template
|
||||
* emits once per app in `apps` (the builder defaults to a single web app).
|
||||
*/
|
||||
export function selectedFiles(
|
||||
resolved: Resolved,
|
||||
apps: readonly AppSpec[] = DEFAULT_BUILDER_APPS,
|
||||
): SelectedFile[] {
|
||||
const out: SelectedFile[] = [];
|
||||
for (const category of categoryOrder) {
|
||||
const home = categoryHome(category);
|
||||
for (const entry of resolved[category] ?? []) {
|
||||
for (const tpl of entry.adapter.templates ?? []) {
|
||||
if (tpl.scope === "app") {
|
||||
for (const app of apps) {
|
||||
out.push({
|
||||
path: resolveTemplatePath(tpl, home, app),
|
||||
template: tpl,
|
||||
owner: { category, module: entry.module.id },
|
||||
});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
out.push({
|
||||
path: resolveTemplatePath(tpl, home, apps[0]!),
|
||||
template: tpl,
|
||||
owner: { category, module: entry.module.id },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function resolveTemplatePath(tpl: TemplateRef, home: InstallHome, app: AppSpec): string {
|
||||
if (tpl.scope === "repo") return tpl.dest;
|
||||
if (tpl.scope === "package") {
|
||||
// Defensive: if a module declares `scope: "package"` for a non-package home,
|
||||
// the CLI runner would error; the preview just falls back to repo root.
|
||||
return home.kind === "package" ? `packages/${home.dir}/${tpl.dest}` : tpl.dest;
|
||||
}
|
||||
return `${app.dir.replace(/\/$/, "")}/${tpl.dest}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the `<pm> create stanza` command from the current state. npm needs a
|
||||
* `--` separator to forward flags; pnpm/bun pass them through directly.
|
||||
|
||||
@@ -33,46 +33,56 @@ async function buildIndex(): Promise<ModuleIndex> {
|
||||
const db = create({ schema: moduleSchema });
|
||||
const summaries = new Map<string, ModuleSummary>();
|
||||
|
||||
for (const summary of index.modules) {
|
||||
let mod: Module | null = null;
|
||||
try {
|
||||
mod = await loadRegistryFile<Module>(`modules/${summary.category}-${summary.id}.json`);
|
||||
} catch {
|
||||
// Per-module file missing (shouldn't happen for first-party modules, but
|
||||
// be tolerant): fall back to summary-only indexing.
|
||||
}
|
||||
|
||||
const deps = new Set<string>();
|
||||
const envNames = new Set<string>();
|
||||
const envDescriptions: string[] = [];
|
||||
if (mod) {
|
||||
for (const k of Object.keys(mod.dependencies ?? {})) deps.add(k);
|
||||
for (const k of Object.keys(mod.devDependencies ?? {})) deps.add(k);
|
||||
for (const e of mod.env ?? []) {
|
||||
envNames.add(e.name);
|
||||
if (e.description) envDescriptions.push(e.description);
|
||||
// Per-module file missing (shouldn't happen for first-party modules, but
|
||||
// be tolerant): fall back to summary-only indexing via `mod: null`.
|
||||
const loaded = await Promise.all(
|
||||
index.modules.map(async (summary) => {
|
||||
try {
|
||||
const mod = await loadRegistryFile<Module>(
|
||||
`modules/${summary.category}-${summary.id}.json`,
|
||||
);
|
||||
return { summary, mod };
|
||||
} catch {
|
||||
return { summary, mod: null as Module | null };
|
||||
}
|
||||
for (const adapter of mod.adapters) {
|
||||
for (const k of Object.keys(adapter.dependencies ?? {})) deps.add(k);
|
||||
for (const k of Object.keys(adapter.devDependencies ?? {})) deps.add(k);
|
||||
for (const e of adapter.env ?? []) {
|
||||
}),
|
||||
);
|
||||
|
||||
const inserted = await Promise.all(
|
||||
loaded.map(async ({ summary, mod }) => {
|
||||
const deps = new Set<string>();
|
||||
const envNames = new Set<string>();
|
||||
const envDescriptions: string[] = [];
|
||||
if (mod) {
|
||||
for (const k of Object.keys(mod.dependencies ?? {})) deps.add(k);
|
||||
for (const k of Object.keys(mod.devDependencies ?? {})) deps.add(k);
|
||||
for (const e of mod.env ?? []) {
|
||||
envNames.add(e.name);
|
||||
if (e.description) envDescriptions.push(e.description);
|
||||
}
|
||||
for (const adapter of mod.adapters) {
|
||||
for (const k of Object.keys(adapter.dependencies ?? {})) deps.add(k);
|
||||
for (const k of Object.keys(adapter.devDependencies ?? {})) deps.add(k);
|
||||
for (const e of adapter.env ?? []) {
|
||||
envNames.add(e.name);
|
||||
if (e.description) envDescriptions.push(e.description);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const id = await insert(db, {
|
||||
category: summary.category,
|
||||
moduleId: summary.id,
|
||||
label: summary.label,
|
||||
description: summary.description,
|
||||
deps: [...deps].join(" "),
|
||||
envNames: [...envNames].join(" "),
|
||||
envDescriptions: envDescriptions.join(" "),
|
||||
});
|
||||
summaries.set(id, summary);
|
||||
}
|
||||
const id = await insert(db, {
|
||||
category: summary.category,
|
||||
moduleId: summary.id,
|
||||
label: summary.label,
|
||||
description: summary.description,
|
||||
deps: [...deps].join(" "),
|
||||
envNames: [...envNames].join(" "),
|
||||
envDescriptions: envDescriptions.join(" "),
|
||||
});
|
||||
return { id, summary };
|
||||
}),
|
||||
);
|
||||
for (const { id, summary } of inserted) summaries.set(id, summary);
|
||||
|
||||
return { db, summaries };
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { createFileRoute, notFound } from "@tanstack/react-router";
|
||||
import { createServerFn } from "@tanstack/react-start";
|
||||
import { renderServerComponent } from "@tanstack/react-start/rsc";
|
||||
import { DocsBody } from "fumadocs-ui/layouts/docs/page";
|
||||
import { createRelativeLink } from "fumadocs-ui/mdx";
|
||||
import { RootProvider } from "fumadocs-ui/provider/tanstack";
|
||||
|
||||
import { DocsSidebar } from "@/components/docs/docs-sidebar";
|
||||
@@ -37,7 +38,11 @@ const getDocLayout = createServerFn({ method: "GET" })
|
||||
</p>
|
||||
)}
|
||||
<DocsBody className="mt-8">
|
||||
<MDX components={getMDXComponents()} />
|
||||
<MDX
|
||||
components={getMDXComponents({
|
||||
a: createRelativeLink(source, page),
|
||||
})}
|
||||
/>
|
||||
</DocsBody>
|
||||
</article>
|
||||
<DocsToc toc={page.data.toc} />
|
||||
|
||||
@@ -203,7 +203,7 @@ function StatsPage() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
<p className="mt-4 text-xs leading-relaxed text-muted-foreground">
|
||||
<p className="mt-4 text-xs leading-7 text-muted-foreground">
|
||||
<strong className="font-medium text-foreground">Opt out</strong> per-invocation with{" "}
|
||||
<code>--no-telemetry</code>, persistently with <code>STANZA_TELEMETRY=0</code> or{" "}
|
||||
<code>DO_NOT_TRACK=1</code>. More in the{" "}
|
||||
|
||||
@@ -114,7 +114,11 @@ function computePeerOptions(
|
||||
out[category] = constraint;
|
||||
} else {
|
||||
// "any" or undefined — list every module that lives in this category.
|
||||
out[category] = index.modules.filter((m) => m.category === category).map((m) => m.id);
|
||||
const ids: string[] = [];
|
||||
for (const m of index.modules) {
|
||||
if (m.category === category) ids.push(m.id);
|
||||
}
|
||||
out[category] = ids;
|
||||
}
|
||||
// De-dup and keep declaration order. Also union in any ids referenced by
|
||||
// adapters that weren't in the declared list — defensive against authors
|
||||
@@ -203,7 +207,7 @@ function pickAdapter(module: Module, peers: Partial<Record<CategoryId, string>>)
|
||||
* - `dependencies` / `devDependencies` / `scripts` merge per-key
|
||||
* - `env` merges by `name` (adapter overrides module)
|
||||
*/
|
||||
export function mergeInstallFields(module: Module, adapter: ModuleAdapter): EffectiveInstallFields {
|
||||
function mergeInstallFields(module: Module, adapter: ModuleAdapter): EffectiveInstallFields {
|
||||
const dependencies: Record<string, string> = {
|
||||
...module.dependencies,
|
||||
...adapter.dependencies,
|
||||
|
||||
@@ -29,9 +29,5 @@
|
||||
"typescript": "^6.0.3",
|
||||
"vite-plus": "catalog:"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22",
|
||||
"pnpm": ">=10"
|
||||
},
|
||||
"packageManager": "pnpm@10.33.4"
|
||||
}
|
||||
|
||||
Generated
+63
-123
@@ -130,15 +130,9 @@ importers:
|
||||
'@tanstack/react-router-devtools':
|
||||
specifier: ^1.167.0
|
||||
version: 1.167.0(@tanstack/react-router@1.170.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@tanstack/router-core@1.171.6)(csstype@3.2.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tanstack/react-router-ssr-query':
|
||||
specifier: ^1.167.0
|
||||
version: 1.167.0(@tanstack/query-core@5.100.14)(@tanstack/react-query@5.100.14(react@19.2.6))(@tanstack/react-router@1.170.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@tanstack/router-core@1.171.6)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tanstack/react-start':
|
||||
specifier: ^1.168.13
|
||||
version: 1.168.13(@vitejs/plugin-rsc@0.5.26(@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3))(crossws@0.4.5(srvx@0.11.16))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tanstack/router-plugin':
|
||||
specifier: ^1.168.11
|
||||
version: 1.168.11(@tanstack/react-router@1.170.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3))
|
||||
'@vercel/functions':
|
||||
specifier: ^3.6.0
|
||||
version: 3.6.0
|
||||
@@ -152,14 +146,11 @@ importers:
|
||||
specifier: ^16.9.1
|
||||
version: 16.9.1(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.15)(lucide-react@1.16.0(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3)
|
||||
fumadocs-mdx:
|
||||
specifier: ^15.0.8
|
||||
version: 15.0.8(@types/mdast@4.0.4)(@types/mdx@2.0.13)(@types/react@19.2.15)(@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3))(fumadocs-core@16.9.1(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.15)(lucide-react@1.16.0(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3))(react@19.2.6)(rolldown@1.0.2)
|
||||
specifier: ^15.0.9
|
||||
version: 15.0.9(@types/mdast@4.0.4)(@types/mdx@2.0.13)(@types/react@19.2.15)(@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3))(fumadocs-core@16.9.1(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.15)(lucide-react@1.16.0(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3))(react@19.2.6)(rolldown@1.0.2)
|
||||
fumadocs-ui:
|
||||
specifier: npm:@fumadocs/base-ui@^16.9.1
|
||||
version: '@fumadocs/base-ui@16.9.1(@tailwindcss/oxide@4.3.0)(@takumi-rs/image-response@1.5.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/mdx@2.0.13)(@types/react@19.2.15)(fumadocs-core@16.9.1(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.15)(lucide-react@1.16.0(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(tailwindcss@4.3.0)'
|
||||
handlebars:
|
||||
specifier: ^4.7.9
|
||||
version: 4.7.9
|
||||
lru-cache:
|
||||
specifier: ^11.5.0
|
||||
version: 11.5.0
|
||||
@@ -167,11 +158,11 @@ importers:
|
||||
specifier: ^3.0.260522-beta
|
||||
version: 3.0.260522-beta(@vercel/functions@3.6.0)(@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3))(chokidar@5.0.0)(dotenv@17.4.2)(jiti@2.7.0)(lru-cache@11.5.0)
|
||||
posthog-js:
|
||||
specifier: ^1.376.0
|
||||
version: 1.376.0
|
||||
specifier: ^1.376.2
|
||||
version: 1.376.2
|
||||
posthog-node:
|
||||
specifier: ^5.35.1
|
||||
version: 5.35.1
|
||||
specifier: ^5.35.4
|
||||
version: 5.35.4
|
||||
react:
|
||||
specifier: ^19.2.6
|
||||
version: 19.2.6
|
||||
@@ -248,9 +239,6 @@ importers:
|
||||
vitest:
|
||||
specifier: npm:@voidzero-dev/vite-plus-test@^0.1.22
|
||||
version: '@voidzero-dev/vite-plus-test@0.1.22(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3))(esbuild@0.28.0)(jiti@2.7.0)(jsdom@29.1.1(@noble/hashes@1.8.0))(typescript@6.0.3)'
|
||||
web-vitals:
|
||||
specifier: ^5.2.0
|
||||
version: 5.2.0
|
||||
|
||||
packages/codemods:
|
||||
dependencies:
|
||||
@@ -729,8 +717,8 @@ packages:
|
||||
resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==}
|
||||
engines: {node: '>=20.19.0'}
|
||||
|
||||
'@dotenvx/dotenvx@1.68.1':
|
||||
resolution: {integrity: sha512-UQgds8NIGJEi/goJtAdPseaVhwz6xWVDik7P0Y1M35KKjTcjWZdsWWaswvDse6cxiBQel9Q7MQFMRxdMAQ2tqA==}
|
||||
'@dotenvx/dotenvx@1.69.1':
|
||||
resolution: {integrity: sha512-kwQB5KcAegxw/+NGUgXAo5ovyOSjlMhoXSSnSEpDhoHJwzMcMO0HE1U0VCYZ7jbAeCMGamed9XdWzOA5ixtTNg==}
|
||||
hasBin: true
|
||||
|
||||
'@ecies/ciphers@0.2.6':
|
||||
@@ -971,12 +959,12 @@ packages:
|
||||
peerDependencies:
|
||||
hono: ^4
|
||||
|
||||
'@inquirer/ansi@2.0.5':
|
||||
resolution: {integrity: sha512-doc2sWgJpbFQ64UflSVd17ibMGDuxO1yKgOgLMwavzESnXjFWJqUeG8saYosqKpHp4kWiM5x1nXvEjbpx90gzw==}
|
||||
'@inquirer/ansi@2.0.6':
|
||||
resolution: {integrity: sha512-I/INw4sHGlVZ/afZOckpLiDP9SmbMl1g/GCqeHjLw1Afw/0PlRs2tRFgTGWmdI0hoNuWZn3y2iHNmG1vyECyQQ==}
|
||||
engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'}
|
||||
|
||||
'@inquirer/confirm@6.0.13':
|
||||
resolution: {integrity: sha512-wkGPC7yJ5WJk1DJ5SX7fzk+gfj4BM8cf5dDDi71B/551xHrdsZVRJOC0WyikXd0pEsb/9cLniuE4atbsMqmFkw==}
|
||||
'@inquirer/confirm@6.1.0':
|
||||
resolution: {integrity: sha512-USpeB76eqK7yGricDlGAupxWlp4a59qpeZOoNWaxO/nJln7agpJveyNkQ1d5u8YXG6TOqxZtQpKPORQQDrdVsA==}
|
||||
engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'}
|
||||
peerDependencies:
|
||||
'@types/node': '>=18'
|
||||
@@ -984,8 +972,8 @@ packages:
|
||||
'@types/node':
|
||||
optional: true
|
||||
|
||||
'@inquirer/core@11.1.10':
|
||||
resolution: {integrity: sha512-a4Q5BXHQAHa9eO202sTaFCHFYVB3x5fauDuThEAdZ9gfn76pSxiKU7wWcEH0N1O0XmQvNfQNU6QXpiRxmYQx+A==}
|
||||
'@inquirer/core@11.2.0':
|
||||
resolution: {integrity: sha512-joR1YS2sI0us+9d0I8ViqFbrRLONO8CFTuyvBX4ZVBSch+VsZiugUABdrhBXXJR1VyEzvpz5SQCix3keETQ58g==}
|
||||
engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'}
|
||||
peerDependencies:
|
||||
'@types/node': '>=18'
|
||||
@@ -1002,12 +990,12 @@ packages:
|
||||
'@types/node':
|
||||
optional: true
|
||||
|
||||
'@inquirer/figures@2.0.5':
|
||||
resolution: {integrity: sha512-NsSs4kzfm12lNetHwAn3GEuH317IzpwrMCbOuMIVytpjnJ90YYHNwdRgYGuKmVxwuIqSgqk3M5qqQt1cDk0tGQ==}
|
||||
'@inquirer/figures@2.0.6':
|
||||
resolution: {integrity: sha512-dsZgQtH2t5Q6ah3aPbZbeEZAxsD9qQu0DXf01AltuEfRTm+NoLN6+rLVbr+4edeEbNCp/wBNM6mALRWtsQpfkw==}
|
||||
engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'}
|
||||
|
||||
'@inquirer/type@4.0.5':
|
||||
resolution: {integrity: sha512-aetVUNeKNc/VriqXlw1NRSW0zhMBB0W4bNbWRJgzRl/3d0QNDQFfk0GO5SDdtjMZVg6o8ZKEiadd7SCCzoOn5Q==}
|
||||
'@inquirer/type@4.0.6':
|
||||
resolution: {integrity: sha512-J+9tdxOskuYuGjsvGaq00AamhDgjR7anhEW2dP4QdQpFCMPngCeC/bCYWQ5NsMWZRdsy53is7kAHb/+7cwDk2g==}
|
||||
engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'}
|
||||
peerDependencies:
|
||||
'@types/node': '>=18'
|
||||
@@ -1615,11 +1603,11 @@ packages:
|
||||
'@polka/url@1.0.0-next.29':
|
||||
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
|
||||
|
||||
'@posthog/core@1.29.9':
|
||||
resolution: {integrity: sha512-DjvuIyBZ2Z/gBhtZlITlM2D8PlnMsHSQ1D78dbUYoVsgGguvanpJTobZObjLlFkybyvfZFYkpoJkFNI/2Pw4IQ==}
|
||||
'@posthog/core@1.29.11':
|
||||
resolution: {integrity: sha512-/4EF7oxAFSWJgaXxppT8bdYp7MGAnWFnKz994+MetTz/T6CKbYpjqIXHCofQXtcOXjEclTYj91igA+IkVFKiSg==}
|
||||
|
||||
'@posthog/types@1.376.0':
|
||||
resolution: {integrity: sha512-gbFfxCuZDs/D4QZMwdE+smD1jsuqgGpS6yKGHZZ19foxMy8RYHsU1E47iG1b88n/uN02fAabLibVwuxLtq8juw==}
|
||||
'@posthog/types@1.376.2':
|
||||
resolution: {integrity: sha512-Y3ROpAxNqgcy2G0w6JoG5Gt+P6WNY2lkHTPMPzWqexRwemYbFegDi5AifDyD9/tstKTlOYKTTExtaJ5EBcghyQ==}
|
||||
|
||||
'@protobufjs/aspromise@1.1.2':
|
||||
resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
|
||||
@@ -2048,9 +2036,6 @@ packages:
|
||||
resolution: {integrity: sha512-hB01dd4rlsYcTCNP7wK186jgAe6K5qimgM1Y5Jtvz+9PUaILvpmeLLjmQNUNSO1l23lIt+CeQR6mO1mjlPvRtQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@tanstack/query-core@5.100.14':
|
||||
resolution: {integrity: sha512-5X41dGpxgeaHISCRW2oYwcSycZeULZzAunaudXT9ov1KOTj9xwt0CH6hbwqP1/z74ZWF7rYFnDpyYH07XFcZew==}
|
||||
|
||||
'@tanstack/react-devtools@0.10.5':
|
||||
resolution: {integrity: sha512-orVsRJ7oAXFb7oyafQCgx9YuK44jpILh5T/ddYuxAsolNfN5DZBr5/NLrWErD7HCGIzvYzg1TZI4sPxmiKvtvA==}
|
||||
engines: {node: '>=18'}
|
||||
@@ -2074,11 +2059,6 @@ packages:
|
||||
react: '>=16.8'
|
||||
react-dom: '>=16.8'
|
||||
|
||||
'@tanstack/react-query@5.100.14':
|
||||
resolution: {integrity: sha512-oOr6aRdSFEwWhzxEkD/9ZcItM3+LjBSkeVmadWKwUssAHTsqd/7bOjWrX4AbvEkoEhgAxzN0Xk6H/aYzXiYBAw==}
|
||||
peerDependencies:
|
||||
react: ^18 || ^19
|
||||
|
||||
'@tanstack/react-router-devtools@1.167.0':
|
||||
resolution: {integrity: sha512-nGw095EG7IHx0h5NtlEmzf6vcCTaFNPWdTSuDKazajhN0ct/v/TkekJ9J6KYUCeV1a8/2ZmToc58M+0rrOyn7w==}
|
||||
engines: {node: '>=20.19'}
|
||||
@@ -2091,16 +2071,6 @@ packages:
|
||||
'@tanstack/router-core':
|
||||
optional: true
|
||||
|
||||
'@tanstack/react-router-ssr-query@1.167.0':
|
||||
resolution: {integrity: sha512-lJC/qySnlB0RaPCwCS4BQbdsDwyaPP2C8tzuEUsrwPTxm8TVYonYv3sptoSVhY0C2f8i5041X8gbRL7+lSY8BQ==}
|
||||
engines: {node: '>=20.19'}
|
||||
peerDependencies:
|
||||
'@tanstack/query-core': '>=5.90.0'
|
||||
'@tanstack/react-query': '>=5.90.0'
|
||||
'@tanstack/react-router': '>=1.127.0'
|
||||
react: '>=18.0.0 || >=19.0.0'
|
||||
react-dom: '>=18.0.0 || >=19.0.0'
|
||||
|
||||
'@tanstack/react-router@1.170.8':
|
||||
resolution: {integrity: sha512-Qw2ju6jjnIsMpuW+VrnHZWHuugqs592PWsnI56sG28qNhg14CgRLahOcNajfuJR9P4MxKGP94WVzmFKSYUz/ig==}
|
||||
engines: {node: '>=20.19'}
|
||||
@@ -2207,13 +2177,6 @@ packages:
|
||||
webpack:
|
||||
optional: true
|
||||
|
||||
'@tanstack/router-ssr-query-core@1.169.0':
|
||||
resolution: {integrity: sha512-zueXiVsF1BbVc8iaalHILRGURDCVlTTOVdUy/36VVeKVKr778vqJzyus+erEoVu5x4vl4DBGGM8RHqCaus1TQQ==}
|
||||
engines: {node: '>=20.19'}
|
||||
peerDependencies:
|
||||
'@tanstack/query-core': '>=5.90.0'
|
||||
'@tanstack/router-core': '>=1.127.0'
|
||||
|
||||
'@tanstack/router-utils@1.162.1':
|
||||
resolution: {integrity: sha512-62layyTGmclHDQS/eidwKRfN1hhCKwViG7iEBcVmL0MXgcAB3OOucWCEcDDGd9Cu11H6b4QQ5oOo47MWIqwz0A==}
|
||||
engines: {node: '>=20.19'}
|
||||
@@ -2857,8 +2820,8 @@ packages:
|
||||
dataloader@1.4.0:
|
||||
resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==}
|
||||
|
||||
dayjs@1.11.20:
|
||||
resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==}
|
||||
dayjs@1.11.21:
|
||||
resolution: {integrity: sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==}
|
||||
|
||||
db0@0.3.4:
|
||||
resolution: {integrity: sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==}
|
||||
@@ -2965,8 +2928,8 @@ packages:
|
||||
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
|
||||
engines: {node: '>= 4'}
|
||||
|
||||
dompurify@3.4.5:
|
||||
resolution: {integrity: sha512-OrwIBKsdNSVEeubdJ1HBv/wNENRM9ytAVCv7YXt//A3vPdVMNuACRqK9mXCGCBW2ln7BT/A4X0jXHo2Gu89miA==}
|
||||
dompurify@3.4.6:
|
||||
resolution: {integrity: sha512-+7gzEI8trIIQkVCvQ3ucGtNfH3nOmDgVTzc62rAAOlMxLth78pwpPoZCPc7CyRzAQF89MqcfPdEWkDwnjgqktg==}
|
||||
|
||||
domutils@3.2.2:
|
||||
resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
|
||||
@@ -3312,8 +3275,8 @@ packages:
|
||||
zod:
|
||||
optional: true
|
||||
|
||||
fumadocs-mdx@15.0.8:
|
||||
resolution: {integrity: sha512-CT9odtkLmpjH/DOTEW8prKY6SYzr7rmHmJj+ZBkvppPMNFstvTLvxxpY0ri8/9RPmCTZQUUMdNBxcPzhsHIcgw==}
|
||||
fumadocs-mdx@15.0.9:
|
||||
resolution: {integrity: sha512-ulKFGcx1r5Irk3Cu7h8M/DH66xba9evdOftURBbnASXWwJIIIahAp7s8oQdDuXtvkzjfv4/M/LpkTxrhkiS2JQ==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@types/mdast': '*'
|
||||
@@ -4079,9 +4042,9 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
mute-stream@3.0.0:
|
||||
resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==}
|
||||
engines: {node: ^20.17.0 || >=22.9.0}
|
||||
mute-stream@4.0.0:
|
||||
resolution: {integrity: sha512-gSrprq0fJ3EiOErzjdIZrjysVVmJ4uu1QWfCDss5LypA5OXvrMje5Ym5z6V6RLyJ2eF87lasX7t6a0AnFvZblg==}
|
||||
engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0}
|
||||
|
||||
nanoid@3.3.12:
|
||||
resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==}
|
||||
@@ -4365,11 +4328,11 @@ packages:
|
||||
resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
||||
posthog-js@1.376.0:
|
||||
resolution: {integrity: sha512-YGfQ6gSmqmEh287PHjXRDJ9zML3Su1UIt1+xjRy7Yk6yW43Sc7sFK3CpCkLchCGhIA4x6VaqK+LaqB+7+MCo7A==}
|
||||
posthog-js@1.376.2:
|
||||
resolution: {integrity: sha512-Anz2pCp7dcNbammTExiZpcKC08dxfrHYaJgaXH6rq5x3Zcfj/4FkcMJF2cGCrdQXel5Y4vftiVSseZda0HAQTQ==}
|
||||
|
||||
posthog-node@5.35.1:
|
||||
resolution: {integrity: sha512-F9S3pEIYfGEVjLYIFHKaqfTIhn5IpS02Dkp7C/f1rqr4Z67Iqbt4jbKO8raWsT0veEI3rUp+DKuXLW1hN07FQA==}
|
||||
posthog-node@5.35.4:
|
||||
resolution: {integrity: sha512-X4OCh3Lr4tfyUc/67ssDhe5cD3fwFVq4QBdNpQwpjtuOCGWZ4wDONc6zSkE1i6FVUkTc884GvwphorKC6To/BQ==}
|
||||
engines: {node: ^20.20.0 || >=22.22.0}
|
||||
peerDependencies:
|
||||
rxjs: ^7.0.0
|
||||
@@ -5724,7 +5687,7 @@ snapshots:
|
||||
|
||||
'@csstools/css-tokenizer@4.0.0': {}
|
||||
|
||||
'@dotenvx/dotenvx@1.68.1':
|
||||
'@dotenvx/dotenvx@1.69.1':
|
||||
dependencies:
|
||||
commander: 11.1.0
|
||||
dotenv: 17.4.2
|
||||
@@ -5898,23 +5861,23 @@ snapshots:
|
||||
dependencies:
|
||||
hono: 4.12.23
|
||||
|
||||
'@inquirer/ansi@2.0.5': {}
|
||||
'@inquirer/ansi@2.0.6': {}
|
||||
|
||||
'@inquirer/confirm@6.0.13(@types/node@25.9.1)':
|
||||
'@inquirer/confirm@6.1.0(@types/node@25.9.1)':
|
||||
dependencies:
|
||||
'@inquirer/core': 11.1.10(@types/node@25.9.1)
|
||||
'@inquirer/type': 4.0.5(@types/node@25.9.1)
|
||||
'@inquirer/core': 11.2.0(@types/node@25.9.1)
|
||||
'@inquirer/type': 4.0.6(@types/node@25.9.1)
|
||||
optionalDependencies:
|
||||
'@types/node': 25.9.1
|
||||
|
||||
'@inquirer/core@11.1.10(@types/node@25.9.1)':
|
||||
'@inquirer/core@11.2.0(@types/node@25.9.1)':
|
||||
dependencies:
|
||||
'@inquirer/ansi': 2.0.5
|
||||
'@inquirer/figures': 2.0.5
|
||||
'@inquirer/type': 4.0.5(@types/node@25.9.1)
|
||||
'@inquirer/ansi': 2.0.6
|
||||
'@inquirer/figures': 2.0.6
|
||||
'@inquirer/type': 4.0.6(@types/node@25.9.1)
|
||||
cli-width: 4.1.0
|
||||
fast-wrap-ansi: 0.2.2
|
||||
mute-stream: 3.0.0
|
||||
mute-stream: 4.0.0
|
||||
signal-exit: 4.1.0
|
||||
optionalDependencies:
|
||||
'@types/node': 25.9.1
|
||||
@@ -5926,9 +5889,9 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@types/node': 25.9.1
|
||||
|
||||
'@inquirer/figures@2.0.5': {}
|
||||
'@inquirer/figures@2.0.6': {}
|
||||
|
||||
'@inquirer/type@4.0.5(@types/node@25.9.1)':
|
||||
'@inquirer/type@4.0.6(@types/node@25.9.1)':
|
||||
optionalDependencies:
|
||||
'@types/node': 25.9.1
|
||||
|
||||
@@ -6377,11 +6340,11 @@ snapshots:
|
||||
|
||||
'@polka/url@1.0.0-next.29': {}
|
||||
|
||||
'@posthog/core@1.29.9':
|
||||
'@posthog/core@1.29.11':
|
||||
dependencies:
|
||||
'@posthog/types': 1.376.0
|
||||
'@posthog/types': 1.376.2
|
||||
|
||||
'@posthog/types@1.376.0': {}
|
||||
'@posthog/types@1.376.2': {}
|
||||
|
||||
'@protobufjs/aspromise@1.1.2': {}
|
||||
|
||||
@@ -6693,7 +6656,7 @@ snapshots:
|
||||
'@tanstack/devtools-ui@0.5.2(csstype@3.2.3)(solid-js@1.9.13)':
|
||||
dependencies:
|
||||
clsx: 2.1.1
|
||||
dayjs: 1.11.20
|
||||
dayjs: 1.11.21
|
||||
goober: 2.1.19(csstype@3.2.3)
|
||||
solid-js: 1.9.13
|
||||
transitivePeerDependencies:
|
||||
@@ -6742,8 +6705,6 @@ snapshots:
|
||||
'@tanstack/devtools-event-client': 0.4.3
|
||||
'@tanstack/store': 0.11.0
|
||||
|
||||
'@tanstack/query-core@5.100.14': {}
|
||||
|
||||
'@tanstack/react-devtools@0.10.5(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(csstype@3.2.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(solid-js@1.9.13)':
|
||||
dependencies:
|
||||
'@tanstack/devtools': 0.12.2(csstype@3.2.3)(solid-js@1.9.13)
|
||||
@@ -6771,11 +6732,6 @@ snapshots:
|
||||
react: 19.2.6
|
||||
react-dom: 19.2.6(react@19.2.6)
|
||||
|
||||
'@tanstack/react-query@5.100.14(react@19.2.6)':
|
||||
dependencies:
|
||||
'@tanstack/query-core': 5.100.14
|
||||
react: 19.2.6
|
||||
|
||||
'@tanstack/react-router-devtools@1.167.0(@tanstack/react-router@1.170.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@tanstack/router-core@1.171.6)(csstype@3.2.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
|
||||
dependencies:
|
||||
'@tanstack/react-router': 1.170.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
@@ -6787,17 +6743,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- csstype
|
||||
|
||||
'@tanstack/react-router-ssr-query@1.167.0(@tanstack/query-core@5.100.14)(@tanstack/react-query@5.100.14(react@19.2.6))(@tanstack/react-router@1.170.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@tanstack/router-core@1.171.6)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
|
||||
dependencies:
|
||||
'@tanstack/query-core': 5.100.14
|
||||
'@tanstack/react-query': 5.100.14(react@19.2.6)
|
||||
'@tanstack/react-router': 1.170.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tanstack/router-ssr-query-core': 1.169.0(@tanstack/query-core@5.100.14)(@tanstack/router-core@1.171.6)
|
||||
react: 19.2.6
|
||||
react-dom: 19.2.6(react@19.2.6)
|
||||
transitivePeerDependencies:
|
||||
- '@tanstack/router-core'
|
||||
|
||||
'@tanstack/react-router@1.170.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
|
||||
dependencies:
|
||||
'@tanstack/history': 1.162.0
|
||||
@@ -6938,11 +6883,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@tanstack/router-ssr-query-core@1.169.0(@tanstack/query-core@5.100.14)(@tanstack/router-core@1.171.6)':
|
||||
dependencies:
|
||||
'@tanstack/query-core': 5.100.14
|
||||
'@tanstack/router-core': 1.171.6
|
||||
|
||||
'@tanstack/router-utils@1.162.1':
|
||||
dependencies:
|
||||
'@babel/core': 7.29.7
|
||||
@@ -7543,7 +7483,7 @@ snapshots:
|
||||
|
||||
dataloader@1.4.0: {}
|
||||
|
||||
dayjs@1.11.20: {}
|
||||
dayjs@1.11.21: {}
|
||||
|
||||
db0@0.3.4: {}
|
||||
|
||||
@@ -7604,7 +7544,7 @@ snapshots:
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
|
||||
dompurify@3.4.5:
|
||||
dompurify@3.4.6:
|
||||
optionalDependencies:
|
||||
'@types/trusted-types': 2.0.7
|
||||
|
||||
@@ -7983,7 +7923,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
fumadocs-mdx@15.0.8(@types/mdast@4.0.4)(@types/mdx@2.0.13)(@types/react@19.2.15)(@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3))(fumadocs-core@16.9.1(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.15)(lucide-react@1.16.0(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3))(react@19.2.6)(rolldown@1.0.2):
|
||||
fumadocs-mdx@15.0.9(@types/mdast@4.0.4)(@types/mdx@2.0.13)(@types/react@19.2.15)(@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(typescript@6.0.3))(fumadocs-core@16.9.1(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.15)(lucide-react@1.16.0(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3))(react@19.2.6)(rolldown@1.0.2):
|
||||
dependencies:
|
||||
'@mdx-js/mdx': 3.1.1
|
||||
'@standard-schema/spec': 1.1.0
|
||||
@@ -8983,7 +8923,7 @@ snapshots:
|
||||
|
||||
msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3):
|
||||
dependencies:
|
||||
'@inquirer/confirm': 6.0.13(@types/node@25.9.1)
|
||||
'@inquirer/confirm': 6.1.0(@types/node@25.9.1)
|
||||
'@mswjs/interceptors': 0.41.9
|
||||
'@open-draft/deferred-promise': 3.0.0
|
||||
'@types/statuses': 2.0.6
|
||||
@@ -9006,7 +8946,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
|
||||
mute-stream@3.0.0: {}
|
||||
mute-stream@4.0.0: {}
|
||||
|
||||
nanoid@3.3.12: {}
|
||||
|
||||
@@ -9349,25 +9289,25 @@ snapshots:
|
||||
picocolors: 1.1.1
|
||||
source-map-js: 1.2.1
|
||||
|
||||
posthog-js@1.376.0:
|
||||
posthog-js@1.376.2:
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.1
|
||||
'@opentelemetry/api-logs': 0.208.0
|
||||
'@opentelemetry/exporter-logs-otlp-http': 0.208.0(@opentelemetry/api@1.9.1)
|
||||
'@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1)
|
||||
'@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.1)
|
||||
'@posthog/core': 1.29.9
|
||||
'@posthog/types': 1.376.0
|
||||
'@posthog/core': 1.29.11
|
||||
'@posthog/types': 1.376.2
|
||||
core-js: 3.49.0
|
||||
dompurify: 3.4.5
|
||||
dompurify: 3.4.6
|
||||
fflate: 0.4.8
|
||||
preact: 10.29.2
|
||||
query-selector-shadow-dom: 1.0.1
|
||||
web-vitals: 5.2.0
|
||||
|
||||
posthog-node@5.35.1:
|
||||
posthog-node@5.35.4:
|
||||
dependencies:
|
||||
'@posthog/core': 1.29.9
|
||||
'@posthog/core': 1.29.11
|
||||
|
||||
powershell-utils@0.1.0: {}
|
||||
|
||||
@@ -9719,7 +9659,7 @@ snapshots:
|
||||
'@babel/parser': 7.29.7
|
||||
'@babel/plugin-transform-typescript': 7.29.7(@babel/core@7.29.7)
|
||||
'@babel/preset-typescript': 7.29.7(@babel/core@7.29.7)
|
||||
'@dotenvx/dotenvx': 1.68.1
|
||||
'@dotenvx/dotenvx': 1.69.1
|
||||
'@modelcontextprotocol/sdk': 1.29.0(zod@3.25.76)
|
||||
'@types/validate-npm-package-name': 4.0.2
|
||||
browserslist: 4.28.2
|
||||
|
||||
Reference in New Issue
Block a user