From 1d76100fbb96cfa6bfa21bbad49657535b9f3d1a Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 18 Oct 2026 20:58:57 +0000 Subject: [PATCH] docs: add JSDoc to VitNode core and the blog plugin Add concise English JSDoc to the developer-facing APIs of @vitnode/core and @vitnode/blog: plugin foundations (buildPlugin, buildApiPlugin, bindApiPlugin, buildModule, buildRoute, manifests), the Content Engine, fetchers and the API registry, events, cron, queues, notifications, WebSockets, widgets, the editor adapter, routing, app configuration, TanStack entry points, server context, AutoForm and form fields, tables, UI primitives, and every symbol the MDX docs import. Every batch was fact-checked against the source. Keep JSDoc in published declarations: the shared tsconfig sets removeComments, which stripped every comment from the .d.ts files the package build emits. Fixes: - AutoFormDateTime spread its rest props after its own onChange/onBlur, so a caller's onChange replaced the handler that writes the form value. The caller's handlers now run after the form update. - Plugin dashboard widgets never reached the AdminCP in TanStack hosts. They now travel on adminNav.admin.dashboard.widgets through admin-nav.gen.ts to the dashboard screen, which also loads the plugins' widget message namespaces. Docs: fix MDX examples importing APIs that don't exist (email adapters, search indexers, captcha, ApiPluginContract), the widget component props and the blog post event note. AGENTS.md gains a JSDoc rule and describes the generated plugin API registry entry. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016fFJwQoQUcq6FtMdeGUaHc --- AGENTS.md | 7 +- apps/web/content/docs/dev/captcha/index.mdx | 51 +++-- apps/web/content/docs/dev/email/index.mdx | 28 ++- .../docs/dev/events/built-in-events.mdx | 2 +- apps/web/content/docs/dev/fetcher.mdx | 2 +- .../dev/plugins/admin/dashboard-widgets.mdx | 81 ++++--- apps/web/content/docs/dev/search.mdx | 62 +++--- .../docs/dev/widgets/defining-a-block.mdx | 4 +- .../scripts/cli/builder/package-build.ts | 8 +- .../vitnode/src/api/adapters/sso/discord.ts | 27 +++ .../vitnode/src/api/adapters/sso/facebook.ts | 27 +++ .../vitnode/src/api/adapters/sso/google.ts | 27 +++ .../vitnode/src/api/adapters/storage/local.ts | 18 ++ packages/vitnode/src/api/builders.ts | 1 + packages/vitnode/src/api/config.ts | 25 +++ packages/vitnode/src/api/lib/ai/action.ts | 79 +++++++ packages/vitnode/src/api/lib/ai/decimal.ts | 10 + packages/vitnode/src/api/lib/ai/errors.ts | 17 ++ .../vitnode/src/api/lib/ai/html-structure.ts | 10 + packages/vitnode/src/api/lib/ai/registry.ts | 5 + packages/vitnode/src/api/lib/ai/usage-cost.ts | 15 ++ .../vitnode/src/api/lib/bind-api-plugin.ts | 20 ++ packages/vitnode/src/api/lib/cache-client.ts | 6 + packages/vitnode/src/api/lib/cache.ts | 43 +++- .../src/api/lib/check-staff-permission.ts | 34 +++ .../vitnode/src/api/lib/content-modules.ts | 31 +++ packages/vitnode/src/api/lib/cron.ts | 62 ++++++ .../vitnode/src/api/lib/editable-pages.ts | 15 ++ packages/vitnode/src/api/lib/events.ts | 41 ++++ .../vitnode/src/api/lib/logger-middleware.ts | 5 + .../src/api/lib/moderation/registry.ts | 3 + .../vitnode/src/api/lib/moderation/scopes.ts | 44 ++++ .../vitnode/src/api/lib/moderation/targets.ts | 38 ++++ packages/vitnode/src/api/lib/module.ts | 41 ++++ .../src/api/lib/notifications/registry.ts | 93 ++++++++ .../vitnode/src/api/lib/passkey-config.ts | 21 ++ .../vitnode/src/api/lib/permission-staff.ts | 38 ++++ packages/vitnode/src/api/lib/plugin.ts | 73 +++++++ packages/vitnode/src/api/lib/queue.ts | 55 +++++ packages/vitnode/src/api/lib/route.ts | 60 ++++++ .../src/api/lib/save-language-words.ts | 25 +++ packages/vitnode/src/api/lib/websocket.ts | 31 +++ .../vitnode/src/api/lib/with-pagination.ts | 52 +++++ .../src/api/middlewares/global.middleware.ts | 74 +++++++ .../api/middlewares/rate-limiter-config.ts | 35 +++ packages/vitnode/src/api/models/ai.ts | 54 +++++ packages/vitnode/src/api/models/email.ts | 46 ++++ packages/vitnode/src/api/models/events.ts | 62 ++++++ packages/vitnode/src/api/models/i18n.ts | 24 +++ .../src/api/models/notifications/index.ts | 30 +++ .../src/api/models/notifications/publish.ts | 19 ++ packages/vitnode/src/api/models/queue.ts | 30 +++ packages/vitnode/src/api/models/search.ts | 52 ++++- packages/vitnode/src/api/models/sso.ts | 29 +++ packages/vitnode/src/api/models/storage.ts | 61 +++++- packages/vitnode/src/blocks/area.ts | 5 + .../vitnode/src/blocks/built-in/index.tsx | 5 + packages/vitnode/src/blocks/define.ts | 53 +++++ packages/vitnode/src/blocks/edit.tsx | 15 ++ packages/vitnode/src/blocks/instance.ts | 2 + packages/vitnode/src/blocks/page.tsx | 16 ++ packages/vitnode/src/blocks/registry.ts | 19 ++ packages/vitnode/src/blocks/renderer.tsx | 21 ++ packages/vitnode/src/blocks/schema.ts | 7 + packages/vitnode/src/blocks/types.ts | 39 ++++ packages/vitnode/src/blocks/variant.ts | 5 + packages/vitnode/src/blocks/zone-meta.ts | 22 ++ packages/vitnode/src/blocks/zone.tsx | 32 +++ .../components/ai/use-available-ai-actions.ts | 6 + .../confirm-action-alert-dialog.tsx | 21 ++ .../src/components/confirm-action/content.tsx | 3 + .../vitnode/src/components/date-format.tsx | 11 + .../src/components/editor-provider.tsx | 4 + .../form/auto-form-sheet-footer.tsx | 28 +++ .../vitnode/src/components/form/auto-form.tsx | 123 +++++++++++ .../src/components/form/common/desc.tsx | 5 + .../src/components/form/common/label.tsx | 6 + .../src/components/form/fields/array.tsx | 12 ++ .../src/components/form/fields/cascader.tsx | 7 + .../src/components/form/fields/checkbox.tsx | 1 + .../src/components/form/fields/color.tsx | 6 + .../src/components/form/fields/combobox.tsx | 16 ++ .../components/form/fields/date-picker.tsx | 6 + .../src/components/form/fields/date-time.tsx | 14 +- .../src/components/form/fields/editor.tsx | 12 ++ .../src/components/form/fields/emoji-icon.tsx | 5 + .../components/form/fields/file-shared.tsx | 11 + .../form/fields/file-upload-queue.ts | 3 + .../src/components/form/fields/file.tsx | 13 ++ .../src/components/form/fields/files.tsx | 9 + .../src/components/form/fields/input-otp.tsx | 11 + .../components/form/fields/input-roles.tsx | 9 + .../components/form/fields/input-users.tsx | 7 + .../src/components/form/fields/input.tsx | 9 + .../fields/multi-lang-default-language.ts | 6 + .../form/fields/multi-lang-language.ts | 12 ++ .../form/fields/multi-lang-presence.ts | 5 + .../src/components/form/fields/multi-lang.tsx | 20 ++ .../form/fields/nullable-number.tsx | 7 + .../src/components/form/fields/number.tsx | 2 + .../components/form/fields/radio-group.tsx | 3 + .../src/components/form/fields/roles.ts | 4 + .../src/components/form/fields/select.tsx | 5 + .../src/components/form/fields/switch.tsx | 1 + .../src/components/form/fields/textarea.tsx | 4 + .../vitnode/src/components/logo-context.tsx | 1 + .../vitnode/src/components/logo-vitnode.tsx | 1 + packages/vitnode/src/components/pet/pet.tsx | 6 + .../rich-text/rich-text-content.tsx | 9 + .../src/components/role-format-content.tsx | 5 + .../components/staff-permission/provider.tsx | 16 ++ .../vitnode/src/components/table/content.tsx | 9 + .../components/table/data-table-content.tsx | 19 ++ .../src/components/table/expansion.tsx | 11 + .../vitnode/src/components/table/filters.tsx | 22 ++ .../src/components/table/navigation.tsx | 13 ++ .../src/components/table/reorder-handle.tsx | 2 + .../src/components/table/reorder-state.ts | 9 + .../vitnode/src/components/table/reorder.tsx | 2 + .../vitnode/src/components/table/row-order.ts | 13 ++ .../src/components/table/selection.tsx | 44 ++++ .../vitnode/src/components/table/url-state.ts | 12 ++ .../vitnode/src/components/ui/accordion.tsx | 14 ++ .../src/components/ui/alert-dialog.tsx | 28 +++ packages/vitnode/src/components/ui/alert.tsx | 12 ++ .../src/components/ui/aspect-ratio.tsx | 4 + .../vitnode/src/components/ui/attachment.tsx | 26 +++ packages/vitnode/src/components/ui/avatar.tsx | 16 ++ packages/vitnode/src/components/ui/badge.tsx | 8 + packages/vitnode/src/components/ui/bubble.tsx | 11 + .../src/components/ui/button-group.tsx | 10 + packages/vitnode/src/components/ui/button.tsx | 17 ++ .../vitnode/src/components/ui/calendar.tsx | 14 ++ packages/vitnode/src/components/ui/card.tsx | 10 + .../vitnode/src/components/ui/carousel.tsx | 24 +++ .../src/components/ui/cascader-utils.ts | 4 + .../vitnode/src/components/ui/cascader.tsx | 28 +++ .../vitnode/src/components/ui/chart-utils.ts | 6 + packages/vitnode/src/components/ui/chart.tsx | 22 ++ .../vitnode/src/components/ui/checkbox.tsx | 4 + .../src/components/ui/color-picker.tsx | 6 + .../src/components/ui/color-preset-picker.tsx | 4 + .../vitnode/src/components/ui/combobox.tsx | 13 ++ .../vitnode/src/components/ui/command.tsx | 16 ++ .../vitnode/src/components/ui/comparison.tsx | 13 ++ .../src/components/ui/context-menu.tsx | 9 + .../vitnode/src/components/ui/copy-button.tsx | 13 ++ .../vitnode/src/components/ui/counter.tsx | 6 + .../vitnode/src/components/ui/date-picker.tsx | 14 ++ .../src/components/ui/date-range-picker.tsx | 26 +++ packages/vitnode/src/components/ui/dialog.tsx | 23 ++ packages/vitnode/src/components/ui/drawer.tsx | 20 ++ .../src/components/ui/dropdown-menu.tsx | 16 ++ .../src/components/ui/dynamic-icon.tsx | 7 + .../src/components/ui/editor-content.tsx | 1 + packages/vitnode/src/components/ui/editor.tsx | 4 + .../src/components/ui/emoji-icon-picker.tsx | 6 + .../vitnode/src/components/ui/emoji-icon.tsx | 5 + .../src/components/ui/emoji-picker.tsx | 4 + packages/vitnode/src/components/ui/empty.tsx | 9 + packages/vitnode/src/components/ui/field.tsx | 25 +++ packages/vitnode/src/components/ui/form.tsx | 37 ++++ packages/vitnode/src/components/ui/frame.tsx | 13 ++ .../vitnode/src/components/ui/hover-card.tsx | 6 + .../vitnode/src/components/ui/icon-picker.tsx | 5 + .../vitnode/src/components/ui/image-zoom.tsx | 5 + .../vitnode/src/components/ui/input-group.tsx | 17 ++ .../vitnode/src/components/ui/input-otp.tsx | 12 ++ packages/vitnode/src/components/ui/input.tsx | 1 + packages/vitnode/src/components/ui/item.tsx | 18 ++ packages/vitnode/src/components/ui/kbd.tsx | 2 + packages/vitnode/src/components/ui/label.tsx | 1 + packages/vitnode/src/components/ui/marker.tsx | 9 + .../vitnode/src/components/ui/menubar.tsx | 12 ++ .../vitnode/src/components/ui/message.tsx | 11 + .../src/components/ui/number-field.tsx | 10 + .../vitnode/src/components/ui/page-title.tsx | 5 + .../vitnode/src/components/ui/pagination.tsx | 16 ++ .../vitnode/src/components/ui/popover.tsx | 8 + .../vitnode/src/components/ui/progress.tsx | 7 + .../vitnode/src/components/ui/radio-group.tsx | 2 + .../vitnode/src/components/ui/resizable.tsx | 6 + .../vitnode/src/components/ui/scroll-area.tsx | 4 + packages/vitnode/src/components/ui/select.tsx | 8 + .../vitnode/src/components/ui/separator.tsx | 1 + packages/vitnode/src/components/ui/sheet.tsx | 15 ++ .../vitnode/src/components/ui/skeleton.tsx | 3 + .../src/components/ui/sliding-number.tsx | 5 + packages/vitnode/src/components/ui/sonner.tsx | 9 + .../vitnode/src/components/ui/spinner.tsx | 5 + packages/vitnode/src/components/ui/switch.tsx | 4 + packages/vitnode/src/components/ui/tabs.tsx | 14 ++ .../vitnode/src/components/ui/textarea.tsx | 3 + .../src/components/ui/toggle-group.tsx | 10 + packages/vitnode/src/components/ui/toggle.tsx | 4 + .../vitnode/src/components/ui/tooltip.tsx | 22 ++ .../vitnode/src/components/user-format.tsx | 4 + .../vitnode/src/content/admin/registry.ts | 10 + packages/vitnode/src/content/cache.ts | 43 +++- packages/vitnode/src/content/conflicts.ts | 8 + packages/vitnode/src/content/const.ts | 1 + .../vitnode/src/content/containers/define.ts | 27 +++ .../content/containers/server/admin-routes.ts | 5 + .../containers/server/public-routes.ts | 4 + .../src/content/containers/server/service.ts | 13 ++ .../vitnode/src/content/containers/tree.ts | 6 + .../vitnode/src/content/containers/types.ts | 12 ++ packages/vitnode/src/content/define.ts | 115 +++++++++- packages/vitnode/src/content/delivery.ts | 35 +++ .../vitnode/src/content/editor/adapter.ts | 12 ++ packages/vitnode/src/content/editor/define.ts | 38 ++++ packages/vitnode/src/content/editor/types.ts | 26 +++ packages/vitnode/src/content/errors.ts | 5 + packages/vitnode/src/content/events.ts | 24 +++ packages/vitnode/src/content/fields.ts | 124 ++++++++++- packages/vitnode/src/content/hash.ts | 5 + packages/vitnode/src/content/ids.ts | 5 + packages/vitnode/src/content/localization.ts | 2 + packages/vitnode/src/content/publication.ts | 2 + packages/vitnode/src/content/revisions.ts | 12 ++ .../vitnode/src/content/rich-text/document.ts | 20 ++ .../vitnode/src/content/rich-text/html.ts | 5 + .../src/content/rich-text/plain-text.ts | 4 + packages/vitnode/src/content/schedules.ts | 6 + packages/vitnode/src/content/server/actor.ts | 5 + .../src/content/server/bind-content-plugin.ts | 25 +++ .../src/content/server/delivery-effects.ts | 13 ++ .../src/content/server/delivery-routes.ts | 5 + .../src/content/server/delivery-service.ts | 4 + .../src/content/server/duplicate-effects.ts | 7 + .../src/content/server/editorial-effects.ts | 21 ++ .../src/content/server/editorial-service.ts | 4 + packages/vitnode/src/content/server/emit.ts | 9 + .../server/localized-public-service.ts | 4 + .../src/content/server/localized-service.ts | 4 + packages/vitnode/src/content/server/model.ts | 50 +++++ packages/vitnode/src/content/server/module.ts | 8 + .../src/content/server/public-module.ts | 8 + .../src/content/server/public-routes.ts | 5 + .../src/content/server/public-service.ts | 38 ++++ .../src/content/server/public-write-routes.ts | 11 + .../content/server/public-write-service.ts | 13 ++ .../vitnode/src/content/server/publication.ts | 45 ++++ .../src/content/server/revalidate-bridge.ts | 14 ++ packages/vitnode/src/content/server/routes.ts | 5 +- .../src/content/server/search-indexer.ts | 15 ++ .../vitnode/src/content/server/search-sync.ts | 19 ++ .../vitnode/src/content/server/service.ts | 31 +++ packages/vitnode/src/content/server/table.ts | 28 +++ .../server/translation-editorial-service.ts | 4 + .../src/content/server/translation-effects.ts | 10 + .../src/content/server/translation-model.ts | 4 + .../src/content/server/translation-routes.ts | 4 + .../src/content/server/translation-table.ts | 8 + .../src/content/server/visibility-effects.ts | 13 ++ .../src/content/server/write-effects.ts | 4 + packages/vitnode/src/content/sitemap.ts | 5 + packages/vitnode/src/content/types.ts | 124 +++++++++++ packages/vitnode/src/content/visibility.ts | 2 + packages/vitnode/src/editor/adapter/memory.ts | 7 + .../vitnode/src/editor/adapter/refusal.ts | 2 + .../vitnode/src/editor/adapter/save-input.ts | 1 + packages/vitnode/src/editor/adapter/types.ts | 19 ++ .../vitnode/src/emails/default-template.tsx | 30 +++ packages/vitnode/src/emails/ui/button.tsx | 7 + packages/vitnode/src/emails/ui/card.tsx | 10 + .../src/framework/api-registry/generate.ts | 6 + .../src/framework/api-registry/types.ts | 1 + .../vitnode/src/framework/dev-error/hints.ts | 20 ++ .../src/framework/plugin-routes/compile.ts | 15 ++ .../vitnode/src/framework/vite/dev-error.ts | 5 + packages/vitnode/src/framework/vite/env.ts | 9 + .../src/framework/vite/optimize-deps.ts | 5 + .../src/framework/vite/plugin-routes.ts | 17 ++ .../src/framework/vite/prerender-routes.ts | 19 ++ .../src/framework/vite/ssr-externals.ts | 6 + .../src/framework/vite/tailwind-sources.ts | 7 + .../vitnode/src/framework/vite/vitnode.ts | 20 ++ .../vitnode/src/hooks/use-before-unload.ts | 7 + packages/vitnode/src/hooks/use-captcha.ts | 12 ++ .../src/hooks/use-intersection-observer.ts | 6 + .../vitnode/src/hooks/use-local-storage.ts | 7 + packages/vitnode/src/hooks/use-mobile.ts | 1 + .../src/hooks/use-sliding-indicator.ts | 13 ++ packages/vitnode/src/lib/ai/assist-client.ts | 18 ++ packages/vitnode/src/lib/ai/stream-client.ts | 16 ++ packages/vitnode/src/lib/config.ts | 29 +++ packages/vitnode/src/lib/emoji-icon.ts | 8 + packages/vitnode/src/lib/fetcher-client.ts | 15 ++ packages/vitnode/src/lib/fetcher/raw.ts | 16 ++ packages/vitnode/src/lib/fetcher/registry.ts | 4 + packages/vitnode/src/lib/fetcher/types.ts | 29 ++- packages/vitnode/src/lib/files/resolve-alt.ts | 15 ++ .../vitnode/src/lib/helpers/multi-lang.ts | 5 + packages/vitnode/src/lib/i18n/types.ts | 35 +++ packages/vitnode/src/lib/metadata.ts | 14 +- packages/vitnode/src/lib/navigation.ts | 22 ++ packages/vitnode/src/lib/plugin-manifest.ts | 33 +++ packages/vitnode/src/lib/plugin.ts | 203 +++++++++++++++++- packages/vitnode/src/lib/query-client.ts | 6 + packages/vitnode/src/page-cache/config.ts | 14 +- .../vitnode/src/page-cache/store.server.ts | 1 + packages/vitnode/src/routing/authoring.ts | 14 ++ packages/vitnode/src/routing/module.ts | 10 + packages/vitnode/src/routing/tree.ts | 64 ++++++ .../vitnode/src/tanstack/admin/breadcrumb.tsx | 13 ++ .../src/tanstack/admin/dashboard/route.tsx | 1 + .../src/tanstack/admin/dashboard/screen.tsx | 59 +++-- packages/vitnode/src/tanstack/admin/index.ts | 8 +- .../src/tanstack/admin/layout-route.tsx | 18 ++ packages/vitnode/src/tanstack/admin/nav.tsx | 26 ++- .../src/tanstack/admin/permissions.tsx | 15 ++ packages/vitnode/src/tanstack/admin/screen.ts | 8 + .../src/tanstack/admin/session-query.ts | 7 + packages/vitnode/src/tanstack/admin/shell.tsx | 5 +- packages/vitnode/src/tanstack/admin/state.ts | 1 + .../src/tanstack/auth/middleware-config.ts | 19 ++ .../src/tanstack/auth/session-query.ts | 30 +++ packages/vitnode/src/tanstack/auth/state.ts | 2 + .../tanstack/breadcrumb/main-breadcrumb.tsx | 5 + .../vitnode/src/tanstack/breadcrumb/model.ts | 37 ++++ .../src/tanstack/content/delivery-page.ts | 47 ++++ .../vitnode/src/tanstack/fetcher/index.ts | 46 ++++ .../vitnode/src/tanstack/fetcher/server.ts | 47 ++++ packages/vitnode/src/tanstack/i18n/locale.ts | 14 ++ .../vitnode/src/tanstack/i18n/messages.ts | 20 ++ .../src/tanstack/i18n/route-messages.tsx | 20 ++ packages/vitnode/src/tanstack/i18n/runtime.ts | 37 ++++ packages/vitnode/src/tanstack/icons/ssr.ts | 8 + .../src/tanstack/layout/document-head.tsx | 5 + .../src/tanstack/layout/document-scripts.tsx | 5 + .../src/tanstack/layout/error-actions.tsx | 1 + .../vitnode/src/tanstack/layout/header.tsx | 24 +++ .../src/tanstack/layout/main-header.tsx | 1 + .../vitnode/src/tanstack/layout/not-found.tsx | 2 + .../src/tanstack/layout/root-providers.tsx | 6 + .../src/tanstack/layout/route-error.tsx | 4 + .../vitnode/src/tanstack/link/href-link.tsx | 33 +++ .../src/tanstack/metadata/alternates.ts | 19 ++ .../vitnode/src/tanstack/metadata/index.ts | 33 ++- .../src/tanstack/moderation/report-button.tsx | 26 +++ .../src/tanstack/notifications/actions.ts | 7 + .../src/tanstack/notifications/bell.tsx | 1 + .../vitnode/src/tanstack/page-cache/server.ts | 12 +- .../pending/route-pending-skeleton.tsx | 12 ++ .../vitnode/src/tanstack/pending/shapes.tsx | 4 + .../src/tanstack/plugin-routes/authoring.ts | 28 +++ .../src/tanstack/plugin-routes/mount.tsx | 24 +++ .../src/tanstack/plugin-routes/specs.ts | 8 + .../tanstack/realtime/realtime-listeners.tsx | 5 + .../vitnode/src/tanstack/search/sources.ts | 27 +++ .../src/tanstack/search/use-record-view.ts | 13 ++ .../src/tanstack/start/create-start.ts | 24 +++ .../src/tanstack/view-transitions/index.ts | 10 + .../src/tanstack/widgets/page-widgets.tsx | 25 +++ .../admin/layouts/sidebar/nav/nav-model.tsx | 19 +- .../admin/views/content/form/context.tsx | 25 +++ .../views/content/form/layout-primitives.tsx | 9 + .../admin/views/content/form/primitives.tsx | 13 ++ .../content/form/translation-freshness.ts | 18 ++ .../views/admin/views/content/form/values.ts | 2 + .../admin/views/content/live/presence.tsx | 7 + .../views/admin/views/content/live/status.tsx | 6 + .../views/core/users/list/users-query.ts | 6 + .../views/core/users/roles/roles-query.ts | 7 + packages/vitnode/src/views/auth/sso/icons.ts | 7 + .../views/layouts/theme/layout-content.tsx | 20 +- packages/vitnode/src/vitnode.config.ts | 191 ++++++++++++++++ packages/vitnode/src/ws/handle.ts | 10 + packages/vitnode/src/ws/notifications.ts | 8 + packages/vitnode/src/ws/provider.tsx | 8 + packages/vitnode/src/ws/registry.ts | 30 +++ packages/vitnode/src/ws/types.ts | 6 + packages/vitnode/src/ws/use-websocket.ts | 18 ++ plugins/blog/src/admin/content.tsx | 8 + plugins/blog/src/admin/nav.tsx | 4 + plugins/blog/src/api/builders.ts | 5 + plugins/blog/src/api/lib/events.ts | 33 ++- plugins/blog/src/config.api.ts | 32 +++ plugins/blog/src/config.tsx | 22 ++ plugins/blog/src/content.ts | 6 + plugins/blog/src/content/category.ts | 11 + plugins/blog/src/content/post.ts | 18 ++ plugins/blog/src/database/categories.ts | 5 + plugins/blog/src/database/posts.ts | 10 + plugins/blog/src/pages/post-query.ts | 27 +++ plugins/blog/src/plugin-info.ts | 4 + plugins/blog/src/routes.ts | 5 + 388 files changed, 6795 insertions(+), 145 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index d762a0d79c..d22e3fa454 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -38,7 +38,7 @@ import { Activity } from "react"; - `fetcher` from `@vitnode/core/tanstack/fetcher` is universal - one call, SSR and browser. Never hand-write `createIsomorphicFn().server(...).client(...)` for a fetch. - A call names the plugin, never an API module: `fetcher({ plugin: "@vitnode/core", method: "get", module: "users", path: "/devices" })`. `plugin`, `module` (any nesting depth, `admin/advanced/cron`), `path`, `method`, `args` and the response are all inferred from the plugin API registry; an invalid combination is a compile error at the offending property. -- The registry is `ApiPluginRegistry` in `@vitnode/core/lib/fetcher/registry`. Core registers itself; an app's `src/api-registry.gen.ts` registers every configured plugin that exports `config.api`, with type-only imports; a plugin registers its own API in its `global.d.ts` so its pages can call it. Never import a plugin API factory as a value outside `vitnode.api.config.ts`. +- The registry is `ApiPluginRegistry` in `@vitnode/core/lib/fetcher/registry`. Core registers itself; an app's `src/api-registry.gen.ts` registers every configured plugin that exports `config.api`, with type-only imports; `vitnode build`/`vitnode dev` write a plugin's own entry to its `types/api-registry.gen.d.ts` (kept out of the published package) so its pages can call it. Never import a plugin API factory as a value outside `vitnode.api.config.ts`. - `@vitnode/core/tanstack/fetcher/server` is for work that is genuinely server-only: server functions, `allowSaveCookies` cookie relay, cron/jobs, upstream secrets or a different `origin`. Same call shape, more options. - Shared `views/*` query modules call `fetcher` directly - no injected transport, no browser-only twin. `@vitnode/core/lib/fetcher-client` is the framework-neutral browser primitive the universal fetcher is built on, for code that never renders on a server. - Write the route inline at the call site - never build a request object elsewhere and pass it in. @@ -81,6 +81,11 @@ import { Activity } from "react"; - Document every new feature. Keep it simple, SEO-friendly, and understandable at any skill level. - Friendly and lightly funny tone - don't overdo it. - Skip big comments; code is self-documenting. +- Developer-facing APIs in feature code (exports of `@vitnode/core` and plugins that app or plugin authors call) need concise English JSDoc on the original declaration: + - Say what it is for, plus constraints, side effects, runtime (server-only, browser-only or universal) and `@throws` only when they are real and non-obvious. + - Document configuration properties one by one, including non-obvious defaults and constraints. + - Give major entry points a minimal `@example` with real imports. + - A behavior change updates the JSDoc in the same change. Keep tutorials in the MDX docs. - Request images with a comment: `// Image prompt: {here_prompt_to_generate_image}` - Put install commands in tabbed code blocks with correct syntax highlighting: diff --git a/apps/web/content/docs/dev/captcha/index.mdx b/apps/web/content/docs/dev/captcha/index.mdx index 45b0c78187..f1863c9565 100644 --- a/apps/web/content/docs/dev/captcha/index.mdx +++ b/apps/web/content/docs/dev/captcha/index.mdx @@ -48,8 +48,8 @@ Enable captcha verification on any custom Hono endpoint with `withCaptcha: true` import { buildRoute } from "@/api/builders" export const createCommentRoute = buildRoute({ - withCaptcha: true, // [!code ++] route: { + withCaptcha: true, // [!code ++] method: "post", path: "/", responses: { 201: { description: "Comment created" } }, @@ -64,36 +64,47 @@ export const createCommentRoute = buildRoute({ ### 3. Render the Frontend Widget -Include `` in your form and supply the received token to the fetcher: +Pass the app's captcha config to `AutoForm`. It loads the widget, keeps the submit button disabled until the captcha is ready, and hands `onSubmit` a fresh token to forward as the fetcher's `captchaToken`: ```tsx title="plugins/blog/src/views/comment-form.tsx" -import { Captcha } from "@vitnode/core/components/captcha" +import { AutoForm } from "@vitnode/core/components/form/auto-form" +import { AutoFormTextarea } from "@vitnode/core/components/form/fields/textarea" +import { useMiddlewareConfigQuery } from "@vitnode/core/tanstack/auth" import { fetcher } from "@vitnode/core/tanstack/fetcher" +import { z } from "zod" + +const formSchema = z.object({ text: z.string().min(1) }) export const CommentForm = () => { - const [captchaToken, setCaptchaToken] = React.useState() - - const handleSubmit = async () => { - await fetcher({ - plugin: "@acme/blog", - method: "post", - module: "comments", - path: "/", - captchaToken, // [!code ++] - args: { body: { text: "Nice article!" } }, - }) - } + const { data: config } = useMiddlewareConfigQuery() return ( -
-