feat(plugin): Add API support and enhance plugin registration process - #809
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8933ac9849
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const key = /\bplugins\s*:\s*\[/g; | ||
| key.lastIndex = from; | ||
|
|
||
| const match = key.exec(source); |
There was a problem hiding this comment.
Constrain the plugin-array search to the config object
When a config contains a commented-out plugins: [] or a nested property with that name before the real top-level array, this regex selects the first textual occurrence after buildConfig(. The generator then edits the comment or nested array and leaves vitNodeConfig.plugins unchanged, so it reports successful registration even though the plugin is not enabled; the search needs to ignore comments and identify the top-level property of the builder argument.
Useful? React with 👍 / 👎.
| const comma = entries.endsWith(",") ? "" : ","; | ||
|
|
||
| return `${head}${entries}${comma}\n${indent}${call},${trailing}${tail}`; |
There was a problem hiding this comment.
Insert the comma before a trailing line comment
When the existing multiline array ends with a valid untrailed entry such as blogPlugin() // keep this, entries.endsWith(",") is false and the generated comma is appended after the comment marker. That comma is ignored, leaving the new factory call adjacent to the previous element without a separator and making the generated config syntactically invalid.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8890e8dc51
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const unusable = registrations.filter( | ||
| ({ status }) => status === "no-plugins-array", | ||
| ); |
There was a problem hiding this comment.
Report configs whose builder call is not recognized
When a discovered config formats or aliases its builder so that registerPluginInSource returns no-config-call—for example, buildConfig /* comment */ ({ ... })—this filter excludes it from unusable. If another config is registered successfully, the fallback warning is also suppressed, so the CLI finishes without telling the user that this app was left unregistered. Treat no-config-call as an unusable config and print a per-file manual-registration warning.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bd37f688f0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| export type AnyFormFieldApi = FormFieldApi<any>; |
There was a problem hiding this comment.
Remove the
any escape hatch from form fields
Because AnyFormFieldApi is passed through both FormField and ItemAutoFormComponentProps, defining it as FormFieldApi<any> collapses field.value and the accepted onChange values to any across every AutoForm control. This allows a custom control expecting one value shape to be connected to an incompatible field without a diagnostic, defeating the type-safe generic introduced here; keep the erased boundary type-safe instead of suppressing the lint rule.
AGENTS.md reference: AGENTS.md:L11-L13
Useful? React with 👍 / 👎.
| const called = new RegExp(`\\b${factory}\\s*\\(`); | ||
| const hasEntry = called.test(source.slice(range.open + 1, range.close)); |
There was a problem hiding this comment.
Ignore commented calls when checking registration
When the target array contains a disabled entry such as // siteNotesPlugin(), this regex treats the comment as a real call. registerPluginInSource then adds only the import—or returns already-registered if the import remains—without inserting an active array element, so the CLI reports registration while the plugin stays disabled. The entry check needs to skip comments and identify an actual top-level call in the array.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e175bb2428
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| spinner.text = "Registering the plugin with the apps that can serve it..."; | ||
| const registrations = await addPluginToConfig({ |
There was a problem hiding this comment.
Update existing workspaces before registering plugins
When the latest CLI adds a plugin to a workspace generated before this commit, this call writes imports whose package exports resolve only through the new plugin's dist, but only the new app template receives the build:plugins task and root sequencing. The plugin is not built here, so an older root dev runs db:prepare, loads the newly edited API config, and fails to resolve the plugin before its watcher can start; production builds have the same missing-output problem. Patch or validate the existing workspace pipeline as part of plugin creation, or build the plugin before activating these imports.
Useful? React with 👍 / 👎.
| if (!body.includes("\n")) { | ||
| const separator = body.trimEnd().endsWith(",") ? " " : ", "; | ||
|
|
||
| return `${head}${body}${separator}${call}${tail}`; |
There was a problem hiding this comment.
Treat inline comment-only arrays as empty
When a valid placeholder is written as plugins: [/* add plugins here */], this branch treats the comment as an existing entry and emits plugins: [/* add plugins here */, newPlugin()]. That leading comma creates an elided undefined array element, violating the typed plugin array and potentially reaching consumers that dereference each plugin; detect whether the body contains actual code before choosing this separator.
Useful? React with 👍 / 👎.
| } catch { | ||
| continue; |
There was a problem hiding this comment.
Report config I/O failures instead of swallowing them
If one discovered config cannot be read or written—for example, a read-only API config while the web config remains writable—this catch omits it from registrations. Because another file can still have status registered, reportConfigRegistrations then suppresses the fallback warning and reports only success, leaving one half of the plugin silently disabled. Preserve a per-file failure status or propagate the error so the CLI can request manual registration.
Useful? React with 👍 / 👎.
… generate package messages source
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 348545b997
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| <Field | ||
| className="@md/field-group:items-end" | ||
| key={index} | ||
| key={rowKey} |
There was a problem hiding this comment.
Preserve nested controls when a row moves
When an earlier row is removed while a later control holds state that is not yet represented in the form store—such as AutoFormNumber's transient invalid text or an upload queue—the stable outer key does not preserve that control. The nested FormField is still keyed by fullFieldName, which changes from (for example) amounts[2].value to amounts[1].value, so React unmounts it and discards its local state. The added test misses this because it enters valid numbers that can be restored from the form store; the nested field also needs an identity that remains stable when its row moves.
Useful? React with 👍 / 👎.
| const packageMessages = resolvePackageMessagesModules( | ||
| plugins, | ||
| relative(appRoot, paths.config), | ||
| ); |
There was a problem hiding this comment.
Watch plugin configs for locale manifest changes
When vitnode dev is already running and a plugin adds or removes a localeFiles entry, its watcher rebuilds the plugin's dist/src/config.js, but this generation pass only watches the app config plus route, admin-nav, and content module files. Because the resolved plugin config module that supplied plugins is never added to the watched set, that rebuild does not request regeneration and package-messages.gen.ts remains stale until the app config is touched or the dev server is restarted. Resolve and watch each configured plugin's config module alongside the other projection inputs.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5b821559c6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| pl: { | ||
| '@vitnode/blog': async () => await import('./@vitnode/blog/pl.json'), | ||
| '@vitnode/core': async () => await import('./@vitnode/core/pl.json'), |
There was a problem hiding this comment.
Register the moved Polish messages in the standalone API
In the split deployment, apps/api/src/i18n.ts still enables pl while leaving messages empty, and this commit removes the Polish loader from core's API locale barrel. The replacement loader added here is imported only by apps/web/src/vitnode.api.config.ts, so requests and emails served by the standalone apps/api process now fall back to English for Polish users; register these moved messages in that API config as well.
Useful? React with 👍 / 👎.
| export const pluginApiClientTemplate = (): string => | ||
| `import type { ApiClient } from "@vitnode/core/tanstack/fetcher"; | ||
|
|
||
| import { createApiClient } from "@vitnode/core/tanstack/fetcher"; |
There was a problem hiding this comment.
Generate direct universal fetcher calls
Replace this scaffolded ApiClient wrapper with a lightweight clientModule<typeof helloModule>(CONFIG_PLUGIN.pluginId) reference and call the universal fetcher inline in the loader. As written, every generated plugin starts with the legacy stored-client abstraction and an explicitly annotated API value, contrary to the repository's required transport pattern and inference boundary.
AGENTS.md reference: AGENTS.md:L35-L40
Useful? React with 👍 / 👎.
…tion check feat(router): ✨ add support for blank routes in the router configuration feat(helpers): ✨ introduce `runPackageScript` to manage package scripts execution feat(plugin): ✨ implement plugin build and restart logic for development servers test(restart-dev-servers): 🧪 add comprehensive tests for dev server restart functionality feat(breadcrumb): ✨ introduce deferred breadcrumbs for dynamic route handling feat(plugin-routes): ✨ enhance plugin route handling with blank area support feat(example-plugin): ✨ add example plugin routes and embed page for demonstration
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9a1b672459
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| import { pageHead } from '@vitnode/core/tanstack/metadata' | ||
| import { Suspense } from 'react' | ||
|
|
||
| import { DocsError, DocsNotFound } from '@/docs/error-views' |
There was a problem hiding this comment.
Keep error screens out of the route topology
Move the newly added error and not-found presentation behind the TanStack adapter rather than importing app views into this route. The repository requires route files to contain topology only and keeps screens in @vitnode/core/tanstack/*; directly wiring DocsError and DocsNotFound here extends the existing coupling and makes future error-screen changes require editing the route definition itself.
AGENTS.md reference: AGENTS.md:L27-L27
Useful? React with 👍 / 👎.
| "icon": "Plug", | ||
| "defaultOpen": true, | ||
| "pages": ["create", "routes", "api", "admin", "breadcrumbs", "..."] | ||
| "pages": ["create", "routes", "breadcrumbs", "api", "admin", "..."] |
There was a problem hiding this comment.
Point the plugin sidebar at the moved routing pages
After this commit deletes dev/plugins/routes.mdx and dev/plugins/breadcrumbs.mdx, these two sidebar entries still resolve to /docs/dev/plugins/routes and /docs/dev/plugins/breadcrumbs, so selecting either one reaches the not-found screen. Their replacements now live at dev/routing/routes.mdx and dev/routing/breadcrumbs.mdx; update the navigation and remaining inbound links, or retain redirects for the old URLs.
Useful? React with 👍 / 👎.
| "pages": [ | ||
| "routes", | ||
| "navigation", | ||
| "metadata", |
There was a problem hiding this comment.
Remove or restore the missing metadata page
When the Routing sidebar is rendered, this entry advertises dev/routing/metadata.mdx, but that file is deleted in the same commit and no replacement exists at that slug. Clicking Metadata therefore leads to a 404; either restore the page, point this entry to the section that absorbed its content, or add a redirect.
Useful? React with 👍 / 👎.
Improving Documentation
pnpm lint:fixto fix formatting issues before opening the PR.Description
What?
Why?