Open
Conversation
68594ae to
29c347d
Compare
29c347d to
a797684
Compare
chore: fixup chore: fixup chore: fixup chore: fixup chore: fixup chore: fixup chore: fixup
a797684 to
80ec1d2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add a
clientConfig()method to the Plugin base class so plugins can expose server-side boot-time configuration to the frontend without dedicated API endpoints, with automatic redaction of leaked environment variables.Main changes
Plugin
clientConfig()API (packages/appkit/src/plugin/plugin.ts,packages/shared/src/plugin.ts):Adds
clientConfig()to thePluginbase class andBasePlugininterface. Plugins override this method to return JSON-serializable data that gets injected into the HTML at server startup. The method is excluded from theasUser()proxy since it runs once at boot, not per-request.FilesPluginadopts it immediately to expose its volumes list.Env var redaction & config validation (
packages/appkit/src/plugins/server/utils.ts):Introduces
sanitizeClientConfig()which validates the return value (rejects BigInts, functions, circular refs,__proto__keys) and then scans all string values for matches against non-publicprocess.envvalues. Matches are replaced with[redacted by appkit]and a warning is logged. Values fromPUBLIC_APPKIT_-prefixed env vars are allowed through, with range-based overlap resolution to handle substring relationships between public and non-public values.Server-side config delivery pipeline (
packages/appkit/src/plugins/server/index.ts,base-server.ts,static-server.ts,vite-dev-server.ts):Replaces
window.__CONFIG__ = ...with an inert<script id="__appkit__" type="application/json">tag containing XSS-escaped JSON, parsed by a companion<script>. TheextendRoutes()method collects and sanitizes each plugin'sclientConfig(), then threads the result throughBaseServer→StaticServer/ViteDevServer→getConfigScript().Client-side config reader (
packages/appkit-ui/src/js/config.ts,packages/appkit-ui/src/react/hooks/use-plugin-config.ts):Provides
getClientConfig()which reads from the boot-time<script>payload, caches in a module-scoped variable (immune towindow.__appkit__mutations), and normalizes partial data.getPluginClientConfig()returns a specific plugin's config with a frozen empty-object fallback for referential stability. TheusePluginClientConfigReact hook wraps this withuseMemo.Supporting infrastructure
packages/appkit-ui/src/js/config.test.ts— 7 tests covering DOM parsing, malformed JSON, caching, partial data, empty content, and stable references.packages/appkit-ui/src/react/hooks/__tests__/use-plugin-config.test.ts— 3 tests for the React hook (typed config, unknown plugin, referential stability).packages/appkit/src/plugins/server/tests/utils.test.ts— 28 new tests forgetRuntimeConfig,getConfigScript, andsanitizeClientConfig(redaction, overlap resolution, embedded values, keys, validation errors).packages/appkit/src/plugins/server/tests/server.test.ts— 3 new tests forextendRoutescollectingclientConfig, handling null returns, and rejecting invalid values.packages/shared/src/plugin.ts— NewPluginClientConfigstype alias.docs/docs/api/appkit/Class.Plugin.md— API reference forclientConfig().Other changes
apps/dev-playground/package.json— AddedNODE_ENV=developmenttodev:inspectscript for consistency withdev.apps/dev-playground/client/src/routes/files.route.tsx— Replacedfetch("/api/files/volumes")+useStatewithusePluginClientConfig("files").packages/appkit/src/plugins/server/remote-tunnel/remote-tunnel-manager.test.ts— Updated assertion fromwindow.__CONFIG__towindow.__appkit__.packages/appkit/src/plugins/server/tests/static-server.test.ts— Updated mocks and assertions to match the new config script format.docs/static/appkit-ui/styles.gen.css— Auto-generated CSS additions (grid utilities, inactive state).How it looks like
if a plugin tries to expose a secret