mirror of
https://github.com/vercel-labs/json-render.git
synced 2026-09-14 13:41:32 +08:00
c1b1aaaddb
* add rate limits
* fix lint
* better
generate prompt
update examples
* fixes
* fixes
* new api
* update docs
* fixes
* fixes
* generated prompt
* Add tests for catalog validation and prompt generation
- Test generateSystemPrompt with components, actions, custom rules
- Test new defineCatalog API from schema system
- Test catalog.prompt() method with custom rules
- Test catalog.validate() for valid and invalid specs
- Test catalog.zodSchema() for custom validation
- Test catalog.jsonSchema() for structured outputs
- Add tests for nested specs with children
- Add tests for rejecting invalid component types
* Fix lint: pass children as nested elements in renderer
Change from children={...} prop to nested children pattern
to satisfy react/no-children-prop rule.
* Fix lint errors in dashboard and web apps
- Disable react/prop-types in both eslint configs (TypeScript handles this)
- Allow styled-jsx 'jsx' property in dashboard
- Add DATABASE_URL to turbo env allowlist
- Remove unused drizzle-orm imports (and, sql)
- Suppress unused variable warnings where intentional
* Add server entry point for @json-render/remotion
The main package entry includes React components that require
client-side context (React.createContext). This causes build
failures when importing in server-side API routes.
Added `@json-render/remotion/server` entry point that exports
only schema and catalog definitions without React dependencies:
- schema, RemotionSchema, RemotionSpec
- standardComponentDefinitions, standardTransitionDefinitions
- standardEffectDefinitions
- Type exports for catalogs
Updated remotion example to import from /server in catalog.ts
* Make dashboard database connection lazy-initialized
The database connection threw an error at module load time if
DATABASE_URL was not set, causing builds to fail in CI where
the database is not available.
Changed to lazy initialization using a Proxy so the error only
occurs when the database is actually used at runtime, not at
build time.
* Fix previousSpec property name and lazy rate limiting
- Fix property name mismatch: playground now passes previousSpec
instead of previousTree to match what useUIStream hook expects
- Make rate limiting lazy-initialized to avoid runtime errors when
Redis env vars (KV_REST_API_URL, KV_REST_API_TOKEN) are not set
- Rate limiting gracefully becomes a no-op when Redis is unavailable
171 lines
4.6 KiB
TypeScript
171 lines
4.6 KiB
TypeScript
import { codeToHtml } from "shiki";
|
|
import { CopyButton } from "./copy-button";
|
|
import { ExpandableCode } from "./expandable-code";
|
|
|
|
const vercelDarkTheme = {
|
|
name: "vercel-dark",
|
|
type: "dark" as const,
|
|
colors: {
|
|
"editor.background": "transparent",
|
|
"editor.foreground": "#EDEDED",
|
|
},
|
|
settings: [
|
|
{
|
|
scope: ["comment", "punctuation.definition.comment"],
|
|
settings: { foreground: "#666666" },
|
|
},
|
|
{
|
|
scope: ["string", "string.quoted", "string.template"],
|
|
settings: { foreground: "#50E3C2" },
|
|
},
|
|
{
|
|
scope: [
|
|
"constant.numeric",
|
|
"constant.language.boolean",
|
|
"constant.language.null",
|
|
],
|
|
settings: { foreground: "#50E3C2" },
|
|
},
|
|
{
|
|
scope: ["keyword", "storage.type", "storage.modifier"],
|
|
settings: { foreground: "#FF0080" },
|
|
},
|
|
{
|
|
scope: ["keyword.operator", "keyword.control"],
|
|
settings: { foreground: "#FF0080" },
|
|
},
|
|
{
|
|
scope: ["entity.name.function", "support.function", "meta.function-call"],
|
|
settings: { foreground: "#7928CA" },
|
|
},
|
|
{
|
|
scope: ["variable", "variable.other", "variable.parameter"],
|
|
settings: { foreground: "#EDEDED" },
|
|
},
|
|
{
|
|
scope: ["entity.name.tag", "support.class.component", "entity.name.type"],
|
|
settings: { foreground: "#FF0080" },
|
|
},
|
|
{
|
|
scope: ["punctuation", "meta.brace", "meta.bracket"],
|
|
settings: { foreground: "#888888" },
|
|
},
|
|
{
|
|
scope: [
|
|
"support.type.property-name",
|
|
"entity.name.tag.json",
|
|
"meta.object-literal.key",
|
|
],
|
|
settings: { foreground: "#EDEDED" },
|
|
},
|
|
{
|
|
scope: ["entity.other.attribute-name"],
|
|
settings: { foreground: "#50E3C2" },
|
|
},
|
|
{
|
|
scope: ["support.type.primitive", "entity.name.type.primitive"],
|
|
settings: { foreground: "#50E3C2" },
|
|
},
|
|
],
|
|
};
|
|
|
|
const vercelLightTheme = {
|
|
name: "vercel-light",
|
|
type: "light" as const,
|
|
colors: {
|
|
"editor.background": "transparent",
|
|
"editor.foreground": "#171717",
|
|
},
|
|
settings: [
|
|
{
|
|
scope: ["comment", "punctuation.definition.comment"],
|
|
settings: { foreground: "#6b7280" },
|
|
},
|
|
{
|
|
scope: ["string", "string.quoted", "string.template"],
|
|
settings: { foreground: "#067a6e" },
|
|
},
|
|
{
|
|
scope: [
|
|
"constant.numeric",
|
|
"constant.language.boolean",
|
|
"constant.language.null",
|
|
],
|
|
settings: { foreground: "#067a6e" },
|
|
},
|
|
{
|
|
scope: ["keyword", "storage.type", "storage.modifier"],
|
|
settings: { foreground: "#d6409f" },
|
|
},
|
|
{
|
|
scope: ["keyword.operator", "keyword.control"],
|
|
settings: { foreground: "#d6409f" },
|
|
},
|
|
{
|
|
scope: ["entity.name.function", "support.function", "meta.function-call"],
|
|
settings: { foreground: "#6e56cf" },
|
|
},
|
|
{
|
|
scope: ["variable", "variable.other", "variable.parameter"],
|
|
settings: { foreground: "#171717" },
|
|
},
|
|
{
|
|
scope: ["entity.name.tag", "support.class.component", "entity.name.type"],
|
|
settings: { foreground: "#d6409f" },
|
|
},
|
|
{
|
|
scope: ["punctuation", "meta.brace", "meta.bracket"],
|
|
settings: { foreground: "#6b7280" },
|
|
},
|
|
{
|
|
scope: [
|
|
"support.type.property-name",
|
|
"entity.name.tag.json",
|
|
"meta.object-literal.key",
|
|
],
|
|
settings: { foreground: "#171717" },
|
|
},
|
|
{
|
|
scope: ["entity.other.attribute-name"],
|
|
settings: { foreground: "#067a6e" },
|
|
},
|
|
{
|
|
scope: ["support.type.primitive", "entity.name.type.primitive"],
|
|
settings: { foreground: "#067a6e" },
|
|
},
|
|
],
|
|
};
|
|
|
|
interface CodeProps {
|
|
children: string;
|
|
lang?: "json" | "tsx" | "typescript" | "bash" | "javascript";
|
|
}
|
|
|
|
export async function Code({ children, lang = "typescript" }: CodeProps) {
|
|
const html = await codeToHtml(children.trim(), {
|
|
lang,
|
|
themes: {
|
|
light: vercelLightTheme,
|
|
dark: vercelDarkTheme,
|
|
},
|
|
defaultColor: false,
|
|
});
|
|
|
|
return (
|
|
<div className="group relative my-6 rounded-lg border border-border bg-neutral-100 dark:bg-[#0a0a0a] text-sm font-mono overflow-hidden max-w-full">
|
|
<div className="absolute top-3 right-3 z-10">
|
|
<CopyButton
|
|
text={children.trim()}
|
|
className="opacity-0 group-hover:opacity-100 text-neutral-500 dark:text-neutral-400 bg-neutral-100 dark:bg-[#0a0a0a]"
|
|
/>
|
|
</div>
|
|
<ExpandableCode>
|
|
<div
|
|
className="overflow-x-auto [&_pre]:bg-transparent! [&_pre]:m-0! [&_pre]:p-4! [&_code]:bg-transparent! [&_.shiki]:bg-transparent!"
|
|
dangerouslySetInnerHTML={{ __html: html }}
|
|
/>
|
|
</ExpandableCode>
|
|
</div>
|
|
);
|
|
}
|